]> git.sur5r.net Git - openldap/commitdiff
allow attribute exclusion list in selective replica
authorPierangelo Masarati <ando@openldap.org>
Sat, 30 Mar 2002 08:52:20 +0000 (08:52 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 30 Mar 2002 08:52:20 +0000 (08:52 +0000)
servers/slapd/config.c
servers/slapd/proto-slap.h
servers/slapd/repl.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c

index b9badcaed7a195a8fc0c87da0ef9b79a0826b0b7..28ba0d17a72c1f9989ede95bdbd89abf99a2742f 100644 (file)
@@ -1830,16 +1830,29 @@ read_config( const char *fname )
 #endif
                                                                break;
                                                        }
-                                               } else if ( strncasecmp( cargv[i], "attr=", 5 ) == 0 ) {
-                                                       if ( add_replica_attrs( be, nr, cargv[i] + 5 ) ) {
+
+                                               } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
+                                                       int exclude = 0;
+                                                       char *arg = cargv[i] + 4;
+
+                                                       if ( arg[0] == '!' ) {
+                                                               arg++;
+                                                               exclude = 1;
+                                                       }
+
+                                                       if ( arg[0] != '=' ) {
+                                                               continue;
+                                                       }
+
+                                                       if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
 #ifdef NEW_LOGGING
                                                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
                                                                                "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
-                                                                               fname, lineno, cargv[i] + 5 ));
+                                                                               fname, lineno, arg + 1 ));
 #else
                                                                Debug( LDAP_DEBUG_ANY,
                                                                                "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
-                                                                               fname, lineno, cargv[i] + 5 );
+                                                                               fname, lineno, arg + 1 );
 #endif
                                                                return( 1 );
                                                        }
index 562c429127ef7b009154ca4bd54feac5af6304c0..e23a04c549c52df318720db6ebec0bff7e729e48 100644 (file)
@@ -715,7 +715,7 @@ LDAP_SLAPD_F (int) add_replica_info LDAP_P(( Backend *be,
 LDAP_SLAPD_F (int) add_replica_suffix LDAP_P(( Backend *be,
        int nr, const char *suffix ));
 LDAP_SLAPD_F (int) add_replica_attrs LDAP_P(( Backend *be,
-       int nr, char *attrs ));
+       int nr, char *attrs, int exclude ));
 LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op,
        struct berval *dn, struct berval *ndn, void *change ));
 
index 3057d4891e38c427d3100c7fc7095ba53f631c80..6f2b3ac262dd11923036fa8fa83aca188e0adc29 100644 (file)
@@ -41,6 +41,8 @@ add_replica_info(
        be->be_replica[ i ] 
                = ch_calloc( sizeof( struct slap_replica_info ), 1 );
        be->be_replica[ i ]->ri_host = ch_strdup( host );
+       be->be_replica[ i ]->ri_nsuffix = NULL;
+       be->be_replica[ i ]->ri_attrs = NULL;
        be->be_replica[ i + 1 ] = NULL;
 
        return( i );
@@ -77,9 +79,19 @@ int
 add_replica_attrs(
        Backend *be,
        int     nr,
-       char    *attrs
+       char    *attrs,
+       int     exclude
 )
 {
+       if ( be->be_replica[nr]->ri_attrs != NULL ) {
+               if ( be->be_replica[nr]->ri_exclude != exclude ) {
+                       fprintf( stderr, "attr selective replication directive '%s' conflicts with previous one (discarded)\n", attrs );
+                       ch_free( be->be_replica[nr]->ri_attrs );
+                       be->be_replica[nr]->ri_attrs = NULL;
+               }
+       }
+
+       be->be_replica[nr]->ri_exclude = exclude;
        be->be_replica[nr]->ri_attrs = str2anlist( be->be_replica[nr]->ri_attrs,
                attrs, "," );
        return ( be->be_replica[nr]->ri_attrs == NULL );
@@ -203,7 +215,16 @@ replog(
                                /* fall thru */
                        case LDAP_REQ_MODIFY:
                                for ( ml = change; ml != NULL; ml = ml->sml_next ) {
-                                       if ( ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs ) ) {
+                                       int is_in, exclude;
+
+                                       is_in = ad_inlist( ml->sml_desc, be->be_replica[i]->ri_attrs );
+                                       exclude = be->be_replica[i]->ri_exclude;
+                                       
+                                       /*
+                                        * there might be a more clever way to do this test,
+                                        * but this way, at least, is comprehensible :)
+                                        */
+                                       if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) {
                                                subsets = 1;
                                                first = ml;
                                                break;
@@ -216,7 +237,12 @@ replog(
                        case LDAP_REQ_ADD:
                                e = change;
                                for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                                       if ( ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs ) ) {
+                                       int is_in, exclude;
+
+                                       is_in = ad_inlist( a->a_desc, be->be_replica[i]->ri_attrs );
+                                       exclude = be->be_replica[i]->ri_exclude;
+                                       
+                                       if ( ( is_in && !exclude ) || ( !is_in && exclude ) ) {
                                                subsets = 1;
                                                first = a;
                                                break;
@@ -267,8 +293,12 @@ replog1(
                ml = first ? first : change;
                for ( ; ml != NULL; ml = ml->sml_next ) {
                        char *type;
-                       if ( ri && ri->ri_attrs && !ad_inlist( ml->sml_desc, ri->ri_attrs ) ) {
-                               continue;
+                       if ( ri && ri->ri_attrs ) {
+                               int is_in = ad_inlist( ml->sml_desc, ri->ri_attrs );
+
+                               if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) {
+                                       continue;
+                               }
                        }
                        type = ml->sml_desc->ad_cname.bv_val;
                        switch ( ml->sml_op ) {
@@ -296,7 +326,8 @@ replog1(
                a = first ? first : e->e_attrs;
                for ( ; a != NULL; a=a->a_next ) {
                        if ( ri && ri->ri_attrs ) {
-                               if ( !ad_inlist( a->a_desc, ri->ri_attrs ) ) {
+                               int is_in = ad_inlist( a->a_desc, ri->ri_attrs );
+                               if ( ( !is_in && !ri->ri_exclude ) || ( is_in && ri->ri_exclude ) ) {
                                        continue;
                                }
                                /* If the list includes objectClass names,
index 146626b628a24a374ab890f5a9753d7ea8e28ece..dc88b57cc54608a2868f3f03072a914ee3ee83d9 100644 (file)
@@ -1006,6 +1006,7 @@ struct slap_replica_info {
        char *ri_host;                          /* supersedes be_replica */
        struct berval **ri_nsuffix;     /* array of suffixes this replica accepts */
        AttributeName *ri_attrs;        /* attrs to replicate, NULL=all */
+       int ri_exclude;                 /* 1 => exclude ri_attrs */
 };
 
 struct slap_limits_set {
index f53f1bde64d97a5aff907d87f882601a3dcb482f..3db426bac42a2c9763730db289879a6632b521b6 100644 (file)
@@ -201,7 +201,7 @@ int add_replica_suffix( Backend *be, int nr, const char *suffix )
        return 0;
 }
 
-int add_replica_attrs( Backend *be, int nr, char *attrs )
+int add_replica_attrs( Backend *be, int nr, char *attrs, int exclude )
 {
        return 0;
 }