Change 33888 by [EMAIL PROTECTED] on 2008/05/20 15:44:38 Integrate: [ 33850] Subject: [perl #53500] op/pwent.t should use the DirectoryService on OS X From: "Tom Wyant via RT" <[EMAIL PROTECTED]> Date: Sun, 11 May 2008 14:40:04 -0700 Message-ID: <[EMAIL PROTECTED]>
Affected files ... ... //depot/maint-5.10/perl/t/op/pwent.t#2 integrate Differences ... ==== //depot/maint-5.10/perl/t/op/pwent.t#2 (xtext) ==== Index: perl/t/op/pwent.t --- perl/t/op/pwent.t#1~32694~ 2007-12-22 01:23:09.000000000 -0800 +++ perl/t/op/pwent.t 2008-05-20 08:44:38.000000000 -0700 @@ -41,6 +41,71 @@ } } + if (not defined $where && # Try dscl + $Config{useperlio} eq 'define') { # need perlio + + # Map dscl items to passwd fields, and provide support for + # mucking with the dscl output if we need to (and we do). + my %want = do { + my $inx = 0; + map {$_ => {inx => $inx++, mung => sub {$_[0]}}} + qw{RecordName Password UniqueID PrimaryGroupID + RealName NFSHomeDirectory UserShell}; + }; + + # The RecordName for a /User record is the username. In some + # cases there are synonyms (e.g. _www and www), in which case we + # get a blank-delimited list. We prefer the first entry in the + # list because getpwnam() does. + $want{RecordName}{mung} = sub {(split '\s+', $_[0], 2)[0]}; + + # The UniqueID and PrimaryGroupID for a /User record are the + # user ID and the primary group ID respectively. In cases where + # the high bit is set, 'dscl' returns a negative number, whereas + # getpwnam() returns its twos complement. This mungs the dscl + # output to agree with what getpwnam() produces. Interestingly + # enough, getpwuid(-2) returns the right record ('nobody'), even + # though it returns the uid as 4294967294. If you track uid_t + # on an i386, you find it is an unsigned int, which makes the + # unsigned version the right one; but both /etc/passwd and + # /etc/master.passwd contain negative numbers. + $want{UniqueID}{mung} = $want{PrimaryGroupID}{mung} = sub { + unpack 'L', pack 'l', $_[0]}; + + foreach my $dscl (qw(/usr/bin/dscl)) { + -x $dscl or next; + open (my $fh, '-|', join (' ', $dscl, qw{. -readall /Users}, + keys %want, '2>/dev/null')) or next; + my $data; + my @rec; + while (<$fh>) { + chomp; + if ($_ eq '-') { + @rec and $data .= join (':', @rec) . "\n"; + @rec = (); + next; + } + my ($name, $value) = split ':\s+', $_, 2; + unless (defined $value) { + s/:$//; + $name = $_; + $value = <$fh>; + chomp $value; + $value =~ s/^\s+//; + } + if (defined (my $info = $want{$name})) { + $rec[$info->{inx}] = $info->{mung}->($value); + } + } + @rec and $data .= join (':', @rec) . "\n"; + if (open (PW, '<', \$data)) { + $where = "dscl . -readall /Users"; + undef $reason; + last; + } + } + } + if (not defined $where) { # Try local. my $PW = "/etc/passwd"; if (-f $PW && open(PW, $PW) && defined(<PW>)) { End of Patch.