From: Kartik S. <kar...@us...> - 2003-06-24 21:59:01
|
Update of /cvsroot/perl-ldap/ldap/contrib In directory sc8-pr-cvs1:/tmp/cvs-serv18847 Modified Files: ldifdiff.pl Log Message: Added options to specify DN attributes, as well as "shared" attributes. Converted to Getopt::Long. Index: ldifdiff.pl =================================================================== RCS file: /cvsroot/perl-ldap/ldap/contrib/ldifdiff.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- ldifdiff.pl 3 Nov 2002 01:47:45 -0000 1.2 +++ ldifdiff.pl 24 Jun 2003 21:58:58 -0000 1.3 @@ -13,29 +13,41 @@ =head1 SYNOPSIS -ldifdiff.pl B<-k keyattr> [B<-a attr1,attr2,...>] [B<-c attr1,attr2,...>] B<sourcefile> B<targetfile> +ldifdiff.pl B<-k|--keyattr keyattr> [B<-a|--sourceattrs attr1,attr2,...>] [B<-c|--ciscmp attr1,...>] [B<--dnattrs attr1,...>] [B<--sharedattrs attr1,...>] B<sourcefile> B<targetfile> =head1 OPTIONS =over 4 -=item B<-k> keyattr +=item B<-k|--keyattr> keyattr Specifies the key attribute to use when comparing source and target entries. Entries in both LDIF files must be sorted by this attribute for comparisons to be meaningful. F<ldifsort.pl> can be used to sort LDIF files by a given attribute. -=item B<-a attr1,attr2,...> +=item B<-a|--sourceattrs attr1,attr2,...> (Optional) Specifies a list of attributes to consider when comparing source and target entries. By default, all attributes are considered. -=item B<-c attr1,attr2,...> +=item B<-c|--ciscmp attr1,...> (Optional) Compare values of the specified attributes case-insensitively. By default, comparisons are case-sensitive. +=item B<--dnattrs attr1,...> + +(Optional) Specifies a list of attributes to be treated as DNs when being +compared. The default set is manager, member, owner and uniqueMember. + +=item B<--sharedattrs attr1,...> + +(Optional) Specifies a list of attribues to be treated as "shared" attributes, +where the source may not be a sole authoritative source. When modifying +these attributes, separate "delete" and "add" LDIF changes are generated, +instead of a single "replace" change. The default set is objectClass. + =item B<sourcefile> Specifies the source LDIF file. @@ -51,17 +63,25 @@ use Net::LDAP; use Net::LDAP::LDIF; use Net::LDAP::Util qw(canonical_dn); -use Getopt::Std; +use Getopt::Long; use strict; -my %args; -getopts("a:c:k:", \%args); - -my $keyattr = $args{k}; -my @sourceattrs = split(/,/, $args{a}); -my %ciscmp = (objectclass => 1, manager => 1, owner => 1, uniquemember => 1); -foreach (split(/,/, $args{c})) { $ciscmp{$_} = 1 } +my @sourceattrs; +my (%ciscmp, %dnattrs, %sharedattrs); +my $keyattr; +GetOptions('a|sourceattrs=s' => sub { @sourceattrs = split(/,/, $_[1]) }, + 'c|ciscmp=s' => sub { my @a = split(/,/,$_[1]); @ciscmp{@a} = (1) x @a }, + 'dnattrs=s' => sub { my @a = split(/,/,$_[1]); @dnattrs{@a} = (1) x @a }, + 'k|keyattr=s' => \$keyattr, + 'sharedattrs=s' => sub { my @a=split(/,/,$_[1]); @sharedattrs{@a}=(1)x @a } + ); +%ciscmp = (objectclass => 1, manager => 1, owner => 1, uniquemember => 1) + unless keys %ciscmp; +%dnattrs = (manager => 1, member => 1, owner => 1, uniquemember => 1) + unless keys %dnattrs; +%sharedattrs = (objectclass => 1) + unless keys %sharedattrs; my ($sourcefile, $targetfile); @@ -189,8 +209,6 @@ my ($source, $target, @attrs) = @_; my ($attr, $val, $ldifstr); - my %sharedattrs = (objectclass => 1); - unless (@attrs) { # add all source entry attributes @attrs = $source->attributes; @@ -211,13 +229,19 @@ my @sourcevals = $source->get_value($attr); my @targetvals = $target->get_value($attr); my (%sourceuniqvals, %targetuniqvals); - if ($ciscmp{$lcattr}) { - @sourceuniqvals{map { lc($_) } @sourcevals} = (); - @targetuniqvals{map { lc($_) } @targetvals} = (); + foreach (@sourcevals) { + my $val = $_; + $val = lc $val if $ciscmp{$lcattr}; + # Get rid of spaces after non-escaped commas in DN attrs + $val =~ s/(?<!\\),\s+/,/g if $dnattrs{$lcattr}; + $sourceuniqvals{$val} = undef; } - else { - @sourceuniqvals{@sourcevals} = (); - @targetuniqvals{@targetvals} = (); + foreach (@targetvals) { + my $val = $_; + $val = lc $val if $ciscmp{$lcattr}; + # Get rid of spaces after non-escaped commas in DN attrs + $val =~ s/(?<!\\),\s+/,/g if $dnattrs{$lcattr}; + $targetuniqvals{$val} = undef; } foreach my $val (keys %sourceuniqvals) { if (exists $targetuniqvals{$val}) { @@ -234,6 +258,11 @@ # For 'shared' attributes (e.g. objectclass) where $source may not # be a sole authoritative source, we issue separate delete and # add modifications instead of a single replace. + # + # Note: this issues deletes/adds for the canonicalized versions of + # values rather than the original values themselves, since the + # canonicalized versions are readily available in a hash, whereas + # the original versions are in a linear array. $target->delete($attr => [ keys(%targetuniqvals) ]) if keys(%targetuniqvals); $target->add($attr => [ keys(%sourceuniqvals) ]) |