#!/bin/busybox sh

showUsage () {
  cat 1>&2 <<- EOUSG
	Usage: ${0##*/} [a|w|ww|aw]
	  a , aw , aww: fullpath command if command line is
	  aw , w : wide (131 col) output
	  aww , ww : show full args
	init (pid==1) is omitted.
	EOUSG
  exit
}

awkcmd='NR==1{sub(/^.*\//,"");}{printf " %s", $0;}'
sedcmd='s/^[^ ]* //;s/^(.{79}).*/\1/'

# i dont like "getopts"
for a do
  case "$a" in
  *aww* | *waw* | *wwa* )
    awkcmd='{printf " %s", $0;}'
    sedcmd='s/^[^ ]* //'
  ;;
  *aw* | *wa* ) 
    awkcmd='{printf " %s", $0;}'
    sedcmd='s/^[^ ]* //;s/^(.{132}).*/\1/'
  ;;
  *ww* ) sedcmd='s/^[^ ]* //' ;;
  *w* ) sedcmd='s/^[^ ]* //;s/^(.{132}).*/\1/' ;;
  *a* ) awkcmd='{printf " %s", $0;}' ;;
  * ) showUsage ;;
  esac
done

tmpout=`mktemp /tmp/pstree_XXXXXX`
for proc in /proc/[1-9]* ; do
  [ -d "$proc" ] || continue
  pid=${proc##*/}
  case $pid in
  $$ | 1 ) continue ;;  # me and init
  esac
  cmdline="$(awk "$awkcmd" $proc/cmdline)"
  cmdline="${cmdline# }"
  [ -z "$cmdline" ] && continue
  while read t i dum ; do
    case "$t" in
    State:) state=$i ;;
    PPid:) ppid=$i; break ;;
    esac
  done < $proc/status
  chain=$(printf %05d $pid)
  while : ; do
    [ -z "$ppid" -o "$ppid" -le 1 ] && break
    chain="$(printf %05d "$ppid")$chain     "
    ppidstatus=/proc/$ppid/status
    [ -f $ppidstatus ] || break
    while read t i dum ; do
      case "$t" in
      PPid:) ppid=$i; break ;;
      esac
    done < $ppidstatus
  done
  printf '%s %5d %s %s\n' "$chain" $pid "$state" "$cmdline"
done > $tmpout
sort $tmpout | sed -r "$sedcmd"
rm -f $tmpout
exit

