#!/system/bin/sh
#
# Move Apps to sd
#
# Malez 2010
# v1.3
# 20100323 Malez move dalvik cache + args
# 20100325 Malez move data
# 20100329 Malez add end function + umount silent + eror retriving data content
#

ERROR=0
KEEP=0
DALVIK=0
DATA=0
LISTCP="app app-private"

end() {
#        sync
#	umount /system/sd
#	umount /data/dalvik-cache 2>/dev/null
#	umount /data/data 2>/dev/null
	exit $1
}


error() {
  echo "Error : $1"
  echo "exiting"
  sync
  end 1
}

for option in "$@" ; do
    case $option in
        -k)
            KEEP=1
            shift
            ;;
        --keep)
            KEEP=1
            shift
            ;;
	-d|--dalvik)
	    DALVIK=1
	    #OTHER=dalvik-cache
	    shift
	    ;;
	--data)
	    DATA=1
	    LISTCP="$LISTCP data"
	    shift
	    ;;
        -h|--help)
            ECHO=echo
            $ECHO "$0 script by Malez"
            $ECHO "Usage: $0 {-k|-h}"
            $ECHO ""
            $ECHO "-h          Display this help"
            $ECHO ""
            $ECHO "-k          Don't delete files on phone after copying to sd"
            $ECHO ""
            $ECHO "-d         Also move dalvik-cache on sd"
            exit 0
            ;;
        --)
            #shift
            break
            ;;
    esac
done



if [ -e /dev/block/mmcblk0p2 ];
then

    umount /system/sd
    umount /data/dalvik-cache  2>/dev/null
    umount /data/data 2>/dev/null

    echo "--- Checking filesystems" 

    # fsck the sdcard filesystem first
    e2fsck -y -f /dev/block/mmcblk0p2;

    # set property with exit code in case an error occurs
    setprop cm.e2fsck.errors $?;

    # mount and set perms
    echo "Mounting sdcard" 
    busybox mount -o noatime,nodiratime -t auto /dev/block/mmcblk0p2 /system/sd;
    mount | grep "/system/sd "
    if [ "$?" = 0 ];
    then
        busybox chown 1000:1000 /system/sd;
        busybox chmod 771 /system/sd;

        # clean up any old symlinks, create data directories
	#echo "Clean up any old symlinks, create data directories" 
        for i in dalvik-cache data;
        do
            if [ -h /data/$i ];
            then
                rm /data/$i;
            fi;
            if [ ! -d /data/$i ];
            then
                mkdir /data/$i;
                busybox chown 1000:1000 /data/$i;
                busybox chmod 771 /data/$i;
            fi;
        done;

        # don't allow /data/data on sd because of upgrade issues - move it if possible
	if [ $DATA == "0" ]; then
	        if [ -d /system/sd/data ];
	        then
          		if [ ! -d /data/data/ -o -h /data/data ]; then
				rm /data/data 2>/dev/null
				mkdir /data/data
	      			chown 1000:1000 /data/data
				chmod 771 /data/data		
		    	fi  
		    echo "copy /data/data back to phone" 
                    ls /system/sd/data/* >/dev/null 2>&1 && \
			(busybox cp -p -f -r /system/sd/data/* /data/data/ || ERROR=1)
		    	if [ $ERROR == 0 ]; then echo "delete /data/data on sd"; busybox rm -rf /system/sd/data; fi
	        fi;
	fi

	#delete dalvik on sd
	busybox rm -fR /system/sd/dalvik-cache

        # copy apps and app-private and OTHER from internal memory to sdcard
        # and symlink
        for i in $LISTCP;
        do
            if [ ! -d /system/sd/$i ];
            then
                mkdir /system/sd/$i;
            fi

            busybox chown 1000:1000 /system/sd/$i;
            busybox chmod 771 /system/sd/$i
	    

            if [ -d /data/$i ] && [ ! -h /data/$i ]
            then
                #-f in case files are olready on sd
                ls /data/${i}/* >/dev/null 2>&1 && \
                   (echo "Copying $i content from internal to sd" && busybox cp -p -f -r /data/$i/* /system/sd/$i/ || ERROR=1)
            fi;
        done;



        # symlink app dirs - they must be on the same filesystem
        #Malez no error only
        for i in app app-private;
        do
            if [ -d /data/$i ] && [ ! -h /data/$i ] && [ $ERROR == 0 ];
            then
		echo "Symlink $i" 
		if [ "a$KEEP" == "a1" ]; then
			busybox mv /data/$i /data/${i}.ori
		else
			busybox rm -fr /data/$i;
		fi
                busybox ln -s /system/sd/$i /data/$i;
            fi;
        done;

	#dalvik cache
	if [ "a$DALVIK" == "a1" ] && [ $ERROR == 0 ] ; then
		if [ ! -d /system/sd/dalvik-cache ]; then
			busybox mkdir /system/sd/dalvik-cache
			busybox chown 1000:1000 /system/sd/dalvik-cache
			busybox chmod 771 /system/sd/dalvik-cache
		fi

		if [ "a$KEEP" == "a1" ]; then 
			busybox mv /data/dalvik-cache /data/dalvik-cache.ori; 
		else
			busybox rm -fr /data/dalvik-cache; 
		fi

		#echo "dalvik-cache CAN'T be a symlink"
                #busybox ln -s /system/sd/dalvik-cache /data/dalvik-cache;
		busybox mkdir /data/dalvik-cache
                busybox chown 1000:1000 /data/dalvik-cache
                busybox chmod 771 /data/dalvik-cache

#		busybox mount -o bind /system/sd/dalvik-cache /data/dalvik-cache && \
#	                busybox chown 1000:1000 /data/dalvik-cache && \
#	                busybox chmod 771 /data/dalvik-cache;
	fi

	#data
	if [ "a$DATA" == "a1" ] && [ $ERROR = 0 ] ; then
		if [ ! -d /system/sd/data ]; then
			busybox mkdir /system/sd/data
			busybox chown 1000:1000 /system/sd/data
			busybox chmod 771 /system/sd/data
		fi
		if [ "a$KEEP" == "a1" ]; then 
			busybox mv /data/data /data/data.ori; 
		else #only if /data/data is not bind mounted
			mount | grep -i "/data/data" && umount /data/data 
			mount | grep -i "/data/data" || busybox rm -fr /data/data; 
		fi
		echo "Symlink data"
		busybox ln -s /system/sd/data /data/data;

		busybox mount -o bind /system/sd/data /data/data && \
	                busybox chown 1000:1000 /data/data && \
	                busybox chmod 771 /data/data;
	fi

        # clean up old whiteouts symlinks
        for i in local misc property system tombstones data;
        do
            if [ -h /system/sd/$i ]; then rm -f /system/sd/$i; fi
        done;

        # please don't put odex files in the app directory people!
        # it causes dexopt to crash when switching builds!
        busybox rm -f /system/sd/app/*.odex


	sync



        ##ERROR CHECK
        if [ $ERROR = 0 ]; then
           setprop cm.a2sd.active 1;
           end 0
        else #ERROR OCCURED WHILE COPYING DELETE COPIED FILES
	   echo "Error occured while copying to sd. Disk space ?"
	   echo "cleaning sd"
           for i in app app-private data dalvik-cache;
           do
		rm -fR /system/sd/$i

	   done

           setprop cm.a2sd.active 0;
           end 1
        fi

        echo "+++ Apps-to-SD successfully enabled" 

	end 0
    else
        echo "*** Unable to mount filesystem for a2sd!" 
        exit 1
    fi
fi
exit 0
