diff --git a/lib/functions.sh b/lib/functions.sh index 3f9f251cab..c4b1773257 100644 --- a/lib/functions.sh +++ b/lib/functions.sh @@ -1733,6 +1733,8 @@ generate_manifest() { GENERATE_ARGS+="--target $f " done fi + logcmd -p $PKGSEND generate $GENERATE_ARGS $DESTDIR > $outf.raw \ + || logerr "---- Failed to generate manifest" # `pkgsend generate` will produce a manifest based on the files it # finds under $DESTDIR. It will set the ownership and group in generated # lines to root:bin, but will copy the mode attribute from the file it @@ -1743,7 +1745,7 @@ generate_manifest() { # group, or the sticky group attribute may be set on directories. # Rather than implicitly trusting the mode that is found, we normalise it # to something more generic. - logcmd -p $PKGSEND generate $GENERATE_ARGS $DESTDIR | sed -E ' + sed -E ' # Strip off any special attributes such as setuid or sticky group s/\/mode=0\1/ # Reduce group/other permissions @@ -1752,7 +1754,7 @@ generate_manifest() { # Convert unexpected modes to something reasonable s/\/mode=0644/ s/\/mode=0755/ - ' > $outf || logerr "------ Failed to generate manifest" + ' < $outf.raw > $outf || logerr "---- Failed cleaning manifest permissions" } convert_version() { @@ -1828,6 +1830,23 @@ make_package() { done } +manifest_mode_map() { + typeset src="$1" + + $PKGFMT -u < $src | $AWK ' + /^file|^dir/ { + delete map + split($0, a) + for (el in a) { + if (split(a[el], b, "=") == 2) + map[b[1]] = b[2] + } + if ("path" in map && "mode" in map) + printf("%4s %6d %s\n", $1, map["mode"], map["path"]) + } + ' +} + make_package_impl() { PKGE=`url_encode $PKG` @@ -1883,12 +1902,12 @@ make_package_impl() { # Mog files are transformed in several stages # - # $DESTDIR +---------+ - # `pkgsend generate` ---> |.p5m.gen | - # +---------+ - # | - # +--------+ v - # |.p5m.mog| <------ `pkgmogrify` + # $DESTDIR +-------------+ fix +----------+ + # `pkgsend generate` ---> |.p5m.gen.raw | --perms--> | .p5m.gen | + # +-------------+ +----------+ + # | + # +--------+ v + # |.p5m.mog| <--------------------------------- `pkgmogrify` # +--------+ # | # v +---------+ @@ -1964,6 +1983,38 @@ make_package_impl() { logerr "Warnings from mogrify process" fi + if [ -z "$BATCH" -a -f "$P5M_GEN.raw" ]; then + logmsg "--- Checking for permission overrides" + # Check for permissions set by the package install scripts which are + # not being preserved. Since the local mog may have added or removed + # files and directories, this is a bit more work than a simple diff. + # + manifest_mode_map $P5M_GEN.raw > $TMPDIR/permdiff.raw.$$ + manifest_mode_map $P5M_MOG > $TMPDIR/permdiff.mog.$$ + + # Find the list of files common to both manifests and generate grep + # patterns to extract the corresponding lines from the mode maps. + for f in raw mog; do + $AWK '{print $3}' < $TMPDIR/permdiff.$f.$$ \ + > $TMPDIR/permdiff.$f.paths.$$ + done + logcmd -p $COMM -12 $TMPDIR/permdiff.{raw,mog}.paths.$$ \ + | $SED 's/.*/ &\$/' > $TMPDIR/permdiff.patt.$$ + + if ! $GDIFF -U0 --color=always --minimal \ + <($EGREP -f $TMPDIR/permdiff.patt.$$ $TMPDIR/permdiff.raw.$$) \ + <($EGREP -f $TMPDIR/permdiff.patt.$$ $TMPDIR/permdiff.mog.$$) \ + > $TMPDIR/permdiff.$$; then + echo + # Not anchored due to colour codes in file + $EGREP -v '(\-\-\-|\+\+\+|\@\@) ' $TMPDIR/permdiff.$$ + note "Some permissions were overridden:" + logcmd $RM -f $TMPDIR/permdiff.$$ + [ -z "$PERMDIFF_NOASK" ] && ask_to_continue + fi + logcmd $RM -f $TMPDIR/permdiff.*.$$ + fi + if [ -n "$DESTDIR" ]; then check_licences [ -z "$SKIP_HARDLINK" -a -z "$BATCH" ] \ @@ -3656,7 +3707,8 @@ clean_up() { logerr "Failed to remove temporary install directory $dir" done logmsg "--- Cleaning up temporary manifest and transform files" - logcmd $RM -f $P5M_GEN $P5M_MOG $P5M_DEPGEN $P5M_DEPGEN.res $P5M_FINAL \ + logcmd $RM -f $P5M_GEN $P5M_GEN.raw $P5M_MOG \ + $P5M_DEPGEN $P5M_DEPGEN.res $P5M_FINAL \ $MY_MOG_FILE $MANUAL_DEPS || \ logerr "Failed to remove temporary manifest and transform files" logmsg "Done."