#!/bin/sh
#LGPL v2 Copyright 2007 Barry Kauler, www.puppylinux.com
#Feb 2010. Rewrited DdShurick PuppyRus.org for Puppy tftpboot



LAYERFS=aufs #aufs or unionfs

check_status()
{
  /bin/echo -en "\\033[72G" >/dev/console #move to column 72.
  if [ $1 -eq 0 ]
  then
    /bin/echo -en "\\033[1;32mdone" >/dev/console
    /bin/echo -e "\\033[0;39m" >/dev/console
  else
    /bin/echo -en "\\033[1;31mfailed" >/dev/console
    /bin/echo -e "\\033[0;39m" >/dev/console
    echo -en "\\033[1;35m" >/dev/console #35=purple
    echo -n "Dumping last lines of /tmp/bootinit.log..." >/dev/console
    /bin/echo -e "\\033[0;39m" >/dev/console
    echo -en "\\033[1;31m" >/dev/console #31=red
    cat /tmp/bootinit.log | tail -n 4 >/dev/console
    /bin/echo -en "\\033[0;39m" >/dev/console
    echo -en "\\033[1;35m" >/dev/console #35=purple
    echo -n "Dumping last lines of kernel log..." >/dev/console
    /bin/echo -e "\\033[0;39m" >/dev/console
    echo -en "\\033[1;31m" >/dev/console #31=red
    dmesg | tail -n 4 >/dev/console
    /bin/echo -en "\\033[0;39m" >/dev/console
    #exit to initial ramdisk shell...
    [ "$RDSH" = "yes" ] && exec /bin/sh >/dev/console 2>&1
    echo "Pausing for 60 seconds..." >/dev/console
    sleep 60
  fi
}


PATH="/bin:/sbin"
KERNVER="`uname -r`"

PUPPYVERSION=`cat /PUPPYVERSION`
PUPMODE=5

mount -t proc none /proc
mount -t sysfs none /sys
mount -t rootfs -o remount,rw rootfs /
ln -s /proc/mounts /etc/mtab #resize2fs,e2fsck need this.

###################LOAD MODULES TO ACCESS DRIVES#####################
echo -n "Loading kernel drivers needed to access disk drives..." > /dev/console #STEP ONE

#v403 pcmcia drive support. i think this may need extra delay though...
if [ "`elspci -l | grep '060700'`" != "" ];then
 modprobe yenta_socket
 #...may have to add on a couple of seconds, need to test with a pcmcia drive.
 #v412 yeah, my pccard-usb adaptor needs delay before elspci recognises 0C0310 interface...
 sleep 2
fi

modprobe squashfs
#filesystems...
modprobe nls_cp437     #needed by windows filesystems.
modprobe nls_iso8859-1 #needed by linux filesystems.
modprobe aufs
modprobe fuse #for ntfs-3g driver.

check_status 0 #END STEP ONE
##############END MODULE LOADING TO ACCESS DRIVES####################

if [ $tftpboot ]; then
echo -n "Ethernet up..." > /dev/console
modprobe via-rhine #only for I
ifconfig lo 127.0.0.1
ifconfig lo up
ifconfig eth0 $clip
ifconfig eth0 up && check_status 0
echo -n "Tftp get pup_420-ru files ..." > /dev/console
tftp $tftpboot -c get pup_420-ru.sfs && check_status 0
mv pup_420-ru.sfs /mnt/dev_save/

fi

##########################LOADING PUPPY FILES###########################
echo -n "Load Puppy files..." > /dev/console
RAMSIZE=`free | grep 'Mem:' | tr -s ' ' | cut -f 3 -d ' '` #total physical ram (less shared video).

#decide the mount-points...
#unionfs layers:            RW (top)      RO1             RO2              PUPMODE
#First boot (or pfix=ram):  tmpfs                         pup_xxx.sfs      5

CREATETMPFS="";CREATEPDEV1="";CREATEPUPXXXSFS="";CREATEPUPSAVE2FS="";CREATEFOLDERS=""

 CREATETMPFS="/pup_rw";CREATEPUPXXXSFS="/pup_ro2"
 OLDFILESMNTPT="";NEWFILESMNTPT="/pup_ro2";UMNTMAIN="/pup_rw=rw:/pup_ro2=ro"


#there are technical problems with loading a swap partition/file before the union
#is created, so not doing it until rc.sysinit runs. however, if a tmpfs needs to be
#created here, set it's size in anticipation of a swap being loaded...
EXTRAALLOCK=0 ; PSWAPFILE=""
SWAPPART="`echo "$PCPARTSALL" | grep '|swap|' | head -n 1`"
[ "$SWAPPART" != "" ] && SWAPPARTSIZE=`echo -n "$SWAPPART" | cut -f 3 -d '|'`
[ $SWAPPARTSIZE ] && EXTRAALLOCK=`expr $SWAPPARTSIZE \/ 2`

FREEK=0
if [ "$CREATETMPFS" != "" ];then
 FREEK=`expr $RAMSIZE \/ 2` #half of physical.
 ALLOCK=`expr $FREEK + $EXTRAALLOCK`
 mount -t tmpfs -o size=${ALLOCK}k tmpfs $CREATETMPFS
fi

#RW (top) layer now has a tmpfs, PDEV1 or pup_save mounted on it. calc free space...
[ $FREEK -eq 0 ] && FREEK=`df | grep ' /pup_rw' | tr -s ' ' | cut -f 4 -d ' '`
[ ! $FREEK ] && FREEK=0

OLDPUPPYVERSION=$PUPPYVERSION
[ -f $OLDFILESMNTPT/etc/puppyversion ] && OLDPUPPYVERSION=`cat $OLDFILESMNTPT/etc/puppyversion`

#move modules to main f.s...
#(do this before loading pup_xxx.sfs, to free up ram space)...
REASON=''

#v405 decide whether to copy sfs's to ram...
COPY2RAM=""
COPYMSG='copying to ram' #purple
#v4.00 lowered rom 230000 to 220000... v403 added PUPSFSDEVMNTPT test... v404 explicit PCOPY needed...
[ $PUPMODE -eq 5 ] && PCOPY="yes" #well, override on first boot.
[ $RAMSIZE -gt 220000 -a "$PCOPY" = "yes" ] && COPY2RAM="yes" #256MB system. note, only checking physical ram.

if [ "$CREATEPUPXXXSFS" != "" ];then
  if [ $tftpboot ]; then
  mount -o loop /mnt/dev_save/pup_420-ru.sfs /mnt/dev_ro2/
  PUPSFSDEVMNTPT="/mnt/dev_ro2"
  UMOUNTME="/mnt/dev_ro2"
  fi
 if [ "$COPY2RAM" = "yes" ];then
  SIZESFSK=`du -k ${PUPSFSDEVMNTPT}${PUPSFSFILE} | cut -f 1`
  SIZESFSK=`expr $SIZESFSK + 1000` #some slack.
  mount -t tmpfs -o size=${SIZESFSK}k tmpfs /mnt/tmpfs
  if [ "${PUPSFSDEVMNTPT}" = "" ];then #v403 humongous initrd.
    mv -f ${PUPSFSDEVMNTPT}${PUPSFSFILE} /mnt/tmpfs/
  else
   echo -e -n " \\033[1;35m${COPYMSG}\\033[0;39m" > /dev/console #purple.
   cp -af ${PUPSFSDEVMNTPT}${PUPSFSFILE} /mnt/tmpfs/
  fi
  sync
  SFSBASENAME=pup_420-ru.sfs
  losetup /dev/loop0 /mnt/tmpfs/${SFSBASENAME}
 else
  losetup /dev/loop0 ${PUPSFSDEVMNTPT}${PUPSFSFILE}
 fi
 mount -r -t squashfs -o noatime /dev/loop0 $CREATEPUPXXXSFS #usually /pup_ro2.
fi

ZLAYER='' #v4.02
#note, traditionally, loop2 kept free for scripts to use.
if [ "$ZDRVINIT" != "yes" ];then
 #v4.02 if ZDRV located, and mounted, put it into the unionfs...
 if [ "$ZDRV" != "" ];then
  ZDEV="`echo "$ZDRV" | cut -f 1 -d ','`"
  ZFS="`echo "$ZDRV" | cut -f 2 -d ','`"
  ZFILE="`echo "$ZDRV" | cut -f 3 -d ','`"
  if [ -f /mnt/dev_ro2${ZFILE} ];then
   if [ "$COPY2RAM" = "yes" ];then #256MB system. note, only checking physical ram.
    SIZEZK=`du -k /mnt/dev_ro2${ZFILE} | cut -f 1`
    SIZEZK=`expr $SIZEZK + 1000` #some slack.
    mount -t tmpfs -o size=${SIZEZK}k tmpfs /mnt/tmpfs2
    cp -af /mnt/dev_ro2${ZFILE} /mnt/tmpfs2/
    sync
    ZBASENAME="`basename $ZFILE`"
    losetup /dev/loop3 /mnt/tmpfs2/${ZBASENAME}
   else
    losetup /dev/loop3 /mnt/dev_ro2${ZFILE}
   fi
   mount -r -t squashfs -o noatime /dev/loop3 /pup_z
   [ $? -eq 0 ] && ZLAYER=':/pup_z=ro'
  fi
 fi
fi

check_status $?
########################END LOADING PUPPY FILES########################


#####/etc/PUPSTATE passes useful variables to the running puppy...####
mkdir -p /pup_rw/etc/rc.d
echo "PUPMODE=$PUPMODE" > /pup_rw/etc/rc.d/PUPSTATE
echo "PDEV1='$PDEV1'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "DEV1FS='$DEV1FS'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "PUPSFS='$PUPSFS'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "PUPSAVE='$PUPSAVE'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "PMEDIA='$PMEDIA'" >> /pup_rw/etc/rc.d/PUPSTATE
if [ -e /proc/ide ];then
 echo "SATADRIVES='$ATADRIVES'"  >> /pup_rw/etc/rc.d/PUPSTATE
else
 echo '#v3.97: kernel with libata pata has both sata and pata drives in ATADRIVES...' >> /pup_rw/etc/rc.d/PUPSTATE
 echo "ATADRIVES='$ATADRIVES'"  >> /pup_rw/etc/rc.d/PUPSTATE
fi
echo '#these directories are unionfs layers in /initrd...' >> /pup_rw/etc/rc.d/PUPSTATE
echo "SAVE_LAYER='$OLDFILESMNTPT'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "PUP_LAYER='$NEWFILESMNTPT'" >> /pup_rw/etc/rc.d/PUPSTATE
#if [ $SMNTPT ];then
 echo "#The partition that has the pup_save file is mounted here..." >> /pup_rw/etc/rc.d/PUPSTATE
 echo "PUP_HOME='${SMNTPT}'" >> /pup_rw/etc/rc.d/PUPSTATE
 echo '#(in /initrd) ...note, /mnt/home is a link to it.' >> /pup_rw/etc/rc.d/PUPSTATE
#fi
echo '#this file has extra kernel drivers and firmware...' >> /pup_rw/etc/rc.d/PUPSTATE
echo "ZDRV='$ZDRV'" >> /pup_rw/etc/rc.d/PUPSTATE #v2.22
echo '#complete set of modules in the initrd (moved to main f.s.)...' >> /pup_rw/etc/rc.d/PUPSTATE
echo "ZDRVINIT='$ZDRVINIT'" >> /pup_rw/etc/rc.d/PUPSTATE #v4.02
echo "PSWAPFILE='$PSWAPFILE'" >> /pup_rw/etc/rc.d/PUPSTATE
echo "PSAVEMARK='$PSAVEMARK'" >> /pup_rw/etc/rc.d/PUPSTATE

#older pup_save.2fs <v2.16 will not have this file...
[ ! -f $OLDFILESMNTPT/etc/rc.d/BOOTCONFIG ] && touch $OLDFILESMNTPT/etc/rc.d/BOOTCONFIG
#note, OLDFILESMNTPT can also be "" so BOOTCONFIG needs to exist in initrd also.
. $OLDFILESMNTPT/etc/rc.d/BOOTCONFIG #can have EXTRASFSLIST variable.

######################SETUP UNIONFS LAYERED FILESYSTEM########################
echo -n "Setting up the layered filesystem..." > /dev/console #STEP FIVE
#are there any other sfs files to load at bottom layers?...
NEWUNIONRECORD=""
if [ "$PUPSAVE" != "" ];then
 if [ "$SMNTPT" != "" -o $PUPMODE -eq 77 ];then #v3.97
  SFSSDIR="$SMNTPT"
  [ $PUPMODE -eq 77 ] && SFSSDIR="$DESTDIR" #v3.97
  #find all the extra sfs files...
  touch /tmp/LOGONEBASES
  NPATTERN="_${PUPPYVERSION}\\.sfs"
  ls -1 $SFSSDIR/*.sfs |
  while read ONEEXTRA
  do
   ONEBASE="`basename $ONEEXTRA`"
   [ "`echo "$ONEBASE" | grep -E '^z|^pup'`" != "" ] && continue
   if [ "$EXTRASFSLIST" = "" ];then #in /etc/BOOTCONFIG
    [ "`echo "$ONEBASE" | grep "$NPATTERN"`" != "" ] && echo "${ONEEXTRA}" >> /tmp/EXTRASFSS
   else
    [ "`echo "$EXTRASFSLIST" | grep "$ONEBASE"`" != "" ] && echo "${ONEEXTRA}" >> /tmp/EXTRASFSS
   fi 
  done
  UMNTRO="" ; EXTRASFSLIST=""
  if [ -f /tmp/EXTRASFSS ];then
   CNTLOOP=4
   for ONEEXTRA in `cat /tmp/EXTRASFSS | tr '\n' ' '`
   do
    ONEBASE="`basename $ONEEXTRA`"
    EXTRASFSLIST="${EXTRASFSLIST}${ONEBASE} " #construct list of actually used.
    losetup /dev/loop${CNTLOOP} $ONEEXTRA
    mount -r -t squashfs -o noatime /dev/loop${CNTLOOP} /pup_ro${CNTLOOP}
    [ $? -eq 0 ] && UMNTRO="${UMNTRO}:/pup_ro${CNTLOOP}=ro"
    CNTLOOP=`expr $CNTLOOP + 1`
    [ $CNTLOOP -eq 23 ] && break 
    #kernel supports max 8 loop devices, changed to support 24 (JB4X4 - v420)
    #...but, only support adding 3 extra .sfs files, as performance degrades as each layer added.
    #...v410 bugfix, change 6 to 7 so can have 3 sfs files.
   done
  fi
  #keep a record of different layer configurations...
  SAVEFILE="`echo -n "$PUPSAVE" | cut -f 3 -d ','`"
  SAVEFILENAMEONLY="`basename $SAVEFILE`"
  SFSFILE="`echo -n "$PUPSFS" | cut -f 3 -d ','`"
  SFSFILENAMEONLY="`basename $SFSFILE`"
  RECORDLIST="$SAVEFILENAMEONLY $SFSFILENAMEONLY $EXTRASFSLIST"
  NEWUNIONRECORD="`echo "$RECORDLIST" | tr -s ' '  | sed -e 's/ $//'`"
 fi
fi

#update /etc/rc.d/BOOTCONFIG with latest unionfs layers configuration...
cat $OLDFILESMNTPT/etc/rc.d/BOOTCONFIG | grep -v '^PREVUNIONRECORD' | sed -e 's/^LASTUNIONRECORD/PREVUNIONRECORD/g' >/pup_rw/etc/rc.d/BOOTCONFIG
sync
echo "LASTUNIONRECORD='$NEWUNIONRECORD'" >> /pup_rw/etc/rc.d/BOOTCONFIG
[ "$LASTUNIONRECORD" = "$NEWUNIONRECORD" ] && NEWUNIONRECORD="" #used below.
#...if layers changed since last boot, code further down will do whiteout files purge.
#.../etc/rc.d/rc.update reads BOOTCONFIG, updates menu (etc) if layers changed.

#after switch_root, rc.sysinit calls rc.update, but need to do pre-cleaning...
if [ "$OLDFILESMNTPT" != "" ];then
 #an empty tmp is required for mounting a tmpfs onto later...
 rm -rf $OLDFILESMNTPT/tmp/*
 rm -rf $OLDFILESMNTPT/tmp/.[0-9a-zA-Z]*
 if [ ! -L $OLDFILESMNTPT/usr/X11R6 ];then #test if a symlink.
  #this is supposed to be a link to X11R7. <2.10 it won't be...
  if [ -d $OLDFILESMNTPT/usr/X11R6 ];then
   mkdir -p $OLDFILESMNTPT/usr/X11R7
   cp -af $OLDFILESMNTPT/usr/X11R6/* $OLDFILESMNTPT/usr/X11R7/
   rm -rf $OLDFILESMNTPT/usr/X11R6
  fi
  ln -s X11R7 $OLDFILESMNTPT/usr/X11R6
 fi
 rm -rf $OLDFILESMNTPT/root/tmp 2>/dev/null
 rm -f $OLDFILESMNTPT/root/.wh.tmp 2>/dev/null
 [ "$PCLEAN" = "yes" ] && OLDPVERSION=`expr $NEWPVERSION - 1`
 [ "$PPURGE" = "yes" ] && OLDPVERSION=`expr $NEWPVERSION - 1`
 if [ $NEWPVERSION -gt $OLDPVERSION ];then
  echo -e "\\033[1;35m"  >/dev/console #35=purple.
  echo "Version update, restoring 'official' files, please wait..." >/dev/console
  echo -en "\\033[0;39m" >/dev/console
  echo "(with a slow CPU this may take sometime, please be patient)" >/dev/console
  #v2.16 do not overwrite rox desktop setup, as /etc/rc.d/rc.update now handles it...
  [ -f $OLDFILESMNTPT/root/Choices/ROX-Filer/PuppyPin ] && touch $OLDFILESMNTPT/root/Choices/ROX-Filer/PuppyPin
  [ -f $OLDFILESMNTPT/root/Choices/ROX-Filer/globicons ] && touch $OLDFILESMNTPT/root/Choices/ROX-Filer/globicons
  mkdir $OLDFILESMNTPT/tmp/versioncleanup
  #make sure that the official boot scripts will be visible at top...
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.country
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.local0
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.modem
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.modules
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.modules2
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.network
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.shutdown
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.sysinit
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.update
  rm -f $OLDFILESMNTPT/etc/rc.d/rc.services #v405
  #i think if a file exists both in OLDFILESMNTPT and in NEWFILESMNTPT, remove
  #it from OLDFILESMNTPT (as OLDFILESMNTPT is upper layer and will hide the
  #'official' file. But, only do it if 'official' file has a newer modify date...
  cd $NEWFILESMNTPT
  #v2.12 this while-loop has become ultra-slow... seems upx compressed execs
  #responsible, recently upx-ed all the execs, now restore busybox, grep, cp.
  DOTCNT=0
  find ./ -noleaf -type f | sed -e 's/^\.//g' |
  while read ONENEW
  do
   DOTCNT=`expr $DOTCNT + 1`
   [ $DOTCNT -gt 100 ] && DOTCNT=0 #display a dot every time cnts to 100.
   [ $DOTCNT -eq 100 ] && echo -n '*' >/dev/console #v2.12
   #note, screens out spaces also...
   [ ! "`echo -n "$ONENEW" | grep -E '^/dev|^/tmp|^/proc| '`" = "" ] && continue
   ONEBASE="`basename $OLDFILESMNTPT$ONENEW`"
   OLDDIR="`dirname $OLDFILESMNTPT$ONENEW`"
   #a whiteout file 'on top' will hide the 'official' file...
   [ -f $OLDDIR/.wh.$ONEBASE ] && rm -f $OLDDIR/.wh.$ONEBASE
   [ -f $OLDDIR/.wh.__dir_opaque ] && rm -f $OLDDIR/.wh.__dir_opaque
   #let's get paranoid and imagine upper-directories also wiped...
   while [ ! "$OLDDIR" = "/" ];do
    OLDDIR="`dirname $OLDDIR`"
    UP1BASE="`basename $OLDDIR`"
    [ -f $OLDDIR/.wh.$UP1BASE ] && rm -f $OLDDIR/.wh.$UP1BASE
    [ -f $OLDDIR/.wh.__dir_opaque ] && rm -f $OLDDIR/.wh.__dir_opaque
   done
   #now check for 'old' files on top layer...
   if [ -f $OLDFILESMNTPT$ONENEW ];then
    #note, this is inaccurate due to local timezone not yet set...
    #i got this 'stat' off ibiblio, v3.3. i think older version than in main puppy f.s...
    MODIFOLD=`$PUPFILESDIR/bin/stat -c %Y $OLDFILESMNTPT$ONENEW`
    MODIFNEW=`$PUPFILESDIR/bin/stat -c %Y $NEWFILESMNTPT$ONENEW`
    [ "$PPURGE" = "yes" ] && MODIFNEW=`expr $MODIFOLD + 1` #force overwrite all.
    if [ $MODIFNEW -ge $MODIFOLD ];then
     echo -n " $ONENEW " >/dev/console
     ONEDIR="`dirname $ONENEW`"
     mkdir -p $OLDFILESMNTPT/tmp/versioncleanup$ONEDIR
     cp -af $OLDFILESMNTPT$ONENEW $OLDFILESMNTPT/tmp/versioncleanup$ONEDIR/
     rm -f $OLDFILESMNTPT$ONENEW
    fi
   fi
  done
  echo >/dev/console
  cd /
 fi
 #need to cleanup whiteout files if a new .sfs layer has been added...
 if [ "$NEWUNIONRECORD" != "" -o "$PPURGE" = "yes" ];then
  #find all .wh.__dir_opaque files at the OLDFILESMNTPT layer...
  cd $OLDFILESMNTPT
  find ./ -noleaf -type f -name ".wh.*" | sed -e 's/^\.//g' |
  while read ONEOPAQUE
  do
   ONEDIR="`dirname $ONEOPAQUE`"
   WHBASE="`basename $ONEOPAQUE`"
   if [ ! "$WHBASE" = ".wh.__dir_opaque" ];then
    #example, .wh.bin alongside bin directory means it is deleted...
    ONEDEL="`echo -n "$WHBASE" | sed -e 's/^\.wh\.//g'`"
    BASEDIR="`basename $ONEDIR`"
    [ ! "$BASEDIR" = "$ONEDEL" ] && continue
   fi
   #if same dir exists lower layer, then wipe the opaque file...
   [ -d /pup_ro3${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro4${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro5${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro6${ONEDIR} ] && rm -f $ONEOPAQUE #v412
   # JB4x4 - added support for extra SFS files v420
   [ -d /pup_ro6${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro7${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro8${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro9${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro10${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro11${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro12${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro13${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro14${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro15${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro16${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro17${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro18${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro19${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro20${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro21${ONEDIR} ] && rm -f $ONEOPAQUE
   [ -d /pup_ro22${ONEDIR} ] && rm -f $ONEOPAQUE
  done
  cd /
 fi
 if [ $NEWPVERSION -gt $OLDPVERSION ];then
  echo -n "$OLDPVERSION" > $OLDFILESMNTPT/etc/puppyversion #v2.14 so rc.update will run.
  sync
  echo -e "\\033[1;35m"  >/dev/console #34=blue, 33=yellow, 32=green, 31=red, 35=purple, 36=aquablue, 38=black.
  [ "$PCLEAN" = "yes" ] && echo "This is a simulated version upgrade, which performs a file cleanup." >/dev/console
  [ "$PPURGE" = "yes" ] && echo "This is a radical file cleanup for broken systems, could alter some settings." >/dev/console
  echo "You are upgrading Puppy from version $OLDPVERSION to $NEWPVERSION." >/dev/console
  echo "Overwritten old files have been moved to /tmp/versioncleanup/" >/dev/console
  echo "After bootup please examine this directory (before shutdown) for anything" >/dev/console
  echo "that you might like to recover. Pausing 30 secs so you can read this msg..." >/dev/console
  echo -en "\\033[0;39m" >/dev/console
  sleep 30 #so can see above messages.
 fi
fi

#create the unionfs layered f.s.... ***THE BIG EVENT***
if [ "$LAYERFS" = "aufs" ];then
 mount -t aufs -o udba=reval,diropq=w,dirs=${UMNTMAIN}${ZLAYER}${UMNTRO} unionfs /pup_new
else #unionfs
 mount -t unionfs -o dirs=${UMNTMAIN}${ZLAYER}${UMNTRO} unionfs /pup_new
fi
check_status $? #END STEP FIVE
#######################END SETUP UNIONFS LAYERED FILESYSTEM###################

#######################SETUP SWITCH TO MAIN FILESYSTEM#######################
echo -n "Performing a 'switch_root' to the layered filesystem..." > /dev/console
#prepare everything for doing a switch_root...
#cpio archive does switch_root, lose the initial-ramfs, so move all mntd...
mkdir -p /pup_new/initrd
mkdir -p /pup_new/initrd/pup_ro1
mkdir -p /pup_new/initrd/pup_ro2
mkdir -p /pup_new/initrd/pup_ro3
mkdir -p /pup_new/initrd/pup_ro4
mkdir -p /pup_new/initrd/pup_ro5
mkdir -p /pup_new/initrd/pup_ro6 #v412
# JB4x4 - added support for extra SFS files
mkdir -p /pup_new/initrd/pup_ro6
mkdir -p /pup_new/initrd/pup_ro7
mkdir -p /pup_new/initrd/pup_ro8
mkdir -p /pup_new/initrd/pup_ro9
mkdir -p /pup_new/initrd/pup_ro10
mkdir -p /pup_new/initrd/pup_ro11
mkdir -p /pup_new/initrd/pup_ro12
mkdir -p /pup_new/initrd/pup_ro13
mkdir -p /pup_new/initrd/pup_ro14
mkdir -p /pup_new/initrd/pup_ro15
mkdir -p /pup_new/initrd/pup_ro16
mkdir -p /pup_new/initrd/pup_ro17
mkdir -p /pup_new/initrd/pup_ro18
mkdir -p /pup_new/initrd/pup_ro19
mkdir -p /pup_new/initrd/pup_ro20
mkdir -p /pup_new/initrd/pup_ro21
mkdir -p /pup_new/initrd/pup_ro22
mkdir -p /pup_new/initrd/pup_rw
mkdir -p /pup_new/initrd/pup_z
mkdir -p /pup_new/initrd/mnt
mkdir -p /pup_new/initrd/mnt/data
mkdir -p /pup_new/initrd/mnt/dev_ro1
mkdir -p /pup_new/initrd/mnt/dev_ro2
mkdir -p /pup_new/initrd/mnt/dev_save
mkdir -p /pup_new/initrd/mnt/swap
mkdir -p /pup_new/initrd/mnt/tmpfs
mkdir -p /pup_new/initrd/mnt/tmpfs2
mkdir -p /pup_new/initrd/mnt/zdrv
mkdir -p /pup_new/initrd/tmp
for ONEMNT in `mount | cut -f 3 -d ' ' | grep -v 'pup_new' | grep '^/pup_' | tr '\n' ' '`
do
 mount -o move $ONEMNT /pup_new/initrd${ONEMNT}
done
for ONEMNT in `mount | cut -f 3 -d ' ' | grep '^/mnt/' | tr '\n' ' '`
do
 mount -o move $ONEMNT /pup_new/initrd${ONEMNT}
done

#v4.02 bring back, but allocate more space (/4 instead of /8)....
#v3.97 a problem can run out of /tmp space, remove...
#to minimise writes to pup_save and to speedup, tmpfs on /tmp...
if [ "$CREATETMPFS" != "/pup_rw" ];then #test if no tmpfs on unionfs top layer.
 #v412 bugfix, versioncleanup dir gets overwritten by this tmpfs on tmp...
 if [ -d /pup_new/tmp/versioncleanup ];then #v412
  cp -a /pup_new/tmp/versioncleanup /tmp/ 2>/dev/console
  rm -rf /pup_new/tmp/*
 fi
 ALLOCK=`expr $RAMSIZE \/ 4 + $EXTRAALLOCK`
 mount -t tmpfs -o size=${ALLOCK}k tmpfs /pup_new/tmp
 if [ -d /tmp/versioncleanup ];then #v412
  cp -a /tmp/versioncleanup /pup_new/tmp/ 2>/dev/console
  rm -rf /tmp/versioncleanup
 fi
 
 ##want var to be in the tmpfs...
 #cp -a /pup_new/var /pup_new/tmp/
 #rm -rf /pup_new/var #note, this creates a .wh.var whiteout file in pup_rw.
 #ln -snf tmp/var /pup_new/var
 #[ -d /pup_new/root/.thumbnails ] && rm -rf /pup_new/root/.thumbnails #image cache for rox.
 #mkdir /pup_new/tmp/thumbnails
 #ln -snf tmp/thumbnails /pup_new/root/.thumbnails
fi

#PNOX is a boot param. /etc/profile prevents X from starting if this file exists...
[ "$PNOX" = "yes" ] && touch /pup_new/tmp/bootcnt.txt
cp -a /PUPPYVERSION /pup_new/initrd/

cp -af /tmp/* /pup_new/initrd/tmp/ #keep any log files.

#RDSH is a boot param. exit to initial ramdisk shell...
if [ "$RDSH" = "yes" ];then
 echo > /dev/console
 echo "Dropped to initramfs shell. Type 'exec switch' to continue booting Puppy." > /dev/console
 exec /bin/sh >/dev/console 2>&1
fi

#v3.01 a bit untidy, but cd may still be mounted when it doesn't have to be...
case $PMEDIA in
 *cd)
  [ "$PDEV1" ] && umount /dev/$PDEV1 2>/dev/null #okay if it fails.
  ;;
esac

sync
umount /proc/bus/usb
umount /sys
umount /proc

#now using cpio archive for initramfs 'initial ramdisk'...
#exec switch_root -c /dev/console /pup_new /bin/busybox init 3
exec switch_root /pup_new /sbin/init

###END###
