fcopy -H

Edgar Fuß ef at math.uni-bonn.de
Fri Jan 27 16:21:56 CET 2017


Außer uns scheint niemand fcopy -H zu benutzen. Weil zusätzlich nicht abgefangen wird, wenn stat() schiefgeht, hatten wir plötzlich Files auf Mode 000. Sehr lustige Effekte, weil es teilweise bei einem softupdate geht und beim nächsten nicht (je nachdem, ob das Link-Ziel bereits existiert).

Leider ist lchmod() nicht POSIX (und auf Linux auch offenbar nicht vorhanden).

Man braucht jetzt zusätzlich libfile-lchown-perl.

Der Patch ist nicht sehr ausgiebig getestet, da sollte nochmal jemand drübersehen, ob ich irgendwelchen Unsinn gemacht habe.
-------------- next part --------------
--- fcopy.1	2017-01-11 16:14:10.000000000 +0100
+++ fcopy.2	2017-01-12 11:54:29.000000000 +0100
@@ -36,6 +36,7 @@
 use File::Basename;
 use File::Spec;
 use File::Temp qw/tempfile/;
+use File::lchown qw/lchown lutimes/;
 use Getopt::Std;
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -298,11 +299,20 @@
     $stime = (stat("$sourcefile/$class"))[9];
   } else {
     # get mtime,uid,gid,mode from source file
-    ($stime, at defmodes) = (stat("$sourcefile/$class"))[9,4,5,2];
+    if ($opt_H) {
+      ($stime, at defmodes) = (lstat("$sourcefile/$class"))[9,4,5,2];
+    } else {
+      ($stime, at defmodes) = (stat("$sourcefile/$class"))[9,4,5,2];
+    }
   }
 
   # get mtime,uid,gid,mode from destination file
-  my ($dtime, at ddefmodes) = (stat("$destfile"))[9,4,5,2];
+  my ($dtime, at ddefmodes);
+  if ($opt_H) {
+    ($dtime, at ddefmodes) = (lstat("$destfile"))[9,4,5,2];
+  } else {
+    ($dtime, at ddefmodes) = (stat("$destfile"))[9,4,5,2];
+  }
   # compare time,uid,gid and mode of source file and target file
 
   if ($modeset) { # use -m values
@@ -314,15 +324,22 @@
   }
 
   # if different: change the values
+  # setting modes on a symlink is not portable, so ignore it
+  my $issymlink = $opt_H && -l $destfile;
   return if ($stime == $dtime && (($ddefmodes[0] == $owner) &&
-      ($ddefmodes[1] == $group) && ($ddefmodes[2] == $mode)));
+      ($ddefmodes[1] == $group) && ($issymlink || ($ddefmodes[2] == $mode))));
 
   ($uid,$gid) = name2num($owner,$group);
   warn "chown/chmod u:$uid g:$gid m:$mode $destfile\n" if $debug;
   return if $dryrun; # do not execute if -n or FCOPY_DRYRUN was given
-  chown ($uid,$gid,     $destfile) || ewarn("chown $owner $group $destfile failed. $!");
-  chmod ($mode,         $destfile) || ewarn("chmod $mode $destfile failed. $!");
-  utime ($stime,$stime, $destfile) || ewarn("utime for $destfile failed. $!");
+  if ($issymlink) {
+    lchown  ($uid,$gid,     $destfile) || ewarn("lchown $owner $group $destfile failed. $!");
+    lutimes ($stime,$stime, $destfile) || ewarn("lutime for $destfile failed. $!");
+  } else {
+    chown ($uid,$gid,     $destfile) || ewarn("chown $owner $group $destfile failed. $!");
+    chmod ($mode,         $destfile) || ewarn("chmod $mode $destfile failed. $!");
+    utime ($stime,$stime, $destfile) || ewarn("utime for $destfile failed. $!");
+  }
 }
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 sub check_mopt {


More information about the linux-fai-devel mailing list