summaryrefslogtreecommitdiff
path: root/pre-commit.d/30store-metadata
blob: 5190a2c5c691428c7144fc8060f0266e1f654896 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/sh
set -e


# Filters out UNKNOWN users and groups, prints a warning on stderr.
filter_unknown() {
	CMD=$1
	while read line; do
		if [ "${line:0:8+${#CMD}}" = "$CMD UNKNOWN" ]; then
			# error message like "Bad owner for ./ppp/peers"
			echo Bad "$2" for "${line:9+${#CMD}}" >&2
		else
			echo "$line"
		fi
	done
}

generate_metadata() {
	# This function generates the script commands to fix any files
	# that aren't owner=root, group=root, or mode=0644 or 0755.
	# The script is produced on stdout.  Errors go to stderr.

	# We maintain the permissions on the directory containing VCS data
	# but we want find to ignore the VCS files themselves.
	NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o'

	# Find all files and directories that don't have root as the owner
	find $NOVCS \! -user root -exec stat --format="chown %U {}" {} \; \
		| sort | filter_unknown chown owner
	# Find all files and directories that don't have root as the group
	find $NOVCS \! -group root -exec stat --format="chgrp %G {}" {} \; \
		| sort | filter_unknown chgrp group

	# Find all directories that aren't 0755
	find $NOVCS -type d \! -perm 0755 \
		-exec stat --format="chmod %a {}" {} \; | sort

	# Find all files that aren't 0644 or 0755 (we can assume the VCS will
	# maintain the executable bit).
	find $NOVCS -type f \! -perm 0644 \! -perm 0755 \
		-exec stat --format="chmod %a {}" {} \; | sort

	# We don't handle xattrs.
	# Maybe check for getfattr/setfattr and use them if they're available?
}


if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
	# ensure the file exists so that it will list its own metadata
	if [ ! -e .fix-metadata ]; then
		touch .fix-metadata
		# Make sure the file is not readable by others, since it can leak
		# information about contents of non-readable directories in /etc.
		chmod 700 .fix-metadata
	fi

	echo "# Generated by etckeeper." > .fix-metadata
	echo >> .fix-metadata
	generate_metadata >> .fix-metadata

	# stage the file as part of the current commit
	if [ "$VCS" = git ]; then
		# this will do nothing if the metadata file is unchanged.
		git add .fix-metadata
	fi
	# hg and bzr add not done, they will automatically
	# include the file in the current commit
fi