diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-02-24 11:40:28 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-02-24 11:40:28 +1100 |
commit | 3a1b4c00eb96634229fb730e9b38e8df5180756a (patch) | |
tree | 2642c03cc4f0f8e52d4718b93facfe411a52d9ab /source4 | |
parent | b9860043dc092df25d4a39074e106d7367ebbe8f (diff) | |
parent | faa1100d229aef56da5d48f5c19ec901e520f8ef (diff) | |
download | samba-3a1b4c00eb96634229fb730e9b38e8df5180756a.tar.gz samba-3a1b4c00eb96634229fb730e9b38e8df5180756a.tar.bz2 samba-3a1b4c00eb96634229fb730e9b38e8df5180756a.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source4')
30 files changed, 117 insertions, 97 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 01f5188b6f..583d1dcf04 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -89,7 +89,7 @@ ldb_samldb_OBJ_FILES = \ [MODULE::ldb_samba3sam] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(samba3sam) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SMBPASSWD \ +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB SMBPASSWD \ NSS_WRAPPER LIBSECURITY NDR_SECURITY # End MODULE ldb_samldb ################################################ @@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \ [MODULE::ldb_simple_ldap_map] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB LIBNDR ENABLE = YES ALIASES = entryuuid nsuniqueid # End MODULE ldb_entryuuid diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 2365a58f78..4e28c8a149 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -30,6 +30,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" struct la_op_store { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 0261bb32e9..898d913965 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -35,6 +35,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/dsdb/samdb/ldb_modules/ranged_results.c b/source4/dsdb/samdb/ldb_modules/ranged_results.c index 8f36baa7d6..5ce69a26a2 100644 --- a/source4/dsdb/samdb/ldb_modules/ranged_results.c +++ b/source4/dsdb/samdb/ldb_modules/ranged_results.c @@ -29,6 +29,7 @@ * Author: Andrew Bartlett */ +#include "includes.h" #include "ldb_module.h" struct rr_context { diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c index 3f10748085..59cb9de717 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sam.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c @@ -6,7 +6,7 @@ */ #include "includes.h" -#include "ldb/include/ldb_module.h" +#include "ldb_module.h" #include "ldb/ldb_map/ldb_map.h" #include "system/passwd.h" diff --git a/source4/dsdb/samdb/ldb_modules/update_keytab.c b/source4/dsdb/samdb/ldb_modules/update_keytab.c index 8920afee71..f1b6863cdb 100644 --- a/source4/dsdb/samdb/ldb_modules/update_keytab.c +++ b/source4/dsdb/samdb/ldb_modules/update_keytab.c @@ -29,6 +29,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" #include "system/kerberos.h" diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index d6b3e40e1a..6abd8a8f88 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb/include/ldb_module.h" #include "param/param.h" diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in index 7f00e8ebee..663dea9f80 100644 --- a/source4/lib/ldb/Makefile.in +++ b/source4/lib/ldb/Makefile.in @@ -67,7 +67,7 @@ MDLD_FLAGS = @MDLD_FLAGS@ OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TEVENT_OBJ) $(TALLOC_OBJ) $(POPT_OBJ) $(LDB_MAP_OBJ) @LIBREPLACEOBJ@ $(EXTRA_OBJ) -headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_includes.h $(srcdir)/include/ldb_module.h +headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_module.h BINS = bin/ldbadd bin/ldbsearch bin/ldbdel bin/ldbmodify bin/ldbedit bin/ldbrename bin/ldbtest diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 2fb5a8f9be..f1b28b6819 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -34,6 +34,19 @@ #include "ldb_private.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]", + ldb); + } + + return 0; +} + /* initialise a ldb context The mem_ctx is required @@ -65,6 +78,8 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) /* 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; } @@ -242,10 +257,24 @@ void ldb_reset_err_string(struct ldb_context *ldb) /* start a transaction */ -static int ldb_transaction_start_internal(struct ldb_context *ldb) +int ldb_transaction_start(struct ldb_context *ldb) { struct ldb_module *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++; + FIRST_OP(ldb, start_transaction); ldb_reset_err_string(ldb); @@ -266,10 +295,29 @@ static int ldb_transaction_start_internal(struct ldb_context *ldb) /* commit a transaction */ -static int ldb_transaction_commit_internal(struct ldb_context *ldb) +int ldb_transaction_commit(struct ldb_context *ldb) { struct ldb_module *module; int 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; + } + FIRST_OP(ldb, end_transaction); ldb_reset_err_string(ldb); @@ -290,10 +338,29 @@ static int ldb_transaction_commit_internal(struct ldb_context *ldb) /* cancel a transaction */ -static int ldb_transaction_cancel_internal(struct ldb_context *ldb) +int ldb_transaction_cancel(struct ldb_context *ldb) { struct ldb_module *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, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, del_transaction); status = module->ops->del_transaction(module); @@ -309,66 +376,13 @@ static int ldb_transaction_cancel_internal(struct ldb_context *ldb) return status; } -int ldb_transaction_start(struct ldb_context *ldb) -{ - /* disable autotransactions */ - ldb->transaction_active++; - - return ldb_transaction_start_internal(ldb); -} - -int ldb_transaction_commit(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_commit_internal(ldb); -} - -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_cancel_internal(ldb); -} - -static int ldb_autotransaction_start(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_start_internal(ldb); -} - -static int ldb_autotransaction_commit(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_commit_internal(ldb); -} - -static int ldb_autotransaction_cancel(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_cancel_internal(ldb); -} - /* autostarts a transacion if none active */ static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req) { int ret; - ret = ldb_autotransaction_start(ldb); + ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return ret; } @@ -379,9 +393,9 @@ static int ldb_autotransaction_request(struct ldb_context *ldb, } if (ret == LDB_SUCCESS) { - return ldb_autotransaction_commit(ldb); + return ldb_transaction_commit(ldb); } - ldb_autotransaction_cancel(ldb); + ldb_transaction_cancel(ldb); if (ldb->err_string == NULL) { /* no error string was setup by the backend */ diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 99a47767e1..ae97ef4cce 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -32,10 +32,7 @@ */ #include "ldb_private.h" - -#if (_SAMBA_BUILD_ >= 4) -#include "includes.h" -#endif +#include "dlinklist.h" #define LDB_MODULE_PREFIX "modules:" #define LDB_MODULE_PREFIX_LEN 8 diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 6990397a74..eb8e0ed11e 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -46,7 +46,19 @@ #define _LDB_H_ 1 /*! \endcond */ -#include "ldb_includes.h" +#ifndef bool +typedef int bool; +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + +#include "talloc.h" +#include "tevent.h" +#include "ldb_errors.h" /* major restrictions as compared to normal LDAP: diff --git a/source4/lib/ldb/include/ldb_includes.h b/source4/lib/ldb/include/ldb_includes.h index a2927139c8..602bbec32c 100644 --- a/source4/lib/ldb/include/ldb_includes.h +++ b/source4/lib/ldb/include/ldb_includes.h @@ -4,11 +4,6 @@ a temporary includes file until I work on the ldb build system */ -#if (_SAMBA_BUILD_ >= 4) -/* tell ldb we have the internal ldap code */ -#define HAVE_ILDAP 1 -#endif - #if (_SAMBA_BUILD_ <= 3) /* allow forbidden string functions - should be replaced with _m functions */ #undef strcasecmp @@ -19,9 +14,5 @@ #include "replace.h" #include "system/filesys.h" #include "system/time.h" -#include <talloc.h> -#include <tevent.h> -#include "ldb_errors.h" -#include "dlinklist.h" #endif /*_LDB_PRIVATE_INCLUDES_H_*/ diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 1ce9e9ecfd..2e8da9941c 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -37,6 +37,7 @@ #ifndef _LDB_PRIVATE_H_ #define _LDB_PRIVATE_H_ 1 +#include "ldb_includes.h" #include "ldb.h" #include "ldb_module.h" @@ -109,10 +110,6 @@ struct ldb_context { struct tevent_context *ev_ctx; }; -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - /* The following definitions come from lib/ldb/common/ldb.c */ int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index b134405048..4447d0e09a 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -40,11 +40,10 @@ * author: Simo Sorce */ - #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" -#include "tevent.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index e1fcdb1353..43a01f75a7 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -38,6 +38,7 @@ * author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" #define LDAP_DEPRECATED 1 diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index ea2bfd1dc1..959540374c 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -35,8 +35,6 @@ * Author: Jelmer Vernooij, Martin Kuehl */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h index 872208174e..3c1fe80895 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.h +++ b/source4/lib/ldb/ldb_map/ldb_map.h @@ -26,6 +26,8 @@ #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. * diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index e915a5f46a..822dea654e 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -24,8 +24,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index 327fa92f8d..eb7b4590ba 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -25,8 +25,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_private.h b/source4/lib/ldb/ldb_map/ldb_map_private.h index 0c46443253..612d215ae9 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_private.h +++ b/source4/lib/ldb/ldb_map/ldb_map_private.h @@ -1,3 +1,4 @@ +#include "ldb_includes.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")); diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index cdbef3944b..ad27c9a9a9 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "dlinklist.h" /* the idxptr code is a bit unusual. The way it works is to replace diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index d6276c4b86..24ec06ea32 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -865,6 +865,7 @@ static int ltdb_end_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_commit(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } @@ -883,6 +884,7 @@ static int ltdb_del_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_cancel(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 7ebf199f6f..0a06cdb1b0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -1,11 +1,5 @@ -#if (_SAMBA_BUILD_ == 3) -#include "tdb/include/tdb.h" -#else -#include "replace.h" -#include "system/wait.h" +#include "ldb_includes.h" #include "tdb.h" -#endif - #include "ldb_module.h" /* this private structure is used by the ltdb backend in the diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index d862638389..43b223b52e 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -73,8 +73,13 @@ modifiersName: not supported by w2k3? */ +#include "ldb_includes.h" #include "ldb_module.h" +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#endif + /* construct a canonical name from a message */ diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index 7d7cdf66a0..2a06c5e6c5 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -32,6 +32,7 @@ * Author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" struct message_store { diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index a5ffcc034a..880678d89d 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -36,6 +36,7 @@ * Simo Sorce Mar 2006 */ +#include "ldb_includes.h" #include "ldb_module.h" struct rename_context { diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index 3dce9b187b..2701de5a48 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -21,6 +21,7 @@ License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 3a915f8bea..9d3bd27983 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -30,7 +30,7 @@ * * Author: Andrew Tridgell */ - +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index 35d4ac7002..ba0a2a8927 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index edaa9fb85c..6af0ee9336 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" |