releasing version 0.14
[jelmer/etckeeper.git] / pre-commit.d / 30store-metadata
1 #!/bin/sh
2 set -e
3
4
5 # Filters out UNKNOWN users and groups, prints a warning on stderr.
6 filter_unknown() {
7         CMD=$1
8         while read line; do
9                 # if the first n chars of $line equal "$CMD UNKNOWN "...
10                 if [ "$(printf %.$((9+${#CMD}))s "$line")" = "$CMD UNKNOWN " ]; then
11                         echo Bad "$2" for "$line" >&2
12                 else
13                         echo "$line"
14                 fi
15         done
16 }
17
18
19 generate_metadata() {
20         # This function generates the script commands to fix any files
21         # that aren't owner=root, group=root, or mode=0644 or 0755.
22         # The script is produced on stdout.  Errors go to stderr.
23
24         # We maintain the permissions on the directory containing VCS data
25         # but we want find to ignore the VCS files themselves.
26         NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o'
27
28         if [ "$VCS" = git ] || [ "$VCS" = hg ]; then
29                 # These version control systems do not track directories,
30                 # so empty directories must be stored specially.
31                 find -type d -empty | grep -v /.git/ | grep -v /.hg/ | grep -v /.bzr/ |
32                         sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/"
33         fi
34
35         # Find all files and directories that don't have root as the owner
36         find $NOVCS \! -user root -exec stat --format="chown %U '{}'" {} \; \
37                 | sort | filter_unknown chown owner
38         # Find all files and directories that don't have root as the group
39         find $NOVCS \! -group root -exec stat --format="chgrp %G '{}'" {} \; \
40                 | sort | filter_unknown chgrp group
41
42         # Find all directories that aren't 0755
43         find $NOVCS -type d \! -perm 0755 \
44                 -exec stat --format="chmod %a '{}'" {} \; | sort
45
46         # Find all files that aren't 0644 or 0755 (we can assume the VCS will
47         # maintain the executable bit).
48         find $NOVCS -type f \! -perm 0644 \! -perm 0755 \
49                 -exec stat --format="chmod %a '{}'" {} \; | sort
50
51         # We don't handle xattrs.
52         # Maybe check for getfattr/setfattr and use them if they're available?
53 }
54
55
56 if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ]; then
57         if [ -f .metadata ]; then
58                 # remove obsolete .metadata file
59                 # git allows fully deleting it at this point, other VCS
60                 # may not (the repo is locked for hg).
61                 if [ "$VCS" = git ]; then
62                         $VCS rm .metadata
63                 else
64                         rm -f .metadata
65                 fi
66         fi
67
68         echo "# Generated by etckeeper.  Do not edit." > .etckeeper
69         echo >> .etckeeper
70
71         # Make sure the file is not readable by others, since it can leak
72         # information about contents of non-readable directories in /etc.
73         chmod 700 .etckeeper
74
75         generate_metadata >> .etckeeper
76
77         # stage the file as part of the current commit
78         if [ "$VCS" = git ]; then
79                 # this will do nothing if the metadata file is unchanged.
80                 git add .etckeeper
81         fi
82         # hg and bzr add not done, they will automatically
83         # include the file in the current commit
84 fi