Magisk/scripts/magic_mask.sh

563 lines
16 KiB
Bash
Raw Normal View History

2016-09-14 04:31:13 +02:00
#!/system/bin/sh
LOGFILE=/cache/magisk.log
IMG=/data/magisk.img
MOUNTPOINT=/magisk
2016-10-06 11:53:52 +02:00
COREDIR=$MOUNTPOINT/.core
2016-09-14 04:31:13 +02:00
TMPDIR=/dev/magisk
DUMMDIR=$TMPDIR/dummy
MIRRDIR=$TMPDIR/mirror
MOUNTINFO=$TMPDIR/mnt
2016-09-14 04:31:13 +02:00
# Use the included busybox for maximum compatibility and reliable results
# e.g. we rely on the option "-c" for cp (reserve contexts), and -exec for find
TOOLPATH=/data/busybox
2016-11-04 19:38:02 +01:00
BINPATH=/data/magisk
2016-11-28 21:16:01 +01:00
export OLDPATH=$PATH
export PATH=$TOOLPATH:$OLDPATH
2016-11-13 09:58:43 +01:00
# Default permissions
umask 022
2016-09-14 04:31:13 +02:00
log_print() {
2016-10-31 21:21:43 +01:00
echo "$1"
echo "$1" >> $LOGFILE
2016-09-14 04:31:13 +02:00
log -p i -t Magisk "$1"
}
mktouch() {
mkdir -p ${1%/*} 2>/dev/null
if [ -z "$2" ]; then
2016-11-13 21:30:05 +01:00
touch "$1" 2>/dev/null
2016-09-14 04:31:13 +02:00
else
2016-11-13 21:30:05 +01:00
echo "$2" > "$1" 2>/dev/null
2016-09-14 04:31:13 +02:00
fi
}
unblock() {
2016-10-02 22:34:50 +02:00
touch /dev/.magisk.unblock
2016-09-14 04:31:13 +02:00
exit
}
run_scripts() {
2016-10-06 11:53:52 +02:00
BASE=$MOUNTPOINT
2016-09-14 04:31:13 +02:00
for MOD in $BASE/* ; do
if [ ! -f "$MOD/disable" ]; then
if [ -f "$MOD/$1.sh" ]; then
chmod 755 $MOD/$1.sh
chcon "u:object_r:system_file:s0" "$MOD/$1.sh"
2016-09-14 04:31:13 +02:00
log_print "$1: $MOD/$1.sh"
sh $MOD/$1.sh
2016-09-14 04:31:13 +02:00
fi
fi
done
}
loopsetup() {
LOOPDEVICE=
for DEV in $(ls /dev/block/loop*); do
2016-11-13 21:30:05 +01:00
if [ `losetup $DEV $1 >/dev/null 2>&1; echo $?` -eq 0 ]; then
2016-09-14 04:31:13 +02:00
LOOPDEVICE=$DEV
break
fi
done
}
target_size_check() {
e2fsck -p -f $1
curBlocks=`e2fsck -n $1 2>/dev/null | cut -d, -f3 | cut -d\ -f2`;
curUsedM=$((`echo "$curBlocks" | cut -d/ -f1` * 4 / 1024));
curSizeM=$((`echo "$curBlocks" | cut -d/ -f2` * 4 / 1024));
curFreeM=$((curSizeM - curUsedM));
}
travel() {
cd "$TRAVEL_ROOT/$1"
2016-09-14 04:31:13 +02:00
if [ -f ".replace" ]; then
rm -rf "$MOUNTINFO/$1"
mktouch "$MOUNTINFO/$1" "$TRAVEL_ROOT"
2016-09-14 04:31:13 +02:00
else
for ITEM in * ; do
if [ ! -e "/$1/$ITEM" ]; then
2016-09-14 04:31:13 +02:00
# New item found
if [ "$1" = "system" ]; then
2016-09-14 04:31:13 +02:00
# We cannot add new items to /system root, delete it
rm -rf "$ITEM"
2016-09-14 04:31:13 +02:00
else
# If we are in a higher level, delete the lower levels
rm -rf "$MOUNTINFO/dummy/$1"
2016-09-14 04:31:13 +02:00
# Mount the dummy parent
mktouch "$MOUNTINFO/dummy/$1"
2016-09-14 04:31:13 +02:00
if [ -d "$ITEM" ]; then
# Create new dummy directory and mount it
mkdir -p "$DUMMDIR/$1/$ITEM"
mktouch "$MOUNTINFO/$1/$ITEM" "$TRAVEL_ROOT"
2016-09-14 04:31:13 +02:00
elif [ -L "$ITEM" ]; then
# Symlinks are small, copy them
mkdir -p "$DUMMDIR/$1" 2>/dev/null
cp -afc "$ITEM" "$DUMMDIR/$1/$ITEM"
2016-09-14 04:31:13 +02:00
else
# Create new dummy file and mount it
mktouch "$DUMMDIR/$1/$ITEM"
mktouch "$MOUNTINFO/$1/$ITEM" "$TRAVEL_ROOT"
2016-09-14 04:31:13 +02:00
fi
fi
else
if [ -d "$ITEM" ]; then
# It's an directory, travel deeper
(travel "$1/$ITEM")
elif [ ! -L "$ITEM" ]; then
# Mount this file
mktouch "$MOUNTINFO/$1/$ITEM" "$TRAVEL_ROOT"
fi
2016-09-14 04:31:13 +02:00
fi
done
fi
}
2016-09-14 04:31:13 +02:00
clone_dummy() {
for ITEM in $1/* ; do
if [ ! -e "$TRAVEL_ROOT$ITEM" ]; then
2016-11-28 21:16:01 +01:00
if [ ! -d "$MOUNTINFO$ITEM" ]; then
if [ -L "$ITEM" ]; then
# Copy original symlink
cp -afc "$ITEM" "$TRAVEL_ROOT$ITEM"
2016-11-28 21:16:01 +01:00
else
# Link to mirror item
ln -s "$MIRRDIR$ITEM" "$TRAVEL_ROOT$ITEM"
2016-11-28 21:16:01 +01:00
fi
else
2016-11-28 21:16:01 +01:00
# Need to clone a skeleton
(clone_dummy "$ITEM")
2016-09-14 04:31:13 +02:00
fi
elif [ -d "$TRAVEL_ROOT$ITEM" ]; then
2016-11-28 21:16:01 +01:00
# Need to clone a skeleton
(clone_dummy "$ITEM")
fi
done
2016-09-14 04:31:13 +02:00
}
make_copy_image() {
TARGETSIZE=$2
if [ -z $TARGETSIZE ]; then
TARGETSIZE=`du -s $1 | awk '{print $1}'`
TARGETSIZE=$((($TARGETSIZE / 10240 + 2) * 10240))
fi
TARGETIMG=/data/magisk/${1//\//_}.img
make_ext4fs -l ${TARGETSIZE}K -a $1 $TARGETIMG
loopsetup $TARGETIMG
mkdir -p $MIRRDIR/copy$1
mount -t ext4 -o rw,noatime $LOOPDEVICE $MIRRDIR/copy$1
return $?
}
mount_copy_image() {
TARGETIMG=/data/magisk/${1//\//_}.img
umount $MIRRDIR/copy$1
rm -rf $MIRRDIR/copy
losetup -d $LOOPDEVICE 2>/dev/null
loopsetup $TARGETIMG
mount -t ext4 -o rw,noatime $LOOPDEVICE $1
return $?
}
2016-09-14 04:31:13 +02:00
bind_mount() {
if [ -e "$1" -a -e "$2" ]; then
mount -o bind $1 $2
2016-10-06 11:53:52 +02:00
if [ "$?" -eq "0" ]; then
log_print "Mount: $1"
else
log_print "Mount Fail: $1"
fi
2016-09-14 04:31:13 +02:00
fi
}
merge_image() {
if [ -f "$1" ]; then
log_print "$1 found"
if [ -f "$IMG" ]; then
log_print "$IMG found, attempt to merge"
# Handle large images
target_size_check $1
MERGEUSED=$curUsedM
target_size_check $IMG
if [ "$MERGEUSED" -gt "$curFreeM" ]; then
NEWDATASIZE=$((((MERGEUSED + curUsedM) / 32 + 2) * 32))
log_print "Expanding $IMG to ${NEWDATASIZE}M..."
resize2fs $IMG ${NEWDATASIZE}M
fi
# Start merging
mkdir /cache/data_img
mkdir /cache/merge_img
# setup loop devices
loopsetup $IMG
LOOPDATA=$LOOPDEVICE
log_print "$LOOPDATA $IMG"
loopsetup $1
LOOPMERGE=$LOOPDEVICE
log_print "$LOOPMERGE $1"
if [ ! -z "$LOOPDATA" ]; then
if [ ! -z "$LOOPMERGE" ]; then
# if loop devices have been setup, mount images
OK=true
if [ `mount -t ext4 -o rw,noatime $LOOPDATA /cache/data_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
OK=false
fi
if [ `mount -t ext4 -o rw,noatime $LOOPMERGE /cache/merge_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
OK=false
fi
if $OK; then
2016-09-14 04:31:13 +02:00
# Merge (will reserve selinux contexts)
2016-10-02 22:34:50 +02:00
cd /cache/merge_img
for MOD in *; do
if [ "$MOD" != "lost+found" ]; then
log_print "Merging: $MOD"
rm -rf /cache/data_img/$MOD
fi
2016-10-02 22:34:50 +02:00
done
2016-11-13 21:30:05 +01:00
cp -afc . /cache/data_img
2016-10-02 22:34:50 +02:00
log_print "Merge complete"
2016-11-08 22:17:14 +01:00
cd /
2016-09-14 04:31:13 +02:00
fi
umount /cache/data_img
umount /cache/merge_img
fi
fi
2016-11-13 21:30:05 +01:00
losetup -d $LOOPDATA
losetup -d $LOOPMERGE
2016-09-14 04:31:13 +02:00
rmdir /cache/data_img
rmdir /cache/merge_img
else
log_print "Moving $1 to $IMG "
mv $1 $IMG
fi
rm -f $1
fi
}
case $1 in
post-fs )
mv $LOGFILE /cache/last_magisk.log
touch $LOGFILE
chmod 644 $LOGFILE
# No more cache mods!
# Only for multirom!
2016-09-14 04:31:13 +02:00
2016-11-08 22:17:14 +01:00
log_print "** Magisk post-fs mode running..."
2016-11-13 14:02:35 +01:00
# Cleanup previous version stuffs...
2016-11-07 16:57:21 +01:00
rm -rf /cache/magisk /cache/magisk_merge /cache/magiskhide.log
2016-11-04 19:38:02 +01:00
2016-11-13 14:02:35 +01:00
if [ -d "/cache/magisk_mount" ]; then
log_print "* Mounting cache files"
2016-11-13 14:02:35 +01:00
find /cache/magisk_mount -type f 2>/dev/null | while read ITEM ; do
2016-11-08 22:17:14 +01:00
chmod 644 "$ITEM"
chcon "u:object_r:system_file:s0" "$ITEM"
2016-11-13 14:02:35 +01:00
TARGET="${ITEM#/cache/magisk_mount}"
2016-11-08 22:17:14 +01:00
bind_mount "$ITEM" "$TARGET"
done
fi
2016-09-14 04:31:13 +02:00
unblock
;;
post-fs-data )
if [ `mount | grep " /data " >/dev/null 2>&1; echo $?` -ne 0 ]; then
# /data not mounted yet, we will be called again later
unblock
fi
if [ `mount | grep " /data " | grep "tmpfs" >/dev/null 2>&1; echo $?` -eq 0 ]; then
# /data not mounted yet, we will be called again later
unblock
fi
# Don't run twice
2016-11-04 19:38:02 +01:00
if [ "`getprop magisk.restart_pfsd`" != "1" ]; then
2016-09-14 04:31:13 +02:00
2016-10-31 21:21:43 +01:00
log_print "** Magisk post-fs-data mode running..."
2016-10-02 22:34:50 +02:00
# Cache support
if [ -d "/cache/data_bin" ]; then
2016-11-04 19:38:02 +01:00
rm -rf $BINPATH $TOOLPATH
mkdir -p $TOOLPATH
mv /cache/data_bin $BINPATH
chmod -R 755 $BINPATH $TOOLPATH
$BINPATH/busybox --install -s $TOOLPATH
ln -s $BINPATH/busybox $TOOLPATH/busybox
# Prevent issues
2016-11-04 19:38:02 +01:00
rm -f $TOOLPATH/su $TOOLPATH/sh
2016-09-14 04:31:13 +02:00
fi
mv /cache/stock_boot.img /data 2>/dev/null
2016-09-14 04:31:13 +02:00
2016-11-13 21:30:05 +01:00
find $BINPATH -exec chcon -h "u:object_r:system_file:s0" {} \;
find $TOOLPATH -exec chcon -h "u:object_r:system_file:s0" {} \;
2016-11-13 09:58:43 +01:00
chmod -R 755 $BINPATH $TOOLPATH
2016-09-14 04:31:13 +02:00
2016-11-28 21:16:01 +01:00
# Live patch sepolicy
$BINPATH/sepolicy-inject --live -s su
# Multirom functions should go here, not available right now
MULTIROM=false
# Image merging
chmod 644 $IMG /cache/magisk.img /data/magisk_merge.img 2>/dev/null
merge_image /cache/magisk.img
merge_image /data/magisk_merge.img
2016-09-14 04:31:13 +02:00
# Mount magisk.img
[ ! -d $MOUNTPOINT ] && mkdir -p $MOUNTPOINT
if [ `cat /proc/mounts | grep $MOUNTPOINT >/dev/null 2>&1; echo $?` -ne 0 ]; then
loopsetup $IMG
if [ ! -z "$LOOPDEVICE" ]; then
mount -t ext4 -o rw,noatime $LOOPDEVICE $MOUNTPOINT
fi
2016-09-14 04:31:13 +02:00
fi
if [ `cat /proc/mounts | grep $MOUNTPOINT >/dev/null 2>&1; echo $?` -ne 0 ]; then
log_print "magisk.img mount failed, nothing to do :("
unblock
2016-09-14 04:31:13 +02:00
fi
# Remove empty directories, legacy paths, symlinks, old temporary images
2016-11-13 21:30:05 +01:00
find $MOUNTPOINT -type d -depth ! -path "*core*" -exec rmdir {} \; 2>/dev/null
rm -rf $COREDIR/bin $COREDIR/dummy $COREDIR/mirror /data/magisk/*.img
2016-09-14 04:31:13 +02:00
# Remove modules that is labeled to be removed
for MOD in $MOUNTPOINT/* ; do
2016-11-13 14:02:35 +01:00
if [ -f "$MOD/remove" ] || [ "$MOD" = "zzsupersu" ]; then
log_print "Remove module: $MOD"
rm -rf $MOD
fi
done
# Unmount, shrink, remount
if [ `umount $MOUNTPOINT >/dev/null 2>&1; echo $?` -eq 0 ]; then
2016-11-13 21:30:05 +01:00
losetup -d $LOOPDEVICE
target_size_check $IMG
NEWDATASIZE=$(((curUsedM / 32 + 2) * 32))
if [ "$curSizeM" -gt "$NEWDATASIZE" ]; then
log_print "Shrinking $IMG to ${NEWDATASIZE}M..."
resize2fs $IMG ${NEWDATASIZE}M
fi
loopsetup $IMG
if [ ! -z "$LOOPDEVICE" ]; then
mount -t ext4 -o rw,noatime $LOOPDEVICE $MOUNTPOINT
fi
if [ `cat /proc/mounts | grep $MOUNTPOINT >/dev/null 2>&1; echo $?` -ne 0 ]; then
log_print "magisk.img mount failed, nothing to do :("
unblock
fi
fi
2016-09-14 04:31:13 +02:00
log_print "* Preparing modules"
2016-09-14 04:31:13 +02:00
mkdir -p $DUMMDIR
mkdir -p $MIRRDIR/system
2016-09-14 04:31:13 +02:00
# Travel through all mods
for MOD in $MOUNTPOINT/* ; do
if [ -f "$MOD/auto_mount" -a -d "$MOD/system" -a ! -f "$MOD/disable" ]; then
TRAVEL_ROOT=$MOD
(travel system)
fi
done
2016-11-13 21:30:05 +01:00
# Proper permissions for generated items
find $TMPDIR -exec chcon -h "u:object_r:system_file:s0" {} \;
# linker(64), t*box required for bin
if [ -f "$MOUNTINFO/dummy/system/bin" ]; then
cp -afc /system/bin/linker* /system/bin/t*box $DUMMDIR/system/bin/
2016-11-13 21:30:05 +01:00
fi
BACKUPLIBS=false
# Libraries are full of issues, copy a full clone to data
# lib
2016-11-13 21:30:05 +01:00
if [ -f "$MOUNTINFO/dummy/system/lib" ]; then
BACKUPLIBS=true
make_copy_image /system/lib
cp -afc /system/lib/. $MIRRDIR/copy/system/lib
cp -afc $DUMMDIR/system/lib/. $MIRRDIR/copy/system/lib
mount_copy_image /system/lib
rm -f $MOUNTINFO/dummy/system/lib
2016-11-13 21:30:05 +01:00
fi
# lib64
2016-11-13 21:30:05 +01:00
if [ -f "$MOUNTINFO/dummy/system/lib64" ]; then
BACKUPLIBS=true
make_copy_image /system/lib64
cp -afc /system/lib64/. $MIRRDIR/copy/system/lib64
cp -afc $DUMMDIR/system/lib64/. $MIRRDIR/copy/system/lib64
mount_copy_image /system/lib64
rm -f $MOUNTINFO/dummy/system/lib64
2016-11-13 21:30:05 +01:00
fi
# Whole vendor
2016-11-13 21:30:05 +01:00
if [ -f "$MOUNTINFO/dummy/system/vendor" ]; then
BACKUPLIBS=true
LIBSIZE=`du -s /vendor/lib | awk '{print $1}'`
if [ -d /vendor/lib64 ]; then
LIB64SIZE=`du -s /vendor/lib64 | awk '{print $1}'`
VENDORLIBSIZE=$(((($LIBSIZE + $LIB64SIZE) / 10240 + 2) * 10240))
else
VENDORLIBSIZE=$((($LIBSIZE / 10240 + 2) * 10240))
fi
make_copy_image /vendor $VENDORLIBSIZE
# Copy lib/lib64
mkdir -p $MIRRDIR/copy/vendor/lib
cp -afc /vendor/lib/. $MIRRDIR/copy/vendor/lib
cp -afc $DUMMDIR/system/vendor/lib/. $MIRRDIR/copy/vendor/lib 2>/dev/null
if [ -d /vendor/lib64 ]; then
mkdir -p $MIRRDIR/copy/vendor/lib64
cp -afc /vendor/lib64/. $MIRRDIR/copy/vendor/lib64
cp -afc $DUMMDIR/system/vendor/lib64/. $MIRRDIR/copy/vendor/lib64 2>/dev/null
fi
cp -afc $DUMMDIR/system/vendor/. $MIRRDIR/copy/vendor
TRAVEL_ROOT=$MIRRDIR/copy
(clone_dummy /vendor)
# Create vendor mirror
if [ `mount | grep -c "on /vendor type"` -ne 0 ]; then
VENDORBLOCK=`mount | grep "on /vendor type" | awk '{print $1}'`
mkdir -p $MIRRDIR/vendor
mount -o ro $VENDORBLOCK $MIRRDIR/vendor
else
ln -s $MIRRDIR/system/vendor $MIRRDIR/vendor
fi
mount_copy_image /vendor
rm -f $MOUNTINFO/dummy/system/vendor
2016-11-13 21:30:05 +01:00
fi
# vendor lib
2016-11-13 21:30:05 +01:00
if [ -f "$MOUNTINFO/dummy/system/vendor/lib" ]; then
BACKUPLIBS=true
make_copy_image /system/vendor/lib
cp -afc /system/vendor/lib/. $MIRRDIR/copy/system/vendor/lib
cp -afc $DUMMDIR/system/vendor/lib/. $MIRRDIR/copy/system/vendor/lib
mount_copy_image /system/vendor/lib
rm -f $MOUNTINFO/dummy/system/vendor/lib
2016-11-13 21:30:05 +01:00
fi
# vendor lib64
2016-11-13 21:30:05 +01:00
if [ -f "$MOUNTINFO/dummy/system/vendor/lib64" ]; then
BACKUPLIBS=true
make_copy_image /system/vendor/lib64
cp -afc /system/vendor/lib64/. $MIRRDIR/copy/system/vendor/lib64
cp -afc $DUMMDIR/system/vendor/lib64/. $MIRRDIR/copy/system/vendor/lib64
mount_copy_image /system/vendor/lib64
rm -f $MOUNTINFO/dummy/system/vendor/lib64
fi
2016-09-14 04:31:13 +02:00
# Crash prevention!!
$BACKUPLIBS && rm -f $COREDIR/magiskhide/enable 2>/dev/null
# Remove crap folder
rm -rf $MOUNTPOINT/lost+found
# Start doing tasks
# Stage 1
TRAVEL_ROOT=$DUMMDIR
log_print "* Bind mount dummy system"
2016-11-13 21:30:05 +01:00
find $MOUNTINFO/dummy -type f 2>/dev/null | while read ITEM ; do
TARGET=${ITEM#$MOUNTINFO/dummy}
ORIG="$DUMMDIR$TARGET"
(clone_dummy "$TARGET")
bind_mount "$ORIG" "$TARGET"
done
# Stage 2
log_print "* Bind mount module items"
2016-11-13 21:30:05 +01:00
find $MOUNTINFO/system -type f 2>/dev/null | while read ITEM ; do
TARGET=${ITEM#$MOUNTINFO}
ORIG=`cat $ITEM`$TARGET
bind_mount $ORIG $TARGET
rm -f $DUMMDIR${TARGET%/*}/.dummy 2>/dev/null
done
# Run scripts
run_scripts post-fs-data
# Bind hosts for Adblock apps
2016-11-08 22:17:14 +01:00
if [ -f "$COREDIR/hosts" ]; then
log_print "* Enabling systemless hosts file support"
2016-11-08 22:17:14 +01:00
bind_mount $COREDIR/hosts /system/etc/hosts
fi
# Expose busybox
if [ -f "$COREDIR/busybox/enable" ]; then
log_print "* Enabling BusyBox"
2016-11-13 21:30:05 +01:00
cp -afc /data/busybox/. $COREDIR/busybox
cp -afc /system/xbin/. $COREDIR/busybox
2016-11-13 14:02:35 +01:00
chmod -R 755 $COREDIR/busybox
chcon -hR "u:object_r:system_file:s0" $COREDIR/busybox
2016-11-08 22:17:14 +01:00
bind_mount $COREDIR/busybox /system/xbin
fi
# Stage 3
log_print "* Bind mount system mirror"
bind_mount /system $MIRRDIR/system
2016-11-04 19:38:02 +01:00
# Restart post-fs-data if necessary (multirom)
$MULTIROM && setprop magisk.restart_pfsd 1
fi
2016-09-14 04:31:13 +02:00
unblock
;;
service )
2016-10-02 22:34:50 +02:00
# Version info
MAGISK_VERSION_STUB
2016-10-31 21:21:43 +01:00
log_print "** Magisk late_start service mode running..."
2016-09-14 04:31:13 +02:00
run_scripts service
2016-10-05 22:31:59 +02:00
2016-11-08 22:17:14 +01:00
# Magisk Hide
2016-10-31 21:21:43 +01:00
if [ -f "$COREDIR/magiskhide/enable" ]; then
log_print "* Removing tampered read-only system props"
2016-11-04 19:38:02 +01:00
VERIFYBOOT=`getprop ro.boot.verifiedbootstate`
FLASHLOCKED=`getprop ro.boot.flash.locked`
VERITYMODE=`getprop ro.boot.veritymode`
[ ! -z "$VERIFYBOOT" -a "$VERIFYBOOT" != "green" ] && \
log_print "`$BINPATH/resetprop -v -n ro.boot.verifiedbootstate green`"
[ ! -z "$FLASHLOCKED" -a "$FLASHLOCKED" != "1" ] && \
log_print "`$BINPATH/resetprop -v -n ro.boot.flash.locked 1`"
[ ! -z "$VERITYMODE" -a "$VERITYMODE" != "enforcing" ] && \
log_print "`$BINPATH/resetprop -v -n ro.boot.veritymode enforcing`"
2016-11-04 19:38:02 +01:00
mktouch $COREDIR/magiskhide/hidelist
2016-10-31 21:21:43 +01:00
chmod -R 755 $COREDIR/magiskhide
# Add Safety Net preset
$COREDIR/magiskhide/add com.google.android.gms.unstable
log_print "* Starting Magisk Hide"
2016-10-31 21:21:43 +01:00
/data/magisk/magiskhide
2016-10-06 11:53:52 +02:00
fi
2016-09-14 04:31:13 +02:00
;;
esac