File libguestfs.mkinitrd.1110.patch of Package libguestfs

---
 mkinitrd/scripts/setup-prepare.sh |   94 +++++++++++++++++++++++++++++++-------
 mkinitrd/scripts/setup-progs.sh   |    4 -
 2 files changed, 79 insertions(+), 19 deletions(-)

Index: 1110/mkinitrd/scripts/setup-prepare.sh
===================================================================
--- 1110.orig/mkinitrd/scripts/setup-prepare.sh
+++ 1110/mkinitrd/scripts/setup-prepare.sh
@@ -13,43 +13,103 @@
 #%param_v: "Verbose mode."
 #%param_L: "Disable logging."
 #%param_h: "This help screen."
 #
 ###### Additional options
 ##
 ## Script inclusion may be overriden by
 ##      1) creating a monster-initrd
 ##      2) including the wanted module in the configuration option ADDITIONAL_FEATURES in /etc/sysconfig/initrd
 ##      3) definition using the -f command line switch
 ##
 
 # Install a binary file
+# cp_bin file target_filename
+# cp_bin file target_directory
+# cp_bin file file target_directory
+# file is either a regular file or a symlink. symlinks and all paths they point to will be copied
+# the "root" of target is $tmp_mnt, which is required to copy symlinks properly
 cp_bin() {
-    cp -a "$@" \
-    || exit_code=1
-
-    # Remember the binaries installed. We need the list for checking
-    # for dynamic libraries.
-    while [ $# -gt 1 ]; do
-        initrd_bins[${#initrd_bins[@]}]=$1
-        shift
-   done
-   # file may print '^setuid ELF ...'
-   # suid mount will fail if mkinitrd was called as user
-   if [ -L "$1" ]; then
-        : do nothing with symlinks
-   elif [ -d "$1" -o -f "$1" ]; then
-     find "$1" -type f -print0 | xargs -0 chmod 0755 
-   fi
+	local -a files
+	local target
+	local target_dirname
+	local file
+
+	# need at least two parameters, source and destination
+	if test $# -lt 2
+	then
+		return 0
+	fi
+	# store source filenames
+	until test $# -eq 1
+	do
+		files=( ${files[@]} $1 )
+		shift
+	done
+	# store target, either file or directory
+	target=$1
+	# if more than two parameters, last entry must be a directory
+	if test ${#files[@]} -gt 1
+	then
+		if ! test -d ${target}
+		then
+			return 0
+		fi
+		target_dirname=${target}
+	else
+		# simplify symlink resolving for sinlge filename
+		target_dirname=${target%/*}
+	fi
+
+	for file in ${files[@]}
+	do
+		local src dst
+		src=${file}
+		dst=${target}
+		# copy requested soure file as is to requested destination
+		cp -a -v --remove-destination ${src} ${dst}
+		# copy symlinks recursivly
+		while [ 1 ]
+		do
+			local tmp_src
+			if test -L ${src}
+			then
+				tmp_src=$(readlink ${src})
+				if test "${tmp_src:0:1}" = "/"
+				then
+					src=${tmp_src}
+				else
+					# relative symlink
+					src=${src%/*}/${tmp_src}
+				fi
+				cp -a -v --remove-destination --parents ${src} $tmp_mnt
+				# if link target exists, proceed to next symlink target
+				if test -e "${src}"
+				then
+					continue
+				fi
+			fi
+			# exit loop in case of dead symlink or if target of symlink was reached
+			break
+		done
+		# if source file exists, add it to list of binaries
+		if test -e "${src}"
+		then
+			# file may print '^setuid ELF ...'
+			# suid mount will fail if mkinitrd was called as user
+			chmod -v 0755 $tmp_mnt/${src}
+			initrd_bins[${#initrd_bins[@]}]=${src}
+		fi
+	done
 }
 
 # check if we should use script or feature $1
 use_script() {
     local condition feature script file
 
     # always use when creating monster initrd
     [ "$create_monster_initrd" ] && return 0
 
     # Normalize to feature name
     feature="${1##*/}"
     feature="${feature#*-}"
     feature="${feature%.sh}"
@@ -146,27 +206,27 @@ fi
 for feature in $ADDITIONAL_FEATURES ; do
     feature_exists "$feature" || echo "[WARNING] Feature \"$feature\" not found. A typo?"
 done
 
 # create an empty initrd
 if ! mkdir $tmp_mnt ; then
     error 1 "could not create temporary directory"
 fi
 
 # fill the initrd
 cp $INITRD_PATH/bin/linuxrc $linuxrc
 mkdir "$tmp_mnt/boot"
 
-mkdir -p $tmp_mnt/{sbin,bin,etc,dev,proc,sys,root,config}
+mkdir -p $tmp_mnt/{sbin,bin,etc,dev,proc,sys,root,config,usr/bin,usr/sbin}
 
 mkdir -p -m 4777 $tmp_mnt/tmp
 
 # Create a dummy /etc/mtab for mount/umount
 echo -n > $tmp_mnt/etc/mtab
 
 # Add modprobe, modprobe.conf*, and a version of /bin/true: modprobe.conf
 # might use it.
 cp -r $root_dir/etc/modprobe.conf $root_dir/etc/modprobe.conf.local \
     $root_dir/etc/modprobe.d $tmp_mnt/etc
 cat > $tmp_mnt/bin/true <<-EOF
 #! /bin/sh
 :
Index: 1110/mkinitrd/scripts/setup-progs.sh
===================================================================
--- 1110.orig/mkinitrd/scripts/setup-progs.sh
+++ 1110/mkinitrd/scripts/setup-progs.sh
@@ -28,29 +28,29 @@ for script in $INITRD_PATH/boot/*.sh; do
           echo "[ \"\$debug\" ] && echo running $file
 source boot/$file
 [ \"\$modules\" ] && load_modules" >> run_all.sh
         [ "$condition" ] && echo "fi" >> run_all.sh
         # and all programs it needs
         for files in $(cat $script | grep '%programs: ' | sed 's/^#%programs: \(.*\)$/\1/'); do
             for file in $(eval echo $files); do
                 if [ "${file:0:17}" = "/lib/mkinitrd/bin" ]; then
                         SOURCE=$file
                         DEST="./bin/"
                 elif [ "${file:0:1}" = "/" ]; then # absolute path files have to stay alive
                         SOURCE=$file
                         [ ! -e $file -a -e /usr$file ] && SOURCE="/usr$file"
-                        DEST=".$file"
+                        DEST=".$SOURCE"
                 else
                         SOURCE=$(which "$file")
-                        DEST="./bin/"
+                        DEST=".$SOURCE"
                 fi
                 cp_bin "$SOURCE" "$DEST"
             done
         done
     fi
 done
 
 echo -ne "Features:       "
 echo $features
 
 [ -e "bin/sh" ] || ln -s /bin/bash bin/sh
 
openSUSE Build Service is sponsored by