#!/bin/sh
#(c) Copyright 2008 Barry Kauler, puppylinux.com
#2008 Lesser GPL licence v2 (see /usr/share/doc/legal)
#/sbin/pup_event_frontend_d creates a desktop icon and copy of this script for each drive, ex:
# for drive sda: cp -a /usr/local/bin/drive_all /root/.pup_event/drive_sda/AppRun
#this script is launched by pup_event_frontend_d when the icon is first created. also,
#this script is launched when user clicks on deskop icon (former is configurable,
# see /usr/sbin/eventmanager.
#passed param is category of drive: card, floppy, optical, usbdrv, drive.
#v4.0.2 jun08: first write of this script, expanding 'pup_eventd' management.
#v403 icon menu, can call with 'unmount', 'eventmanager' and 'pmount_<DRV_CATEGORY>' params.
#v411 added 'quiet' option for vfat, suppresses error msg when file attribs not preserved on copy.
#w002 left click to unmount a partition.
#w476 fix codepage for vfat f.s.
# 13jun09 by Masaki Shinomiya <shino@pos.to> vfat and so9660 - utf8 option as the default
# 15jun09 : look up /etc/codepage only for vfat utf8 option
# 27jun09 : vfat mount options by Masaki Shinomiya <shino@pos.to>
# 30jun09 I18N
# 08jul09 looking up ONDRVNAME, ask to remove CD
# 16jul09 not ask to remove CD, only open tray
#v424 have added right-click menu item to unmount all partitions (see pup_event_frontend_d)...
#v424 have removed this dlg box. maybe make it optional in the future...
#091223 extra check for invalid desktop drive icon.
#100118 optional defaultcdplayer, defaultdvdplayer.
#100127 codepage fixes. 100131 iso9660 fix.
#100706 BK: bug fixes, introduced with i81n support.
#100719 BK: correct detection of DVD vidoe and launching mediaplayer.
#110126 support /dev/hd* optical device nodes.
#110505 support sudo for non-root user.
#110720 should not open a layer inside aufs, ex: session saved entire partition, desktop drive icon is /initrd/pup_rw.
#110721 detect if have clicked on a close-box of mounted partition.
#120110 running as fido, popup password box changes mouse pointer position, need read before run sudo.
#120129 karl godt: fix ZOMBIES, see http://murga-linux.com/puppy/viewtopic.php?t=71767&start=420. see also rc.shutdown, pmount, pup_event_frontend_d.
#120323 partial replace 'xmessage' with 'pupmessage'.
#120516 pup_event_frontend_d may call here when a drive plugged in, fix handling of automounting.
#120517 syntax error in 120516, quotes needed.
#130128 convert i18n "technosaurus-method" to gettext.
#130128 optical media, if has a f.s., can be either iso9660 or udf (see updated probepart and pup_event_frontend_d).
#130203 change probedisk2 to probedisk.
#130216 add support f2fs.

export TEXTDOMAIN=drive_all
export OUTPUT_CHARSET=UTF-8
. gettext.sh

[ ! -f /tmp/desktop_drives_curpos ] && getcurpos > /tmp/desktop_drives_curpos #120110
[ "`whoami`" != "root" ] && exec sudo -A ${0} ${@} #110505
CURPOS="`cat /tmp/desktop_drives_curpos`" #120110
rm -f /tmp/desktop_drives_curpos #120110
#CURPOS="`getcurpos`" #110721 get mouse pointer position as soon as possible.

export LANG	# need to restart pmount with correct locale

#w002 extracted as a func...
unmount_func() {
 rox -D $MNTPT
 sync
 while [ 1 ];do
  umount $MNTPT ; umVAL=$?
  #fix zombie process prevents partition unmount, invisible to fuser...
  if [ $umVAL -ne 0 ];then
   #120129 karl godt: fix ZOMBIES, see http://murga-linux.com/puppy/viewtopic.php?t=71767&start=420 ...
   #ZOMBIES="`ps -H -A | grep '<defunct>' | sed -e 's/  /|/g' | grep -v '|||' | cut -f 1 -d ' ' | tr '\n' ' '`"
   ZOMBIES="`ps -H -A | grep '<defunct>' | sed 's/^[[:blank:]]*//;s/  /|/g' | grep -v '|||' | cut -f 1 -d ' ' | tr '\n' ' '`"
   for ONEZOMBIE in $ZOMBIES
   do
    echo "Killing parentless zombie process $ONEZOMBIE"
    kill $ONEZOMBIE
   done
   umount $MNTPT ; umVAL=$?
  fi
  #rare ocassion, partition got unmounted before umount runs above...
  umPATTERN="${MNTPT} "
  [ "`busybox mount | grep "$umPATTERN"`" = "" ] && umVAL=0
  if [ $umVAL -ne 0 ];then
   EXTRAMSG0="`fuser -v -m $MNTPT`"  
   if [ "$EXTRAMSG0" = "" ];then
    pupmessage -bg "#ff8080" -title "$(gettext 'Puppy drive manager: ERROR')" -center "$(gettext 'FAILURE! In the case of removable media, the most
common reason is the media is not currently inserted.
If so, please remedy.')"
   else
    xmessage -bg "#ff99ff" -title "$(gettext 'Puppy drive manager: FAIL')" -center -buttons "$(gettext 'KILL')":10,"$(gettext 'EXIT')":20 "$(gettext 'FAILURE!')
$(gettext 'One or more processes (programs) are currently
using the partition. Here they are:')
${EXTRAMSG0}

$(gettext "If you press the 'KILL' button, Puppy will attempt to
kill the offending programs for you. Only do this as a
last resort.")
$(gettext "Firstly you should try to close the programs
manually, so do not press 'KILL'.")
$(gettext "PLEASE PRESS THE 'EXIT' BUTTON!")"

    if [ $? -eq 10 ];then
     fuser -k -m $MNTPT
     continue
    fi
   fi
  else
   [ "$DRV_CATEGORY" = "optical" ]  && eject_cd /dev/$ONEDRVNAME
  fi
  break
 done
}

eject_cd ()
{
	eject $1 # && gxmessage  -title "$(gettext 'Puppy drive manager')" -center -buttons "$(gettext 'OK')":0 "$(gettext "Remove medium, then press 'OK'")" && eject -t $1
}

FSTYPE=""
[ $2 ] && FSTYPE="$2" #see pup_event_frontend_d.
PARAM1=""
[ $1 ] && PARAM1="$1"

#extract drive name from end of the script name...
#note, when click on desktop icon, /root/.pup_event/drive_<ONEDRVNAME> is executed,
#however a script may run /root/.pup_event/drive_<ONEDRVNAME>/AppRun ...
#ONEDRVNAME="`echo "${0}" | sed -e 's%/AppRun%%' | rev | cut -f 1 -d '_' | rev`"
ONEDRVNAME=$(dirname $0|sed -e 's/^.*_//')
if [ "`echo "${PARAM1}" | grep 'pmount_'`" != "" ];then #v403 chose pmount from drive icon menu.
 DRV_CATEGORY="`echo -n "${PARAM1}" | cut -f 2 -d '_'`"
 if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
  killall gtkdialog_pmount 2>/dev/null
  sleep 0.1
 fi
 exec pmount ${DRV_CATEGORY}
fi

#echo "PARAM1=${PARAM1}" >> /tmp/drive_apprun_${ONEDRVNAME}.log #TEST

#110721 detect if have clicked on a close-box of mounted partition...
#when left-click desktop icon, param1 passed this script: drive|card|floppy|optical|usbdrv
# and param2 has the fs type...
case $PARAM1 in
 drive|card|floppy|optical|usbdrv)
  mPATTERN='^/dev/'"$ONEDRVNAME"' '
  MNTPT="`df | grep "$mPATTERN" | tr -s ' ' | cut -f 6 -d ' '`"
  if [ "$MNTPT" ];then
   #get coords of desktop icon...
   drPTN=">/root/.pup_event/drive_${ONEDRVNAME}<"
   PPENTRY="`grep "$drPTN" /root/Choices/ROX-Filer/PuppyPin`"
   if [ "$PPENTRY" ];then
    xleft="`echo -n "$PPENTRY" | grep -o ' x="[0-9]*"' | cut -f 2 -d '"'`" #'geany
    ytop="`echo -n "$PPENTRY" | grep -o ' y="[0-9]*"' | cut -f 2 -d '"'`" #'geany
    CURPOSX=`echo -n "$CURPOS" | cut -f 1 -d ' '`
    CURPOSY=`echo -n "$CURPOS" | cut -f 2 -d ' '`
    #hmmm, have to apply correction to cursor position...
    CURPOSX=$(($CURPOSX + 24))
    CURPOSY=$(($CURPOSY + 32))
    xcloseleft=$(($xleft + 35)) #close-box is 13x13 pixels, want bigger pickup area.
    xcloseright=$(($xleft + 53))
    yclosetop=$(($ytop - 5))
    yclosebottom=$(($ytop + 13))
    #echo "xleft=$xleft ytop=$ytop CURPOSX=$CURPOSX CURPOSY=$CURPOSY xcloseleft=$xcloseleft xcloseright=$xcloseright yclosetop=$yclosetop yclosebottom=$yclosebottom"  >> /tmp/drive_apprun_${ONEDRVNAME}.log #TEST
    if [ $CURPOSX -ge $xcloseleft ];then
     if [ $CURPOSX -le $xcloseright ];then
      if [ $CURPOSY -ge $yclosetop ];then
       if [ $CURPOSY -le $yclosebottom ];then
        PARAM1="unmount"
       fi
      fi
     fi
    fi
   fi
  fi
 ;;
esac

if [ "$PARAM1" = "eventmanager" ];then #v403 chosen from drive icon menu.
 #v405 'desktop' param, cutdown tabs for desktop drive icons only...
 exec eventmanager desktop
fi

if [ "$PARAM1" = "unmount" ];then #v403 chose unmount from drive icon menu.
 mPATTERN='^/dev/'"$ONEDRVNAME"' '
 #MNTPT="`mount | grep "$mPATTERN" | cut -f 3 -d ' '`"
 MNTPT="`df | grep "$mPATTERN" | tr -s ' ' | cut -f 6 -d ' '`"
 #DRV_CATEGORY=$(grep '<Item.option=.pmount_'  "/root/.pup_event/drive_$ONEDRVNAME/AppInfo.xml"| sed -e 's/^.*Item.option=.pmount_//' -e 's/.[ ].*$//')
 DRV_CATEGORY=""
 PROBEDISK="probedisk"
 DRV_CATEGORY=$($PROBEDISK | grep "^/dev/$ONEDRVNAME|" | cut -d'|' -f 2)
 echo "$DRV_CATEGORY" | grep '^cd' && DRV_CATEGORY="optical"
 [ "$MNTPT" = "" ] && [ "$DRV_CATEGORY" = "optical" ] && eject_cd /dev/$ONEDRVNAME
 [ "$MNTPT" = "" ] && exit #precaution.
 if [ "$MNTPT" = "/" -o "`echo "$MNTPT" | grep '/initrd/'`" != "" ];then
  pupmessage -bg "#ff8080" -title "$(gettext 'Puppy drive manager')" -center "$(eval_gettext "/dev/\${ONEDRVNAME} mounted on \${MNTPT}
is in use by Puppy. You cannot unmount it.")"
  exit
 fi
 unmount_func
 exit
fi

#v424 have added right-click menu item to unmount all partitions (see pup_event_frontend_d)...
if [ "$PARAM1" = "unmountall" ];then
 for MNTPT in `mount | grep '^/dev/' | grep -vE '^/dev/loop|^/dev/ram' | cut -f 3 -d ' ' | grep -v '^/initrd/' | grep -v '^/$' | tr '\n' ' '`
 do
  unmount_func
 done
 exit
fi

#w002 left-mouse-click to unmount...
#info: params passed to this script:
# left-click: 0=/root/.pup_event/drive_sda3/AppRun 1=drive 2=ext3
# right-menu: 0=/root/.pup_event/drive_sda3/AppRun 1=unmount 2=
# right-menu: 0=/root/.pup_event/drive_sda3/AppRun 1=pmount_drive 2=
# right-menu: 0=/root/.pup_event/drive_sda3/AppRun 1=eventmanager 2=
#in first ex $1 can be drive,floppy,usbdrv,optical,card.

#v424 have removed this dlg box. maybe make it optional in the future...
#if [ $2 ];then
# #if partition already mounted, offer to unmount it...
# mPATTERN='^/dev/'"$ONEDRVNAME"' '
# MNTPT="`df | grep "$mPATTERN" | tr -s ' ' | cut -f 6 -d ' '`"
# if [ "$MNTPT" != "" ];then
#  if [ "$MNTPT" != "/" -a "`echo "$MNTPT" | grep '/initrd/'`" = "" ];then
#   #it is allowed to be unmounted (not in use by woof)...
#   xmessage -bg "orange" -title "Puppy drive manager" -center -buttons " NO :11,Unmount ${ONEDRVNAME}:10,Unmount all:12" "Do you want to unmount ${ONEDRVNAME}?
#It is currently mounted on ${MNTPT}"
#   UMNTFLG=$?
#   if [ $UMNTFLG -eq 10 ];then
#    unmount_func
#	exit
#   fi
#   if [ $UMNTFLG -eq 12 ];then
#    for MNTPT in `mount | grep '^/dev/' | grep -vE '^/dev/loop|^/dev/ram' | cut -f 3 -d ' ' | grep -v '^/initrd/' | grep -v '^/$' | tr '\n' ' '`
#	do
#	 unmount_func
#	done
#    exit
#   fi
#  fi
# fi
#fi

DRV_CATEGORY="${PARAM1}"
[ "$DRV_CATEGORY" = "" ] && DRV_CATEGORY="drive" #precaution.
[ "$DRV_CATEGORY" = "all" ] && DRV_CATEGORY="drive" #precaution.

[ -f /etc/eventmanager ] && . /etc/eventmanager #written by /usr/sbin/eventmanager
[ "$ICONDESK" != "true" -a "$ICONDESK" != "false" ] && ICONDESK="true"
[ ! $RAMSAVEINTERVAL ] && RAMSAVEINTERVAL=30
[ "$HOTPLUGNOISY" != "true" -a "$HOTPLUGNOISY" != "false" ] && HOTPLUGNOISY="false"
[ "$AUTOTARGET" != "true" -a "$AUTOTARGET" != "false" ] && AUTOTARGET="true"
[ "$ICONPARTITIONS" != "true" -a "$ICONPARTITIONS" != "false" ] && ICONPARTITIONS="true"

#if ICONDESK=false (see /etc/eventmanager and /sbin/pup_eventd) then there will only
#be one icon on the desktop, labelled 'drives' and handler script is /usr/local/bin/drive_drives
if [ "$ONEDRVNAME" = "drives" ];then
 if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
  killall gtkdialog_pmount 2>/dev/null
  sleep 0.1
 fi
 exec pmount $DRV_CATEGORY
fi

#decision... we can bring up a "handler" window, that explains things, good for beginners.
#or jump direct to most appropriate target application, or do nothing.
#for now only have AUTOTARGET=true go direct to most appropriate target app,
# =false always start Pmount.
if [ "$AUTOTARGET" = "false" ];then
 if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
  killall gtkdialog_pmount 2>/dev/null
  sleep 0.1
 fi
 exec pmount $DRV_CATEGORY
fi

#oh, now have to analyse the media, decide what app to run...
dPATTERN='^/dev/'"$ONEDRVNAME"' '
FLAGOPTICAL='no'
case $ONEDRVNAME in #110126
 sr*)
  FLAGOPTICAL='yes'
 ;;
 hd*)
  [ -e /proc/ide/$ONEDRVNAME/media ] && [ "`cat /proc/ide/$ONEDRVNAME/media`" = "cdrom" ] && FLAGOPTICAL='yes'
 ;;
esac
if [ "$FLAGOPTICAL" = "yes" ];then
 if [ "`busybox mount | grep "$dPATTERN"`" = "" ];then
  cddetect -q -d/dev/${ONEDRVNAME}
  RETVAL=$?
  case $RETVAL in
  3) #iso file: normal data cd.
   true
   ;;
  1) #audio
   ln -snf /dev/${ONEDRVNAME} /dev/cdrom
   if [ -f /usr/local/bin/defaultcdplayer ];then #100118
    exec defaultcdplayer
   else
    exec defaultmediaplayer cdda://
   fi
   ;;
  5) #video dvd
   ln -snf /dev/${ONEDRVNAME} /dev/dvd
   [ -f /usr/local/bin/defaultdvdplayer ] && exec defaultdvdplayer
   [ "`grep 'mplayer' /usr/local/bin/defaultmediaplayer`" != "" ] && exec defaultmediaplayer dvdnav:// #100719
   exec defaultmediaplayer dvd://
   ;;
  0) #failed to detect type.
   #cddetect does not work properly for dvd's, try something else...
   #100719 properly detect dvd video...
   if [ "`df | grep "$dPATTERN"`" = "" ];then #only test if not mounted.
    FLAGDVDVIDEO="`dvd+rw-mediainfo /dev/${ONEDRVNAME} | grep 'Mounted Media: .* DVD-ROM'`"
    if [ "$FLAGDVDVIDEO" = "" ];then
     #mount and look for 'video_ts' directory (dir should contain file video_ts.ifo)...
     mkdir -p /mnt/${ONEDRVNAME}
     mount -t iso9660 /dev/${ONEDRVNAME} /mnt/${ONEDRVNAME}
     if [ $? -eq 0 ];then
      [ -d /mnt/${ONEDRVNAME}/video_ts -o -d /mnt/${ONEDRVNAME}/VIDEO_TS ] && FLAGDVDVIDEO="yes"
      umount /mnt/${ONEDRVNAME}
     fi
    fi
    if [ "$FLAGDVDVIDEO" != "" ];then
     ln -snf /dev/${ONEDRVNAME} /dev/dvd
     [ -f /usr/local/bin/defaultdvdplayer ] && exec defaultdvdplayer
     [ "`grep 'mplayer' /usr/local/bin/defaultmediaplayer`" != "" ] && exec defaultmediaplayer dvdnav://
     exec defaultmediaplayer dvd://
    fi
   fi
   ;;
  esac
 fi
 #FSTYPE="iso9660"
 #130128 probepart now detects udf, FSTYPE should already be set to that...
 [ "$FSTYPE" != "udf" ] && FSTYPE="iso9660" #would already have been iso9660 anyway.
fi

#if dropped down here, it is likely to be a data partition...

#120516 pup_event_frontend_d may call here when a drive plugged in, but only passes one parameter (PARAM1). want FSTYPE also...
# also, for AUTOTARGET=true in /etc/eventmanager will come here, and a plugged in drive may be more than one partition to automount...
if [ "$FSTYPE" != "" ];then
 DOPARTS="${ONEDRVNAME}|${FSTYPE}" #120517
else
 #ONEDRVNAME is probably a drive name, ex sda...
 pPTN="/dev/${ONEDRVNAME}" #no space on end!
 DOPARTS="`probepart -m | grep "$pPTN" | cut -f 1,2 -d '|' | cut -f 3 -d '/' | grep -E 'f2fs|ext2|ext3|ext4|udf|is09660|vfat|reiser|btrfs|ntfs|msdos|minix' | tr '\n' ' '`" #ex: sda1|ext3 sda2|vfat sda3|ext3  130216 added f2fs
fi

#if it is a mountable partition then mount and open with rox. If already mntd then open in rox...
#if [ "$ICONPARTITIONS" = "true" ];then
EXITFLAG=no
for ONEDO in $DOPARTS
do
 xONEDRVNAME="`echo -n "$ONEDO" | cut -f 1 -d '|'`"
 xFSTYPE="`echo -n "$ONEDO" | cut -f 2 -d '|'`"
 if [ "`df | grep "$dPATTERN"`" = "" ];then
  #not mounted...
  mkdir -p /mnt/$xONEDRVNAME
  case $xFSTYPE in
   ntfs)
    #'mount' is a script that takes care of mounting ntfs...
    mount -t ntfs /dev/$xONEDRVNAME /mnt/$xONEDRVNAME
    RETVAL1=$?
    ;;
   vfat)
    #w476 modify codepage and iocharset (note: this code also in /usr/sbin/pmount)...
    #note, could also set iocharset=iso8859-2 (default: codepage=437, iocharset=iso8859-1)
    # 27jul09 lookup /etc/codepage and LANG by Masaki Shinomiya <shino@pos.to>
    NLS_PARAM=""
    if [ -f /etc/codepage ]; then #100127...
     grep -q -i '850' /etc/codepage && [ "$(echo $LANG|cut -d'.' -f1)" != "en_US" ] && NLS_PARAM=",codepage=850"
     grep -q -i '852' /etc/codepage && NLS_PARAM=",codepage=852,iocharset=iso8859-2"
    fi
    echo $LANG | grep -q -i '\.utf' && NLS_PARAM="$NLS_PARAM,utf8"
    mount -t vfat -o shortname=mixed,quiet${NLS_PARAM} /dev/$xONEDRVNAME /mnt/$xONEDRVNAME #v411
    RETVAL1=$?
    ;;
   #100127 not certain about this (inserted by shinobar)... 100131 shinobar informs needed for cds created in windows...
   iso9660|udf) #130128 add udf.
    mount -t $xFSTYPE -o iocharset=utf8 /dev/$xONEDRVNAME /mnt/$xONEDRVNAME
    RETVAL1=$?
    ;;  
   *)
    mount -t $xFSTYPE /dev/$xONEDRVNAME /mnt/$xONEDRVNAME
    RETVAL1=$?
    ;;
  esac
  if [ $RETVAL1 -eq 0 ];then
   rox -x /mnt/$xONEDRVNAME -d /mnt/$xONEDRVNAME &
   EXITFLAG=yes
  else
   #091223 why did it fail?
   dd if=/dev/$xONEDRVNAME of=/dev/null bs=512 count=1 > /dev/null 2>&1
   if [ $? -ne 0 ];then
    #/tmp/pup_event_frontend_block_request is used in /sbin/pup_event_frontend_d to refresh drv...
    case $xONEDRVNAME in
     mmcblk*)
      yONEDRV="`echo -n "$xONEDRVNAME" | cut -c 1-7`"
     ;;
     *)
      yONEDRV="`echo -n "$xONEDRVNAME" | cut -c 1-3`"
     ;;
    esac
    echo "$yONEDRV" > /tmp/pup_event_frontend_block_request
   fi
  fi
 else
  #mounted...
  MNTPT="`df | grep "$dPATTERN" | tr -s ' ' | cut -f 6 -d ' '`"
  if [ -h /mnt/home ];then
   [ "`readlink /mnt/home`" = "$MNTPT" ] && MNTPT="/mnt/home"
  fi
  #110720 should not open a layer inside aufs, ex: session saved entire partition, desktop drive icon is /initrd/pup_rw...
  case $MNTPT in
   /initrd/pup_*)
    MNTPT="/" #open rox at top of aufs layers.
   ;;
  esac
  #exec rox -x /mnt/$xONEDRVNAME -d /mnt/$xONEDRVNAME
  rox -x $MNTPT -d $MNTPT &
  EXITFLAG=yes
 fi
done
[ "$EXITFLAG" = "yes" ] && exit

#NOTE: if pmount already running, don't really want to kill then restart,
# just want to bring the window up if it's minimised ...how?

if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, kill it.
 killall gtkdialog_pmount 2>/dev/null
 sleep 0.1
fi

exec pmount ${DRV_CATEGORY}

###END###
