Advertisement
Guest User

Untitled

a guest
Dec 8th, 2016
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 2.51 KB | None | 0 0
  1. #!/bin/bash
  2. # btrfs-undelete
  3. # Copyright (C) 2013 Jörg Walter <info@syntax-k.de>
  4. # This program is free software; you can redistribute it and/or modify it under
  5. # the term of the GNU General Public License as published by the Free Software
  6. # Foundation; either version 2 of the License, or any later version.
  7.  
  8. if [ ! -b "$1" -o -z "$2" -o -z "$3" ]; then
  9.     echo "Usage: $0 <dev> <file/dir> <dest>" 1>&2
  10.     echo
  11.     echo "This program tries to recover the most recent version of the"
  12.     echo "given file or directory (recursively)"
  13.     echo
  14.     echo "<dev> must not be mounted, otherwise this program may appear"
  15.     echo "to work but find nothing."
  16.     echo
  17.     echo "<file/dir> must be specified relative to the filesystem root,"
  18.     echo "obviously. It may contain * and ? as wildcards, but in that"
  19.     echo "case, empty files might be 'recovered'. If <file/dir> is a"
  20.     echo "single file name, this program tries to recover the most"
  21.     echo "recent non-empty version of the file."
  22.     echo
  23.     echo "<dest> must be a writable directory with enough free space"
  24.     echo "to hold the files you're trying to restore."
  25.     exit 1
  26. fi
  27. dev="$1"
  28. file="$2"
  29.  
  30. file="${file#/}"
  31. file="${file%/}"
  32. regex="${file//\\/\\\\}"
  33.  
  34. # quote regex special characters
  35. regex="${regex//./\.}"
  36. regex="${regex//+/\+}"
  37. regex="${regex//|/\|}"
  38. regex="${regex//(/\(}"
  39. regex="${regex//)/\)}"
  40. regex="${regex//\[/\[}"
  41. regex="${regex//]/\]}"
  42. regex="${regex//\{/\{}"
  43. regex="${regex//\}/\}}"
  44.  
  45. # treat shell wildcards specially
  46. regex="${regex//\*/.*}"
  47. regex="${regex//\?/.}"
  48.  
  49. # extract number of slashes in order to get correct number of closing parens
  50. slashes="${regex//[^\/]/}"
  51.  
  52. # build final regex
  53. regex="^/(|${regex//\//(|/}(|/.*${slashes//?/)}))\$"
  54.  
  55. roots="$(mktemp --tmpdir btrfs-undelete.roots.XXXXX)"
  56. out="$(mktemp --tmpdir="$3" -d btrfs-undelete.XXXXX)"
  57. cd $out
  58.  
  59. trap "rm $roots" EXIT
  60. trap "rm -r $out &> /dev/null; exit 1" SIGINT
  61.  
  62. echo -ne "Searching roots..."
  63. btrfs-find-root "$dev" 2>&1 \
  64.     | grep ^Well \
  65.     | sed -r -e 's/Well block ([0-9]+).*/\1/' \
  66.     | sort -rn >$roots || exit 1
  67. echo
  68.  
  69. i=0
  70. max="$(wc -l <$roots)"
  71.  
  72. while read id; do
  73.     ((i+=1))
  74.     echo -e "Trying root $id... ($i/$max)"
  75.     btrfs restore -t $id --path-regex "$regex" "$dev" . &>/dev/null
  76.     if [ "$?" = 0 ]; then
  77.         found=$(find . -type f ! -size 0c | wc -l)
  78.         if [ $found -gt 0 ]; then
  79.             echo "Recovered $found non-empty file(s) into $out"
  80.             exit 0
  81.         fi
  82.         find . -type f -size 0c -exec echo "Found {} but it's empty" \; -delete
  83.     fi
  84. done <$roots
  85. rm -r $out
  86. echo "Didn't find '$file'"
  87. exit 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement