diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in
index 6a68d4d..1690583 100644
--- a/contrib/paccache.sh.in
+++ b/contrib/paccache.sh.in
@@ -256,6 +256,8 @@ while :; do
 			delete=1 ;;
 		-u|--uninstalled)
 			IFS=$'\n' read -r -d '' -a ign < <(pacman -Qq)
+			# pacman -Qq may exit with an error, thus making ign an empty array
+			(( ${#ign[@]} )) || die 'failed to retrieve the list of installed packages'
 			blacklist+=("${ign[@]}")
 			unset ign ;;
 		-V|--version)
diff --git a/contrib/paclist.sh.in b/contrib/paclist.sh.in
index 1c10b32..f4fd540 100644
--- a/contrib/paclist.sh.in
+++ b/contrib/paclist.sh.in
@@ -31,7 +31,7 @@ if ! type gettext &>/dev/null; then
 fi
 
 usage() {
-	printf "%s (pacman) v%s\n" "${myname}" "myver"
+	printf "%s (pacman) v%s\n" "${myname}" "${myver}"
 	echo
 	printf "List all packages installed from a given repository\n" "${myname}"
 	echo
diff --git a/contrib/updpkgsums.sh.in b/contrib/updpkgsums.sh.in
index b0d2d69..7b92efe 100644
--- a/contrib/updpkgsums.sh.in
+++ b/contrib/updpkgsums.sh.in
@@ -82,9 +82,6 @@ fi
 export BUILDDIR=$(mktemp -d --tmpdir updpkgsums.XXXXXX)
 newbuildfile=$(mktemp --tmpdir updpkgsums.XXXXXX)
 
-# In case the eventual replacement fails, we don't want to leave behind
-# $newbuildfile as garbage in $TMPDIR. This fails silently if the replacement
-# succeeds.
 trap "rm -rf '$BUILDDIR' '$newbuildfile'" EXIT
 newsums=$(makepkg -g -p "$buildfile") || die 'Failed to generate new checksums'
 awk -v newsums="$newsums" '
@@ -100,8 +97,9 @@ awk -v newsums="$newsums" '
 	END { if (!w) print newsums }
 ' "$buildfile" > "$newbuildfile" || die 'Failed to write new PKGBUILD'
 
-# Replace the original buildfile.
-if ! mv -- "$newbuildfile" "$buildfile"; then
+# Rewrite the original buildfile. Use cat instead of mv/cp to preserve
+# permissions implicitly.
+if ! cat -- "$newbuildfile" >"$buildfile"; then
 	die "Failed to update %s. The file has not been modified." "$buildfile"
 fi
 
diff --git a/doc/PKGBUILD.5.txt b/doc/PKGBUILD.5.txt
index 7fa91ff..c95c41d 100644
--- a/doc/PKGBUILD.5.txt
+++ b/doc/PKGBUILD.5.txt
@@ -216,7 +216,7 @@ underscore and the architecture name e.g., 'checkdepends_x86_64=()'.
 	and are not utilized by pacman during dependency resolution. The format
 	for specifying optdepends is:
 
-	optdepends=('fakeroot: for makepkg usage as normal user')
+	optdepends=('python: for library bindings')
 +
 Additional architecture-specific optdepends can be added by appending an
 underscore and the architecture name e.g., 'optdepends_x86_64=()'.
@@ -336,10 +336,9 @@ files into the packaging directory, with optional `prepare()`, `build()`, and
 *package() Function*::
 	The `package()` function is used to install files into the directory that
 	will become the root directory of the built package and is run after all
-	the optional functions listed below. When specified in combination with
-	the fakeroot BUILDENV option in linkman:makepkg.conf[5], fakeroot usage
-	will be limited to running the packaging stage. All other functions will
-	be run as the user calling makepkg.
+	the optional functions listed below. The packaging stage is run using
+	fakeroot to ensure correct file permissions in the resulting package.
+	All other functions will be run as the user calling makepkg.
 
 *prepare() Function*::
 	An optional `prepare()` function can be specified in which operations to
diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in
index 712ca60..19f673d 100644
--- a/etc/makepkg.conf.in
+++ b/etc/makepkg.conf.in
@@ -19,6 +19,13 @@ DLAGENTS=('ftp::/usr/bin/curl -qfC - --ftp-pasv --retry 3 --retry-delay 3 -o %o
 # /usr/bin/lftpget -c
 # /usr/bin/wget
 
+#-- The package required by makepkg to download VCS sources
+#  Format: 'protocol::package'
+VCSCLIENTS=('bzr::bzr'
+            'git::git'
+            'hg::mercurial'
+            'svn::subversion')
+
 #########################################################################
 # ARCHITECTURE, COMPILE FLAGS
 #########################################################################
diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c
index d232bcc..9af5e84 100644
--- a/lib/libalpm/log.c
+++ b/lib/libalpm/log.c
@@ -52,7 +52,7 @@ int SYMEXPORT alpm_logaction(alpm_handle_t *handle, const char *prefix,
 		int fd;
 		do {
 			fd = open(handle->logfile, O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC,
-					0000);
+					0644);
 		} while(fd == -1 && errno == EINTR);
 		if(fd >= 0) {
 			handle->logstream = fdopen(fd, "a");
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index e2997f6..d9ed3d3 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -574,7 +574,7 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
 	newpkg->installdate = pkg->installdate;
 	STRDUP(newpkg->packager, pkg->packager, goto cleanup);
 	STRDUP(newpkg->md5sum, pkg->md5sum, goto cleanup);
-	STRDUP(newpkg->sha256sum, pkg->md5sum, goto cleanup);
+	STRDUP(newpkg->sha256sum, pkg->sha256sum, goto cleanup);
 	STRDUP(newpkg->arch, pkg->arch, goto cleanup);
 	newpkg->size = pkg->size;
 	newpkg->isize = pkg->isize;
diff --git a/scripts/makepkg-template.pl.in b/scripts/makepkg-template.pl.in
index 6e6d944..d9da167 100755
--- a/scripts/makepkg-template.pl.in
+++ b/scripts/makepkg-template.pl.in
@@ -70,7 +70,7 @@ sub parse_template_line {
 	foreach my $element (@elements) {
 		my ($key, $val) = ($element =~ /^([a-z0-9]+)=(.*)$/);
 		unless ($key and $val) {
-			die gettext("invalid key/value pair\n%s:%s: %s"),
+			die gettext("invalid key/value pair\n"),
 				"$filename:$linenumber: $line";
 		}
 		$values{$key} = $val;
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 33dff24..da68dc7 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -362,11 +362,11 @@ download_file() {
 	# replace %o by the temporary dlfile if it exists
 	if [[ ${cmdline[*]} = *%o* ]]; then
 		dlfile=$filename.part
-		cmdline=("${cmdline[@]//%o/"$dlfile"}")
+		cmdline=("${cmdline[@]//%o/$dlfile}")
 	fi
 	# add the URL, either in place of %u or at the end
 	if [[ ${cmdline[*]} = *%u* ]]; then
-		cmdline=("${cmdline[@]//%u/"$url"}")
+		cmdline=("${cmdline[@]//%u/$url}")
 	else
 		cmdline+=("$url")
 	fi
@@ -1317,47 +1317,41 @@ verify_integrity_sums() {
 	fi
 }
 
-have_sources() {
-	local a
-
-	(( ${#source[*]} )) && return 0
+check_checksums() {
+	local integ a
+	declare -A correlation
+	(( SKIPCHECKSUMS )) && return 0
 
+	# Initialize a map which we'll use to verify that every source array has at
+	# least some kind of checksum array associated with it.
+	(( ${#source[*]} )) && correlation['source']=1
 	case $1 in
 		all)
 			for a in "${arch[@]}"; do
-				array_build _ source_"$a" && return 0
+				array_build _ source_"$a" && correlation["source_$a"]=1
 			done
 			;;
 		*)
-			array_build _ source_"$CARCH" && return 0
+			array_build _ source_"$CARCH" && correlation["source_$CARCH"]=1
 			;;
 	esac
 
-	return 1
-}
-
-check_checksums() {
-	(( SKIPCHECKSUMS )) && return 0
-	have_sources "$1" || return 0
-
-	local correlation=0
-	local integ a
 	for integ in "${known_hash_algos[@]}"; do
-		verify_integrity_sums "$integ" && correlation=1
+		verify_integrity_sums "$integ" && unset "correlation[source]"
 
 		case $1 in
 			all)
 				for a in "${arch[@]}"; do
-					verify_integrity_sums "$integ" "$a" && correlation=1
+					verify_integrity_sums "$integ" "$a" && unset "correlation[source_$a]"
 				done
 				;;
 			*)
-				verify_integrity_sums "$integ" "$CARCH" && correlation=1
+				verify_integrity_sums "$integ" "$CARCH" && unset "correlation[source_$CARCH]"
 				;;
 		esac
 	done
 
-	if (( ! correlation )); then
+	if (( ${#correlation[*]} )); then
 		error "$(gettext "Integrity checks are missing.")"
 		exit 1 # TODO: error code
 	fi
@@ -1504,7 +1498,7 @@ check_pgpsigs() {
 			esac
 			errors=1
 		else
-			if (( ${#validpgpkeys[@]} == 0 && ! $trusted )); then
+			if (( ${#validpgpkeys[@]} == 0 && !trusted )); then
 				printf "%s ($(gettext "the public key %s is not trusted"))" $(gettext "FAILED") "$fingerprint" >&2
 				errors=1
 			elif (( ${#validpgpkeys[@]} > 0 )) && ! in_array "$fingerprint" "${validpgpkeys[@]}"; then
@@ -1627,7 +1621,10 @@ merge_arch_attrs() {
 
 source_buildfile() {
 	source_safe "$@"
-	merge_arch_attrs
+
+	if (( !SOURCEONLY )); then
+		merge_arch_attrs
+	fi
 }
 
 run_function_safe() {
@@ -1835,7 +1832,7 @@ tidy_install() {
 	# check existence of backup files
 	local file
 	for file in "${backup[@]}"; do
-		if [[ ! -f $file ]]; then
+		if [[ ! -f $file && ! -h $file ]]; then
 			warning "$(gettext "%s entry file not in package : %s")" "backup" "$file"
 		fi
 	done
@@ -2469,6 +2466,9 @@ array_build() {
 	# Build an array of the indicies of the source array.
 	eval "keys=(\"\${!$2[@]}\")"
 
+	# Clear the destination array
+	eval "$dest=()"
+
 	# Read values indirectly via their index. This approach gives us support
 	# for associative arrays, sparse arrays, and empty strings as elements.
 	for i in "${keys[@]}"; do
@@ -2896,7 +2896,7 @@ get_vcsclient() {
 }
 
 check_vcs_software() {
-	local ret=0
+	local all_sources all_deps deps ret=0
 
 	if (( SOURCEONLY == 1 )); then
 		# we will not download VCS sources
@@ -2908,7 +2908,17 @@ check_vcs_software() {
 		return $ret
 	fi
 
-	for netfile in ${source[@]}; do
+	# we currently only use global depends/makedepends arrays for --syncdeps
+	for attr in depends makedepends; do
+		pkgbuild_get_attribute "$pkg" "$attr" 1 'deps'
+		all_deps+=("${deps[@]}")
+
+		pkgbuild_get_attribute "$pkg" "${attr}_$CARCH" 1 'deps'
+		all_deps+=("${deps[@]}")
+	done
+
+	get_all_sources_for_arch 'all_sources'
+	for netfile in ${all_sources[@]}; do
 		local proto=$(get_protocol "$netfile")
 
 		case $proto in
@@ -2921,7 +2931,7 @@ check_vcs_software() {
 					uninstalled="$(set +E; check_deps $client)" || exit 1
 					# if not installed, check presence in depends or makedepends
 					if [[ -n "$uninstalled" ]] && (( ! NODEPS || ( VERIFYSOURCE && !DEP_BIN ) )); then
-						if ! in_array "$client" ${depends[@]} ${makedepends[@]}; then
+						if ! in_array "$client" ${all_deps[@]}; then
 							error "$(gettext "Cannot find the %s package needed to handle %s sources.")" \
 									"$client" "${proto%%+*}"
 							ret=1
@@ -3435,7 +3445,7 @@ CARCH=${_CARCH:-$CARCH}
 if (( ! INFAKEROOT )); then
 	if (( EUID == 0 )); then
 		error "$(gettext "Running %s as root is not allowed as it can cause permanent,\n\
-catastrophic damage to your system.")"
+catastrophic damage to your system.")" "makepkg"
 		exit 1 # $E_USER_ABORT
 	fi
 else
@@ -3597,7 +3607,7 @@ if (( SOURCEONLY )); then
 		download_sources allarch
 	elif ( (( ! SKIPCHECKSUMS )) || \
 			( (( ! SKIPPGPCHECK )) && source_has_signatures ) ); then
-		download_sources novcs
+		download_sources allarch novcs
 	fi
 	check_source_integrity all
 	cd_safe "$startdir"
diff --git a/scripts/pacman-db-upgrade.sh.in b/scripts/pacman-db-upgrade.sh.in
index 7bb277b..7d01bce 100644
--- a/scripts/pacman-db-upgrade.sh.in
+++ b/scripts/pacman-db-upgrade.sh.in
@@ -19,6 +19,9 @@
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+# Avoid creating world-unreadable files
+umask 022
+
 # gettext initialization
 export TEXTDOMAIN='pacman-scripts'
 export TEXTDOMAINDIR='@localedir@'
@@ -167,6 +170,8 @@ if [[ -z "$db_version" ]]; then
 	fi
 
 	# pacman 4.1 to 4.2 upgrade - remove directory symlink support
+	msg "$(gettext "Pre-4.2 database format detected - upgrading...")"
+
 	dirlist=()
 
 	unset GREP_OPTIONS
@@ -180,8 +185,6 @@ if [[ -z "$db_version" ]]; then
 		done)
 
 	if [[ ${#dirlist[@]} != 0 ]]; then
-		msg "$(gettext "Pre-4.2 database format detected - upgrading...")"
-
 		pacroot="$(resolve_dir "$pacroot")"
 
 		for dir in "${dirlist[@]}"; do