#!/bin/sh
#(c) Copyright 2008 Barry Kauler puppylinux.com
#2008 Lesser GPL licence v2 (http://www.fsf.org/licensing/licenses/lgpl.html)
#this is /sbin/pup_event_frontend_d, created June 2008 for Puppy Linux 4.x, by Barry Kauler.
#This script is part of 'pup_event', my (very) light-weight alternative to udev.
#responds to events posted to /tmp/pup_event_backend_s by /sbin/pup_event_backend_d.
#this script is launched from /root/.xinitrc.
#v407 added hotplug support for zip and ls120 diskettes.
#v407 hotplug fix for /dev/hd* optical drives.
#v408 fix for k2.6.21.7, does not set DEVTYPE.
#v408 rewrite, now works by polling /sys/block.
#v410 rerwin: detect optical disc not inserted.
#v410 avoid exact overlapping icons.
#v411 rerwin: avoid icon getting duplicated if it is renamed
#v412 workaround, someone had RAMSAVEINTERVAL not set.

#v408 when testing k2.6.21.7, no DEVTYPE, had to modify udev rules which causes udevd to
#do multiple overlapping writes to /tmp/pup_event_backend_s. Even with 2.6.25.x, plugging
#in two USB drives at once can cause this. So, dropping that, going back to primitive,
#simple polling loop.
#Translated for Russian by Valerij Kruvjalis (vkvkvk).

sleep 2 #let the dust settle after X has started.
[ "$DISPLAY" = "" ] && exit #X not running.

#v404 /usr/sbin/video-wizard (Xvesa) does create /tmp/pup_event_icon_change_flag
#which /sbin/clean_desk_icons reads via .xinirc when X starts, to wipe all drive icons.
#however I think it would be good to test here also if X mode not yet settled on...
if [ -f /tmp/videomode ];then #only exists during X resolution setup.
 if [ "`readlink /usr/X11R7/bin/X`" = "Xvesa" ];then
  while [ -f /tmp/videomode ];do
   sleep 1
  done
 fi
fi

TOGGLE=1
SAVECNT=0

ZDRV='';ZDRVINIT='no' #these usually set in PUPSTATE.
. /etc/rc.d/PUPSTATE
PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11R7/bin"
KERNVER="`uname -r`"
. /etc/eventmanager #has RAMSAVEINTERVAL, ICONDESK, HOTPLUGNOISY, ICONPARTITIONS, BACKENDON
. /etc/rc.d/functions4puppy4

SCRNXY="`xwininfo -root | grep -o '\-geometry .*' | tr -s ' ' | cut -f 2 -d ' ' | cut -f 1 -d '+'`"
SCRN_X="`echo -n "$SCRNXY" | cut -f 1 -d 'x'`"
SCRN_Y="`echo -n "$SCRNXY" | cut -f 2 -d 'x'`"

[ "$RAMSAVEINTERVAL" = "" ] && RAMSAVEINTERVAL=30 #412
RAMSAVEINTERVAL=`expr $RAMSAVEINTERVAL \* 60` #convert minutes to seconds.

SIZE_MODS_M=0
if [ "$ZDRVINIT" = "yes" ];then 
 #all mods were in initrd at bootup, then moved to main f.s.
 SIZE_MODS_M=`du -m -s /lib/modules | cut -f 1`
fi
RETVALm=1
PREVSIZETMPM=0
PREVSIZEFREEM=0

format_size_func() {
 [ ! $SIZE ] && SIZE=0
 if [ $SIZE -gt 1048576 ];then #1024*1024
  SIZE="`dc $SIZE 1048576 \/ p`"
  SIZE="`printf "%.1f" $SIZE`GB"
 else
  if [ $SIZE -gt 99 ];then
   SIZE="`expr $SIZE \/ 1024`MB"
  else
   SIZE="`dc $SIZE 1024 \/ p`"
   SIZE="`printf "%.1f" $SIZE`MB"
  fi
 fi
 [ "$SIZE" = "0.0MB" ] && SIZE="0"
}

create_appinfo_func() { #needs INFO, DRV_CATEGORY, MOREITEMS, ONEDRVNAME
   echo "<?xml version=\"1.0\"?>
<AppInfo>
  <Summary>${INFO}</Summary>
  <About>
   <Purpose>Drive icons are part of Puppy Event Manager, see System menu</Purpose>
   <Authors>Barry Kauler LGPL 2008</Authors>
  </About>
  <AppMenu>
   <Item option=\"pmount_${DRV_CATEGORY}\" icon=\"gtk-harddisk\"><Label>Запустить Pmount - монтирование дисков</Label></Item><Item option=\"eventmanager\" icon=\"gtk-execute\"><Label>Запустить Менеджер значков дисков Рабочего стола</Label></Item>${MOREITEMS}
  </AppMenu>
</AppInfo>" > /root/.pup_event/drive_${ONEDRVNAME}/AppInfo.xml
}

free_coord() {
 #find a free place on desktop. v410 avoid exact overlapping icons...
 COORDSGRID="`grep -o ' x="[0-9]*" y="[0-9]*" ' /root/Choices/ROX-Filer/PuppyPin | sed 's/[0-9]"/"/g'`"
 COORD_Y=`expr $SCRN_Y - 64`
 COORD_X=32
 MAX_X=`expr $SCRN_X - 96`
 xPATTERN=" x=\"${COORD_X}\" y=\"${COORD_Y}\" "
 while [ 1 ];do
  xgPATTERN="`echo -n "$xPATTERN" |  sed 's/[0-9]"/"/g'`"
  [ "`echo "$COORDSGRID" | grep "$xgPATTERN"`" = "" ] && break
  COORD_X=`expr $COORD_X + 64`
  xPATTERN=" x=\"${COORD_X}\" y=\"${COORD_Y}\" "
  [ $COORD_X -gt $MAX_X ] && break
 done
}

add_pinboard_func() { #needs ONEDRVNAME, DRV_CATEGORY, FSTYPE
 #ppPATTERN=' label="'"$ONEDRVNAME"'"'
 #v411 rerwin: avoid icon getting duplicated if it is renamed...
 ppPATTERN="/root/.pup_event/drive_${ONEDRVNAME}<"
 [ "`grep "$ppPATTERN" /root/Choices/ROX-Filer/PuppyPin`" != "" ] && return #precaution.
 free_coord
 echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <PinboardAdd>
   <Path>/root/.pup_event/drive_${ONEDRVNAME}</Path>
   <X>${COORD_X}</X>
   <Y>${COORD_Y}</Y>
   <Label>${ONEDRVNAME}</Label>
   <Args>${DRV_CATEGORY} ${FSTYPE}</Args>
  </PinboardAdd>
 </env:Body>
</env:Envelope>"  | rox -R
}

create_icon_func() {
 #create desktop icon, and directory with handler script, icon and help...
 #requires global variables DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION.
 #if a passed param $1, then PROBEPART already known, inefficient to rerun here each time.
 DRVINFO="$DRV_NAME"'|0|0'
 if [ "$ICONPARTITIONS" = "true" ];then
  #display an icon for each partition...
  [ ! $1 ] && PROBEPART="`probepart -k | grep -E '\|ntfs\||\|msdos\||\|vfat\||\|ext2\||\|ext3\||\|iso9660\||\|xfs\||\|reiser'`"
  drvPATTERN='^/dev/'"${DRV_NAME}" #important, no space on end!
  DRVINFO="`echo "$PROBEPART" | grep "$drvPATTERN" | cut -f 1,2,3 -d '|' | tr '\n' ' '`"
 fi
 for ONEDRVINFO in $DRVINFO
 do
  ONEDRVNAME="`echo -n "$ONEDRVINFO" | cut -f 1 -d '|' | cut -f 3 -d '/'`"
  FSTYPE="`echo -n "$ONEDRVINFO" | cut -f 2 -d '|'`"
  SIZE=`echo -n "$ONEDRVINFO" | cut -f 3 -d '|'`
  drvPATTERN='^/dev/'"${ONEDRVNAME}"' ' #important, a space on end!
  if [ ! -d /root/.pup_event/drive_${ONEDRVNAME} ];then
   mkdir /root/.pup_event/drive_${ONEDRVNAME}
   cp -af /usr/local/bin/drive_all /root/.pup_event/drive_${ONEDRVNAME}/AppRun
   if [ -e /sys/block/${ONEDRVNAME} ];then
    #device is an entire drive.
    SIZE=`cat /sys/block/${ONEDRVNAME}/size`
    SIZE=$(($SIZE/2)) #get KB.
    format_size_func #formats SIZE for display.
    INFO="Описание: ${DRV_DESCRIPTION} Размер: ${SIZE}"
   else
    if [ "$FSTYPE" = "0" -a "$SIZE" = "0" ];then
     INFO="Puppy drive manager"
    else
     #pPATTERN=' '"$ONEDRVNAME"'$'
     #SIZE=`grep "$pPATTERN" /proc/partitions | tr -s ' ' | cut -f 4 -d ' '`
     format_size_func #formats SIZE for display.
     INFO="Файловая система: $FSTYPE Размер: $SIZE"
    fi
   fi
   MOREITEMS="<Item option=\"unmount\" icon=\"gtk-harddisk\"><Label>Размонтировать ${ONEDRVNAME} (если смонтирован сейчас)</Label></Item>"
   create_appinfo_func #needs INFO, DRV_CATEGORY, MOREITEMS, ONEDRVNAME
  fi
#  if [ "$ICONDESK" = "true" ];then #see /etc/eventmanager.
   MNTSTATUS="`df | grep "$drvPATTERN"`"
   if [ "$MNTSTATUS" = "" ];then
    icon_unmounted_func $ONEDRVNAME $DRV_CATEGORY #see functions4puppy4.
   else
    icon_mounted_func $ONEDRVNAME $DRV_CATEGORY #see functions4puppy4.
   fi
   add_pinboard_func #needs ONEDRVNAME, DRV_CATEGORY, FSTYPE.
#  fi
 done
 #always create a handler for entire drive, even if no icon displayed...
 if [ ! -d /root/.pup_event/drive_${DRV_NAME} ];then
  if [ -e /sys/block/${DRV_NAME} ];then
   mkdir /root/.pup_event/drive_${DRV_NAME}
   cp -af /usr/local/bin/drive_all /root/.pup_event/drive_${DRV_NAME}/AppRun
   SIZE=`cat /sys/block/${DRV_NAME}/size`
   SIZE=$(($SIZE/2)) #get KB.
   format_size_func #formats SIZE for display.
   INFO="Описание: ${DRV_DESCRIPTION} Размер: ${SIZE}"
   MOREITEMS=""
   ONEDRVNAME="$DRV_NAME"
   create_appinfo_func #needs INFO, DRV_CATEGORY, MOREITEMS, ONEDRVNAME
  fi
 fi
}

remove_pinboard_func() { #needs DRV_NAME (name of entire drive)
 ppPATTERN=' label="'"$DRV_NAME"'.*" '
 [ "`grep "$ppPATTERN" /root/Choices/ROX-Filer/PuppyPin`" = "" ] && return
 ALLNAMES="`grep -o "$ppPATTERN" /root/Choices/ROX-Filer/PuppyPin | cut -f 2 -d '"' | tr '\n' ' '`" #'geany
 for ONEDRVNAME in $ALLNAMES
 do
  echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <PinboardRemove>
   <Path>/root/.pup_event/drive_${ONEDRVNAME}</Path>
  </PinboardRemove>
 </env:Body>
</env:Envelope>"  | rox -R
 done
}

#note that init script in initrd takes care of restoring modules if enough space.
delete_func() { #called from free_func() and free_flash_func(). delete modules to create more free space.
 #passed param: /pup_rw=delete tmpfs top layer only.
 DEL_LAYER=$1
 #find out what modules are loaded, keep those...
 for ONEKEEP_MOD in `lsmod | cut -f 1 -d ' ' | grep -v 'Module'`
 do
  ONEKEEP_SPEC="`modinfo -F filename ${ONEKEEP_MOD}`"
  ONEKEEP_PATH="`dirname $ONEKEEP_SPEC`"
  mkdir -p /tmp${ONEKEEP_PATH}
  cp -af ${ONEKEEP_SPEC} /tmp${ONEKEEP_PATH}/
 done
 if [ "$DEL_LAYER" != "" ];then
  rm -rf ${DEL_LAYER}/lib/modules
 else
  if [ $PUPMODE -eq 3 -o $PUPMODE -eq 7 -o $PUPMODE -eq 13 ];then
   rm -rf ${SAVE_LAYER}/lib/modules
  fi
  rm -rf /lib/modules
 fi
 cp -af /tmp/lib/modules /lib/modules
 depmod -a
}

free_initrd_func() { #UniPup, runs entirely in initramfs.
 SIZEFREEK=`free | grep '^Total:' | tr -s ' ' | cut -f 4 -d ' '`
 SIZEFREEM=`expr $SIZEFREEK \/ 1024`
 [ -s /tmp/pup_event_sizefreem ] && PREVSIZEFREEM=`cat /tmp/pup_event_sizefreem`
 [ "$PREVSIZEFREEM" = "$SIZEFREEM" ] && return
 #save to a file, freememapplet can read this...
 echo "$SIZEFREEM" > /tmp/pup_event_sizefreem
}

free_func() { #called every 4 seconds.
 case $PUPMODE in
  6|12)
   SIZEFREEM=`df -m | grep ' /initrd/pup_rw$' | tr -s ' ' | cut -f 4 -d ' '`
  ;;
  *)
   SIZEFREEM=`df -m | grep ' /$' | tr -s ' ' | cut -f 4 -d ' '`
  ;;
 esac
 WARNMSG=""
 [ -s /tmp/pup_event_sizefreem ] && PREVSIZEFREEM=`cat /tmp/pup_event_sizefreem`
 [ $PREVSIZEFREEM -eq $SIZEFREEM ] && return
 if [ $SIZEFREEM -lt 10 ];then
  if [ -d /initrd/pup_rw/lib/modules/all-firmware -a "$ZDRVINIT" = "yes" ];then
   delete_func /initrd/pup_rw #save layer is at top, delete mods.
  else
   WARNMSG="ПРЕДУПРЕЖДЕНИЕ: Персональное хранилище файлов заполнено, настоятельно рекомендуется увеличить его размер или удалить ненужные файлы!"
  fi
 fi
 VIRTUALFREEM=$SIZEFREEM
 if [ "$ZDRVINIT" = "yes" ];then #full set of modules present, moved from initrd.
  if [ -d /initrd/pup_rw/lib/modules/all-firmware ];then #have not yet deleted modules.
   #calc the "virtual" free space (would have if modules not there...)
   VIRTUALFREEM=`expr $SIZEFREEM + $SIZE_MODS_M`
   VIRTUALFREEM=`expr $VIRTUALFREEM - 1` #allow for some mods will not be deleted.
  fi
 fi
 #save to a file, freememapplet can read this...
 echo "$VIRTUALFREEM" > /tmp/pup_event_sizefreem
 [ $PUPMODE -eq 5 -o $PUPMODE -eq 2 ] && return 0 #5=first boot, no msgs at top of screen.
 if [ "$WARNMSG" != "" ];then
  killall yaf-splash
  yaf-splash -margin 2 -bg red -bw 0 -placement top -font "9x15B" -outline 0 -text "$WARNMSG" &
 fi
}

free_flash_func() { #PUPMODE 3,7,13. called every 4 seconds.
 WARNMSG=""
 SIZEFREEM=`df -m | grep ' /initrd/pup_ro1$' | tr -s ' ' | cut -f 4 -d ' '`
 SIZETMPM=`df -m | grep ' /initrd/pup_rw$' | tr -s ' ' | cut -f 4 -d ' '`
 [ -s /tmp/pup_event_sizefreem ] && PREVSIZEFREEM=`cat /tmp/pup_event_sizefreem`
 [ -s /tmp/pup_event_sizetmpm ] && PREVSIZETMPM=`cat /tmp/pup_event_sizetmpm`
 [ $PREVSIZEFREEM -eq $SIZEFREEM -a $PREVSIZETMPM -eq $SIZETMPM ] && return
 if [ $SIZEFREEM -lt 10 ];then
  if [ -d /initrd/pup_ro1/lib/modules/all-firmware -a "$ZDRVINIT" = "yes" ];then
   delete_func /initrd/pup_ro1 #delete modules in save layer only.
  else
   WARNMSG="ПРЕДУПРЕЖДЕНИЕ: Персональное хранилище файлов заполнено, настоятельно рекомендуется увеличить его размер или удалить ненужные файлы!"
  fi
 fi
 if [ $SIZETMPM -lt 5 ];then
  if [ -d /initrd/pup_rw/lib/modules/all-firmware -a "$ZDRVINIT" = "yes" ];then
   delete_func /initrd/pup_rw #delete modules in top tmpfs layer only.
  else
   WARNMSG="ПРЕДУПРЕЖДЕНИЕ: Свободной RAM осталось только ${SIZETMPM}MB, рекомендуется перезагрузка для очистки RAM"
  fi
 fi
 VIRTUALFREEM=$SIZEFREEM
 if [ "$ZDRVINIT" = "yes" ];then #full set of modules present at bootup.
  if [ -d /initrd/pup_ro1/lib/modules/all-firmware ];then #have not yet deleted modules.
   #calc the "virtual" free space (would have if modules not there...)
   VIRTUALFREEM=`expr $SIZEFREEM + $SIZE_MODS_M`
   VIRTUALFREEM=`expr $VIRTUALFREEM - 1` #allow for some mods will not be deleted.
  fi
 fi
 echo "$SIZETMPM" > /tmp/pup_event_sizetmpm
 #save to a file, freememapplet can read this...
 echo "$VIRTUALFREEM" > /tmp/pup_event_sizefreem
 if [ "$WARNMSG" != "" ];then
  killall yaf-splash
  yaf-splash -margin 2 -bg red -bw 0 -placement top -font "9x15B" -outline 0 -text "$WARNMSG" &
 fi
}

savepuppy_func() { #called every 4 seconds.
 if [ -f /tmp/snapmergepuppyrequest ];then #by request.
  rm -f /tmp/snapmergepuppyrequest
  yaf-splash -font "8x16" -outline 0 -margin 4 -bg orange -placement top -text "Сохранение содержимого RAM в файл 'pup_save'..." &
  YAFPID=$!
  sync
  nice -n 19 /usr/sbin/snapmergepuppy
  kill $YAFPID
 fi
}

#v407 fixed so works for sr* and hd* optical...
probe_optical_func() { #passed param is sr<0-9> or hd<a-z>
 DRV_NAME="$1"
 DRV_CATEGORY="optical"
 CDSTATUS2="0"
 opticalPATTERN='^/dev/'"${DRV_NAME}"' '
 [ "`grep "$opticalPATTERN" /proc/mounts`" != "" ] && return #only check cd if unmounted.
 cddetect_quick -d/dev/${DRV_NAME} >/dev/null 2>&1 #very fast.
 #...returns 0 if disc inserted, else 255.
 CDSTATUS2="$?"
 [ "$CDSTATUS2" != "0" ] && [ -d /root/.pup_event/drive_${DRV_NAME} ] && rm -rf /root/.pup_event/drive_${DRV_NAME} #v410 ensure no drive directory if drive empty.
 echo "$CDSTATUS2" > /tmp/pup_event_frontend_identify2_${DRV_NAME}
 [ ! -f /tmp/pup_event_frontend_identify1_${DRV_NAME} ] && cp /tmp/pup_event_frontend_identify2_${DRV_NAME} /tmp/pup_event_frontend_identify1_${DRV_NAME}
 CDSTATUS1="`cat /tmp/pup_event_frontend_identify1_${DRV_NAME}`"
 [ "$CDSTATUS1" = "$CDSTATUS2" ] && return
 cp -f /tmp/pup_event_frontend_identify2_${DRV_NAME} /tmp/pup_event_frontend_identify1_${DRV_NAME}
 if [ "$CDSTATUS2" = "0" ];then
  #VENDOR="`cat /sys/block/${DRV_NAME}/device/vendor | tr -s ' '`"
  #MODEL="`cat /sys/block/${DRV_NAME}/device/model | tr -s ' '`"
  #DRV_DESCRIPTION="$VENDOR $MODEL"
  opticalPATTERN='^/dev/'"${DRV_NAME}"'|'
  DRV_DESCRIPTION="`echo "$PROBEDISK" | grep "$opticalPATTERN" | cut -f 3 -d '|'`"
  create_icon_func #requires DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION.
  [ "$HOTPLUGNOISY" = "true" ] && /root/.pup_event/drive_${DRV_NAME}/AppRun optical & #handler script.
 else
  rm -rf /root/.pup_event/drive_${DRV_NAME} 2>/dev/null
  remove_pinboard_func #needs DRV_NAME
 fi
}

#v407 detect ls120 and zip disc inserted...
probe_floppy_func() { #passed param is drive name (exs: hdc, sdc)
 DRV_NAME="$1"
 DRVMAIN="`echo -n "$DRV_NAME" | cut -c 1,2`" #sd or hd.
 DRV_CATEGORY="floppy"
 floppyPATTERN="^/dev/$DRV_NAME"
 [ "`grep "$floppyPATTERN" /proc/mounts`" != "" ] && return #mounted.
 if [ "$DRVMAIN" = "hd" ];then
  cat /proc/ide/${DRV_NAME}/identify > /tmp/pup_event_frontend_identify2_${DRV_NAME}
 else
  #this method not as good, as only detects disc if it has a partition...
  floppyPATTERN=" ${DRV_NAME}"
  grep "$floppyPATTERN" /proc/partitions > /tmp/pup_event_frontend_identify2_${DRV_NAME}
 fi
 [ ! -f /tmp/pup_event_frontend_identify1_${DRV_NAME} ] && cp /tmp/pup_event_frontend_identify2_${DRV_NAME} /tmp/pup_event_frontend_identify1_${DRV_NAME}
 [ "`diff -s /tmp/pup_event_frontend_identify1_${DRV_NAME} /tmp/pup_event_frontend_identify2_${DRV_NAME} | grep ' are identical'`" != "" ] && return
 cp -f /tmp/pup_event_frontend_identify2_${DRV_NAME} /tmp/pup_event_frontend_identify1_${DRV_NAME}
 FLOPPYSTATUS=1
 [ "`disktype /dev/${DRV_NAME} 2>&1 | grep 'I/O error'`" = "" ] && FLOPPYSTATUS=0
 if [ "$FLOPPYSTATUS" = "0" ];then
  if [ "$DRVMAIN" = "hd" ];then
   DRV_DESCRIPTION="`cat /proc/ide/${DRV_NAME}/model`"
  else
   DRV_DESCRIPTION="`cat /sys/block/${DRV_NAME}/device/model | tr -s ' '`"
  fi
  create_icon_func #requires DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION.
  [ "$HOTPLUGNOISY" = "true" ] && /root/.pup_event/drive_${DRV_NAME}/AppRun floppy & #handler script.
 else
  rm -rf /root/.pup_event/drive_${DRV_NAME} 2>/dev/null
  remove_pinboard_func #needs DRV_NAME
 fi
}

######################################################################
#stuff to setup at entry...
mkdir -p /root/.pup_event

#build the desktop icons...
DRV_CATEGORY='drive'
PROBEDISK="`probedisk2`"
#v407 ls120/zip floppy drives are probed every 4 secs...
DRVS_FLOPPY="`echo "$PROBEDISK" | grep '|floppy|' | cut -f 1 -d '|' | cut -f 3 -d '/'`"
#v407 same thing for all optical drives...
DRVS_OPTICAL="`echo "$PROBEDISK" | grep '|optical|' | cut -f 1 -d '|' | cut -f 3 -d '/'`"
if [ "$ICONDESK" = "false" ];then
 #only show a single 'drives' icon on desktop...
 DRV_NAME='drives'
 DRV_CATEGORY='any' #see pmount.
 DRV_DESCRIPTION="all drives"
 create_icon_func #needs DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION.
else
 #show all drives on desktop...
 PROBEPART="`probepart -k | grep -E '\|ntfs\||\|msdos\||\|vfat\||\|ext2\||\|ext3\||\|iso9660\||\|xfs\||\|reiser'`"
 if [ "$FD0ICON" = "true" ];then #see /etc/eventmanager
  if [ -e /sys/block/fd0 ];then
   PROBEDISK="/dev/fd0|floppy|Legacy floppy drive
$PROBEDISK"
   PROBEPART="/dev/fd0|vfat|1440
$PROBEPART"
  fi
 fi
 for ONEDRV in `echo "$PROBEDISK" | cut -f 1,2,3 -d '|' | tr ' ' '_' | tr '\n' ' '`
 do
  DRV_NAME="`echo -n "$ONEDRV" | cut -f 1 -d '|' | cut -f 3 -d '/'`"
  DRV_CATEGORY="`echo -n "$ONEDRV" | cut -f 2 -d '|'`"
  DRV_DESCRIPTION="`echo -n "$ONEDRV" | cut -f 3 -d '|' | tr '_' ' '`"
  [ "`echo "$PROBEPART" | grep "$DRV_NAME"`" = "" ] && continue #precaution (such as CD not inserted).
  create_icon_func startup #needs DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION, PROBEPART.
 done
fi

if [ "$BACKENDON" = "false" ];then #see /etc/eventmanager.
 killall hotplug2stdout #pup_event_backend_d #no module/firmware hotplug support.
 #...kill hotplug2stdout, as that will cause pup_eventd_backend_d to die.
 [ -f /sbin/udevd ] && killall udevd #alternative to pup_event_backend_d.
 exit
fi
[ "$HOTPLUGON" = "false" ] && exit #turn off all frontend hotplug support. see /etc/eventmanager.


###################################################################
#now go into a two-second loop...
while [ 1 ]
do
 sleep 2

 #graceful exit if shutdown X (see /usr/X11R7/bin/restartwm,wmreboot,wmpoweroff)...
 [ -f /tmp/wmexitmode.txt ] && break

 #test for any change in /sys/block...
 ls -1 --hide=ram* --hide=loop* /sys/block > /tmp/pup_event_frontend_block2
 [ ! -f /tmp/pup_event_frontend_block1 ] && cp /tmp/pup_event_frontend_block2 /tmp/pup_event_frontend_block1
 
 BLOCKDIFF="`diff /tmp/pup_event_frontend_block1 /tmp/pup_event_frontend_block2`"
 
 #########hotplug block event##########
 if [ "$BLOCKDIFF" != "" ];then
 
  cp -f /tmp/pup_event_frontend_block2 /tmp/pup_event_frontend_block1
 
  BLOCKSADD="`echo "$BLOCKDIFF" | grep '^> ' | cut -f 2-9 -d ' ' | tr '\n' ' '`"
  BLOCKSREM="`echo "$BLOCKDIFF" | grep '^< ' | cut -f 2-9 -d ' ' | tr '\n' ' '`"
  
  ACTION=add
  SUBSYSTEM=block
  DEVTYPE=disk
  for DRV_NAME in $BLOCKSADD
  do
   [ ! -e /sys/block/$DRV_NAME ] && continue #precaution
   DEVPATH=/block/$DRV_NAME
   odPATTERN='^/dev/'"$DRV_NAME"'|'
   PROBEDISK="`probedisk2`"
   DRVS_OPTICAL="`echo "$PROBEDISK" | grep '|optical|' | cut -f 1 -d '|' | cut -f 3 -d '/'`" #update
   DRVS_FLOPPY="`echo "$PROBEDISK" | grep '|floppy|' | cut -f 1 -d '|' | cut -f 3 -d '/'`" #update
   DRV_CATEGORY="`echo -n "$PROBEDISK" | grep "$odPATTERN" | cut -f 2 -d '|'`"
   DRV_DESCRIPTION="`echo -n "$PROBEDISK" | grep "$odPATTERN" | cut -f 3 -d '|' | tr -s ' '`"
   [ "$ICONDESK" = "true" ] && create_icon_func #uses DRV_NAME, DRV_CATEGORY, DRV_DESCRIPTION
   [ "$HOTPLUGNOISY" = "true" ] && /root/.pup_event/drive_${DRV_NAME}/AppRun ${DRV_CATEGORY} & #handler script.
  done
 
  ACTION=remove
  for DRV_NAME in $BLOCKSREM
  do
   [ -e /sys/block/$DRV_NAME ] && continue #precaution
   DRVS_OPTICAL="`echo "$DRVS_OPTICAL" | grep -v "$DRV_NAME"`" #update
   DRVS_FLOPPY="`echo "$DRVS_FLOPPY" | grep -v "$DRV_NAME"`" #update
   DEVPATH=/block/$DRV_NAME
   if [ "`pidof gtkdialog_pmount`" != "" ];then #if pmount running, refresh it.
    killall gtkdialog_pmount 2>/dev/null
    sleep 0.1
    pmount &
   fi
   remove_pinboard_func #needs DRV_NAME
   rm -rf /root/.pup_event/drive_${DRV_NAME}* 2>/dev/null
  done
 
 fi

 if [ $TOGGLE -eq 0 ];then #slow down to every 4 seconds.
  TOGGLE=1
  continue
 else
  TOGGLE=0
 fi

 #######four second timeout procesing#########
 SAVECNT=`expr $SAVECNT + 4`
 if [ $RAMSAVEINTERVAL -ne 0 -a $SAVECNT -gt $RAMSAVEINTERVAL ];then
  touch /tmp/snapmergepuppyrequest #request to savepuppy_func.
  SAVECNT=0
 fi
 #some apps should not be disturbed by this background stuff...
 RUNPS="`ps`"
 [ "`echo "$RUNPS" | grep -E 'xine|petget|wget|axel|dotpup|mplayer|gcurl|gimv|burniso2cd|growisofs|cdrecord|pcdripper|xfmedia|xmms|ripoff|pdvdrsab|pburn|mhwaveedit'`" != "" ] && continue
 #monitor free memory, periodic save of tmpfs top layer...
 case $PUPMODE in
  3|7|13)
   free_flash_func
   savepuppy_func
  ;;
  16|24|17|25) #unipup.
   free_initrd_func
  ;;
  *)   
   free_func
  ;;
 esac
 [ "$ICONDESK" = "false" ] && continue #v405 see /etc/eventmanager
 #unfortunately, we have to poll at regular intervals to see if a cd is inserted...
 for ONEOPTICAL in $DRVS_OPTICAL
 do
  [ "$ONEOPTICAL" = "" ] && continue #precaution
  probe_optical_func $ONEOPTICAL
 done
 #v407 poll to see if a ls120 or zip floppy diskette inserted...
 for ONEFLOPPY in $DRVS_FLOPPY
 do
  [ "$ONEFLOPPY" = "" ] && continue #precaution
  probe_floppy_func $ONEFLOPPY
 done


done #2 second loop.


###END###
