#!/bin/sh
#(c) Copyright Barry Kauler, Feb. 12 2015. License GPL3
#called from "save" icon on desktop, when running in ram (live-CD, frugal HD).
#woofQ has script 7build-live-cd that creates "save" icon.
#150216 first release.
#150217 show progress burning to CD.
#150219 removed "-processors 1" from mksquashfs.
#150223 use urxvt when erase optical media.
#150317 frugal: /usr/sbin/installquirky places q.sfs outside of initrd, uncompressed. refer also: /boot/initrd-tree/init
#150318 do not save /run (or /var). they are only symlinks. note, rc.sysinit will recreate them.
#150318 add  .fsckme.flg root/.XLOADED to exclude-list.
#150925 xanad: export TEXTDOMAIN, OUTPUT_CHARSET.
#151106 find a large-enough temporary working place.
#151106 new front gui for live-cd, offer remaster or save-to-hard-drive.
#151107 quick-save window for live-cd if already has saved-session. rewrite frugal save.
#151108 exclude some dirs from s.sfs
#151108 remove any spaces from DESTFOLDER
#151112 help button for entering save-folder.
#151123 BOOT_DEV may have UUID. ex: BOOT_DEV=UUID=1234-4567-6789-4321
#151127 replace BOOT_ with INSTALL_, ex BOOT_DEV with INSTALL_DEV
#151128 do not use /etc/rc.d/install.log anymore.
#151129 fix burning to cd-rw. revert, cd-rw does not work on my laptop, use dvd-rw. 151201 plus fixes.
#151203 choose optical dev for optional remaster-cd (save-to-hd choice).
#151204 test if dvd already erased.
#151205 mksquashfs, screen out /initrd, otherwise aufs layers stuff things up.
#151206 autodetect cd or dvd.
#160419 ISO may be in optical or usb media.
#170112 fix for overlayfs.
#170717 reword, not "remaster", it is only a boot-cd with q.sfs and s.sfs on the hd.
#170723 save sound state before creating s.sfs
#170727 improve 170717.
#180226 Leon: save sound state. ref: http://murga-linux.com/puppy/viewtopic.php?p=983011#983011

export TEXTDOMAIN=savesession
export OUTPUT_CHARSET=UTF-8

. /etc/DISTRO_SPECS
. /etc/rc.d/PUPSTATE
. /usr/local/install_quirky/install-funcs #151106

#saving a session only applies for 'frugal' and 'livecd' modes.
if [ "$PDEV1" != "zram0" ];then #151128
 popup "background=#FF8080 level=top process=wait terminate=ok|$(gettext 'Saving a session does not apply to a full installation. Aborting.')"
 exit 0
fi

[ -f /etc/asound.state ] && alsactl -f /etc/asound.state store #180226

CR='
'

#151106
WDcurrent="`pwd`"
exit_func() { #these variables set in find_working_place_func...
 cd "$WDcurrent"
 sync
 [ $TMPWKG_MNTPTflag ] && [ $TMPWKG_MNTPTflag -eq 1 ] && busybox umount $TMPWKG_MNTPT
 [ $TMPWKG_PARTMNTflag ] && [ $TMPWKG_PARTMNTflag -eq 1 ] && busybox umount $TMPWKG_PARTMNT
 exit $1
}

#151128 handle live-cd-with-prior-saved-session, and frugal install...
if [ -s /boot/initrd-tree/INSTALL_SPECS ];then
 . /boot/initrd-tree/INSTALL_SPECS #INSTALL_DEV, INSTALL_FS, INSTALL_FOLDER
 [ "${INSTALL_DEV:0:4}" == "UUID" ] && INSTALL_DEV="$(blkid | grep "\"${INSTALL_DEV:5}\"" | cut -f 1 -d ':' | cut -f 3 -d '/')" #151123
 if [ "${INSTALL_DEV:0:2}" != "sr" ];then #exclude optical.
  save_session_frugal_func #in /usr/local/install_quirky/install-funcs
  [ $? -eq 0 ] && gtkdialog-splash -bg '#40FF40' -timeout 4 -text 'Session saved'
  exit_func 0
 fi
fi

#151128 come here for live-cd, no save-file.
 #151106 two save options...
 export SS_DLG0="<window title=\"$(gettext "Save Session: live-CD")\" icon-name=\"gtk-convert\">
 <hbox>
  <vbox>
   <text use-markup=\"true\"><label>\"<b>$(gettext 'Welcome, Quirky is booted from an ISO, currently running totally in RAM')</b>\"</label></text>
   <text use-markup=\"true\"><label>\"$(gettext 'The word <i>session</i> means your usage of Quirky since startup. At the very least, you will have to setup an Internet connection, and it would be good to save this so that you do not have to go through Internet setup at next bootup of the ISO.')\"</label></text>
   <text><label>$(gettext 'Saving the session will include all settings, downloaded files and installed packages.')</label></text>
   <text><label>$(gettext 'There are two different ways that you can save the current session:')</label></text>
   <text><label>$(gettext 'Note: OPTION1 currently only valid if you have booted from a CD/DVD drive')</label></text>
   <text><label>\"   \"</label></text>
   <hbox><button cancel></button></hbox>
  </vbox>
  <vbox>
   <frame $(gettext 'OPTION1: Remaster the CD')>
    <text use-markup=\"true\"><label>\"<b>$(gettext 'Burn everything to a new CD or DVD')</b>\"</label></text>
    <text><label>$(gettext 'Choose this option if you only want to save the session once (or very occasionally) and/or do not want to touch the hard drive.')</label></text>
    <hbox>
     <text><label>$(gettext 'Click to remaster:')</label></text>
     <button><label>$(gettext 'REMASTER')</label><action type=\"exit\">remaster</action></button>
    </hbox>
   </frame>
   <frame $(gettext 'OPTION2: Save to hard drive')>
    <text use-markup=\"true\"><label>\"<b>$(gettext 'Save the session to a hard drive partition')</b>\"</label></text>
    <text><label>$(gettext 'The session will be saved to a file on the hard drive, and reloaded at every bootup of the ISO.')</label></text>
    <text><label>$(gettext 'Choose this for frequent saving of your session.')</label></text>
    <hbox>
     <text><label>$(gettext 'Click to save:')</label></text>
     <button><label>$(gettext 'SAVE')</label><action type=\"exit\">harddrv</action></button>
    </hbox>
   </frame>
   
  </vbox>
 </hbox>
 </window>"
 RETSTRING0="$(gtkdialog --program=SS_DLG0 --center)"
 [ $? -ne 0 ] && exit
 eval "$RETSTRING0"
 [ "$EXIT" != "remaster" -a "$EXIT" != "harddrv" ] && exit
 EXIT0="$EXIT"
 
 ####
  CDMSG="$(gettext 'Erasing CD, please wait...')"
  DVDMSG="$(gettext 'Erasing DVD, please wait...')"
  SSOPT="$(gettext 'Erasing:')"
  echo "#!/bin/sh
  OPTDEV=\"\$1\"
  #151206 determine cd or dvd...
  dvd+rw-mediainfo /dev/\${OPTDEV} > /tmp/ss-type-dvd 2>&1
  if [ \$? -eq 0 ];then #=0 DVD
   MEDIATYPE='dvd'
  else
   MEDIATYPE='cd'
  fi
  if [ \"\$MEDIATYPE\" == \"cd\" ];then
   popup \"placement=center background=#FFC080 level=top|<big>${CDMSG}</big>\" #daemonizes
   cdrecord -tao -v blank=fast dev=/dev/\${OPTDEV}
   #urxvt -geometry 80x5+0+0 -bg orange -fg black -title \"${SSOPT} \${OPTDEV}\" -e cdrecord -tao -v blank=fast dev=/dev/\${OPTDEV}
   RETVAL=\$?
  else
   #151204 test if already erased...
   if [ \"\$(grep ' Disc status: *blank' /tmp/ss-type-dvd)\" != \"\" ];then
    pupmessage -bg '#8080FF' -title \"$(gettext 'Already erased')\" \"$(gettext 'The optical media is already erased. Proceed to the next step.')\"
    exit 0
   fi
   popup \"placement=center background=#FFC080 level=top|<big>${DVDMSG}</big>\" #daemonizes
   dvd+rw-format -force /dev/\${OPTDEV}
   #growisofs -Z /dev/\${OPTDEV}=/dev/zero
   #urxvt -geometry 80x5+0+0 -bg orange -fg black -title \"${SSOPT} \${OPTDEV}\" -e growisofs -Z /dev/\${OPTDEV}=/dev/zero
   RETVAL=\$?
  fi
  sync
  killall popup
  if [ \$RETVAL -ne 0 ];then
   pupmessage -bg '#FF8080' -title \"$(gettext 'Erase error')\" \"$(gettext 'Have you chosen the correct drive? Is media inserted?')\"
  else
   pupmessage -bg '#80FF80' -title \"$(gettext 'Erase completed')\" \"$(gettext 'The optical media has been erased. You may now proceed to the next step.')\"
  fi" > /tmp/ss-erase-cd
  chmod 755 /tmp/ss-erase-cd
 
 #########################################################################
 if [ "$EXIT0" == "remaster" ];then #151106
 
  #do some probing... 160419 moved down.
  OPTICALS="$(probedisk | grep 'optical' | cut -f 1 -d '|' | cut -f 3 -d '/')"
  if [ "$OPTICALS" == "" ];then
   pupmessage -bg '#FF8080' -title "$(gettext 'Save Session: error')" "$(gettext 'Sorry, no optical drives found. Aborting save.')"
   exit
  fi
  for AOPTICAL in $OPTICALS
  do
   OPTICALITEMS="${OPTICALITEMS}<item>${AOPTICAL}</item>"
  done
 
  export SS_DLG1="<window title=\"$(gettext "Save Session: live-CD")\" icon-name=\"gtk-convert\">
 <vbox>
  <text><label>$(gettext 'Welcome, you are currently running Quirky from a live-CD.')</label></text>
  <text><label>$(gettext 'Saving the session will include all settings, downloaded files and installed packages.')</label></text>
  <text><label>$(gettext 'If the live CD or DVD is "-RW", that is rewritable, you may erase then save to it, or write to a new blank CD')</label></text>
  <text use-markup=\"true\"><label>\"<span fgcolor='#800080'><b>$(gettext 'Please insert CD or DVD media now!')</b></span>\"</label></text>
  <frame STEP1: Target>
   <text><label>$(gettext 'Please choose optical device node:')</label></text>
   <hbox>
    <combobox><variable>OPTICALDEV</variable>${OPTICALITEMS}</combobox>
   </hbox>
  </frame>
  <frame STEP2: Erase>
  <hbox>
   <vbox>
    <text><label>$(gettext 'If you want to erase a CD-RW or DVD-RW, and save the session to it, click the ERASE button now, before saving the session:')</label></text>
    <text><label>$(gettext 'WARNING: CD RW media may not work properly on laptop and external drives. Recommend use DVD-RW.')</label></text>
   </vbox>
   <vbox><button><label>$(gettext "ERASE")</label><action>/tmp/ss-erase-cd \$OPTICALDEV > /dev/null 2>&1 </action></button></vbox>
  </hbox>
  </frame>
  <frame STEP3: Save>
   <text><label>$(gettext 'Having chosen the device-node in STEP1, and optionally erased a -RW media in STEP2, you are now ready to save the session.')</label></text>
   <text><label>$(gettext 'STEP3 will create a complete live-CD, that will boot without scanning the hard drives.')</label></text>
   <hbox>
    <text><label>$(gettext 'Click to save:')</label></text>
    <button><label>$(gettext 'SAVE')</label><action type=\"exit\">savenow</action></button>
   </hbox>
  </frame>
  <hbox>
   <button><label>$(gettext 'Back')</label><action type=\"exit\">goback</action></button>
   <button cancel></button>
  </hbox>
 </vbox>
 </window>"
  RETSTRING1="$(gtkdialog --program=SS_DLG1 --center)"
  [ $? -ne 0 ] && exit
  eval "$RETSTRING1"
  [ "$EXIT" == "goback" ] && exec savesession
  [ "$EXIT" != "savenow" ] && exit
  SAVEMSG="$(gettext 'Saving session to optical media, please wait...')"
  popup "placement=center background=#FFC080 level=top|<big>${SAVEMSG}</big>" #daemonizes
  
  #151206 already determined, but just to be sure...
  dvd+rw-mediainfo /dev/${OPTICALDEV} > /dev/null 2>&1
  if [ $? -eq 0 ];then #=0 DVD
   OPTICALTYPE='DVD'
  else
   OPTICALTYPE='CD'
  fi

  #151106 find working area...
  find_working_place_func 700 xxx #pass reqd space (MB), exclude-devs. returns TMPWKG_MNTPT. 151129 increase 400 to 700
  if [ $? -ne 0 ];then
   errTITLE="$(gettext 'Insufficient working space')"
   errMSG="$(gettext 'Unable to find sufficient free space. Aborting save.')"
   ${PRE}popup "level=top background=#FF8080 terminate=ok|<b>${errTITLE}</b>${CR}${errMSG}"
   exit_func 1
  fi
  
  #7build-live-cd created /boot/vmlinuz and /boot/iso/*
  #'init' script in initrd copies initrd-tree to /boot/initrd-tree
  rm -rf ${TMPWKG_MNTPT}/initrd-tree 2>/dev/null
  rm -rf ${TMPWKG_MNTPT}/build 2>/dev/null
  mkdir ${TMPWKG_MNTPT}/build
  cp -a /boot/initrd-tree ${TMPWKG_MNTPT}/
  cd ${TMPWKG_MNTPT}
  
  #151108 /run and /var are symlinks into /tmp, created only at 1st boot, so do not exclude them...
  echo -e 'dev\nproc\nsys\ntmp\nmnt\n.fsckme.flg\nroot/.XLOADED' > /tmp/ss-excl-dirs #150318 add: run .fsckme.flg root/.XLOADED
  [ -d /file/tmpwkgdir ] && echo 'file/tmpwkgdir' >> /tmp/ss-excl-dirs #151108 refer find_working_place_func()
  [ -d /initrd ] && echo 'initrd' >> /tmp/ss-excl-dirs #151205 otherwise aufs layers stuff things up.
  [ -d /lost+found ] && echo 'lost+found' >> /tmp/ss-excl-dirs #151205
  #mksquashfs / q.sfs -comp xz -processors 1 -ef /tmp/ss-excl-dirs
  #150219 removed " -processors 1"
  urxvt -geometry 80x3+0+0 -bg orange -fg black -title "$(gettext 'Rebuilding:') q.sfs $(gettext 'inside:') initrd.q" -e mksquashfs / build/q.sfs -comp xz -ef /tmp/ss-excl-dirs #151128
  sync

  cd ${TMPWKG_MNTPT}/initrd-tree
  [ -f q.sfs ] && rm -f q.sfs #151128 don't want it inside initrd.
  mv -f ../build/q.sfs ./ #151205 actually, I do. want this remaster to boot without scanning hard drives.
  #151205 no, leave Q_ID out, as will boot without scanning drives (refer 'init' in initrd)...
  #date +%Y%m%d%H%M > ./Q_ID #151128 unique id, used for finding installed files. YYYMMDDHHMM
  [ -f ./Q_ID ] && rm -f ./Q_ID #151205
  sync
  find . | cpio -o -H newc > ../build/initrd.q  #.cpio
  cd ..

  cp -a /boot/iso/* build/
  cp -a /boot/vmlinuz build/
  sync
  
  echo '#!/bin/sh' > /tmp/ss-new2cd.sh #150217
  if [ "$OPTICALTYPE" == "CD" ];then
   #151129 bad burn to cd-rw (if not new) when pipe... also need to use -dao ... 151201 revert...
   echo "mkisofs -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table build/ | cdrecord -tao -pad -data -eject -v speed=4 padsize=300k gracetime=2 dev=/dev/${OPTICALDEV} -" >> /tmp/ss-new2cd.sh #150217
   #echo "mkisofs -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o tmp.iso build/" >> /tmp/ss-new2cd.sh #151129
   #echo "cdrecord -dao -pad -data -eject speed=4 padsize=63s gracetime=2 dev=/dev/${OPTICALDEV} tmp.iso" >> /tmp/ss-new2cd.sh #151129
  else
   echo "growisofs -speed=1 -Z /dev/${OPTICALDEV} -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table build/" >> /tmp/ss-new2cd.sh #150217
  fi
  echo "sync" >> /tmp/ss-new2cd.sh #150217
  echo "[ -f tmp.iso ] && rm -f tmp.iso" >> /tmp/ss-new2cd.sh #151129
  chmod 755 /tmp/ss-new2cd.sh #150217
  urxvt -geometry 80x5+0+0 -bg orange -fg black -title "$(gettext 'Writing to:') ${OPTICALDEV}" -e /tmp/ss-new2cd.sh #150217
  rm -rf initrd-tree #151106
  rm -rf build #151106
  killall popup
  echo change > /sys/block/${OPTICALDEV}/uevent #151203 update desktop icon.
  SAVEDMSG="$(gettext "Quirky has been saved to optical media. This is a new bootable live-")${OPTICALTYPE}"
  pupmessage -bg '#80FF80' -title "$(gettext 'Save completed')" "${SAVEDMSG}"
 fi #end remaster option
 
 ###########################################################################
 if [ "$EXIT0" == "harddrv" ];then #151106
  #choose a partition to save, save /initrd/q_rw as s.sfs
  #setup INSTALL_SPECS, either as a file remastered in a CD, or as boot manager parameters.
  #also offer to remaster the CD with q.sfs moved to the hard drive (for fast bootup).
  
  #160419 do some probing...
  OPTICALS="$(probedisk | grep 'optical' | cut -f 1 -d '|' | cut -f 3 -d '/')"
  if [ "$OPTICALS" != "" ];then
   for AOPTICAL in $OPTICALS
   do
    OPTICALITEMS="${OPTICALITEMS}<item>${AOPTICAL}</item>"
   done
  fi
 
  COMBOITEMS2=""
  PARTS="$(probepart -k | grep -v 'zram' | grep -E 'ext2|ext3|ext4|f2fs|minix|reiser|ntfs|msdos|fat' | cut -f 3 -d '/')"
  [ "$PARTS" == "" ] && exit
  for APART in $PARTS
  do
   DEVA="$(echo -n $APART | cut -f 1 -d '|')"
   FSB="$(echo -n $APART | cut -f 2 -d '|')"
   ONESIZEK="$(echo -n $APART | cut -f 3 -d '|')"
   #code from pmount...
   if [ $ONESIZEK -gt 1048576 ];then #1024*1024
    ONESIZE="`LANG=C busybox dc $ONESIZEK 1048576 \/ p`" #150228
    ONESIZE="`LANG=C busybox printf "%.1f" $ONESIZE`G" #150228
   else
    if [ $ONESIZEK -gt 99 ];then
     ONESIZE="`expr $ONESIZEK \/ 1024`M"
    else
     ONESIZE="`LANG=C busybox dc $ONESIZEK 1024 \/ p`" #150228
     ONESIZE="`LANG=C busybox printf "%.1f" $ONESIZE`M" #150228
    fi
   fi
   [ "$ONESIZE" = "0.0M" ] && ONESIZE="error"
   COMBOITEMS2="${COMBOITEMS2}<item>${DEVA} (${FSB}, ${ONESIZE})</item>"
  done
  
  ZRAMKe=`df -k | grep '^/dev/zram0' | tr -s ' ' | cut -f 2 -d ' '`
  ZRAMKc=$(($ZRAMKe/2)) #estimated compressed size.
  ZRAMK=$(($ZRAMKc+500000)) #extra to save q.sfs
  if [ $ZRAMK -gt 1048576 ];then #1024*1024
   WANTFREE="`LANG=C busybox dc $ZRAMK 1048576 \/ p`"
   WANTFREE="`LANG=C busybox printf "%.1f" $WANTFREE`G"
  else
   if [ $ZRAMK -gt 99 ];then
    WANTFREE="`expr $ZRAMK \/ 1024`M"
   else
    WANTFREE="`LANG=C busybox dc $ZRAMK 1024 \/ p`" #150228
    WANTFREE="`LANG=C busybox printf "%.1f" $WANTFREE`M" #150228
   fi
  fi
  
  #151112
  HELPICON="gtk-index"
  M_close="`gettext 'Close'`"
  H_folder="$(gettext 'Type any unique name for the folder, without spaces. It must be a name that does not already exist on the partition.')${CR}$(gettext 'You may also specify a path, for example <b>quirky/werewolf-7.3</b>, and the path will be created if it does not exist.')${CR}${CR}$(gettext 'Note1: A leading <b>/</b> will be removed if you type it in.')${CR}$(gettext 'Note2: If you type spaces, they will be removed.')${CR}$(gettext 'Note3: Currently only 2-deep is supported. So, quirky/saves/werewolf-7.3 is not supported.')"
  export DLG_HELP_FOLDER="<window resizable=\"false\" title=\"$(gettext 'Help: save folder')\" icon-name=\"${HELPICON}\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${H_folder}\"</label><variable>DLG_HELP_FOLDER</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP_FOLDER</action></button></hbox></vbox></window>"
  #151201...
  H_pspace="$(gettext 'The required amount of free space in the partition is an estimate of the maximum that will be required.')${CR}$(gettext 'It is based on how large the session can grow in the <b>zram</b>, which is compressed RAM space. The session is saved as a compressed SFS file, named <b>s.sfs</b>, using gzip compression.')${CR}$(gettext 'You will notice at first that s.sfs is quite small, but as you use Quirky, downloading files, application caching, installing packages, etc., s.sfs will grow.')"
  export DLG_HELP_PSPACE="<window resizable=\"false\" title=\"$(gettext 'Help: partition space')\" icon-name=\"${HELPICON}\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${H_pspace}\"</label><variable>DLG_HELP_PSPACE</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP_PSPACE</action></button></hbox></vbox></window>"

  DEF_FOLDER="${DISTRO_FILE_PREFIX}-${DISTRO_VERSION}"
  
  export SS_DLG2="<window title=\"$(gettext "Save Session: ISO")\" icon-name=\"gtk-convert\">
 <vbox>
  <text use-markup=\"true\"><label>\"<b>$(gettext 'Save the session as a file on the hard drive, which will be reloaded at next bootup of the ISO')</b>\"</label></text>
  
  <frame $(gettext 'STEP1: Hard Drive')>
   <text><label>Choose any partition. It does not matter what filesystem. The folder can be any unique name (without spaces).</label></text>
   <hbox>
    <text use-markup=\"true\"><label>\"$(gettext 'The partition must have at least this much free space:') <b>${WANTFREE}</b>\"</label></text>
    <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP_PSPACE</action></button>
   </hbox>
   <hbox>
    <text><label>$(gettext 'Choose the partition to save to:')</label></text>
    <combobox><variable>COMBO2</variable>${COMBOITEMS2}</combobox>
   </hbox>
   <hbox>
    <text><label>$(gettext 'Type a name for the folder:')</label></text>
    <entry><default>${DEF_FOLDER}</default><variable>DESTFOLDER</variable></entry>
    <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP_FOLDER</action></button>
   </hbox>
  </frame>
  
  <frame $(gettext 'STEP2: Save')>
   <text><label>$(gettext 'After making choices in STEP 1 above, now save the session')</label></text>
   <hbox>
    <text><label>$(gettext 'Click to save session:')</label></text>
    <button><label>$(gettext 'SAVE')</label><action type=\"exit\">savenow</action></button>
   </hbox>
  </frame>

  <hbox>
   <button><label>$(gettext 'Back')</label><action type=\"exit\">goback</action></button>
   <button cancel></button>
  </hbox>
 </vbox>
 </window>"
  RETSTRING2="$(gtkdialog --program=SS_DLG2 --center)"
  [ $? -ne 0 ] && exit
  eval "$RETSTRING2"
  [ "$EXIT" == "goback" ] && exec savesession
  [ "$EXIT" != "savenow" ] && exit
  DESTFOLDER="$(echo -n "$DESTFOLDER" | tr -d ' ')" #151108 remove spaces.
  DESTFOLDER="$(echo -n "$DESTFOLDER" | sed -e 's%^/%%')" #151112 remove a leading /
  DESTFOLDER="$(echo -n "$DESTFOLDER" | sed -e 's%/.*/%/%g')" #151201 remove multiple /
  
  CHECK_QSFS='true' #151128
  #copy files to hard drive...
  KEEPMNT=1
  DESTDEV="$(echo -n "$COMBO2" | cut -f 1 -d ' ')"
  DESTFS="$(echo -n "$COMBO2" | cut -f 2 -d '(' | cut -f 1 -d ',')"
  DESTMNTPT="$(mount | grep "^/dev/${DESTDEV} " | cut -f 3 -d ' ')"
  if [ "$DESTMNTPT" == "" ];then
   mkdir -p /mnt/${DESTDEV}
   mount -t ${DESTFS} /dev/${DESTDEV} /mnt/${DESTDEV}
   if [ $? -eq 0 ];then
    DESTMNTPT="/mnt/${DESTDEV}"
    KEEPMNT=0
   fi
  fi
  if [ "$DESTMNTPT" == "" ];then
   errMSG="$(gettext 'Sorry, unable to mount partition:') ${DESTDEV}"
   popup "level=top background=#FF8080 terminate=ok|<b>${errTITLE}</b>${CR}${errMSG}"
   exit 1
  fi
  WAITMSG="$(gettext 'Partition:') ${DESTDEV}${CR}$(gettext 'Folder:') ${DESTFOLDER}${CR}$(gettext 'Saving session, please wait...')"
  popup "placement=center background=#FFC080 level=top|<big>${WAITMSG}</big>" #daemonizes
  [ -f /etc/asound.state ] && alsactl -f /etc/asound.state store #170723 save to /etc/asound.state.
  mkdir -p ${DESTMNTPT}/${DESTFOLDER}
  rm -f ${DESTMNTPT}/${DESTFOLDER}/s.sfs 2>/dev/null
  echo -e 'dev\nproc\nsys\ntmp\nroot/.XLOADED' > /tmp/ss-excl-dirs #151108 note, do want /var, /run symlinks to be saved.
  [ -d /file/tmpwkgdir ] && echo 'file/tmpwkgdir' >> /tmp/ss-excl-dirs #151108 refer find_working_place_func() above.
  [ -d /initrd ] && echo 'initrd' >> /tmp/ss-excl-dirs #151205 otherwise aufs layers stuff things up.
  [ -d /lost+found ] && echo 'lost+found' >> /tmp/ss-excl-dirs #151205
  sync #170723 precaution, before reading from rw layer.
  if [ -d /initrd/q_rw/rw ];then #1701012 overlayfs (refer init script in initrd-tree)
   urxvt -borderLess -geometry 80x3+0+0 -bg orange -fg black -title "$(gettext 'Building:') s.sfs $(gettext 'Folder:') ${DESTFOLDER}" -e mksquashfs /initrd/q_rw/rw ${DESTMNTPT}/${DESTFOLDER}/s.sfs -ef /tmp/ss-excl-dirs
  else #aufs
   urxvt -borderLess -geometry 80x3+0+0 -bg orange -fg black -title "$(gettext 'Building:') s.sfs $(gettext 'Folder:') ${DESTFOLDER}" -e mksquashfs /initrd/q_rw ${DESTMNTPT}/${DESTFOLDER}/s.sfs -ef /tmp/ss-excl-dirs
  fi
  sync
  if [ "$CHECK_QSFS" == "true" ];then
   urxvt -borderLess -geometry 80x3+0+0 -bg orange -fg black -title "$(gettext 'Moving:') q.sfs $(gettext 'Folder:') ${DESTFOLDER}" -e cp -a -f /initrd/q_ro/q.sfs ${DESTMNTPT}/${DESTFOLDER}/
   sync
  fi
  cp -a -f /boot/initrd-tree/Q_ID ${DESTMNTPT}/${DESTFOLDER}/ #151128
  sync
  killall popup
  [ $KEEPMNT -eq 0 ] && umount $DESTMNTPT
  
  SAVEDMSG="$(gettext 'The session has been saved to hard drive partition.')${CR}$(gettext 'Partition:') ${DESTDEV}${CR}$(gettext 'Folder:') ${DESTFOLDER}"
  pupmessage -bg '#80FF80' -title "$(gettext 'Save completed')" "${SAVEDMSG}"

  #151128 want it in UUID format...
  zDESTDEV="$(blkid | grep "^/dev/${DESTDEV}:" | grep -o ' UUID=[^ ]*' | cut -f 2 -d '"')"
  #151201 create here, in case user runs savesession again, before rebooting...
  echo -e "INSTALL_DEV=UUID=${zDESTDEV}\nINSTALL_FS=${DESTFS}\nINSTALL_FOLDER=${DESTFOLDER}" > /boot/initrd-tree/INSTALL_SPECS
 
  if [ "$OPTICALS" == "" ];then #160419
   EXIT='getout'
  else
   #151128 optional, offer to remaster cd for fast boot...
   #<text><label>$(gettext 'The advantage of this will be faster bootup.')</label></text>
   #170717 reword, not "remaster", it is only a boot-cd with q.sfs and s.sfs on the hd...
   export SS_DLG8="<window title=\"$(gettext "Optional boot-CD")\" icon-name=\"gtk-convert\">
 <vbox>
  <text use-markup=\"true\"><label>\"<b>$(gettext 'This is optional!')</b>\"</label></text>
  <text><label>$(gettext 'Click the BURN button to create a boot-CD, that is hardcoded with the location of the saved session, so will not have to scan the drives at bootup.')</label></text>
  <text use-markup=\"true\"><label>\"$(gettext 'This will be a skeleton CD, as the main Quirky file <b>q.sfs</b>, as well as saved session <b>s.sfs</b>, are in the hard drive.')\"</label></text>
  <text use-markup=\"true\"><label>\"<span fgcolor='#800080'><b>$(gettext 'Please insert CD or DVD media now!')</b></span>\"</label></text>
  <frame STEP1: Target>
   <text><label>$(gettext 'Please choose optical device node:')</label></text>
   <hbox>
    <combobox><variable>OPTICALDEV</variable>${OPTICALITEMS}</combobox>
   </hbox>
  </frame>
  <frame $(gettext 'STEP2: Erase')>
   <hbox>
    <vbox>
     <text use-markup=\"true\"><label>\"$(gettext 'A blank CD or DVD is required. If you need to erase a RW media, insert it now and click the button:')\"</label></text>
     <text><label>$(gettext 'WARNING: CD RW media may not work properly on laptop and external drives. Recommend use DVD-RW.')</label></text>
    </vbox>
    <vbox><button><label>$(gettext "Erase")</label><action>/tmp/ss-erase-cd \$OPTICALDEV > /dev/null 2>&1 </action></button></vbox>
   </hbox>
  </frame>
  <frame $(gettext 'STEP3: Burn')>
   <text use-markup=\"true\"><label>\"<b>A blank CD or DVD media must be inserted</b>\"</label></text>
   <hbox>
    <text><label>$(gettext 'Click to burn:')</label></text>
    <button><label>$(gettext 'BURN')</label><action type=\"exit\">newlivecd</action></button>
   </hbox>
  </frame>
  <hbox>
   <text><label>$(gettext 'Click here if you do not want to create a boot-CD:')</label></text>
   <button><label>$(gettext 'DO NOT BURN')</label><action type=\"exit\">donot</action></button>
  </hbox>
 </vbox>
 </window>"
   RETSTRING2="$(gtkdialog --program=SS_DLG8 --center)"
   eval "$RETSTRING2"
  fi #160419
  
  if [ "$EXIT" == "newlivecd" ];then
   #remaster cd...
   SAVEMSG="$(gettext 'Burning to CD, please wait...')"
   popup "placement=center background=#FFC080 level=top|<big>${SAVEMSG}</big>" #daemonizes
   
   #151206 already determined, but just to be sure...
   dvd+rw-mediainfo /dev/${OPTICALDEV} > /dev/null 2>&1
   if [ $? -eq 0 ];then #=0 DVD
    OPTICALTYPE='DVD'
   else
    OPTICALTYPE='CD'
   fi

   #151106 find working area...
   find_working_place_func 700 xxx #pass reqd space (MB), exclude-devs. returns TMPWKG_MNTPT. 151129 400 to 700.
   if [ $? -ne 0 ];then
    errTITLE="$(gettext 'Insufficient working space')"
    errMSG="$(gettext 'Unable to find sufficient free space. Aborting save.')"
    popup "level=top background=#FF8080 terminate=ok|<b>${errTITLE}</b>${CR}${errMSG}"
    exit_func 1
   fi
   echo "$TMPWKG_MNTPT" > /tmp/savesession-tmp-wkg-mntpt #TEST
   
   rm -rf ${TMPWKG_MNTPT}/initrd-tree 2>/dev/null
   rm -rf ${TMPWKG_MNTPT}/build 2>/dev/null
   mkdir ${TMPWKG_MNTPT}/build
   cp -a /boot/initrd-tree ${TMPWKG_MNTPT}/
   cd ${TMPWKG_MNTPT}/initrd-tree
   [ "$CHECK_QSFS" == "false" ] && cp -a -f /initrd/q_ro/q.sfs ./
   echo -e "INSTALL_DEV=UUID=${zDESTDEV}\nINSTALL_FS=${DESTFS}\nINSTALL_FOLDER=${DESTFOLDER}" > INSTALL_SPECS
   sync
   find . | cpio -o -H newc > ../build/initrd.q  #.cpio
   cd ..
   cp -a /boot/iso/* build/
   cp -a /boot/vmlinuz build/
   sync
   
   echo '#!/bin/sh' > /tmp/ss-new2cd.sh
   if [ "$OPTICALTYPE" == "CD" ];then
    #151129 bad burn to cd-rw (if not new) when pipe... also need to use -dao ... 151201 revert...
    echo "mkisofs -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table build/ | cdrecord -tao -pad -data -eject -v speed=4 padsize=300k gracetime=2 dev=/dev/${OPTICALDEV} -" >> /tmp/ss-new2cd.sh #150217
    #echo "mkisofs -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o tmp.iso build/" >> /tmp/ss-new2cd.sh #151129
    #echo "cdrecord -dao -pad -data -eject speed=4 padsize=63s gracetime=2 dev=/dev/${OPTICALDEV} tmp.iso" >> /tmp/ss-new2cd.sh #151129
   else
    echo "growisofs -speed=1 -Z /dev/${OPTICALDEV} -D -R -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table build/" >> /tmp/ss-new2cd.sh
   fi
   echo "sync" >> /tmp/ss-new2cd.sh
   chmod 755 /tmp/ss-new2cd.sh
   urxvt -borderLess -geometry 80x5+0+0 -bg orange -fg black -title "$(gettext 'Writing to:') ${OPTICALDEV}" -e /tmp/ss-new2cd.sh
   rm -rf initrd-tree
   rm -rf build
   
   killall popup
   echo change > /sys/block/${OPTICALDEV}/uevent #151203 update desktop icon.
   SAVEDMSG="$(gettext "Burn to optical media completed. Type of media:") ${OPTICALTYPE}"
   pupmessage -bg '#80FF80' -title "$(gettext 'Boot-CD created')" "${SAVEDMSG}"
  fi
  
 fi #end harddrv option.
 

exit_func 0 #151106
###END###
