/etckeeper/pre-commit.d/30store-metadata

http://github.com/brinkman83/bashrc · Shell · 130 lines · 69 code · 17 blank · 44 comment · 19 complexity · 98fa84fa386cd9c0fc210ea8a8009f26 MD5 · raw file

  1. #!/bin/sh
  2. set -e
  3. # Filters out UNKNOWN users and groups, prints a warning on stderr.
  4. filter_unknown() {
  5. CMD=$1
  6. while read line; do
  7. # if the first n chars of $line equal "$CMD UNKNOWN "...
  8. if [ "$(printf %.$((9+${#CMD}))s "$line")" = "$CMD UNKNOWN " ]; then
  9. echo Bad "$2" for "$line" >&2
  10. else
  11. echo "$line"
  12. fi
  13. done
  14. }
  15. filter_ignore() {
  16. if [ "$VCS" = darcs ]; then
  17. ignorefile=.darcsignore
  18. fi
  19. if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then
  20. # Spaces embedded into patterns would break it.
  21. # But really, why would anyone want to use ' ' instead of '\s' ?
  22. #patterns=$( grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" | xargs -n 1 printf " -e %s" )
  23. #grep -Ev $patterns
  24. #unset patterns
  25. # Alternative using a temp file
  26. patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
  27. grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true
  28. grep -Evf "$patternsfile"
  29. rm -f "$patternsfile"
  30. unset patternsfile
  31. else
  32. cat -
  33. fi
  34. }
  35. generate_metadata() {
  36. # This function generates the script commands to fix any files
  37. # that aren't owner=root, group=root, or mode=0644 or 0755.
  38. # The script is produced on stdout. Errors go to stderr.
  39. #
  40. # The script can use a 'maybe' function, which only runs a command
  41. # if the file in its last argument exists.
  42. # We maintain the permissions on the directory containing VCS data
  43. # but we want find to ignore the VCS files themselves.
  44. #
  45. # (Note that when using this, the find expression must end with
  46. # -print or -exec, else the excluded directories will actually be
  47. # printed!)
  48. NOVCS='. -wholename ./.git -prune -o -wholename ./.bzr -prune -o -wholename ./.hg -prune -o -wholename ./_darcs -prune -o'
  49. # Keep the sort order the same at all times.
  50. LC_COLLATE=C
  51. export LC_COLLATE
  52. if [ "$VCS" = git ] || [ "$VCS" = hg ]; then
  53. # These version control systems do not track directories,
  54. # so empty directories must be stored specially.
  55. find $NOVCS -type d -empty -print |
  56. sort | sed -e "s/^/mkdir -p '/" -e "s/\$/'/"
  57. fi
  58. if [ "$VCS" = darcs ]; then
  59. # This version control system does not track symlinks,
  60. # so they must be stored specially.
  61. find $NOVCS -type l -print | sort | filter_ignore | while read link; do
  62. dest=$( readlink "$link" )
  63. printf "ln -sf '%s' '%s'\n" "$dest" "$link"
  64. done
  65. fi
  66. # Find all files and directories that don't have the current user as the owner
  67. find $NOVCS \! -user "$(id -u)" -exec stat --format="maybe chown %U '{}'" {} \; \
  68. | sort | filter_unknown 'maybe chown' owner
  69. # Find all files and directories that don't have root as the group
  70. find $NOVCS \! -group $(id -g) -exec stat --format="maybe chgrp %G '{}'" {} \; \
  71. | sort | filter_unknown 'maybe chgrp' group
  72. # Find all directories that aren't 0755
  73. find $NOVCS -type d \! -perm 0755 \
  74. -exec stat --format="maybe chmod %a '{}'" {} \; | sort
  75. if [ "$VCS" = darcs ]; then
  76. # Find all files that aren't 0644 (darcs doesn't maintain
  77. # the executable bit).
  78. find $NOVCS -type f \! -perm 0644 \
  79. -exec stat --format="maybe chmod %a '{}'" {} \; | sort
  80. else
  81. # Find all files that aren't 0644 or 0755 (we can assume the VCS will
  82. # maintain the executable bit).
  83. find $NOVCS -type f \! -perm 0644 \! -perm 0755 \
  84. -exec stat --format="maybe chmod %a '{}'" {} \; | sort
  85. fi
  86. # We don't handle xattrs.
  87. # Maybe check for getfattr/setfattr and use them if they're available?
  88. }
  89. if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
  90. if [ -f .metadata ]; then
  91. # remove obsolete .metadata file
  92. # git allows fully deleting it at this point, other VCS
  93. # may not (the repo is locked for hg).
  94. if [ "$VCS" = git ]; then
  95. $VCS rm .metadata
  96. else
  97. rm -f .metadata
  98. fi
  99. fi
  100. echo "# Generated by etckeeper. Do not edit." > .etckeeper
  101. echo >> .etckeeper
  102. # Make sure the file is not readable by others, since it can leak
  103. # information about contents of non-readable directories in /etc.
  104. chmod 700 .etckeeper
  105. generate_metadata >> .etckeeper
  106. # stage the file as part of the current commit
  107. if [ "$VCS" = git ]; then
  108. # this will do nothing if the metadata file is unchanged.
  109. git add .etckeeper
  110. fi
  111. # hg, bzr and darcs add not done, they will automatically
  112. # include the file in the current commit
  113. fi