s243a icon

psandbox2.sh (draft #1)

s243a | PRO | 12/15/20 12:11:34 AM UTC (Edited) | 0 ⭐ | 1401 👁️ | Never ⏰ | []
Bash |

47.83 KB

|

None

|

0 👍

/

0 👎

#!/bin/bash
#Based on James Budiono 2015 sandbox.sh (version 10) but with many options added
# version 10 - (2015) use pid/mount namespaces if available
#
# 0. directory locations
#. $BOOTSTATE_PATH # AUFS_ROOT_ID
#XTERM="defaultterm"
#
# All options below were added by s243a:
#
# -o, --output-file 
#    Just write layer paths to an output file but don't mount the sandbox. 
# --no-exit
#   if an output file is specified (i.e. -o or --output-file) layer paths are just written to a file and the program exits unless the no-exit flag is specified.
# f, --input-file
#   read layer paths from a file rather than reading existing layers
# m,--pmedia
#   determines pupmodes. Refer to puppy boot parmaters
# d, --pdrv
#   this is the particiaion where the puppy files are located. The default is /mnt/home
# s, psubdir
#   this is the sub directory where the puppy files are located
# c, --clear-env
#   deletes enviornental variabls
# --env-prefix
#   enviornental variable prefix
# b --boot-config
#   path to boot config (e.g. /etc/rc.d/BOOTCONFIG
# --disto-specs
#   path to distro specs (e.g. /etc/DISTRO_SPECS; e.g. /initrd/distro-specs)
# L, --layer
#   a subgke kater
#  e, --extra-sfs
#   a list of extra sfs files (space seperated)
#  u, --union-record
# --xterm
# --sandbox
# -initrd
# --save
# --noexit
# --psave
# --pupmode
 
#I thought some assoitive arrays might be useful but I'm not using them yet. 
#declare -A KEYs_by_MNT_PT
#declare -A KEYs_by_FILE_PATH
#declare -A KEYs_by_trimmed_MNT_PT
#declare -A KEYs_by_trimmed_FILE_PATH
#declare -A MNT_PTs
#declare -A FILE_PATHs
#declare -A ON_status
CWD=$(realpath .)
[ -z "$CWD" ] && CWD="$PWD"
declare -a bind_sources
declare -a bind_targets
declare -a rev_bind_sources
declare -a rev_bind_targets
cd "$(dirname "$0")"
MAX_STR_LEN=50
SANDBOX_ID=
TMPFILE=$(mktemp -p /tmp)
# use namespaces if available
#[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1
 
XTERM=${XTERM:-urxvt}
SANDBOX_ROOT=${SANDBOX_ROOT:-/mnt/sb}
 
declare -a options2
declare -a binds
LOG_INITIALIZED=false
 
RP_FN="`which realpath`"
RP_TARGET=$($RP_FN "$RP_FN")
[ -z "$RP_TARGET" ] && RP_TARGET="`readlink $RP_FN`"
declare -a del_rules_filter
declare -a del_rules_action
declare -a umount_rules_filter
declare -a umount_rules_action
 
unset SANDBOX_ID
unset rwbranch
unset FAKEROOT
unset SANDBOX_TMPFS
unset FAKEROOT_dir
unset SANDBOX_IMG
FAKEROOT_SET=false
 
function realpath(){
    case "$RP_TARGET" in
    *busybox*)
      if [ "$1" = -m ]; then
        shift
        A_PATH=$1
        A_PATH=$(echo "$A_path" | sed 's#^./#'"$CWD"'#g' )
        A_PATH=$(echo "$A_path" | sed 's#^../#'"$CWD"'#g' ) && A_PATH=$(dirname $A_PATH)
        echo "Warning simulating '-m' option since it isn't supported by busybox" >2
        echo "A_PATH=$A_PATH" >2
        if [ -f  "$A_PATH" ] || [ -d  "$A_PATH" ]; then
          $RP_FN "$@"
        else
          echo "$A_PATH"
        fi
      else
        $RP_FN "$@"
      fi
      ;;
    *)
      $RP_FN "$@"
      ;;
    esac 
}
export -f realpath
 
if [ -f ../local/psandbox/sandbox.awk ]; then 
  SANDBOX_AWK="$(realpath ../local/psandbox/sandbox.awk)"
elif [ -f /usr/local/psandbox/sandbox.awk ]; then
 SANDBOX_AWK=/usr/local/psandbox/sandbox.awk
fi
SANDBOX_AWK_DIR="$(dirname $SANDBOX_AWK)"
if [ -f ../local/psandbox/sb_db_rec_field.awk ]; then
  SB_DB_REC_FIELD_AWK="$(realpath ../local/psandbox/sb_db_rec_field.awk)"
elif [ -f /usr/local/psandbox/sb_db_rec_field.awk ]; then
  SB_DB_REC_FIELD_AWK=/usr/local/psandbox/sb_db_rec_field.awk
fi
 
if [ -f ../local/psandbox/sandbox_mnt_fn.sh ]; then
  SANDBOX_MNT_FN="$(realpath ../local/psandbox/sandbox_mnt_fn.sh)"
elif [ -f /usr/local/psandbox/sandbox_mnt_fn.sh ]; then
  SANDBOX_MNT_FN=/usr/local/psandbox/sandbox_mnt_fn.sh
fi
 
. "$SANDBOX_MNT_FN"
 
function get_items(){
    local out
    OUTFILE=/tmp/get_items_out
    rm "$OUTFILE"
    cd "$SANDBOX_AWK_DIR"
    out+="$(
  { echo ==mount==; cat /proc/mounts; 
    echo ==losetup==; losetup-FULL -a; 
    echo ==branches==; 
      if [ $# -eq 0 ]; then
        ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//';
      else
        if [ "$1" = "-f" ]; then
          cat "$2";
        elif [ "$1" = "-s" ]; then
          cat <<<"$2";
        fi;
      fi; } | \
    awk -v PDRV="$PDRV" -v MAX_STR_LEN="$MAX_STR_LEN" -v OUTFILE="$OUTFILE" \
-f "$SANDBOX_AWK"
)"
  echo "$out"
}
function process_psubdir(){
      item_source="$1"
      if [ "$item_source" = "maybe-psubdir" ]; then
         [ ! -z "$items" ] && continue
      fi
      [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'adrv.*\.sfs$')" 
      [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'ydrv.*\.sfs$')"   
      [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'zdrv.*\.sfs$')"
      [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'fdrv.*\.sfs$')"                        
      [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'puppy_.*\.sfs$')"
 
      new_items=""
      for rec in "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_PUPPYSFS";  do
        #MNT_PATH="${rec}"
        [ -z "$rec" ] && continue
        #[ ! -z "${PSUBDIR}" ] && MNT_PATH=${PSUBDIR}/${MNT_PATH}
        MNT_PATH="${PDRV}/${PSUBDIR}/$rec"
        MNT_PT="$(mount_fn "$MNT_PATH")"
        new_items+="\"${MNT_PT}\" \"$rec\" \"on\""$'\n' 
        
      done
      #export new_items="$new_items"
      #echo "$new_items"
      log stop
      new_items_result="$(get_items -s "$new_items")"$'\n' 
      items+="$new_items_result" 
      echo "items+=\"$new_items_result\""
      log start
      
}
process_union_record(){
       new_items=''
       for rec in $LASTUNIONRECORD; do
        if [ -f "$rec" ]; then
          MNT_PT="$(mount_fm "$rec" )"
          new_items+="\"$MNT_PT\" \"$rec\" \"on\""$'\n'
        elif [ -f "$PDRV/$rec" ]; then
          MNT_PT="$(mount_fm "$PDRV/$rec" )"
          new_items+="\"$MNT_PT\", \"$PDRV/$rec\", \"on\""$'\n'
        fi
      done 
      items+="$(get_items -f <<<"$new_items")"$'\n'     
}
process_extra_sfs(){
     EXTRASFSLIST="$2";
     unset new_items
     if [ ! -f "$EXTRASFSLIST" ]; then
       EXTRASFSLIST_tmp=$(realpath "$PDRV/$PSUBDIR/$EXTRASFSLIST")
       if [ -f "$EXTRASFSLIST_tmp" ]; then
         EXTRASFSLIST="$EXTRASFSLIST_tmp"
       fi
     fi
     if [ ! -f "$EXTRASFSLIST" ]; then
       EXTRASFSLIST_tmp=$(realpath "$PDRV/$EXTRASFSLIST")
       if [ -f "$EXTRASFSLIST_tmp" ]; then
         EXTRASFSLIST="$EXTRASFSLIST_tmp"
       fi
     fi
     if [[ "$EXTRASFSLIST" = *.sfs ]]; then
         a_sfs="$EXTRASFSLIST"
         MNT_PT="$(mount_fn "$a_sfs" )"
         new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'
     else
       while read a_sfs; do
         a_sfs=$(echo"$a_sfs") #Trims leading and trailing whitespace
         if [ -f "$a_sfs" ]; then
           a_sfs=$(realpath "$a_sfs")
         else
           a_sfs1="$PDRV/${PSUBDIR}/$a_sfs"
           a_sfs=$(realpath "$a_sfs")
           if [ -f "$a_sfs"]; then
             a_sfs=$(realpath "$a_sfs")
           else         
             a_sfs1="$PDRV/$a_sfs1"
             if [ -f "$a_sfs1" ]; then
               a_sfs=$(realpath "$a_sfs")
             fi             
           fi 
         fi
         if [ -f  "$a_sfs" ]; then
           MNT_PT="$(mount_fn "$a_sfs" )"
           new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'         
         fi
       done <"$EXTRASFSLIST"
     fi 
     items+="$(get_items -s "$new_items")"$'\n'
     #items+="$(get_items -f <<<"$new_items")" 
}
process_layer(){
      item_path="$2"
      if [ -f "$item_path" ]; then
        MNT_PT="$(mount_fm "$item_path" )"
      elif [ -d "$item_path" ]; then  
        MNT_PT="$item_path" #This isn't really a mount poing
      elif [ ! -d  "$item_path" ]; then
        echo "Warning  cannot mount $item_path"
        continue
      fi
      items+="\"$MNT_PT\" \"$item_path\" \"on\""$'\n'   
}
 
function mount_items(){
  local Moun_Point
  local File_PATH #Might be a directory
  cd "$SANDBOX_AWK_DIR"
  while IFS="" read -r p || [ -n "$p" ]; do #https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
     File_PATH="$(echo "$1" | awk -v FIELD_NUM=6 -f "$SB_DB_REC_FIELD_AWK")"
     Mount_Point="$(echo "$1" | awk -v FIELD_NUM=1 -f "$SB_DB_REC_FIELD_AWK")"
     PDRV_MNT="$(echo "$1" | awk -v FIELD_NUM=7 -f "$SB_DB_REC_FIELD_AWK")"
     PDRV_UUID="$(echo "$1" | awk -v FIELD_NUM=8 -f "$SB_DB_REC_FIELD_AWK")"
     
     [ -z "$PDRV_MNT" ] && 
     mount_fn2 "PDRV" "$File_PATH" "$Moun_Point"
  done <"$1"
}
function log(){
  local SET_X=false
  set +x #TODO add more verbose log option that doesn't do this. 
  local logfile="${2}"
  local trace="$3"
  #[ -z "$logfile" ] && LOGFILE 
  #[ -z "$trace" ] && trace=TRACE
  if [ ! -z "$LOGFILE" ]; then
    case "$1" in
    init)
      [ "$TRACE" = true ] && SET_X=true
      [ ! -f "$LOGFILE" ] && rm "$LOGFILE"
      exec 6>&1           # Link file descriptor #6 with stdout.
      #exec &1> >(tee -a "$LOGFILE")
      #exec &2> >(tee -a "$LOGFILE")
      [ ! -f "$LOGFILE" ] && touch "$LOGFILE"
      exec &> >(tee -a "$LOGFILE")
      ;;
    start)
      [ "$TRACE" = true ] && SET_X=true
      #exec &1> >(tee -a "$LOGFILE")
      #exec &2> >(tee -a "$LOGFILE") 
      
      exec &> >(tee -a "$LOGFILE") 
      ;;
    stop)
      #https://stackoverflow.com/questions/21106465/restoring-stdout-and-stderr-to-default-value
      #[ "$TRACE" = true ] && set +x
      exec 1>&6  
      #exec 6>&-      # Restore stdout and close file descriptor #6.
      exec &2> /dev/stderr    
      ;;
    esac
  fi    
  [ "$SET_X" = true ] && set -x
}
 
 
 
safe_delete(){
    unset safe_delete_result
    POLICY="" #Default action if no rule is found
  if [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | sed 's:/$::')" - )" ] ||
     [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | xargs realpath )" - )" ] ; then
          #It is not safe to delete a mounted directory
          safe_delete_result=1 #This is in case one doesn't want to use the return status right away
          return 1    
  else
    PATH_TO_DEL="$(realpath -m $1)"
    [ -d "$PATH_TO_DEL" ] && "PATH_TO_DEL=$PATH_TO_DEL/"
    for a_rule_key in "${!del_rules_filter[@]}"; do
      rule_i="${a_rull_key[$a_rule_key]}"
      if [ ! -z "$(echo $PATH_TO_DEL | grep "$rule_i")" ] ||
         [[ "$PATH_TO_DEL" = $rule_i ]]; then
        action="${del_rules_action[$a_rule_key]}"
        case $action in
        DELETE)
          safe_delete_result=0 #This is in case one doesn't want to use the return status right away
          return 0
          break #This is probably redundant
          ;;
        KEEP)
          safe_delete_result=1 #This is in case one doesn't want to use the return status right away
          return 1
          break #This is probably redundant
          ;;          
        POLICY_KEEP)
          POLICY=KEEP
          ;;    
        POLICY_DELETE)
          POLICY=DELETE
          ;;    
        esac
      fi
    done
    if [ -z ${safe_delete_result+x} ]; then #If we don't have a result yet set result based on policy
      case "$POLICY" in
      KEEP)
        safe_delete_result=1
        return 1; ;; 
      DELETE)
        safe_delete_result=0
        return 0; ;;
      *)
        echo "No Delete policy set, so keeping file/dir $1"
        safe_delete_result=1
        return 1    
      esac
    fi
  fi
}
safe_umount(){
    unset safe_umount_result
    POLICY="" #Default action if no rule is found
    PATH_TO_UMOUNT="$(realpath -m $1)"
    [ -d "$PATH_TO_UMOUNT" ] && PATH_TO_UMOUNT="$PATH_TO_UMOUNT/" #TODO, this should always be true so add error if it is not.
 
    for a_rule_key in "${!umount_rules_filter[@]}"; do
      rule_i="${a_rull_key[$a_rule_key]}"
      if [ ! -z "$(echo $1 | grep "$rule_i")" ] ||
        [[ "$PATH_TO_UMOUNT" = $rule_i ]]; then
        action="${umount_rules_action[$a_rule_key]}"
        case $action in
        DELETE)
          safe_umount_result=0 #This is in case one doesn't want to use the return status right away
          return 0
          break #This is probably redundant
          ;;
        UMOUNT)
          safe_umount_result=1 #This is in case one doesn't want to use the return status right away
          return 1
          break #This is probably redundant
          ;;          
        POLICY_KEEP)
          POLICY=KEEP
          ;;    
        POLICY_UMOUNT)
          POLICY=UMOUNT
          ;;    
        esac
      fi
    done
    if [ -z ${safe_umount_result+x} ]; then #If we don't have a result yet set result based on policy
      case "$POLICY" in
      KEEP)
        safe_umount_result=1
        return 1; ;; 
      UMOUNT)
        safe_umount_result=0
        return 0; ;;
      *)
        echo "No Delete policy set, so keeping file/dir $1"
        safe_umount_result=1
        return 1    
      esac
    fi
  
}
umountall() {
  {
  log start
  set -x
  #R_FR=$(realpath -m "$FAKEROOT")
  #[ ${#R_FR} -lt 2 ] && exit
  safe_umount $SANDBOX_TMPFS
  [ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
  if [ PUPMODE = 2 ]; then #Full Install
      safe_umount $FAKEROOT/tmp
      umount -l $FAKEROOT/tmp
    else
      safe_umount $FAKEROOT/initrd/mnt/tmpfs
      [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT/initrd/mnt/tmpfs
    fi
  for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
    layer="$(eval 'echo $'$layer_name)"
    if [ ! -z "$layer" ] ; then
      safe_umount "$FAKEROOT/initrd/$layer_name"
      [ $safe_umount_result -eq 0 ] && umount -l "$FAKEROOT/initrd/$layer_name"
    fi
  done 
  for aFolder in /proc /sys /dev ""; do
     safe_umount $FAKEROOT"/$aFolder"
     [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT$aFolder
  done
  
  
  if [ -z "$RW_LAYER" ]; then
    safe_umount "$SANDBOX_TMPFS"
    [ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
    safe_delete "$SANDBOX_TMPFS"
    [ $safe_delete_result -eq 0 ] && rmdir $SANDBOX_TMPFS
  fi
  
  safe_delete $FAKEROOT
  [ $safe_delete_result -eq 0 ] && rmdir $FAKEROOT
 
  } # 2> /dev/null
}
function choose_save(){
    # location not specified - then ask
    log stop
    dialog --backtitle "rw image sandbox" --title "choose rw image" \
    --extra-button --extra-label "Create" --ok-label "Locate" \
    --yesno "You didn't specify the location of the rw image file. Do you want to locate existing file, or do you want to create a new one?" 0 0
    chosen=$?
    log start
    case $chosen in
        0) # ok - locate
            log stop
            dialog --backtitle "rw image sandbox" --title "Specify location of existing rw image" --fselect `pwd` 8 60 2> $TMPFILE
            savebranch=`cat $TMPFILE`
            log start
            rm $TMPFILE
            if [ -n "$savebranch" ]; then
                if [ -d "$savebranch" ]; then
                  case "$savebranch" in
                  "/mnt"|"/mnt/"|"/mnt/home"|"/mnt/home/"|"/")
                    log stop
                    echo "warning chose the following savebranch $savebranch"
                    read -p "Press enter to continue"
                    log start
                    set_sandbox_img ""
                    ;;
                  esac
                  SANDBOX_IMG=$savebranch
                elif [ ! -f "$savebranch" ]; then
                    echo "$savebranch doesn't exist - exiting."
                    echo "will use tmpfs instead"
                    log stop
                    read -p "Press enter to continue"
                    log start
                    savebranch=""
                else
                  set_sandbox_img ""                    
                fi
            else
                echo "You didn't specify any file or you pressed cancel. Exiting."
                exit
            fi
            ;;
        3) # create
            echo "create"
            log stop
            dialog --backtitle "save image sandbox" --title "Specify name and path of new the file" --fselect `pwd` 8 60 2> $TMPFILE
            savebranch=`cat $TMPFILE`
            log start
            rm $TMPFILE
            if [ -n "$savebranch" ]; then
                if [ -f "$savebranch" ]; then
                    echo "$savebranch already exist - exiting."
                    exit
                else
                    # get the size
                    log stop
                    dialog --title "Create new save image" --inputbox "Specify size (in megabytes)" 0 40 100 2> $TMPFILE
                    size=`cat $TMPFILE`
                    log start
                    rm $TMPFILE
                    
                    if [ -n "$size" ]; then
                        if dd if=/dev/zero of="$savebranch" bs=1 count=0 seek="$size"M; then
                            if ! mke2fs -F "$savebranch"; then
                                echo "I fail to make an ext2 filesystem at $savebranch, exiting."
                                exit
                            fi
                        else
                            echo "I fail to create a ${size}M file at $savebranch,, exiting."
                            exit
                        fi
                    else
                        echo "You didn't specify the size or your press cancel. Exiting."
                        exit
                    fi                  
                fi
            else
                echo "You didn't specify any file or you pressed cancel. Exiting."
                exit
            fi
            ;;
        1 | 255) # 1 is cancel, 255 is Escape
            ;&
        *) # invalid input - treat as cancel
            echo "Cancelled - exiting."
            exit
            ;;
    esac
}
function find_save(){
  for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do
    for dir in "$PDRV/${PSUBDIR}" "PDRV";  do
       
      ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")"
      if [ -z "$ONE_SAVE" ]; then
         continue
      else
         SAVE_FILE="$ONE_SAVE"
         FULL_SAVE_PATH="$dir"/ONE_SAVE
         break
      fi
    done
   done
   echo "PSAVE"mount_items
}
function find_bk_folders(){
  for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here
    for a_psubdir in "${PSUBDIR}" "";  do
      MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")"
      #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981
      BKFOLDERS="$(find $MT_PT_of_Folder -maxdepth 1 -xdev -type d -name '20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | sed -e s%^${SAVE_MP}/%% | sort -r)"
      [ ! -z "#BKFOLDERS" ] && break   
    done
  done
}
function mk_initrd_dir(){
  mkdir -p "$FAKEROOT"/initrd
  if [ -z "$PUPMODE" ] ; then
    if [ -z "$PMEDIA" ]; then
      #if [ "$PUPMODE" = 5 ] ; then
      #  #aufs layers:              RW (top)      RO1             RO2              PUPMODE
      #  #First boot (or pfix=ram): tmpfs                         pup_xxx.sfs      5
      PUPMODE=5 #MAYBE PUPMODE=2 would be better
    elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then
      find_save
      if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
        #aufs layers:               RW (top)      RO1             RO2              PUPMODE
        #Normal running puppy:      pup_save.3fs                  pup_xxx.sfs      12      
        PUPMODE=12
      else
        echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
        PUMPMODE=2
        #TODO, prompt to either search for save file/folder or alternatively create it. 
      fi
    elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then
      find_save
      #aufs layers:                 RW (top)      RO1             RO2              PUPMODE
      #ditto, but flash drive:      tmpfs         pup_save.3fs    pup_xxx.sfs      13
      if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then
        #aufs layers:               RW (top)      RO1             RO2              PUPMODE
        #ditto, but flash drive:    tmpfs         pup_save.3fs    pup_xxx.sfs      13
        PUPMODE=13
      else
        echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
        PUPMODE=5
      fi
    elif [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ] ; then 
      find_bk_folders
      if [ ! -z "$BKFOLDERS" ]; then
        PUPMODE=77  #MULTI-Session CD
      else #First Boot
        find_save
        if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
          PUPMODE=13      
        else
          PUPMODE=5
        fi
      fi
      #aufs layers:            RW (top)      RO1             RO2              PUPMODE
      #Multisession cd/dvd:       tmpfs         folders         pup_xxx.sfs      77
    else #[PUPMODE=2 -> full install
      PUPMODE=2
    fi
    #TODO: add option to make initrd anyway even if full install. For now make it regardless:
    if [ "$PUPMODE" = 2 ] && [ 1 -ne 1 ]; then #Full install; then #Full install
      echo "Full install has no initrd"
    else
      mkdir -p "$FAKEROOT/initrd"
      cd $FAKEROOT/initrd
      if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ] 
        ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw
      elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then 
        ln -s mnt/tmpfs/pup_rw pup_rw
        if [ "$PUPMODE" = 13 ]; then  # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]
          ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1
        elif [ "$PUPMODE" = 77 ]; then
          ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1  #Usually [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ] 
        fi
      fi
      #!!!! This code was moved from elsehwere inside this section. 
       mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
      mount -o bind  /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
      mkdir $FAKEROOT/mnt
      cd $FAKEROOT/mnt
      ln -s ../initrd/mnt/dev_save
      cd $FAKEROOT
      mount -o bind $SANDBOX_IMG initrd/mnt/tmpfs/pup_rw #not sure if this applies to all pupmodes.     
    fi
  fi
}
function set_fakeroot(){
    unset CLEANUP_SANDBOX_ROOT
    # if SANDBOX_ROOT is set to null then set it in this function
    # if FAKEROOT is null then this implies "/"
    if [ -z ${FAKEROOT+x} ] && [ $FAKEROOT_SET = false ]; then 
      FAKEROOT=fakeroot
      CLEANUP_SANDBOX_ROOT=yes
    fi
    if [ ! -z ${SANDBOX_ROOT+x} ] || [ ${#FAKEROOT} -gt 1 ]; then 
       
      if [ "${CLEANUP_SANDBOX_ROOT}" = yes ]; then
        SANDBOX_ROOT=/mnt/sb
      else
        FAKEROOT_SET
      fi    
      
 
      if [ ${#SANDBOX_ROOT} -gt 1 ] && [ $FAKEROOT_SET = false ]; then
        FAKEROOT=$SANDBOX_ROOT/$FAKEROOT
        FAKEROOT_SET=true
      elif [ ! -z ${FAKEROOT+x} ]; then
        FAKEROOT_SET=true
      fi
       FAKEROOT_dir="${FAKEROOT%/*}"
      [ -z "${SANDBOX_ROOT}" ] && SANDBOX_ROOT=${FAKEROOT_dir}
      if grep -q $FAKEROOT /proc/mounts; then
        if [ ! "$SANDBOX_ROOT" = /mnt/sb ]; then
            log stop
            dialog --backtitle "rename root" --title "already mounted" \
            --extra-button --extra-label "Rename" --ok-label "Keep" \
            --yesno "FAKEROOTI is already a mount point. Rename Root?" 0 0
            chosen=$?
            log start      
           case "#chosen" in
           1)
             RENAME_ROOT=yes; ;;
           0)
             RENAME_ROOT=no; ;;
           esac
           
        else
          RENAME_ROOT=yes
        fi  
        
        if [ "${RENAME_ROOT}" = yes ]; then     
          FAKEROOT=$(mktemp -d -p ${FAKEROOT%/*}/ ${FAKEROOT##*/}.XXXXXXX)
          SANDBOX_ID=".${FAKEROOT##*.}"
          if [ -z "$SANDBOX_IMG" ]; then
            [ -z "$savebranch" ] && choose_save
            savebranch="$(realpath -m $savebranch)"
            if [ -d  "$savebranch" ]; then
              #TODO: verify this works if savebranch is a mounted directory.
              SANDBOX_IMG="$savebranch"
            else
              [ ! -z "$savebranch"  ] && loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//" )
              if [ ! -z "$loop" ]; then
                SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
              fi
              if [ -z "$SANDBOX_IMG" ] ; then
                SANDBOX_IMG=$FAKEROOT_dir/sandbox_img${SANDBOX_ID}
                mkdir -p $SANDBOX_IMG
              fi
            fi
            rmdir $FAKEROOT
          else
            log stop
            echo "Warning chose to remount over existing mount! $FAKEROOT"
            echo "ctrl-c to quote"
            read -p "Press enter to continue"  
            log start     
          fi
        fi
      else
            echo "This is our first sandbox"
      fi
    else
      echo "Warning sandbox root not defined" 
      #[ -z "$FAKEROOT" ] && FAKEROOT=/
    fi
    if [ $CLEANUP_SANDBOX_ROOT = yes ]; then
      if [ ${#del_rules_filter} -eq 0 ]; then
         del_rules_filter+=( $SANDBOX_ROOT"/*" )
         del_rules_filter+=( POLICY_DELETE )
      fi
      if [ ${#umount_rules_filter} -eq 0 ]; then
         umount_rules_filter+=( $SANDBOX_ROOT"/*" )
         umount_rules_filter+=( POLICY_UMOUNT )
      fi    
    fi
    mkdir -p "$SANDBOX_ROOT"
    mkdir -p "$FAKEROOT"
}
function set_sandbox_img(){
     [ -z ${FAKEROOT_dir+x} ] &&  set_fakeroot
     if [ ! -z ${SANDBOX_IMG+x} ]  && [ -z "${SANDBOX_IMG}" ] || [ ! -z ${1+x} ]; then
      SANDBOX_IMG=sandbox_img
      SANDBOX_IMG=${SANDBOX_IMG}${SANDBOX_ID}
      [ ! -z "$FAKEROOT_dir" ] && SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
     elif [ -z "${FAKEROOT_dir}" ] ; then 
      SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
     fi
}
function set_sandbox_tmpfs(){
     [ -z ${FAKEROOT_dir+x} ] &&  set_fakeroot
     if [ ! -z ${SANDBOX_TMPFS+x} ]  && [ -z "${SANDBOX_TMPFS}" ]; then
      SANDBOX_TMPFS=sandbox_tmpfs
      SANDBOX_TMPFS=${SANDBOX_TMPFS}${SANDBOX_ID}
      [ -z "$FAKEROOT_dir" ] && SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
    elif [ -z "${FAKEROOT_dir}" ] ; then 
      SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
    fi
}
 
 
declare -a options="$(getopt -o f:,o:,m:,d:,s:,b:,e:,l:,t::,a::,u::,r::,j: --long input-file:,output-file:,:tmpfs::,root::,pmedia:,pdrv:,psubdir:,boot-config:,distro-specs:,extra-sfs:,aufs,maybe-aufs,maybe-psubdir:,no-exit::,psave:,pupmode:,logfile:,trace::,rw-layer:,copy-Xauth::,bind-X11-sockets::,copy-resolv_conf::,layer:,rev-bind:,bind:,before-chroot: -- "$@")"
eval set --"$options_str"
#set -- $options
#declare -a options=$( $options_str )
eval set --"$options"
while [ $# -gt 0 ]; do
  log stop
  echo "processing args: $@"
  log start
  case $1 in
  -f|--input-file) 
     INPUT_FILE=$2 
    mount_items "$INPUT_FILE"
    items+="$(get_items -f "$INPUT_FILE")"
    shift 2; ;;      
  -o|--output-file) OUTPUT_FILE=$2; shift 2; ;;
  --no-exit) 
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      NO_EXIT="$2"
      [ -z "$NO_EXI" ] && NO_EXIT=true
      shift 2
    else
      NO_EXIT=true
      shift 1
    fi; ;;
  -p|--env-prefix) ENV_PREFIX=$2; shift 2; ;;
  -m|--pmedia) PMEDIA=$2; shift 2; ;;
  -d| --pdrv) PDRV=$2; shift 2; ;;
  -s|--psubdir) PSUBDIR=$2; 
    process_psubdir psubdir
    shift 2; ;;
    --maybe-psubdir) PSUBDIR=$2; 
    process_psubdir maybe-psubdir     
    shift 2; ;;    
  --distro-specs) 
     DISTRO_SPECS=$2; 
     [ -f "$DISTRO_SPECS" ] && . "$DISTRO_SPECS"
     shift 2 
     ;;
   --boot-config)
       BOOTCONFIG=$2; 
     [ -f "$BOOTCONFIG" ] && . "$BOOTCONFIG"
     shift 2 
     ;; 
   --union-record)  
     LASTUNIONRECORD=$2; 
     process_union_record union-record "$LASTUNIONRECORD"
     shift 2; ;;
   -e|--extra-sfs) 
     EXTRASFSLIST=$2;
     process_extra_sfs extra-sfs "$EXTRASFSLIST"
     shift 2; ;;
  --aufs)
    items+="$(get_items)"
    shift 1; ;;
  --maybe-aufs)
    [  -z "$items" ] && items+="$(get_items)"
    shift 1; ;;
   -t|--tmpfs)
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      SANDBOX_TMPFS="$2"
      set_sandbox_tmpfs
      shift 2
    else
      SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
      set_sandbox_tmpfs
      shift 1
    fi; ;;   
    -r|--root)
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      SANDBOX_ROOT="$2"
      shift 2
    else
      SANDBOX_ROOT="" #Later we use [ -z ${SANDBOX_ROOT+x} ] to check that this is set
      shift 1
    fi; ;;   
   -f|-n|--fake-root|--new-root)
      if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
        FAKEROOT="$2"
        set_fakeroot
        shift 2
      else
        FAKEROOT="" #Later we use [ -z ${FAKEROOT+x} ] to check that this is set
        set_fakeroot
        shift 1
      fi; ;;    
  --psave)
    #!!!!New code. See the -s|--save option of remount_save.sh https://pastebin.com/0ZeU2Prj
    #PSAVE=$2
    #shift 2
    #;;
       if [ -d "$2" ]; then
        SANDBOX_IMG=$2
        savebranch=$2
      else [ -f "$2" ]
        #mnt_sb_immage
        #mount -o loop "$rwbranch" $SANDBOX_IMG;
        savebranch=$1
        loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//")
        if [ ! -z "$loop" ]; then
          SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2)
        else
          SANDBOX_IMG=""
          set_sandbox_img
        fi
        shift 2;
      fi; ;;   
  --pupmode)
    PUPMODE=$2
    shift 2
    ;;
  --rw-layer)
    RW_LAYER=$2
    shift 2
    ;;
  --layer)
    RW_LAYER=$2
    process_layer layer $2
    shift 2
    ;;
  -l|--logfile)
    LOGFILE=$2
    [ -z "$TRACE" ] && TRACE=true
    shift 2
    log init
    ;;  
  -t|--trace)
    TRACE=$2
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      TRACE="$2"
      [ -z "$TRACE" ] && TRACE=true
      shift 2
    else
      TRACE=true
      shift 1
    fi
    log init
    ;;
  -a|--copy-Xauth)
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      XAUTH=$(realpath "$2")
      log stop
      [ -z "$XAUTH" ] && XAUTH=$(realpath "~/.Xauthority")
      shift 2
    else
      log stop
      XAUTH=$(realpath "~/.Xauthority")
      shift 1
    fi
    echo "XAUTH=$XAUTH"
    log start
    ;;
  -u|--bind-X11-sockets)
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      uSocketDir=$(realpath "$2"); 
      log stop
      [ -z "$uSocketDir" ] && uSocketDir=/tmp/.X11-unix
      shift 2
    else
      log stop
      uSocketDir=/tmp/.X11-unix
      shift 1
    fi
    echo "uSocketDir=$uSocketDir"
    log start
    ;;
  -r|--copy-resolv_conf)
    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
      RESOLV_CONF_PATH=$(realpath "$2")
      log stop
      [ -z "$RESOLV_CONF_PATH" ] && RESOLV_CONF_PATH=/etc/resolv.conf
      shift 2
    else
      log stop
      RESOLV_CONF_PATH=/etc/resolv.conf
      shift 1
    fi
    echo "RESOLV_CONF_PATH=$RESOLV_CONF_PATH"
    log start
    ;;
  --rev-bind) #Bind the fakeroot into a folder (e.g. a samba share)
       unset rev_b_source
      unset rev_b_target
      while true
      do
        if [ $# -lt 1 ]; then
          break
        fi
        case "$1" in
        --)    
 
          if [ ! -z "$rev_b_source" ]; then
            break
          else
          #TODO, add some further checking here. What we want to do is eat the -- at the end of the positional parameters if we are missing a target. 
            shift
            continue
          fi
          ;;
        --rev-bind)
            shift 
            continue
            ;;
        -*)
            break
            ;;
        esac
        if [ -z "$rev_b_source" ]; then
          if [ ! -z "$1" ]; then
            rev_b_source="$1"; shift
            continue
          fi        
        elif [ -z "$b_target" ]; then
          if [ ! -z "$1" ]; then
            rev_b_target="$1"; shift
            
            log stop
            
            echo "rev_bind_sources+=( \"$rev_b_source\" )"
            echo "rev_bind_targets+=( \"$rev_b_target\" )"
            
            
            rev_bind_sources+=( "$rev_b_source" )
            rev_bind_targets+=( "$rev_b_target" )
            
            log start
            
            unset rev_b_source
            unset rev_b_target
            shift
            continue
          else
            shift
            continue
          fi       
        else
          shift
          break
        fi
      done
 #   fi
    ;; 
  --before-chroot)
     BEFORE_CHROOT_CMD="$2"; 
     shift 2 
     ;; 
  --bind)
#    if [ $# -ge 4 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ] && \
#[[ "$3" = -j ]] && [[ ! "$4" = --* ]] && [ ! -z "$4" ]; then
#       bind_source=$(realpath "$2")
#       bind_target=$(realpath "$2")
#       bind_sources+=( "$bind_source" )
#       bind_targets+=( "$bind_target" )
#       shift 4
#    else 
      unset b_source
      unset b_target
      while true
      do
        if [ $# -lt 1 ]; then
          break
        fi
        case "$1" in
        --)    
 
          if [ ! -z "$b_source" ] && [ $# -lt 3 ]; then
            break
          else
          #TODO, add some further checking here. What we want to do is eat the -- at the end of the positional parameters if we are missing a target. 
            shift
            continue
          fi
          ;;
        --bind)
            shift 
            continue 
            ;;       
        -*)
        
            break
            ;;
        esac        
        if [[ $1 = -* ]]; then
          if [ ! -z "$b_target" ]; then
            break
          else
          #TODO, add some further checking here. What we want to do is eat the -- at the end of the positional parameters if we are missing a target. 
            shift
            continue
          fi
        fi
        if [ -z "$b_source" ]; then
          if [ ! -z "$1" ]; then
            b_source="$1"; shift
            continue
          fi
        elif [ -z "$b_target" ]; then
          if [ ! -z "$1" ]; then
            b_target="$1"; shift
            log stop
            
            echo "bind_sources+=( \"$b_source\" )"
            echo "bind_targets+=( \"$b_target\" )"            
            
            bind_sources+=( "$b_source" )
            bind_targets+=( "$b_target" )
            log start
            
            unset b_source
            unset b_target
            shift
            continue
          fi        
        fi
        shift
      done
 #   fi
    ;;           
  --) 
    shift 1
    options2+=( "$@" )
    break; ;;
  *)
     options2+=( "$1" )
     shift 1; ;;
  esac
done
items="$(echo "$items" | sed -n '/^\s*\(on\)\?\s*$/! p' | sed -n '/^Error: Expected on/! p' | sed -n '/^Use --help on/! p')"
 
      log stop
      read -p "Press enter to continue"
      log start 
 
#!!!! Use new code further down to find and mount PDRV
 
#!!!!Fake root now set with set_fakeroot() (above) for old code see psandbox_removed.sh
 
if [ -z ${SANDBOX_ROOT+x} ] && [ -z ${FAKEROOT+x} ]; then
  SANDBOX_ROOT="" #Later this will change to SANDBOX_ROOT=/mnt/sb
  set_fakeroot
  [ -z $SANDBOX_IMG ] && set_sandbox_img
fi 
 
# umount all if we are accidentally killed
trap 'umountall' 1
 
#!!!! Old umountall() function removed. See new function above 
 
 
# 0.1 must be root
if [ $(id -u) -ne 0 ]; then
  echo "You must be root to use sandbox."
  exit
fi
 
# 0.2 cannot launch sandbox within sandbox
if [ "$AUFS_ROOT_ID" != "" ] ; then
  grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 &&
    echo "Cannot launch sandbox within sandbox." && exit
fi
 
# 0.3 help
case "$1" in
  --help|-h)
  echo "Usage: ${0##*/}"
  echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave."
  exit
esac
 
# 0.4 if not running from terminal but in Xorg, then launch via terminal
! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@"
! [ -t 0 ] && exit
# 1. get aufs system-id for the root filesystem
if [ -z "$AUFS_ROOT_ID" ] ; then
  AUFS_ROOT_ID=$(
    awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts
  )
fi
 
 
# 3. Ask user to choose the SFS
#TODO: add quite mode. 
echo "items=$items"
cat <<EOF
dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
EOF
 
log stop
dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
chosen="$(cat $TMPFILE)"
log start
clear
if [ -z "$chosen" ]; then 
  echo "Cancelled or no SFS is chosen - exiting."
  exit 1 #TODO: Maybe instead of exiting we ask the user if they want to continue. For instance, perhaps the user wants an empty chroot directory to work with. 
fi
 
 
# 4. convert chosen SFS to robranches
robranches=""
for a in $(cat $TMPFILE) ; do
    #a="$(echo "$a" | sed 's/,$//')" # | sed 's/^'//' | sed 's/'$//' )"
    echo "a=$a"
      log stop
      read -p "Press enter to continue"
      log start 
    a="$(echo "$a" | sed 's/"//g')" # | sed 's/^'//' | sed 's/'$//' )"
  robranches=$robranches:$a=ro
  #TODO, remove line if layer is off in config file. 
  sed -i "\#^$a # {s/ off / on /}" /tmp/get_items_out #If we have a config file then we may need to strip out some stuff like if the layer is off or on. 
  
done
if [ ! -z "$OUTPUT_FILE" ]; then
  cp "/tmp/get_items_out" "$OUTPUT_FILE"
  if [ ! "$NO_EXIT" = true ]; then
    exit 0
  fi
fi
rm $TMPFILE
 
#!!!! New Section Get rw image if not specified (unless pfx=ram?), and mount SANDBOX_IMG if not already mounted and nt a directory. 
# 5. get location of rw image
[ -z ${savebranch+x} ] && choose_save
mkdir -p $SANDBOX_IMG
[ ${#SANDBOX_IMG} -gt 1 ] || echo "Pathlenth too short SANDBOX_IMG='$SANDBOX_IMG'"
if [ ! -z "$savebranch"  ]; then
  if [ -f "$savebranch" ]; then
        loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//" )
        if [ ! -z "$loop" ]; then
          SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
        else
          mount -o loop "$savebranch" $SANDBOX_IMG
        fi
  fi
fi
 
 
#!!!! New code. Flag TMPFS for creation, if in suitable pumode.
#!!!! TMPFS may already be flagged for creation if suitable option is provided. 
  if [ ! -z "$PUPMODE" ]; then
    if [ $PUPMODE  -ne 5 ] && [ $PUPMODE  -ne 5 ] && [ $PUPMODE  -ne 13 ] && [ $PUPMODE  -ne 77 ]; then
      if  [ -z ${SANDBOX_TMPFS+x} ]; then
        SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
      fi
    fi
  fi
 
#!!!! New find PDRV code
if [ ! -z "$SANDBOX_ROOT" ]; then
  DEV_SAVE=$SANDBOX_ROOT/dev_save
  mkdir -p "$DEV_SAVE"
  if [ -z "$PDRV" ]; then
    if [[ "$SANDBOX_IMG" = *"/mnt/"* ]]; then
      PSUBDIR=${SANDBOX_IMG#/mnt/*/}
      PDRV=${SANDBOX_IMG%"/$PSUBDIR"}
      PDRV_real=$(cat /proc/mounts | grep $(realpath $PDRV) | cut -d " " -f1)
          PSUBDIR_i=${PSUBDIR}
          PDRV_i=${PDRV}
          PDRV_real_i=${PDRV_real}      
      while (true); do
 
          if [[ PDRV_real_i = /dev/loop* ]]; then
            PDRV_real_i=$(losetup-FULL -a | grep "$(basename PDRV_real)")
            PDRV_real_i=${PDRV_real#*(}
            PDRV_real_i=${PDRV_real%)}
            PSUBDIR_i=${PDRV_real_i#/mnt/*/}
            PDRV_real=$PSUBDIR_i/$PDRV_real
            PDRV_real_i=${SANDBOX_IMG%"/$PSUBDIR_i"}
            PDRV_real_i=$(cat /proc/mounts | grep $(realpath $PDRV_real_i) | cut -d " " -f1)
          elif [[ PDRV_real_i = /dev/* ]]; then
            PDRV_real=$(blkid | grep $PDRV_real)
            break
          else
            echo "could not identify PDRV_real"
            break
          fi
          
      done
    fi
  fi
fi
 
#(!!!!Removed Section -- old set set_sandbox_tmpfs code -- Se psandbox_removed.sh)
 
 
[ -z $PDRV ] && PDRV=/mnt/home
if [ -z  "$SANDBOX_IMG" ] || [ ! -z ${SANDBOX_TMPFS+x} ]; then 
  if [ -z "$SANDBOX_TMPFS" ] ; then
    #SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox
    set_sandbox_tmpfs
    
    #if grep -q $SANDBOX_TMPFS /proc/mounts; then
    #  #FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
    #  #SANDBOX_ID=".${FAKEROOT##*.}"
    #  SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_ID/}${SANDBOX_ID}
    #  mkdir -p -f SANDBOX_TMPFS
    #  mount -t tmpfs none $SANDBOX_TMPFS; #We could exit if this fails but we don't need to becuase we can still write to SANDBOX_TMPFS even if it isn't tmpfs.
    #  rmdir $FAKEROOT
    #fi
  fi
  
  if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
    mount -t tmpfs none $SANDBOX_TMPFS;
  fi
elif [ ! -z "${SANDBOX_TMPFS}" ]; then
  if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
    mount -t tmpfs none $SANDBOX_TMPFS;
  fi 
fi
if [ -z "$SANDBOX_TMPFS" ]; then 
  SANDBOX_TMPFS=$SANDBOX_IMG
else
  if [ $robranches ~= ** ]; then
    robranches=$SANDBOX_IMG=rr:$robranches
  fi
fi
mkdir -p $FAKEROOT
 
#mk_initrd_dir
 
 
## (!!!Removed Section. See psandbox_removed.sh!!) 6. do the magic - mount the tmpfs first, and then the rest with aufs
 
 
 
 
 
# 5. do the magic - mount the rw image first, and then the rest with aufs
#if mount -o loop "$rwbranch" $SANDBOX_IMG; then
if [ ${#FAKEROOT} -gt 1 ] && ! grep -q $FAKEROOT /proc/mounts; then
 
 
  echo "mount -t aufs -o \"br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT}"
  echo "About to mount FAKEROOT at $FAKEROOT"
  read -p "Press enter to continue"
  
    mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT}
 
        # 5. record our new aufs-root-id so tools don't hack real filesystem
        SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #'
        sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null
        echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE  
    
    
    # 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp    
    
    mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp
    mkdir -p  "$DEV_SAVE/${PSUBDIR}"
    mount -o bind  "$PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}"
    
    #mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save"
    mount -o bind  "$DEV_SAVE" "$FAKEROOT/initrd/mnt/dev_save"
 
    #Maybe optionally do this based on some input paramater:
    #Also pull these layers from an array
    for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
        layer="$(eval 'echo $'$layer_name)"
      if [ ! -z "$layer" ] ; then
        mount -o bind  "$layer" "$FAKEROOT/initrd/$layer_name"
      fi
    done
 
    case "$(uname -a)" in
    *fatdog*)
      mkdir -p "$FAKEROOT/aufs"
      #mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/aufs/dev_save"
      mkdir -p "$FAKEROOT/aufs/dev_save"
      mount -o bind  /mnt/home "$FAKEROOT/aufs/dev_save"
      cd $FAKEROOT
      #mkdir -p mnt/home
      cd mnt
      ln -s home ../aufs/dev_save
      pup_save="$SANDBOX_IMG" 
      mount -o bind  "$pup_save" "$FAKEROOT/aufs/pup_save"
      base_sfs=/aufs/pup_ro
      mount -o bind  "$base_sfs" "$FAKEROOT/aufs/pup_ro"
      if [ "$SANDBOX_TMPFS" != "$SANDBOX_IMG" ]; then
         pup_rw="$SANDBOX_TMPFS"
         mount -o bind  "$pup_rw" "$FAKEROOT/aufs/pup_rw"
      fi
      ;;    
    *) #assume this is puppy
      mk_initrd_dir
      #mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
      #mount -o bind  /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
      #mkdir $FAKEROOT/mnt
      #cd $FAKEROOT/mnt
      #ln -s ../initrd/mnt/dev_save
      ;;
    esac
    mkdir -p $FAKEROOT/mnt/home
    mount -o rbind /dev $FAKEROOT/dev
    mount -t sysfs none $FAKEROOT/sys
    mount -t proc none $FAKEROOT/proc
    if [ PUPMODE = 2 ] || [[ "$(uname -a)" = *fatdog* ]]; then #Full Install #Maybe don't base this on PUPMODE
      tmp_des=$FAKEROOT/tmp
      tmp_source=/tmp
    else
      #case "$(uname -a)" in 
      #*fadog*)
      #
      #*) #assume this is puppy
        mkdir -p $FAKEROOT/initrd/mnt/tmpfs
        tmp_des=$FAKEROOT/initrd/mnt/tmpfs
        tmp_source=/initrd/mnt/tmpfs
        cd $FAKEROOT
      rm tmp
      ln -s initrd/mnt/tmpfs tmp
    fi
    mount -o bind $tmp_source $tmp_des
 
    cd $FAKEROOT
    case "$(uname -a)" in
    *fatdog*)
      mkdir -p $FAKEROOT/aufs
      mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS
      ;;
    *) #assume this is puppy
      mk_initrd_dir
      #ln -s initrd/mnt/tmpfs tmp   
      #mkdir -p $FAKEROOT/$SANDBOX_TMPFS
      #mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox
      ;;
    esac
 
#    #mkdir -p $FAKEROOT/$SANDBOX_TMPFS
#    mkdir -p $FAKEROOT/$SANDBOX_IMG
#    mount -o bind $SANDBOX_IMG $FAKEROOT/$SANDBOX_IMG  # so we can access it within sandbox    
     cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
    
 
 
        # 8. optional copy, to enable running sandbox-ed xwin 
        cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
        
        # 9. make sure we identify ourself as in sandbox - and we're good to go!
        echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600
        sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog
        
    if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file
      if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then
        #TODO: when PUPMODE=77 (multisession cd) we need to copy folders. See: https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1084
        #and copy_folders()  https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482
          #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091
          mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT" 
          #mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT" 
      fi
    fi
        
        
        echo "Starting sandbox now."
        log stop 
        if [ $USE_NS ]; then
            unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT
        else
            chroot $FAKEROOT
        fi
        log start
        # 8. done - clean up everything 
        umountall
        echo "Leaving sandbox."  
    
elif [ "${FAKEROOT:-/}" = "/" ]; then
  #[ -z "$FAKEROOT" ] &&  $FAKEROOT="/"
  echo "mount -t aufs -o \"remount,br:$SANDBOX_TMPFS=rw$robranches\" aufs  ${FAKEROOT:-/}"
  echo "Warning!  about to remount rootfs at $FAKEROOT"
  read -p "Press enter to continue"
  trap - 1 #Clear traps
  trap
  mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT:-/};
  mkdir -p /dev /sys /proc /tmp #These probably already exist
  [[ "`mountpoint /dev`"  != *"is a mountpoint"* ]] && mount -t devtmpfs devtmpfs /dev
  mkdir -p /initrd/mnt/tmpfs
  [[ "`mountpoint /initrd/mnt/tmpfs`"  != *"is a mountpoint"* ]] && mount -t tmpfs none /initrd/mnt/tmpfs
  mkdir -p /initrd/mnt/tmpfs/tmp
  if [[ "`mountpoint /tmp`"  != *"is a mountpoint"* ]]; then
    if [[ "`mountpoint /initrd/mnt/tmpfs`"  != *"is a mountpoint"* ]]; then
      mount -o bind /initrd/mnt/tmpfs/tmp /tmp
    else
      mount -t tmpfs none /tmp
    fi
  fi
else
  echo "not implemented for FAKEROOT=${FAKEROOT:-/}}"
  exit
fi
 

Comments