]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/dn2id.c
Set lock detector to DEFAULT, not NORUN.
[openldap] / servers / slapd / back-bdb / dn2id.c
index 4fca067aafceb89285f259e25e79a6d7dc9bdb6c..c05dcae2231238ae1742f843f3491ff8406a753c 100644 (file)
@@ -1,7 +1,7 @@
 /* dn2id.c - routines to deal with the dn2id index */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -60,42 +60,52 @@ bdb_dn2id_add(
                        ptr, rc, 0 );
                        goto done;
                }
-       }
-
-       pdn = dn_parent( be, ptr );
-
-       if( pdn != NULL ) {
+               
+               rc = dnParent( ptr, (const char **)&pdn );
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "=> bdb_dn2id_add: dnParent(\"%s\") failed\n",
+                               ptr, 0, 0 );
+                       goto done;
+               }
+       
                key.size -= pdn - ptr;
                pdn[-1] = DN_ONE_PREFIX;
                key.data = pdn - 1;
+               ptr = pdn;
 
                rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
 
                if( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "=> bdb_dn2id_add: parent (%s) insert failed: %d\n",
-                                       pdn, rc, 0 );
+                                       ptr, rc, 0 );
                        goto done;
                }
        }
 
-       while( pdn != NULL ) {
-               if ( be_issuffix( be, pdn ))
-                       break;
-               pdn[-1] = DN_SUBTREE_PREFIX;
+       while( !be_issuffix( be, ptr )) {
+               ptr[-1] = DN_SUBTREE_PREFIX;
 
                rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
 
                if( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
-                                       pdn, rc, 0 );
+                                       ptr, rc, 0 );
                        break;
                }
-               ptr = pdn;
-               pdn = dn_parent( be, pdn );
+               rc = dnParent( ptr, &pdn );
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "=> bdb_dn2id_add: dnParent(\"%s\") failed\n",
+                               ptr, 0, 0 );
+                       goto done;
+               }
+
                key.size -= pdn - ptr;
                key.data = pdn - 1;
+               ptr = pdn;
        }
 
 done:
@@ -146,42 +156,51 @@ bdb_dn2id_delete(
                        ptr, rc, 0 );
                        goto done;
                }
-       }
 
-       pdn = dn_parent( be, ptr );
+               rc = dnParent( ptr, &pdn );
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "=> bdb_dn2id_delete: dnParent(\"%s\") failed\n",
+                               ptr, 0, 0 );
+                       goto done;
+               }
 
-       if( pdn != NULL ) {
                key.size -= pdn - ptr;
                pdn[-1] = DN_ONE_PREFIX;
                key.data = pdn - 1;
+               ptr = pdn;
 
                rc = bdb_idl_delete_key( be, db, txn, &key, e->e_id );
 
                if( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "=> bdb_dn2id_delete: parent (%s) delete failed: %d\n",
-                               pdn, rc, 0 );
+                               ptr, rc, 0 );
                        goto done;
                }
        }
 
-       while( pdn != NULL ) {
-               if ( be_issuffix( be, pdn ))
-                       break;
-
-               pdn[-1] = DN_SUBTREE_PREFIX;
+       while( !be_issuffix( be, ptr )) {
+               ptr[-1] = DN_SUBTREE_PREFIX;
 
                rc = bdb_idl_delete_key( be, db, txn, &key, e->e_id );
                if( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
-                               pdn, rc, 0 );
+                               ptr, rc, 0 );
                        goto done;
                }
-               ptr = pdn;
-               pdn = dn_parent( be, pdn );
+               rc = dnParent( ptr, &pdn );
+               if ( rc != LDAP_SUCCESS ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "=> bdb_dn2id_delete: dnParent(\"%s\") failed\n",
+                               ptr, 0, 0 );
+                       goto done;
+               }
+
                key.size -= pdn - ptr;
                key.data = pdn - 1;
+               ptr = pdn;
        }
 
 done:
@@ -237,7 +256,7 @@ bdb_dn2id_matched(
        DB_TXN *txn,
        struct berval   *in,
        ID *id,
-       char **matchedDN )
+       ID *id2 )
 {
        int             rc;
        DBT             key, data;
@@ -260,8 +279,6 @@ bdb_dn2id_matched(
        data.ulen = sizeof(ID);
        data.flags = DB_DBT_USERMEM;
 
-       *matchedDN = NULL;
-
        while(1) {
                dn[-1] = DN_BASE_PREFIX;
 
@@ -271,7 +288,17 @@ bdb_dn2id_matched(
                rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
 
                if( rc == DB_NOTFOUND ) {
-                       char *pdn = dn_parent( be, dn );
+                       char    *pdn = NULL;
+
+                       if ( ! be_issuffix( be, dn ) ) {
+                               rc = dnParent( dn, &pdn );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "<= bdb_dn2id_matched: dnParent(\"%s\") failed\n",
+                                               dn, 0, 0 );
+                                       break;
+                               }
+                       }
 
                        if( pdn == NULL || *pdn == '\0' ) {
                                Debug( LDAP_DEBUG_TRACE,
@@ -293,12 +320,12 @@ bdb_dn2id_matched(
                        }
 
                        if( dn != buf+1 ) {
-                               *matchedDN = (char *) dn;
+                               *id2 = *id;
                        }
 
                        Debug( LDAP_DEBUG_TRACE,
                                "<= bdb_dn2id_matched: id=0x%08lx: %s %s\n",
-                               (long) *id, *matchedDN == NULL ? "entry" : "matched", dn );
+                               (long) *id, *id2 == 0 ? "entry" : "matched", dn );
                        break;
 
                } else {
@@ -343,9 +370,10 @@ bdb_dn2id_children(
        data.dlen = sizeof(id);
 
        rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
+       free( key.data );
 
        Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %schildren (%d)\n",
-               dn,
+               dn->bv_val,
                rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
                        db_strerror(rc) ), rc );
 
@@ -471,7 +499,11 @@ node_rdn_cmp(
        idNode *b
 )
 {
+#if 0
        return strcmp(a->i_rdn->nrdn.bv_val, b->i_rdn->nrdn.bv_val);
+#endif
+       /* should be slightly better without ordering drawbacks */
+       return ber_bvcmp(&a->i_rdn->nrdn, &b->i_rdn->nrdn);
 }
 
 idNode * bdb_find_id_node(
@@ -606,7 +638,7 @@ int bdb_fix_dn(
        o = bdb_find_id_node(id, bdb->bi_tree);
        rlen = be->be_suffix[0]->bv_len + 1;
        nrlen = be->be_nsuffix[0]->bv_len + 1;
-       for (n = o; n; n=n->i_parent) {
+       for (n = o; n && n->i_parent; n=n->i_parent) {
                rlen += n->i_rdn->rdn.bv_len + 1;
                nrlen += n->i_rdn->nrdn.bv_len + 1;
        }
@@ -616,7 +648,7 @@ int bdb_fix_dn(
        e->e_nname.bv_val = e->e_name.bv_val + rlen;
        ptr = e->e_name.bv_val;
        nptr = e->e_nname.bv_val;
-       for (n = o; n; n=n->i_parent) {
+       for (n = o; n && n->i_parent; n=n->i_parent) {
                ptr = slap_strcopy(ptr, n->i_rdn->rdn.bv_val);
                *ptr++ = ',';
                nptr = slap_strcopy(nptr, n->i_rdn->nrdn.bv_val);
@@ -624,8 +656,6 @@ int bdb_fix_dn(
        }
        ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
 
-       ptr--;
-       nptr--;
        strcpy(ptr, be->be_suffix[0]->bv_val);
        strcpy(nptr, be->be_nsuffix[0]->bv_val);
 
@@ -665,7 +695,7 @@ bdb_dn2id_add(
        d->rdn.bv_val -= (long)d;
        d->nrdn.bv_val -= (long)d;
 
-       if (pdn) {
+       if (pdn->bv_len) {
                bdb_dn2id(be, txn, pdn, &d->parent);
        } else {
                d->parent = 0;
@@ -744,7 +774,7 @@ bdb_dn2id_matched(
        DB_TXN *txn,
        struct berval   *in,
        ID *id,
-       char **matchedDN )
+       ID *id2 )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        int             i;
@@ -763,8 +793,10 @@ bdb_dn2id_matched(
        rdns = ldap_explode_dn(in->bv_val, 0);
        for (i=0; rdns[i]; i++);
        i -= bdb->bi_nrdns;
-       if (i < 0)
+       if (i < 0) {
+               charray_free(rdns);
                return -1;
+       }
        n = p;
        ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
        for (--i; i>=0; i--) {
@@ -775,22 +807,12 @@ bdb_dn2id_matched(
                p = n;
        }
        ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);
+       charray_free(rdns);
 
        if (n) {
                *id = n->i_id;
-       } else if (matchedDN) {
-               int len = 0, j;
-               char *ptr;
-               ++i;
-               for (j=i; rdns[j]; j++)
-                       len += strlen(rdns[j]) + 1;
-               ptr = ch_malloc(len);
-               *matchedDN = ptr;
-               for (;rdns[i]; i++) {
-                       ptr = slap_strcopy(ptr, rdns[i]);
-                       *ptr++ = ',';
-               }
-               ptr[-1] = '\0';
+       } else if (id2) {
+               *id2 = p->i_id;
        }
        return n ? 0 : DB_NOTFOUND;
 }