#!/bin/bash
#
#  Midnight Commander compatible EXTFS for accessing Android devices over adb
#
#  Writen by Volodymyr M. Lisivka <vlisivka@gmail.com> 2011
#
#  This file is part of the Midnight Commander.
#
#  The Midnight Commander is free software; you can redistribute it
#  and/or modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  The Midnight Commander is distributed in the hope that it will be
#  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
#  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.

BBOX="$(adb shell ls /data/local/busybox)"
BBOX="${BBOX%"${BBOX##*[![:space:]]}"}"
if [ "$BBOX" = "/data/local/busybox" ]
then
  UPLOAD_BUSYBOX="no"
else
  UPLOAD_BUSYBOX="yes"
fi

#UPLOAD_BUSYBOX="${UPLOAD_BUSYBOX:-yes}"
if [ "$UPLOAD_BUSYBOX" = "yes" ]
then
#  BUSYBOX="${BUSYBOX:-/sqlite_stmt_journals/busybox}"
  BUSYBOX="${BUSYBOX:-/data/local/busybox}"
  BUSYBOX_ARMV5="${0%/*}/busybox.armv5"
else
  BUSYBOX="${BUSYBOX:-busybox}"
fi

ADB="${ADB:-adb}"

adb_list() {
  local DIR="$1"
  [ -n "$DIR" ] || {
    DIR="/"
  }

if [ "$UPLOAD_BUSYBOX" = "yes" ]
then
  adb push "$BUSYBOX_ARMV5" "$BUSYBOX" 2>/dev/null
  adb shell chmod 755 "$BUSYBOX"
fi

#"$ADB" shell "$BUSYBOX" ls --color=never -aelR "$DIR" | tr -d '\r' >adb.ls-lR

"$ADB" shell "$BUSYBOX" ls --color=never -aelR "$DIR" | tr -d '\r' | {
    PREFIX="/"
    while read -ra ITEMS
    do
      case "${ITEMS[0]}" in
        # Dir entry:
        # /data/tombstones:
        '/'*':')
          PREFIX="${ITEMS[0]%:}/" # Strip trailing ":", append '/'
          PREFIX="${PREFIX/\/\///}" # Replace '//' by '/'
          PREFIX="${PREFIX#/}" # Strip first "/"
        ;;

        # Dir
        # drwxrwx--x    1 1000     1000         2048 Sun Dec 26 00:04:55 2010 data
        # File
        # -rwxr-x---    1 0        0          103208 Thu Jan  1 00:00:00 1970 init
        # Symlink
        # lrwxrwxrwx    1 0        0              11 Thu May 12 15:02:45 2011 etc -> /system/etc
        d[rwxst-]????????|-[rwxst-]????????|l[rwxst-]????????)
          PERMISSIONS="${ITEMS[0]}"
#          LINKS="${ITEMS[1]}"
          OWNER="${ITEMS[2]}"
          GROUP="${ITEMS[3]}"
          SIZE="${ITEMS[4]}"
#          WDAY="${ITEMS[5]}"
          MONTH="${ITEMS[6]}"
          DAY="${ITEMS[7]}"
          TIME="${ITEMS[8]%:*}" # Strip last two digits: 00:00:00 -> 00:00
          YEAR="${ITEMS[9]}"
          FILE="${ITEMS[*]:10}"

          case "$FILE" in
            # lrwxrwxrwx    1 0        0               0 Fri May 13 09:13:22 2011 cwdls: /proc/1/cwd: cannot read link (not a symlink?)
            *': cannot read link (not a symlink?)')
              FILE="${FILE/ls: / -> }" # Replace ls: by ->
            ;;
            '.'|'..')
              continue # Skip '.' and '..' directrory entries
            ;;
          esac

          case "$DAY" in
            [0-9]) DAY="0$DAY" ;;
          esac

          case "$MONTH" in
            [0-9]) MONTH="0$MONTH" ;;
            [0-9][0-9]) ;; # MONTH="$MONTH" ;;
            Jan) MONTH="01" ;;
            Feb) MONTH="02" ;;
            Mar) MONTH="03" ;;
            Apr) MONTH="04" ;;
            May) MONTH="05" ;;
            Jun) MONTH="06" ;;
            Jul) MONTH="07" ;;
            Aug) MONTH="08" ;;
            Sep) MONTH="09" ;;
            Oct) MONTH="10" ;;
            Nov) MONTH="11" ;;
            Dec) MONTH="12" ;;
            *) MONTH="01" ;;
          esac

          echo "$PERMISSIONS 1 $OWNER $GROUP $SIZE $MONTH-$DAY-$YEAR $TIME $PREFIX$FILE"
        ;;

        # Device
        # crw-rw----    1 1000     1005      10,  56 Thu May 12 15:02:45 2011 msm_pcm_in
        [cb][rwxst-]????????)
          PERMISSIONS="${ITEMS[0]}"
#          LINKS="${ITEMS[1]}"
          OWNER="${ITEMS[2]}"
          GROUP="${ITEMS[3]}"
          MAJOR="${ITEMS[4]%,}" # Strip trailing ","
          MINOR="${ITEMS[5]}"
#          WDAY="${ITEMS[6]}"
          MONTH="${ITEMS[7]}"
          DAY="${ITEMS[8]}"
          TIME="${ITEMS[9]%:*}" # Strip last two digits: 00:00:00 -> 00:00
          YEAR="${ITEMS[10]}"
          FILE="${ITEMS[*]:11}"

          case "$DAY" in
            [0-9]) DAY="0$DAY" ;;
          esac

          case "$MONTH" in
            [0-9]) MONTH="0$MONTH" ;;
            [0-9][0-9]) ;; # MONTH="$MONTH" ;;
            Jan) MONTH="01" ;;
            Feb) MONTH="02" ;;
            Mar) MONTH="03" ;;
            Apr) MONTH="04" ;;
            May) MONTH="05" ;;
            Jun) MONTH="06" ;;
            Jul) MONTH="07" ;;
            Aug) MONTH="08" ;;
            Sep) MONTH="09" ;;
            Oct) MONTH="10" ;;
            Nov) MONTH="11" ;;
            Dec) MONTH="12" ;;
            *) MONTH="01" ;;
          esac

          echo "$PERMISSIONS 1 $OWNER $GROUP $MAJOR, $MINOR $MONTH-$DAY-$YEAR $TIME $PREFIX$FILE"
        ;;

        # Insufficient permissions
        # ls: can't open '/data': Permission denied
        'ls:')
          echo "lrwxrwxrwx 1 0 0 0 01-01-1970 00:00:00 ${ITEMS[3]//[\':]/}/INFO -> ${ITEMS[*]}"
        ;;

#        *)
#          # Skip: empty lines and totals
#        ;;
      esac
    done
  }

}

adb_pull() {
  $ADB pull "$@" 2>/dev/null
}

adb_push() {
  $ADB push "$@" 2>/dev/null
}

adb_cmd() {
  $ADB shell "$@" 2>/dev/null
}

# override any locale for dates
LC_ALL=C
export LC_ALL

#echo "$@" >&2

COMMAND="$1"
case "$COMMAND" in
# Command: list
  list)
    adb_list /
  ;;

# Command: copyout curdir storedfilename extractto
  copyout)
    LOCAL="$4"
    REMOTE="$3"
    adb_pull "$REMOTE" "$LOCAL"
  ;;

# Command: copyin curdir storedfilename sourcefile
  copyin)
    LOCAL="$4"
    REMOTE="$3"
    adb_push "$LOCAL" "$REMOTE"
  ;;

# Command: rm curdir storedfilename
  rm)
    REMOTE="$3"
    adb_cmd $BUSYBOX rm -f "$REMOTE"
  ;;

# Command: mkdir curdir dirname
  mkdir)
    REMOTE="$3"
    adb_cmd $BUSYBOX mkdir -p "$REMOTE"
  ;;

# Command: rmdir curdir dirname
  rmdir)
    REMOTE="$3"
    adb_cmd $BUSYBOX rm -rf "$REMOTE"
  ;;

# Command: run curdir command [arguments?]
  run)
    REMOTE_COMMAND="$3"
    shift 3
    adb_cmd $BUSYBOX "/$REMOTE_COMMAND" "$@"
  ;;

  *)
    exit 1
  ;;
esac

exit
