diff --git a/Alien/Package.pm b/Alien/Package.pm index f99f48e..7dbec40 100644 --- a/Alien/Package.pm +++ b/Alien/Package.pm @@ -130,6 +130,13 @@ to a true value. Points to a directory where the package has been unpacked. +=item owninfo + +If set this will be a reference to a hash, with filename as key, that holds +ownership/group information for files that cannot be represented on the +filesystem. Typically that is because the owners or groups just don't exist +yet. It will be set at unpack time. + =back =head1 METHODS diff --git a/Alien/Package/Deb.pm b/Alien/Package/Deb.pm index 7e4a79f..7188601 100644 --- a/Alien/Package/Deb.pm +++ b/Alien/Package/Deb.pm @@ -703,6 +703,40 @@ sub username { return $username; } +=item postinst + +Returns the postinst. This may include generated shell code to set owners +and groups from the owninfo field. + +=cut + +sub postinst { + my $this=shift; + + my $owninfo = $this->owninfo; + my $postinst = $this->{postinst}; + return $postinst unless ref $owninfo; + + # If there is no postinst, let's make one up.. + $postinst="#!/bin/sh\n" unless defined $postinst; + + my ($firstline, $rest)=split(/\n/, $postinst, 2); + if ($firstline !~ m/^#!\s*\/bin\/sh/) { + print STDERR "warning: unable to add ownership fixup code to postinst as the postinst is not a shell script!\n"; + return $postinst; + } + + my $permscript="# alien added permissions fixup code\n"; + foreach my $file (keys %$owninfo) { + my $quotedfile=$file; + $quotedfile=~s/'/'"'"'/g; # no single quotes in single quotes.. + $permscript.="chown '$owninfo->{$file}' '$quotedfile'\n"; + } + return "$firstline\n$permscript\n$rest"; +} + +=cut + =head1 AUTHOR Joey Hess diff --git a/Alien/Package/Rpm.pm b/Alien/Package/Rpm.pm index 3135dff..601469c 100644 --- a/Alien/Package/Rpm.pm +++ b/Alien/Package/Rpm.pm @@ -176,63 +176,48 @@ sub unpack { or die "error moving unpacked files into the default prefix directory: $!"; } - # When cpio extracts the file, any child directories that are - # present, but whose parent directories are not, end up mode 700. - # This next block corrects that to 755, which is more reasonable. - # - # Of course, this whole thing assumes we get the filelist in sorted - # order. - my $lastdir=''; - my %tochmod; - foreach my $file (@{$this->filelist}) { - $file=~s/^\///; - if (($lastdir && $file !~ m:^\Q$lastdir\E/[^/]*$:) || !$lastdir) { - # We've found one of the nasty directories. Fix it - # up. - # - # Note that I strip the trailing filename off $file - # here, for two reasons. First, it makes the loop - # easier, we don't need to fix the perms on the - # last file, after all! Second, it makes the -d - # test below fire, which saves us from trying to - # fix a parent directory twice. - $file=$1 if $file=~m:(.*)/.*?:; - my $dircollect=''; - - foreach my $dir (split(/\//,$file)) { - $dircollect.="$dir/"; - # Use a hash to prevent duplicate chmods. - $tochmod{"$workdir/$dircollect"}=1; - } + # cpio does not necessarily store all parent directories in an + # archive, and so some directories, if it has to make them and has + # no permission info, may come out mode 700. Here I just chown all + # extracted directories to mode 755, which is more reasonable. + # Note that the next section overrides these default permissions, + # if override data exists in the rpm permissions info. And such + # data should always exist, so this is probably a no-op. + system("find $workdir -type d -perm 700 -print0 | xargs --no-run-if-empty -0 chmod 700"); + + # rpm files have two sets of permissions; the set in the cpio + # archive, and the set in the control data; which override them. + # The set in the control data are more correct, so let's use those. + # Some permissions setting may have to be postponed until the + # postinst. + my %owninfo = (); + open (GETPERMS, 'rpm --queryformat \'[%{FILEMODES} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]\' -qp '.$this->filename.' |'); + while () { + chomp; + my ($mode, $owner, $group, $file) = split(/ /, $_, 4); + $mode = $mode & 07777; # remove filetype + my $uid = getpwnam($owner); + if (! defined $uid || $> != 0) { + $owninfo{$file}=$owner; + $uid=0; } - $lastdir=$file if -d "./$file"; - } - chmod 0755, keys %tochmod if %tochmod; - - if ($> == 0) { - # rpm files have two sets of permissions; the set in the cpio - # archive, and the set in the control data; which override them. - # The set in the control data are more correct, so let's use those. - open (GETPERMS, 'rpm --queryformat \'[%{FILEMODES} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]\' -qp '.$this->filename.' |'); - while () { - chomp; - my ($mode, $owner, $group, $file) = split(/ /, $_, 4); - $mode = $mode & 07777; # remove filetype - my $uid = getpwnam($owner); - if (! defined $uid) { - print STDERR "WARNING: $file is owned by a user ($owner) not on this system; using root instead\n"; - $uid=0; + my $gid = getgrnam($group); + if (! defined $gid || $> != 0) { + if (exists $owninfo{$file}) { + $owninfo{$file}.=":$group"; } - my $gid = getgrnam($group); - if (! defined $gid) { - print STDERR "WARNING: $file is owned by a group ($group) not on this system; using group root instead\n"; - $gid=0; + else { + $owninfo{$file}=":$group"; } - next unless -e "$workdir/$file"; # skip broken links + $gid=0; + } + next unless -e "$workdir/$file"; # skip broken links + if ($> == 0) { chown($uid, $gid, "$workdir/$file") || die "failed chowning $file to $uid\:$gid\: $!"; - chmod($mode, "$workdir/$file") || die "failed changing mode of $file to $mode\: $!"; } + chmod($mode, "$workdir/$file") || die "failed changing mode of $file to $mode\: $!"; } + $this->owninfo(\%owninfo); return 1; } diff --git a/debian/changelog b/debian/changelog index a5baf0d..f898795 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +alien (8.20) unstable; urgency=low + + * Added support inspired by aj for converted rpm packages that create + users/groups in their preinst, and which alien therefore cannot ship the + files with proper ownerships in the .deb. In this case alien will now + insert appropriate chown commands into the postinst script of the + converted package. + * That only works when converting rpm to deb, not the other way around, + for now. + * Removed the cpio directory permissions fixup code, which was probably + broken, and is obsolete since I get directory perms from the rpm now. + + -- Joey Hess Sun, 25 Aug 2002 15:17:57 -0400 + alien (8.19) unstable; urgency=low * Added upsated jdk patches from Gerald Turner.