summaryrefslogtreecommitdiffstats
path: root/prebuilt/common/bin/backuptool_ab.sh
blob: 157110f8dae89d82f90582943f1e27c397742929 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/system/bin/sh
#
# Backup and restore addon /system files
#

export S=/system
export C=/postinstall/tmp/backupdir
export V=16.0

export ADDOND_VERSION=2

# Scripts in /system/addon.d expect to find backuptool.functions in /tmp
mkdir -p /postinstall/tmp/
cp -f /postinstall/system/bin/backuptool_ab.functions /postinstall/tmp/backuptool.functions

# Preserve /system/addon.d in /tmp/addon.d
preserve_addon_d() {
  if [ -d /system/addon.d/ ]; then
    mkdir -p /postinstall/tmp/addon.d/
    cp -a /system/addon.d/* /postinstall/tmp/addon.d/

    # Discard any scripts that aren't at least our version level
    for f in /postinstall/tmp/addon.d/*sh; do
      SCRIPT_VERSION=$(grep "^# ADDOND_VERSION=" $f | cut -d= -f2)
      if [ -z "$SCRIPT_VERSION" ]; then
        SCRIPT_VERSION=1
      fi
      if [ $SCRIPT_VERSION -lt $ADDOND_VERSION ]; then
        rm $f
      fi
    done

    chmod 755 /postinstall/tmp/addon.d/*.sh
  fi
}

# Restore /postinstall/system/addon.d from /postinstall/tmp/addon.d
restore_addon_d() {
  if [ -d /postinstall/tmp/addon.d/ ]; then
    mkdir -p /postinstall/system/addon.d/
    cp -a /postinstall/tmp/addon.d/* /postinstall/system/addon.d/
    rm -rf /postinstall/tmp/addon.d/
  fi
}

# Proceed only if /system is the expected major and minor version
check_prereq() {
# If there is no build.prop file the partition is probably empty.
if [ ! -r /system/build.prop ]; then
    return 0
fi

grep -q "^ro.lineage.version=$V.*" /system/build.prop && return 1

echo "Not backing up files from incompatible version: $V"
return 0
}

check_blacklist() {
  if [ -f /system/addon.d/blacklist -a -d /$1/addon.d/ ]; then
      ## Discard any known bad backup scripts
      cd /$1/addon.d/
      for f in *sh; do
          [ -f $f ] || continue
          s=$(md5sum $f | cut -c-32)
          grep -q $s /system/addon.d/blacklist && rm -f $f
      done
  fi
}

check_whitelist() {
  found=0
  if [ -f /system/addon.d/whitelist ];then
      ## forcefully keep any version-independent stuff
      cd /$1/addon.d/
      for f in *sh; do
          s=$(md5sum $f | cut -c-32)
          grep -q $s /system/addon.d/whitelist
          if [ $? -eq 0 ]; then
              found=1
          else
              rm -f $f
          fi
      done
  fi
  return $found
}

# Execute /system/addon.d/*.sh scripts with $1 parameter
run_stage() {
if [ -d /postinstall/tmp/addon.d/ ]; then
  for script in $(find /postinstall/tmp/addon.d/ -name '*.sh' |sort -n); do
    # we have no /sbin/sh in android, only recovery
    # use /system/bin/sh here instead
    sed -i '0,/#!\/sbin\/sh/{s|#!/sbin/sh|#!/system/bin/sh|}' $script
    # we can't count on /tmp existing on an A/B device, so utilize /postinstall/tmp
    # as a pseudo-/tmp dir
    sed -i 's|. /tmp/backuptool.functions|. /postinstall/tmp/backuptool.functions|g' $script
    $script $1
  done
fi
}

case "$1" in
  backup)
    mkdir -p $C
    if check_prereq; then
        if check_whitelist postinstall/system; then
            exit 127
        fi
    fi
    check_blacklist postinstall/system
    preserve_addon_d
    run_stage pre-backup
    run_stage backup
    run_stage post-backup
  ;;
  restore)
    if check_prereq; then
        if check_whitelist postinstall/tmp; then
            exit 127
        fi
    fi
    check_blacklist postinstall/tmp
    run_stage pre-restore
    run_stage restore
    run_stage post-restore
    restore_addon_d
    rm -rf $C
    rm -rf /postinstall/tmp
    sync
  ;;
  *)
    echo "Usage: $0 {backup|restore}"
    exit 1
esac

exit 0