Layer for changing content of /system
* create system tree named 'panini'
panini/priv-app/delicious/delicious.apk
panini/priv-app/dict/dict.apk
panini/etc/dict/...
* adb push 01make_panini /data/local/tmp
* adb push panini /data/local/tmp
* adb shell
* su
* cp /data/local/tmp/01make_panini /su/su.d/01make_panini
* chmod 755 /su/su.d/01make_panini
* cp -r /data/local/tmp/panini /su/panini
* find /su/panini -type d -exec chmod 755 {} \;
* find /su/panini -type f -exec chmod 644 {} \;
* chown -R root:root /su/panini
* reboot
* for disable panini: touch /su/etc/disable_panini
#!/system/bin/sh
# Panini by shakalaca@23pin
LOG_FILE=/cache/panini.log
DISABLE_FILE=/su/etc/disable_panini
ROOT_MNT_SYSTEM=/su/mnt/system
ROOT_BIND_SYSTEM=/su/system_bind
ROOT_PANINI=/su/panini
# set to true if you want to use /system/vendor/app instead of /oem
# remember to do 'cp -af /system/vendor/app/* /su/panini/app/'
USE_VENDOR_APP=false
# before you try to disable this please turn on 'Enable su during boot'
JUST_INSTALL_SYSTEM_APP=true
log_d() {
echo $1
echo $1 >> $LOG_FILE
log -p i -t PANINI "$1"
}
bind_mount() {
mount -o bind $1 $2 &
log_d "Glue $1 and $2 together"
}
is_mounted() {
if [ ! -z "$2" ]; then
cat /proc/mounts | grep $1 | grep $2, >/dev/null
else
cat /proc/mounts | grep $1 >/dev/null
fi
return $?
}
get_mount_dev() {
_mount=`cat /proc/mounts | grep "$1"`
echo ${_mount% /*}
}
process() {
if [ "$1" == "/system" ]; then
# one level only:
# system/<input>/dir
EXTRA_OPT="-maxdepth 1"
else
EXTRA_OPT=""
fi
for t in `find $1/$2 $EXTRA_OPT -type d -o -type l -o -type f`; do
bind_fpath=$ROOT_BIND_SYSTEM${t#$1}
panini_fpath=$ROOT_PANINI${t#$1}
if [ -d $t ]; then
# skip removed content
if [ -f $panini_fpath/.remove ]; then
echo Skipping $t
rmdir $bind_fpath
else
mkdir -p $bind_fpath
chmod 755 $bind_fpath
fi
continue
fi
if [ -L $t ]; then
# copy link file
cp -af $t $bind_fpath
elif [ -f $t ]; then
# skip '.remove'
if [ "${t##*/}" != ".remove" ]; then
touch $bind_fpath
chmod 644 $bind_fpath
fi
fi
done
}
install_system_app() {
if [ -d /system/vendor/app ] && ($USE_VENDOR_APP); then
bind_mount $ROOT_PANINI/app /system/vendor/app
else
if ( is_mounted /oem ); then
mount -o rw,remount /oem
else
mount -o rw,remount /
fi
if [ ! -d /oem ]; then
mkdir /oem
chmod 755 /oem
fi
if [ ! -d /oem/app ]; then
mkdir /oem/app
fi
chmod 755 /oem/app
chcon u:object_r:system_file:s0 /oem/app
bind_mount $ROOT_PANINI/app /oem/app
fi
}
exclude_system_app() {
for app in `ls $ROOT_PANINI/app`; do
if [ -f $ROOT_PANINI/app/$app/.remove ]; then
bind_mount $ROOT_PANINI/app/$app /system/app/$app
fi
done
}
if [ ! -d $ROOT_PANINI ]; then
exit 0
fi
if [ -f $DISABLE_FILE ]; then
exit 0
fi
if [ ! $(is_mounted $ROOT_MNT_SYSTEM )]; then
# clean up the kitchen
rm -f $LOG_FILE
rm -rf $ROOT_BIND_SYSTEM
# preparing bread
# remove old tree
mkdir -p $ROOT_BIND_SYSTEM
chmod 755 $ROOT_BIND_SYSTEM
mkdir -p $ROOT_MNT_SYSTEM
chmod 755 $ROOT_MNT_SYSTEM
mount -r -t ext4 $(get_mount_dev " /system ") $ROOT_MNT_SYSTEM
# preparing roast beef
# traverse panini directory
for dir in `ls $ROOT_PANINI`; do
# do not allow new root directory of /system
if [ -d $ROOT_PANINI/$dir ] && [ -d /system/$dir ]; then
if [ "$dir" == "app" ] && ($JUST_INSTALL_SYSTEM_APP); then
install_system_app
exclude_system_app
else
process $ROOT_PANINI $dir
process /system $dir
bind_mount $ROOT_BIND_SYSTEM/$dir /system/$dir
fi
fi
done
# lets do it !
for bind_f in `find $ROOT_BIND_SYSTEM -type f -o -type d`; do
TARGET=/system${bind_f#$ROOT_BIND_SYSTEM}
PANINI=$ROOT_PANINI${bind_f#$ROOT_BIND_SYSTEM}
ORIGIN=$ROOT_MNT_SYSTEM${bind_f#$ROOT_BIND_SYSTEM}
if [ -d $PANINI ]; then
# skip directory for panini (mount file instead)
log_d "Using panini for $TARGET"
elif [ -f $PANINI ]; then
bind_mount $PANINI $TARGET
else
bind_mount $ORIGIN $TARGET
fi
done
fi