$NetBSD: patch-aa,v 1.3 2005/12/27 08:56:47 kim Exp $

--- rsnapshot-program.pl.orig	2005-04-10 01:22:29.000000000 +0300
+++ rsnapshot-program.pl	2005-12-25 11:16:47.000000000 +0200
@@ -32,6 +32,7 @@
 use File::Path;			# mkpath(), rmtree()
 use File::stat;			# stat(), lstat()
 use POSIX qw(locale_h);	# setlocale()
+use Lchown qw(lchown LCHOWN_AVAILABLE);
 
 ########################################
 ###     DECLARE GLOBAL VARIABLES     ###
@@ -3277,24 +3278,9 @@
 	
 	# CHOWN DEST (if root)
 	if (0 == $<) {
-		# make sure destination is not a symlink
-		if ( ! -l "$dest" ) {
-			# print and/or log this if necessary
-			if (($verbose > 4) or ($loglevel > 4)) {
-				my $cmd_string = "chown(" . $st->uid . ", " . $st->gid . ", \"$dest\")";
-			
-				if ($verbose > 4) {
-					print_cmd($cmd_string);
-				} elsif ($loglevel > 4) {
-					log_msg($cmd_string, 4);
-				}
-			}
-			
-			$result = chown($st->uid, $st->gid, "$dest");
-			if (! $result) {
-				print_err("Warning! Could not chown(" . $st->uid . ", " . $st->gid . ", \"$dest\");", 2);
-				return(0);
-			}
+		$result = safe_chown($st->uid, $st->gid, $dest);
+		if (! $result) {
+			return(0);
 		}
 	}
 	
@@ -3501,6 +3487,43 @@
 	return (1);
 }
 
+# choose between lchown or chown
+sub safe_chown {
+	my $uid = shift(@_);
+	my $gid = shift(@_);
+	my $dest = shift(@_);
+
+	my $result = 0;
+
+	# logging
+	if (LCHOWN_AVAILABLE || ! -l $dest) {
+		# print and/or log this if necessary
+		if (($verbose > 4) or ($loglevel > 4)) {
+			my $cmd_string = 'chown(' . $uid . ', ' . $gid . ', "' . $dest . '")';
+			if ($verbose > 4) {
+				print_cmd($cmd_string);
+			} elsif ($loglevel > 4) {
+				log_msg($cmd_string, 4);
+			}
+		}
+	}
+
+	if (LCHOWN_AVAILABLE) {
+		$result = lchown($uid, $gid, $dest);
+	} else {
+		# make sure destination is not a symlink
+		if ( ! -l $dest ) {
+			$result = chown($uid, $gid, $dest);
+		}
+	}
+
+	if (! $result) {
+		print_err('Warning! Could not safe_chown(' . $uid . ', ' . $gid . ', "' . $dest . '")', 2);
+	}
+
+	return($result);
+}
+
 # accepts a path
 # displays the rm command according to the config file
 sub display_rm_rf {
@@ -3777,13 +3800,9 @@
 	
 	# CHOWN DEST (if root)
 	if (0 == $<) {
-		# make sure dest is not a symlink
-		if ( ! -l "$dest" ) {
-			$result = chown($st->uid, $st->gid, "$dest");
-			if (! $result) {
-				print_err("Warning! Could not chown(" . $st->uid . ", " . $st->gid . ", \"$dest\");", 2);
-				return(0);
-			}
+		$result = safe_chown($st->uid, $st->gid, $dest);
+		if (! $result) {
+			return(0);
 		}
 	}
 	
@@ -3998,25 +4017,9 @@
 	# CHOWN DEST (if root)
 	if (0 == $<) {
 		if ( -e "$dest" ) {
-			# make sure destination is not a symlink
-			if ( ! -l "$dest" ) {
-				# print and/or log this if necessary
-				if (($verbose > 4) or ($loglevel > 4)) {
-					my $cmd_string = "chown(" . $st->uid . ", " . $st->gid . ", \"$dest\");";
-				
-					if ($verbose > 4) {
-						print_cmd($cmd_string);
-					} elsif ($loglevel > 4) {
-						log_msg($cmd_string, 4);
-					}
-				}
-				
-				$result = chown($st->uid, $st->gid, "$dest");
-				
-				if (! $result) {
-					print_err("Warning! Could not chown(" . $st->uid . ", " . $st->gid . ", \"$dest\")", 2);
-					return (0);
-				}
+			$result = safe_chown($st->uid, $st->gid, $dest);
+			if (! $result) {
+				return (0);
 			}
 		}
 	}
