#!/bin/sh
#(c) Copyright Barry Kauler 22 Dec 2013, bkhome.org
#Licence: GPL3 (/usr/share/doc/legal)
#for Quirky 6.x, take a snapshot of the entire system, with exclusions.
#131221 first version. 131224 implemented recovery.
#131225 run in text-mode, recovery only.
#131225 /sbin/init (in ramdisk) can call this script with passed-param of required rollback date.
#131225 need to prefix target path when run snapshot-manager from ramdisk. another passed-param.
#131226 test if /lost+found exists before excluding.
#131226 gui recovery, this script may change, so run a copy. fix snapshot-mark-delete.
#131226 include /boot in snapshot. restore vmlinuz in 1st partition.
#131226 exclude sockets/pipes/fifos from snapshot.
#131227 use cmptree to delete files after recovery.
#131229 cmptree: can't just compare with ${PRE}/ as that will delete /dev, /tmp etc.
#140103 fix for "p" in mmcklb0p1.
#140103 if there is only one snapshot, that have just recovered from, do not delete it.
#140104 fix copy symlink/file/dir clashes.
#140105 run urxvt instead of rxvt, as latter not work if 'misc' dir missing.
#140105 some error logging.
#140106 $FIRSTSNAP is actually the older date, use that in the popup msg.
#140106 when cp-fix-code relocates a folder, cmptree then deletes it. fixed.
#140112 140106 cp-fix-code needed another test.
#140112 140103 was not completely implemented.
#140121 want a comment for each snapshot. new file /audit/snapshot-comments
#140124 /archive no longer exists.
#140125 fixed recovery failure.
#140201 exclude /file from snapshots. 140202
#140206 after recovery: /audit/deposed/<pkg>DEPOSED.sfs, pkg not in /root/.packages/user-installed-packages, then delete.
#140212 want to call from /usr/sbin/delayedrun, take a snapshot at 1st bootup. passed-param = take ['comment']   140213
#151007 clarify in help window that /file not saved.
#151117 guess_fstype broken, reported 'unknown' for 'vfat' partition. (see also 5create-service-packs)
#151206 exclude /initrd from snapshot.
#151210 fix for frugal installation.
#161209 recovery now always requires a reboot, done in 'easyinit' initramfs/ramdisk.

mkdir -p /tmp/audit
#131226 run copy of script...
if [ "$(echo "$0" | grep '/tmp/audit')" = "" ];then
 cp -a -f /usr/sbin/snapshot-manager /tmp/audit/snapshot-manager
 exec /tmp/audit/snapshot-manager
fi

PRE=""; TAKE=0; DEFAULTCOMMENT=""
if [ $1 ];then
 if [ "$1" = "take" ];then #140212
  TAKE=1
  [ $2 ] && DEFAULTCOMMENT="$2"
 fi
fi

export TEXTDOMAIN=snapshot-manager
export OUTPUT_CHARSET=UTF-8

. ${PRE}/etc/rc.d/PUPSTATE #want PDEV1
mkdir -p ${PRE}/audit/snapshots
touch ${PRE}/audit/snapshot-comments #140121
touch ${PRE}/audit/audit-specs
. ${PRE}/audit/audit-specs
[ ! "$SNAPSHOT_LIMIT" ] && SNAPSHOT_LIMIT=5
[ ! "$SNAPSHOT_ARCHTYPE" ] && SNAPSHOT_ARCHTYPE='sfs'
. /etc/DISTRO_SPECS #161209
DISTRONAME1="$(echo -n "$DISTRO_NAME" | cut -f 1 -d ' ')" #161209 'Quirky' or 'Easy'

case $SNAPSHOT_ARCHTYPE in
 cpio)  EXT='cpio' ;;
 usfs)  EXT='usfs' ; COMPR='-noI -noD -noF -noX' ;; #no compression.
 sfs)   EXT='sfs' ; COMPR='' ;;
esac

CR='
'

#151210 detect frugal install...
if [ "$(cat /proc/mounts | grep '^layerfs / ')" != "" ];then
 if [ -d /initrd/q_rw ];then
  INSTALL_MODE='frugal'
  #cop out for now...
  msg1="$(gettext 'Snapshot Manager: abort')"
  msg2="$(gettext 'The Snapshot Manager is designed for a <b>Full</b> installation. You are currently running in a <b>Frugal</b> installation.')"
  msg3="$(gettext 'Note: It is easy to take snapshots in a Frugal installation, by making backup copies of the <b>s.sfs</b> file (the saved session).')"
  popup "background=#FF8080 terminate=ok level=top process=wait|<big><b>${msg1}</b></big>${CR}${CR}${msg2}${CR}${CR}${msg3}"
  exit
 fi
fi

cd ${PRE}/audit/snapshots

limitsnaps_func() {
DELTASNAPS="$(find ./ -mindepth 1 -maxdepth 1 -type f -name '[0-9]*.xdelta' | sed -e 's%./%%' -e 's%.xdelta$%%' | sort -n -r)" #sort in reverse, need to go back in time down list.
xSNAPSHOT_LIMIT=`expr $SNAPSHOT_LIMIT - 1`
NUMDELTAS=`echo "$DELTASNAPS" | wc -l`
if [ $NUMDELTAS -gt $xSNAPSHOT_LIMIT ];then
 NUMTAIL=`expr $NUMDELTAS - $xSNAPSHOT_LIMIT`
 rm -f $(echo "$DELTASNAPS" | tail -n ${NUMTAIL} | sed -e 's%$%.xdelta%' | tr '\n' ' ')
fi
}

###131225 text-mode, recovery only###
#161209 removed, now in easyinit, script sbin/rollback
if [ ! $DISPLAY ];then
 echo 'Snapshot Manager must be run in X'
 exit
fi
###END text mode, recovery only###

echo -e '1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n15\n20' > /tmp/audit/snapshot-combo2-items

#maybe need to reduce max allowed number of snapshots...
SIZEM=`du -m /audit/snapshots | cut -f 1` #space used by snapshots.
#reduce number-snapshots-limit... 151210 fix for frugal...
TOTALM=`df -m / | grep -E '^/dev|^layerfs' | tr -s ' ' | cut -f 2 -d ' '`
USEDM=`df -m / | grep -E '^/dev|^layerfs' | tr -s ' ' | cut -f 3 -d ' '`
xUSEDM=`expr $USEDM - $SIZEM`
xUSEDP=`expr $xUSEDM \* 100 \/ $TOTALM` #percent-free without snapshots
if [ $xUSEDP -gt 75 ];then
 #do not allow any snapshots.
 rm -f ./*.xdelta ./*.${EXT} 2>/dev/null
 echo -e '0' > /tmp/audit/snapshot-combo2-items
 SNAPSHOT_LIMIT=0
elif [ $xUSEDP -gt 70 ];then
 #only allow one snapshot...
 rm -f *.xdelta 2>/dev/null
 echo -e '1\n2' > /tmp/audit/snapshot-combo2-items
 SNAPSHOT_LIMIT=1
elif [ $xUSEDP -gt 60 ];then
 #allow max two snapshots...
 rm -f $(find ./ -mindepth 1 -maxdepth 1 -type f -name '[0-9]*.xdelta' 2>/dev/null | sort -n -r | tail -n +3 | tr '\n' ' ') 2>/dev/null
 echo -e '1\n2' > /tmp/audit/snapshot-combo2-items
 [ $SNAPSHOT_LIMIT -gt 2 -o $SNAPSHOT_LIMIT -eq 0 ] && SNAPSHOT_LIMIT=2
elif [ $xUSEDP -gt 55 ];then
 #allow max three snapshots...
 rm -f $(find ./ -mindepth 1 -maxdepth 1 -type f -name '[0-9]*.xdelta' 2>/dev/null | sort -n -r | tail -n +4 | tr '\n' ' ') 2>/dev/null
 echo -e '1\n2\n3' > /tmp/audit/snapshot-combo2-items
 [ $SNAPSHOT_LIMIT -gt 3 -o $SNAPSHOT_LIMIT -eq 0 ] && SNAPSHOT_LIMIT=3
fi
sed -i -e '/SNAPSHOT_LIMIT/d' /audit/audit-specs
echo "SNAPSHOT_LIMIT=${SNAPSHOT_LIMIT}" >> /audit/audit-specs

USEDP=`df -m / | grep -E '^/dev/|^layerfs' | tr -s ' ' | cut -f 5 -d ' ' | cut -f 1 -d '%'` #used percentage. 151210 fix frugal.
FREEP=`expr 100 - $USEDP`

HOMEPART="$(rdev | cut -f 1 -d ' ' | cut -f 3 -d '/')"
FIRSTSNAP="$(find ./ -mindepth 1 -maxdepth 1 -type f -name "[0-9]*.${EXT}" | sed -e 's%./%%' -e "s%.${EXT}$%%" | sort -n | head -n 1)" #there should only be one of these.
DELTASNAPS="$(find ./ -mindepth 1 -maxdepth 1 -type f -name '[0-9]*.xdelta' | sed -e 's%./%%' -e 's%.xdelta$%%' | sort -n -r)" #sort in reverse, need to go back in time down list.

if [ "$FIRSTSNAP" ];then
 DATELIST="$FIRSTSNAP"
 if [ "$DELTASNAPS" ];then
  DATELIST="${DATELIST}
$(echo "$DELTASNAPS" | cut -f 2 -d '_')" #2nd field has the older date.
 fi
 #140121 insert comments...
 echo -n "" > /tmp/audit/snapshot-manager-datelist
 echo -n "" > /tmp/audit/snapshot-comments2
 for ADATE in $DATELIST
 do
  ACOMMENT="`grep "^${ADATE}" /audit/snapshot-comments | cut -f 2- -d ' '`"
  xDATE="$(echo "$ADATE" | sed -r -e 's%([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])%\1-\2-\3 \4:\5%')" #reformat 201312221645 to 2013-12-22 16:45
  echo "${xDATE} ${ACOMMENT}" >> /tmp/audit/snapshot-manager-datelist
  echo "${ADATE} ${ACOMMENT}" >> /tmp/audit/snapshot-comments2
 done
 mv -f /tmp/audit/snapshot-comments2 /audit/snapshot-comments #precaution, removed any invalid comments.
 #xDATELIST="$(echo "$DATELIST" | sed -r -e 's%([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])%\1-\2-\3 \4:\5%')" #reformat 201312221645 to 2013-12-22 16:45
 #echo "$xDATELIST" > /tmp/audit/snapshot-manager-datelist
 RECOVERXML="   <text><label>$(gettext 'This is a list of previous snapshots. Choose one, and click the Recover button. Note that this is a one-way operation, and you will not be able to "go forward" afterward. Everything that has changed after the chosen snapshot will be lost.')</label></text>
   <hbox>
    <comboboxtext>
     <variable>COMBO1</variable>
     <input file>/tmp/audit/snapshot-manager-datelist</input>
    </comboboxtext>
    <button><label>$(gettext 'Recover')</label><action function=\"exit\">RECOVER</action></button>
   </hbox>"
else
 RECOVERXML="<text use-markup=\"true\"><label>\"<b>$(gettext 'No snapshots taken yet!')</b>\"</label></text>"
fi

if [ $SNAPSHOT_LIMIT -gt 0 ];then
 TAKEXML="   <text><label>$(gettext 'Click the button to take a snapshot of the system. Please be aware that this may take awhile, as it is going to record almost everything in partition') ${HOMEPART}</label></text>
   <hbox>
    <button><label>$(gettext 'Take snapshot')</label><action function=\"exit\">TAKESNAPSHOT</action></button>
   </hbox>"
else
 TAKEXML="<text use-markup=\"true\"><label>\"<b>$(gettext 'Insufficient free space in partition to take a snapshot!')</b>\"</label></text>"
fi

M_close="$(gettext 'Close')"
case $DISTRONAME1 in
 Quirky) MSG0="$(gettext 'This partition is where Quirky is installed.')" ;;
 Easy)   MSG0="$(gettext 'This partition is where Easy is installed.')" ;;
 *)      MSG0="" ;;
esac
M_help1="<b><big>$(gettext 'Partition:') ${HOMEPART}</big></b>

${MSG0} $(gettext 'A snapshot makes a copy of most of the directories, including:')
<i>/bin, /boot, /lib, /root, /run, /sbin, /usr, /var</i>
$(gettext 'Excluding:') <i>/audit, /dev, /file, /mnt, /proc, /sys, /tmp</i>

$(gettext '<b>Recovery</b> is the key word here: the Snapshot Manager is an emergency tool, enabling you to go back to a hopefully working system, in case the current system has gone wrong.')
$(gettext 'Software developers might find the Snapshot Manager to be a useful tool, as it is a way of getting rid of a lot of compiled and installed source packages -- take a snapshot before, then recover afterward.')

$(gettext '<b>Important:</b> Please be sure that the partition is no more than half-full, to allow sufficient working-space for creating the snapshots. As usage grows over 50%, the maximum allowed number of snapshots is automatically reduced.')

$(gettext '<b>Note 1:</b> The time taken to make a snapshot may be from several minutes upward, depending on the size of all the files in the partition. Recovery of older snapshots takes longer, as they are only kept as delta (difference) files, that need to be reconstituted in sequence.')
$(gettext '<b>Note 2:</b> The main window shows the storage-space of the snapshots, in directory /audit/snapshots. The latest snapshot is very large, whereas older snapshots are delta-files and smaller, so reducing the number-of-snapshots-limit does not proportionally reduce archive storage-usage')
$(gettext '<b>Note 3:</b> Directory /file is <i>not</i> saved, as this has personal files.')"
M_help2=""
export DLG_HELP1="<window resizable=\"false\" title=\"$(gettext 'Help: Snapshot Manager')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help1}\"</label><variable>DLG_HELP1</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP1</action></button></hbox></vbox></window>"

M_w1="<span fgcolor='"'red'"'><b>$(gettext "Please close all other applications now")</b></span>" #need some funny stuff.

export SNAP1_DIALOG="<window title=\"$(gettext 'Snapshot Manager')\" icon-name=\"gtk-about\" window_position=\"1\">
 <vbox>
  <text><label>$(gettext 'The Snapshot Manager takes a snapshot of the entire system. Previous snapshots are retained, enabling recovery back to any earlier snapshot.')</label></text>
  <text use-markup=\"true\"><label>\"${M_w1}\"</label></text>
  <frame $(gettext 'Take Snapshot')>
   ${TAKEXML}
  </frame>
  <frame $(gettext 'Recover')>
   ${RECOVERXML}
  </frame>
  <frame $(gettext 'Manage')>
   <text use-markup=\"true\"><label>\"$(gettext 'Archival storage-space used:') <b>${SIZEM}MB</b>\"</label></text>
   <text><label>$(gettext 'Free space left in partition:') ${FREEP}%</label></text>
   <text><label>$(gettext 'To constrain processing time and storage-space, the maximum allowed number of snapshots is automatically limited. Set limit:')</label></text>
   <hbox>
   <comboboxtext>
    <variable>COMBO2</variable>
    <default>${SNAPSHOT_LIMIT}</default>
    <input file>/tmp/audit/snapshot-combo2-items</input>
   </comboboxtext>
   <button>
    <label>$(gettext 'Apply')</label>
    <action>sed -i -e '/SNAPSHOT_LIMIT/d' /audit/audit-specs</action>
    <action>echo SNAPSHOT_LIMIT=\$COMBO2 >> /audit/audit-specs</action>
    <action>pupmessage -bg yellow -fg black -title \"$(gettext 'Snapshot limit changed to:') \$COMBO2\" '$(gettext 'This sets the maximum number of snapshots that can be taken. The new setting has now taken effect. Note, the Snapshot Manager will automatically override this setting and reduce it, as used space in the system partition grows above 50%.')'</action>
   </button>
   </hbox>
  </frame>
  <hbox>
   <hbox><button cancel></button></hbox>
   <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP1</action></button>
  </hbox>
 </vbox>
 </window>"

if [ $TAKE -eq 1 ];then #140212
 EXIT="TAKESNAPSHOT"
 [ $SNAPSHOT_LIMIT -eq 0 ] && exit 9
 [ $SNAPSHOT_LIMIT -eq 1 ] && exit 9
else
 RETVARS="$(gtkdialog --program=SNAP1_DIALOG)"
 #ex: COMBO1="2013-12-22 20:39"
 #EXIT="RECOVER"
 echo "$RETVARS"
 eval "$RETVARS"
 sed -i -e '/SNAPSHOT_LIMIT/d' /audit/audit-specs
 echo "SNAPSHOT_LIMIT=${COMBO2}" >> /audit/audit-specs
 SNAPSHOT_LIMIT=${COMBO2}
fi

cd /audit/snapshots #have to do it again?

###take snapshot###
if [ "$EXIT" = "TAKESNAPSHOT" ];then
 DATE="$(date +%Y%m%d%H%M)"
 rm -f ${DATE}.${EXT} 2>/dev/null
 xDATE="$(echo -n "$DATE" | sed -r -e 's%([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])%\1-\2-\3 \4:\5%')" #reformat 201312221645 to 2013-12-22 16:45

 #140121...
 if [ "$DEFAULTCOMMENT" = "" ];then #140212
  export SNAP9_DLG="<window title=\"$(gettext 'Snapshot Manager')\" icon-name=\"gtk-about\" window_position=\"1\">
 <vbox>
  <text use-markup=\"true\"><label>\"<b><big>$(gettext 'Snapshot date:') ${xDATE}</big></b>\"</label></text>
  <text><label>$(gettext 'You have chosen to take a snapshot of the entire installation.')</label></text>
  <frame $(gettext 'Optional comment')>
   <text><label>Enter a short comment for this snapshot:</label></text>
   <entry width_chars=\"32\" max-length=\"32\"><variable>SNAPCOMMENT</variable></entry>
  </frame>
  <hbox>
   <hbox><button cancel></button></hbox>
   <button><label>$(gettext 'Take snapshot')</label><action type=\"exit\">SNAPNOW</action></button>
  </hbox>
 </vbox>
 </window>"
  RETVARS2="$(gtkdialog --program=SNAP9_DLG)"
  eval "$RETVARS2"
  [ "$EXIT" != "SNAPNOW" ] && exit 7 #140212
 fi
 
 sed -i -e "/${DATE}/d" ${PRE}/audit/snapshot-comments
 echo "${DATE} ${SNAPCOMMENT}" > /tmp/audit/snapshot-comments3
 cat ${PRE}/audit/snapshot-comments >> /tmp/audit/snapshot-comments3
 mv -f /tmp/audit/snapshot-comments3 ${PRE}/audit/snapshot-comments

 yaf-splash -bg '#FB9003' -fg black -close never -fontsize large -text "$(gettext 'Taking a snapshot, please wait...')" &
 YAFPID1=$!
 if [ "$SNAPSHOT_ARCHTYPE" = "cpio" ];then
  find /bin /lib /root /run /sbin /tmp/var /tmp/run /usr -mindepth 1 -mount | grep -v '/tmp/var/local' | cpio -o -H newc > ${DATE}.cpio  # | gzip -2 > ${DATE}.cpio.gz
 else
  echo -e '/audit\n/dev\n/mnt\n/proc\n/root\n/run\n/sys\n/tmp\n/var\n/.fsckme.flg' > /tmp/audit/rootfs-snapshot-exclusions1
  [ -d "/archive" ] && echo '/archive' >> /tmp/audit/rootfs-snapshot-exclusions1 #140124
  [ -d "/lost+found" ] && echo '/lost+found' >> /tmp/audit/rootfs-snapshot-exclusions1 #131226
  [ -d "/home" ] && echo '/home' >> /tmp/audit/rootfs-snapshot-exclusions1 #140201
  [ -d "/file" ] && echo '/file' >> /tmp/audit/rootfs-snapshot-exclusions1 #140201
  [ -d "/media" ] && echo '/media' >> /tmp/audit/rootfs-snapshot-exclusions1 #140202
  [ -d "/initrd" ] && echo '/initrd' >> /tmp/audit/rootfs-snapshot-exclusions1 #151206
  #mksquashfs / ${DATE}.usfs -ef /tmp/audit/rootfs-snapshot-exclusions1 -no-exports -noI -noD -noF -noX
  T_1="$(gettext 'Creating:')"
  urxvt -geometry 96x3+0+0 -bg orange -fg black -title "${T_1} /audit/snapshots/${DATE}.${EXT}" -e mksquashfs / ${DATE}.${EXT} -ef /tmp/audit/rootfs-snapshot-exclusions1 -no-exports ${COMPR} #-noI -noD -noF -noX
  sync
  #131226 exclude sockets/pipes/fifos from snapshot...
  echo '/root/.XLOADED' > /tmp/audit/rootfs-snapshot-exclusions4 #see /usr/bin/xwin.
  ROOTSPECIAL="$(find /root -type s -o -type p)" #find pipes and sockets.
  [ "$ROOTSPECIAL" ] && echo "$ROOTSPECIAL" >> /tmp/audit/rootfs-snapshot-exclusions4
  mksquashfs /root ${DATE}.${EXT} -ef /tmp/audit/rootfs-snapshot-exclusions4 -keep-as-directory -no-exports ${COMPR} #-noI -noD -noF -noX
  sync
  #/run and /var are symlinks into /tmp...
  echo '/tmp/var/local' > /tmp/audit/rootfs-snapshot-exclusions2
  VARSPECIAL="$(find /tmp/var -type s -o -type p)" #find pipes and sockets.
  [ "$VARSPECIAL" ] && echo "$VARSPECIAL" >> /tmp/audit/rootfs-snapshot-exclusions2
  mksquashfs /tmp/var ${DATE}.${EXT} -ef /tmp/audit/rootfs-snapshot-exclusions2 -keep-as-directory -no-exports ${COMPR} #-noI -noD -noF -noX
  sync
  echo '/tmp/run/zzzzzz' > /tmp/audit/rootfs-snapshot-exclusions3
  RUNSPECIAL="$(find /tmp/run -type s -o -type p)" #find pipes and sockets.
  [ "$RUNSPECIAL" ] && echo "$RUNSPECIAL" >> /tmp/audit/rootfs-snapshot-exclusions3
  mksquashfs /tmp/run ${DATE}.${EXT} -ef /tmp/audit/rootfs-snapshot-exclusions3 -keep-as-directory -no-exports ${COMPR} #-noI -noD -noF -noX
 fi
 sync
 pupkill $YAFPID1

 #131224 if there is a prior snapshot, create a delta-file and delete prior snapshot...
 if [ "$FIRSTSNAP" ];then
  #140106 $FIRSTSNAP is actually the older date, use that in the popup msg...
  xFIRSTSNAP="$(echo -n "$FIRSTSNAP" | sed -r -e 's%([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])%\1-\2-\3 \4:\5%')" #reformat 201312221645 to 2013-12-22 16:45
  yaf-splash -bg '#FBF303' -fg black -close never -fontsize large -text "$(gettext 'Creating delta-file:') ${xFIRSTSNAP}. $(gettext 'Please wait...')" &
  YAFPID1=$!
  #xdelta3 -e -s "$SOURCEFILE_OLD" "$SOURCEFILE_NEW" "$SOURCEFILE_DELTA"
  echo "xdelta3 -e -s ${DATE}.${EXT} ${FIRSTSNAP}.${EXT} ${DATE}_${FIRSTSNAP}.xdelta" #see what is happening.
  xdelta3 -e -s ${DATE}.${EXT} ${FIRSTSNAP}.${EXT} ${DATE}_${FIRSTSNAP}.xdelta #going back in time!
  sync
  rm ${FIRSTSNAP}.${EXT}
  pupkill $YAFPID1
 fi
 
 [ "$DEFAULTCOMMENT" = "" ] && pupmessage -bg '#AAFB03' -fg black -title "$(gettext 'Snapshot:') ${xDATE}" "$(gettext "That's it, the snapshot has been taken!")" #' 140213
fi
###END take snapshot###

###Recover###
if [ "$EXIT" = "RECOVER" ];then
 MARKDONE=0
 echo "${FIRSTSNAP}.${EXT}" > /tmp/audit/snapshot-mark-delete #as going to roll back, mark later snapshots for deletion.
 [ ! "$DELTASNAPS" ] && AOLD="$FIRSTSNAP"
 GRN=160 #hex: a0
 #140121 comment added...
 #COMBO1 has the selected date, 2nd field of a .xdelta file, older date. ex: COMBO1="2013-12-24 00:52 <comment>"
 rDATE="$(echo -n "$COMBO1" | cut -f 1,2 -d ' ')"
 rCOMMENT="$(echo -n "$COMBO1" | cut -f 3- -d ' ')"
 OLDESTDATE="$(echo -n "$rDATE" | tr -d '[\- :]')" #ex: 201312240052
 COMMENTXML=""
 if [ "$rCOMMENT" ];then
  COMMENTXML="<text><label>$(gettext 'There was a comment lodged with this snapshot:')</label></text>
  <text use-markup=\"true\"><label>\"<b>${rCOMMENT}</b>\"</label></text>"
 fi
 
 #offer to reboot to do recovery...
 export SNAP2_DLG="<window title=\"$(gettext 'Snapshot Manager')\" icon-name=\"gtk-about\" window_position=\"1\">
 <vbox>
  <text use-markup=\"true\"><label>\"<b><big>$(gettext 'Recovery date:') ${rDATE}</big></b>\"</label></text>
  <text><label>$(gettext 'You have chosen to roll the installation back to the snapshot taken on this date.')</label></text>
  ${COMMENTXML}
  <text><label>\" \"</label></text>
  <text use-markup=\"true\"><label>\"<b>$(gettext 'Technical notes')</b>
$(gettext 'A reboot is required to ensure that the rollback succeeds. A file /recover.flg will now be created, containing the date to be rolled-back to, which will be read at bootup by /sbin/init, and a tiny operating system named <b>easyinit</b> will run in RAM and rollback the installation.')\"</label></text>
  <hbox>
   <hbox><button cancel></button></hbox>
   <button><label>$(gettext 'Reboot then restore')</label><action type=\"exit\">REBOOT</action></button>
  </hbox>
 </vbox>
 </window>"
 RETVARS2="$(gtkdialog --program=SNAP2_DLG)"
 eval "$RETVARS2"
 if [ "$EXIT" = "REBOOT" ];then ###reboot system, see /sbin/init###
  echo -n "$OLDESTDATE" > /recover.flg
  exec wmreboot
 fi
 #161209 recover code deleted.
fi
###END Recover###

#131224 limit number of snapshots...
limitsnaps_func

exit 0
###END###
