s243a

psandbox2.sh (draft #1)

Dec 13th, 2020 (edited)
978
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 47.83 KB | None | 0 0
  1. #!/bin/bash
  2. #Based on James Budiono 2015 sandbox.sh (version 10) but with many options added
  3. # version 10 - (2015) use pid/mount namespaces if available
  4. #
  5. # 0. directory locations
  6. #. $BOOTSTATE_PATH # AUFS_ROOT_ID
  7. #XTERM="defaultterm"
  8. #
  9. # All options below were added by s243a:
  10. #
  11. # -o, --output-file
  12. #    Just write layer paths to an output file but don't mount the sandbox.
  13. # --no-exit
  14. #   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.
  15. # f, --input-file
  16. #   read layer paths from a file rather than reading existing layers
  17. # m,--pmedia
  18. #   determines pupmodes. Refer to puppy boot parmaters
  19. # d, --pdrv
  20. #   this is the particiaion where the puppy files are located. The default is /mnt/home
  21. # s, psubdir
  22. #   this is the sub directory where the puppy files are located
  23. # c, --clear-env
  24. #   deletes enviornental variabls
  25. # --env-prefix
  26. #   enviornental variable prefix
  27. # b --boot-config
  28. #   path to boot config (e.g. /etc/rc.d/BOOTCONFIG
  29. # --disto-specs
  30. #   path to distro specs (e.g. /etc/DISTRO_SPECS; e.g. /initrd/distro-specs)
  31. # L, --layer
  32. #   a subgke kater
  33. #  e, --extra-sfs
  34. #   a list of extra sfs files (space seperated)
  35. #  u, --union-record
  36. # --xterm
  37. # --sandbox
  38. # -initrd
  39. # --save
  40. # --noexit
  41. # --psave
  42. # --pupmode
  43.  
  44. #I thought some assoitive arrays might be useful but I'm not using them yet.
  45. #declare -A KEYs_by_MNT_PT
  46. #declare -A KEYs_by_FILE_PATH
  47. #declare -A KEYs_by_trimmed_MNT_PT
  48. #declare -A KEYs_by_trimmed_FILE_PATH
  49. #declare -A MNT_PTs
  50. #declare -A FILE_PATHs
  51. #declare -A ON_status
  52. CWD=$(realpath .)
  53. [ -z "$CWD" ] && CWD="$PWD"
  54. declare -a bind_sources
  55. declare -a bind_targets
  56. declare -a rev_bind_sources
  57. declare -a rev_bind_targets
  58. cd "$(dirname "$0")"
  59. MAX_STR_LEN=50
  60. SANDBOX_ID=
  61. TMPFILE=$(mktemp -p /tmp)
  62. # use namespaces if available
  63. #[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1
  64.  
  65. XTERM=${XTERM:-urxvt}
  66. SANDBOX_ROOT=${SANDBOX_ROOT:-/mnt/sb}
  67.  
  68. declare -a options2
  69. declare -a binds
  70. LOG_INITIALIZED=false
  71.  
  72. RP_FN="`which realpath`"
  73. RP_TARGET=$($RP_FN "$RP_FN")
  74. [ -z "$RP_TARGET" ] && RP_TARGET="`readlink $RP_FN`"
  75. declare -a del_rules_filter
  76. declare -a del_rules_action
  77. declare -a umount_rules_filter
  78. declare -a umount_rules_action
  79.  
  80. unset SANDBOX_ID
  81. unset rwbranch
  82. unset FAKEROOT
  83. unset SANDBOX_TMPFS
  84. unset FAKEROOT_dir
  85. unset SANDBOX_IMG
  86. FAKEROOT_SET=false
  87.  
  88. function realpath(){
  89.     case "$RP_TARGET" in
  90.     *busybox*)
  91.       if [ "$1" = -m ]; then
  92.         shift
  93.         A_PATH=$1
  94.         A_PATH=$(echo "$A_path" | sed 's#^./#'"$CWD"'#g' )
  95.         A_PATH=$(echo "$A_path" | sed 's#^../#'"$CWD"'#g' ) && A_PATH=$(dirname $A_PATH)
  96.         echo "Warning simulating '-m' option since it isn't supported by busybox" >2
  97.         echo "A_PATH=$A_PATH" >2
  98.         if [ -f  "$A_PATH" ] || [ -d  "$A_PATH" ]; then
  99.           $RP_FN "$@"
  100.         else
  101.           echo "$A_PATH"
  102.         fi
  103.       else
  104.         $RP_FN "$@"
  105.       fi
  106.       ;;
  107.     *)
  108.       $RP_FN "$@"
  109.       ;;
  110.     esac
  111. }
  112. export -f realpath
  113.  
  114. if [ -f ../local/psandbox/sandbox.awk ]; then
  115.   SANDBOX_AWK="$(realpath ../local/psandbox/sandbox.awk)"
  116. elif [ -f /usr/local/psandbox/sandbox.awk ]; then
  117.  SANDBOX_AWK=/usr/local/psandbox/sandbox.awk
  118. fi
  119. SANDBOX_AWK_DIR="$(dirname $SANDBOX_AWK)"
  120. if [ -f ../local/psandbox/sb_db_rec_field.awk ]; then
  121.   SB_DB_REC_FIELD_AWK="$(realpath ../local/psandbox/sb_db_rec_field.awk)"
  122. elif [ -f /usr/local/psandbox/sb_db_rec_field.awk ]; then
  123.   SB_DB_REC_FIELD_AWK=/usr/local/psandbox/sb_db_rec_field.awk
  124. fi
  125.  
  126. if [ -f ../local/psandbox/sandbox_mnt_fn.sh ]; then
  127.   SANDBOX_MNT_FN="$(realpath ../local/psandbox/sandbox_mnt_fn.sh)"
  128. elif [ -f /usr/local/psandbox/sandbox_mnt_fn.sh ]; then
  129.   SANDBOX_MNT_FN=/usr/local/psandbox/sandbox_mnt_fn.sh
  130. fi
  131.  
  132. . "$SANDBOX_MNT_FN"
  133.  
  134. function get_items(){
  135.     local out
  136.     OUTFILE=/tmp/get_items_out
  137.     rm "$OUTFILE"
  138.     cd "$SANDBOX_AWK_DIR"
  139.     out+="$(
  140.  { echo ==mount==; cat /proc/mounts;
  141.    echo ==losetup==; losetup-FULL -a;
  142.    echo ==branches==;
  143.      if [ $# -eq 0 ]; then
  144.        ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//';
  145.      else
  146.        if [ "$1" = "-f" ]; then
  147.          cat "$2";
  148.        elif [ "$1" = "-s" ]; then
  149.          cat <<<"$2";
  150.        fi;
  151.      fi; } | \
  152.    awk -v PDRV="$PDRV" -v MAX_STR_LEN="$MAX_STR_LEN" -v OUTFILE="$OUTFILE" \
  153. -f "$SANDBOX_AWK"
  154. )"
  155.   echo "$out"
  156. }
  157. function process_psubdir(){
  158.       item_source="$1"
  159.       if [ "$item_source" = "maybe-psubdir" ]; then
  160.          [ ! -z "$items" ] && continue
  161.       fi
  162.       [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'adrv.*\.sfs$')"
  163.       [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'ydrv.*\.sfs$')"  
  164.       [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'zdrv.*\.sfs$')"
  165.       [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'fdrv.*\.sfs$')"                        
  166.       [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'puppy_.*\.sfs$')"
  167.  
  168.       new_items=""
  169.       for rec in "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_PUPPYSFS";  do
  170.         #MNT_PATH="${rec}"
  171.         [ -z "$rec" ] && continue
  172.         #[ ! -z "${PSUBDIR}" ] && MNT_PATH=${PSUBDIR}/${MNT_PATH}
  173.         MNT_PATH="${PDRV}/${PSUBDIR}/$rec"
  174.         MNT_PT="$(mount_fn "$MNT_PATH")"
  175.         new_items+="\"${MNT_PT}\" \"$rec\" \"on\""$'\n'
  176.        
  177.       done
  178.       #export new_items="$new_items"
  179.       #echo "$new_items"
  180.       log stop
  181.       new_items_result="$(get_items -s "$new_items")"$'\n'
  182.       items+="$new_items_result"
  183.       echo "items+=\"$new_items_result\""
  184.       log start
  185.      
  186. }
  187. process_union_record(){
  188.        new_items=''
  189.        for rec in $LASTUNIONRECORD; do
  190.         if [ -f "$rec" ]; then
  191.           MNT_PT="$(mount_fm "$rec" )"
  192.           new_items+="\"$MNT_PT\" \"$rec\" \"on\""$'\n'
  193.         elif [ -f "$PDRV/$rec" ]; then
  194.           MNT_PT="$(mount_fm "$PDRV/$rec" )"
  195.           new_items+="\"$MNT_PT\", \"$PDRV/$rec\", \"on\""$'\n'
  196.         fi
  197.       done
  198.       items+="$(get_items -f <<<"$new_items")"$'\n'    
  199. }
  200. process_extra_sfs(){
  201.      EXTRASFSLIST="$2";
  202.      unset new_items
  203.      if [ ! -f "$EXTRASFSLIST" ]; then
  204.        EXTRASFSLIST_tmp=$(realpath "$PDRV/$PSUBDIR/$EXTRASFSLIST")
  205.        if [ -f "$EXTRASFSLIST_tmp" ]; then
  206.          EXTRASFSLIST="$EXTRASFSLIST_tmp"
  207.        fi
  208.      fi
  209.      if [ ! -f "$EXTRASFSLIST" ]; then
  210.        EXTRASFSLIST_tmp=$(realpath "$PDRV/$EXTRASFSLIST")
  211.        if [ -f "$EXTRASFSLIST_tmp" ]; then
  212.          EXTRASFSLIST="$EXTRASFSLIST_tmp"
  213.        fi
  214.      fi
  215.      if [[ "$EXTRASFSLIST" = *.sfs ]]; then
  216.          a_sfs="$EXTRASFSLIST"
  217.          MNT_PT="$(mount_fn "$a_sfs" )"
  218.          new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'
  219.      else
  220.        while read a_sfs; do
  221.          a_sfs=$(echo"$a_sfs") #Trims leading and trailing whitespace
  222.          if [ -f "$a_sfs" ]; then
  223.            a_sfs=$(realpath "$a_sfs")
  224.          else
  225.            a_sfs1="$PDRV/${PSUBDIR}/$a_sfs"
  226.            a_sfs=$(realpath "$a_sfs")
  227.            if [ -f "$a_sfs"]; then
  228.              a_sfs=$(realpath "$a_sfs")
  229.            else        
  230.              a_sfs1="$PDRV/$a_sfs1"
  231.              if [ -f "$a_sfs1" ]; then
  232.                a_sfs=$(realpath "$a_sfs")
  233.              fi            
  234.            fi
  235.          fi
  236.          if [ -f  "$a_sfs" ]; then
  237.            MNT_PT="$(mount_fn "$a_sfs" )"
  238.            new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'        
  239.          fi
  240.        done <"$EXTRASFSLIST"
  241.      fi
  242.      items+="$(get_items -s "$new_items")"$'\n'
  243.      #items+="$(get_items -f <<<"$new_items")"
  244. }
  245. process_layer(){
  246.       item_path="$2"
  247.       if [ -f "$item_path" ]; then
  248.         MNT_PT="$(mount_fm "$item_path" )"
  249.       elif [ -d "$item_path" ]; then  
  250.         MNT_PT="$item_path" #This isn't really a mount poing
  251.       elif [ ! -d  "$item_path" ]; then
  252.         echo "Warning  cannot mount $item_path"
  253.         continue
  254.       fi
  255.       items+="\"$MNT_PT\" \"$item_path\" \"on\""$'\n'  
  256. }
  257.  
  258. function mount_items(){
  259.   local Moun_Point
  260.   local File_PATH #Might be a directory
  261.   cd "$SANDBOX_AWK_DIR"
  262.   while IFS="" read -r p || [ -n "$p" ]; do #https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
  263.      File_PATH="$(echo "$1" | awk -v FIELD_NUM=6 -f "$SB_DB_REC_FIELD_AWK")"
  264.      Mount_Point="$(echo "$1" | awk -v FIELD_NUM=1 -f "$SB_DB_REC_FIELD_AWK")"
  265.      PDRV_MNT="$(echo "$1" | awk -v FIELD_NUM=7 -f "$SB_DB_REC_FIELD_AWK")"
  266.      PDRV_UUID="$(echo "$1" | awk -v FIELD_NUM=8 -f "$SB_DB_REC_FIELD_AWK")"
  267.      
  268.      [ -z "$PDRV_MNT" ] &&
  269.      mount_fn2 "PDRV" "$File_PATH" "$Moun_Point"
  270.   done <"$1"
  271. }
  272. function log(){
  273.   local SET_X=false
  274.   set +x #TODO add more verbose log option that doesn't do this.
  275.   local logfile="${2}"
  276.   local trace="$3"
  277.   #[ -z "$logfile" ] && LOGFILE
  278.   #[ -z "$trace" ] && trace=TRACE
  279.   if [ ! -z "$LOGFILE" ]; then
  280.     case "$1" in
  281.     init)
  282.       [ "$TRACE" = true ] && SET_X=true
  283.       [ ! -f "$LOGFILE" ] && rm "$LOGFILE"
  284.       exec 6>&1           # Link file descriptor #6 with stdout.
  285.       #exec &1> >(tee -a "$LOGFILE")
  286.       #exec &2> >(tee -a "$LOGFILE")
  287.       [ ! -f "$LOGFILE" ] && touch "$LOGFILE"
  288.       exec &> >(tee -a "$LOGFILE")
  289.       ;;
  290.     start)
  291.       [ "$TRACE" = true ] && SET_X=true
  292.       #exec &1> >(tee -a "$LOGFILE")
  293.       #exec &2> >(tee -a "$LOGFILE")
  294.      
  295.       exec &> >(tee -a "$LOGFILE")
  296.       ;;
  297.     stop)
  298.       #https://stackoverflow.com/questions/21106465/restoring-stdout-and-stderr-to-default-value
  299.       #[ "$TRACE" = true ] && set +x
  300.       exec 1>&6  
  301.       #exec 6>&-      # Restore stdout and close file descriptor #6.
  302.       exec &2> /dev/stderr    
  303.       ;;
  304.     esac
  305.   fi    
  306.   [ "$SET_X" = true ] && set -x
  307. }
  308.  
  309.  
  310.  
  311. safe_delete(){
  312.     unset safe_delete_result
  313.     POLICY="" #Default action if no rule is found
  314.   if [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | sed 's:/$::')" - )" ] ||
  315.     [ ! -z "$(cat /proc/mounts | grep -F "$(ls -1d $1 | xargs realpath )" - )" ] ; then
  316.          #It is not safe to delete a mounted directory
  317.          safe_delete_result=1 #This is in case one doesn't want to use the return status right away
  318.          return 1    
  319.  else
  320.    PATH_TO_DEL="$(realpath -m $1)"
  321.    [ -d "$PATH_TO_DEL" ] && "PATH_TO_DEL=$PATH_TO_DEL/"
  322.    for a_rule_key in "${!del_rules_filter[@]}"; do
  323.      rule_i="${a_rull_key[$a_rule_key]}"
  324.      if [ ! -z "$(echo $PATH_TO_DEL | grep "$rule_i")" ] ||
  325.         [[ "$PATH_TO_DEL" = $rule_i ]]; then
  326.        action="${del_rules_action[$a_rule_key]}"
  327.        case $action in
  328.        DELETE)
  329.          safe_delete_result=0 #This is in case one doesn't want to use the return status right away
  330.          return 0
  331.          break #This is probably redundant
  332.          ;;
  333.        KEEP)
  334.          safe_delete_result=1 #This is in case one doesn't want to use the return status right away
  335.          return 1
  336.          break #This is probably redundant
  337.          ;;          
  338.        POLICY_KEEP)
  339.          POLICY=KEEP
  340.          ;;    
  341.        POLICY_DELETE)
  342.          POLICY=DELETE
  343.          ;;    
  344.        esac
  345.      fi
  346.    done
  347.    if [ -z ${safe_delete_result+x} ]; then #If we don't have a result yet set result based on policy
  348.      case "$POLICY" in
  349.      KEEP)
  350.        safe_delete_result=1
  351.        return 1; ;;
  352.      DELETE)
  353.        safe_delete_result=0
  354.        return 0; ;;
  355.      *)
  356.        echo "No Delete policy set, so keeping file/dir $1"
  357.        safe_delete_result=1
  358.        return 1    
  359.      esac
  360.    fi
  361.  fi
  362. }
  363. safe_umount(){
  364.    unset safe_umount_result
  365.    POLICY="" #Default action if no rule is found
  366.    PATH_TO_UMOUNT="$(realpath -m $1)"
  367.    [ -d "$PATH_TO_UMOUNT" ] && PATH_TO_UMOUNT="$PATH_TO_UMOUNT/" #TODO, this should always be true so add error if it is not.
  368.  
  369.    for a_rule_key in "${!umount_rules_filter[@]}"; do
  370.      rule_i="${a_rull_key[$a_rule_key]}"
  371.      if [ ! -z "$(echo $1 | grep "$rule_i")" ] ||
  372.        [[ "$PATH_TO_UMOUNT" = $rule_i ]]; then
  373.        action="${umount_rules_action[$a_rule_key]}"
  374.        case $action in
  375.        DELETE)
  376.          safe_umount_result=0 #This is in case one doesn't want to use the return status right away
  377.          return 0
  378.          break #This is probably redundant
  379.          ;;
  380.        UMOUNT)
  381.          safe_umount_result=1 #This is in case one doesn't want to use the return status right away
  382.          return 1
  383.          break #This is probably redundant
  384.          ;;          
  385.        POLICY_KEEP)
  386.          POLICY=KEEP
  387.          ;;    
  388.        POLICY_UMOUNT)
  389.          POLICY=UMOUNT
  390.          ;;    
  391.        esac
  392.      fi
  393.    done
  394.    if [ -z ${safe_umount_result+x} ]; then #If we don't have a result yet set result based on policy
  395.      case "$POLICY" in
  396.      KEEP)
  397.        safe_umount_result=1
  398.        return 1; ;;
  399.      UMOUNT)
  400.        safe_umount_result=0
  401.        return 0; ;;
  402.      *)
  403.        echo "No Delete policy set, so keeping file/dir $1"
  404.        safe_umount_result=1
  405.        return 1    
  406.      esac
  407.    fi
  408.  
  409. }
  410. umountall() {
  411.  {
  412.  log start
  413.  set -x
  414.  #R_FR=$(realpath -m "$FAKEROOT")
  415.  #[ ${#R_FR} -lt 2 ] && exit
  416.  safe_umount $SANDBOX_TMPFS
  417.  [ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
  418.  if [ PUPMODE = 2 ]; then #Full Install
  419.      safe_umount $FAKEROOT/tmp
  420.      umount -l $FAKEROOT/tmp
  421.    else
  422.      safe_umount $FAKEROOT/initrd/mnt/tmpfs
  423.      [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT/initrd/mnt/tmpfs
  424.    fi
  425.  for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  426.    layer="$(eval 'echo $'$layer_name)"
  427.    if [ ! -z "$layer" ] ; then
  428.      safe_umount "$FAKEROOT/initrd/$layer_name"
  429.      [ $safe_umount_result -eq 0 ] && umount -l "$FAKEROOT/initrd/$layer_name"
  430.    fi
  431.  done
  432.  for aFolder in /proc /sys /dev ""; do
  433.     safe_umount $FAKEROOT"/$aFolder"
  434.     [ $safe_umount_result -eq 0 ] && umount -l $FAKEROOT$aFolder
  435.  done
  436.  
  437.  
  438.  if [ -z "$RW_LAYER" ]; then
  439.    safe_umount "$SANDBOX_TMPFS"
  440.    [ $safe_umount_result -eq 0 ] && umount -l $SANDBOX_TMPFS
  441.    safe_delete "$SANDBOX_TMPFS"
  442.    [ $safe_delete_result -eq 0 ] && rmdir $SANDBOX_TMPFS
  443.  fi
  444.  
  445.  safe_delete $FAKEROOT
  446.  [ $safe_delete_result -eq 0 ] && rmdir $FAKEROOT
  447.  
  448.  } # 2> /dev/null
  449. }
  450. function choose_save(){
  451.    # location not specified - then ask
  452.    log stop
  453.    dialog --backtitle "rw image sandbox" --title "choose rw image" \
  454.    --extra-button --extra-label "Create" --ok-label "Locate" \
  455.    --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
  456.    chosen=$?
  457.    log start
  458.    case $chosen in
  459.        0) # ok - locate
  460.            log stop
  461.            dialog --backtitle "rw image sandbox" --title "Specify location of existing rw image" --fselect `pwd` 8 60 2> $TMPFILE
  462.            savebranch=`cat $TMPFILE`
  463.            log start
  464.            rm $TMPFILE
  465.            if [ -n "$savebranch" ]; then
  466.                if [ -d "$savebranch" ]; then
  467.                  case "$savebranch" in
  468.                  "/mnt"|"/mnt/"|"/mnt/home"|"/mnt/home/"|"/")
  469.                    log stop
  470.                    echo "warning chose the following savebranch $savebranch"
  471.                    read -p "Press enter to continue"
  472.                    log start
  473.                    set_sandbox_img ""
  474.                    ;;
  475.                  esac
  476.                  SANDBOX_IMG=$savebranch
  477.                elif [ ! -f "$savebranch" ]; then
  478.                    echo "$savebranch doesn't exist - exiting."
  479.                    echo "will use tmpfs instead"
  480.                    log stop
  481.                    read -p "Press enter to continue"
  482.                    log start
  483.                    savebranch=""
  484.                else
  485.                  set_sandbox_img ""                    
  486.                fi
  487.            else
  488.                echo "You didn't specify any file or you pressed cancel. Exiting."
  489.                exit
  490.            fi
  491.            ;;
  492.        3) # create
  493.            echo "create"
  494.            log stop
  495.            dialog --backtitle "save image sandbox" --title "Specify name and path of new the file" --fselect `pwd` 8 60 2> $TMPFILE
  496.            savebranch=`cat $TMPFILE`
  497.            log start
  498.            rm $TMPFILE
  499.            if [ -n "$savebranch" ]; then
  500.                if [ -f "$savebranch" ]; then
  501.                    echo "$savebranch already exist - exiting."
  502.                    exit
  503.                else
  504.                    # get the size
  505.                    log stop
  506.                    dialog --title "Create new save image" --inputbox "Specify size (in megabytes)" 0 40 100 2> $TMPFILE
  507.                    size=`cat $TMPFILE`
  508.                    log start
  509.                    rm $TMPFILE
  510.                    
  511.                    if [ -n "$size" ]; then
  512.                        if dd if=/dev/zero of="$savebranch" bs=1 count=0 seek="$size"M; then
  513.                            if ! mke2fs -F "$savebranch"; then
  514.                                echo "I fail to make an ext2 filesystem at $savebranch, exiting."
  515.                                exit
  516.                            fi
  517.                        else
  518.                            echo "I fail to create a ${size}M file at $savebranch,, exiting."
  519.                            exit
  520.                        fi
  521.                    else
  522.                        echo "You didn't specify the size or your press cancel. Exiting."
  523.                        exit
  524.                    fi                  
  525.                fi
  526.            else
  527.                echo "You didn't specify any file or you pressed cancel. Exiting."
  528.                exit
  529.            fi
  530.            ;;
  531.        1 | 255) # 1 is cancel, 255 is Escape
  532.            ;&
  533.        *) # invalid input - treat as cancel
  534.            echo "Cancelled - exiting."
  535.            exit
  536.            ;;
  537.    esac
  538. }
  539. function find_save(){
  540.  for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do
  541.    for dir in "$PDRV/${PSUBDIR}" "PDRV";  do
  542.      
  543.      ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")"
  544.      if [ -z "$ONE_SAVE" ]; then
  545.         continue
  546.      else
  547.         SAVE_FILE="$ONE_SAVE"
  548.         FULL_SAVE_PATH="$dir"/ONE_SAVE
  549.         break
  550.      fi
  551.    done
  552.   done
  553.   echo "PSAVE"mount_items
  554. }
  555. function find_bk_folders(){
  556.  for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here
  557.    for a_psubdir in "${PSUBDIR}" "";  do
  558.      MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")"
  559.      #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981
  560.      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)"
  561.      [ ! -z "#BKFOLDERS" ] && break  
  562.    done
  563.  done
  564. }
  565. function mk_initrd_dir(){
  566.  mkdir -p "$FAKEROOT"/initrd
  567.  if [ -z "$PUPMODE" ] ; then
  568.    if [ -z "$PMEDIA" ]; then
  569.      #if [ "$PUPMODE" = 5 ] ; then
  570.      #  #aufs layers:              RW (top)      RO1             RO2              PUPMODE
  571.      #  #First boot (or pfix=ram): tmpfs                         pup_xxx.sfs      5
  572.      PUPMODE=5 #MAYBE PUPMODE=2 would be better
  573.    elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then
  574.      find_save
  575.      if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  576.        #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  577.        #Normal running puppy:      pup_save.3fs                  pup_xxx.sfs      12      
  578.        PUPMODE=12
  579.      else
  580.        echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  581.        PUMPMODE=2
  582.        #TODO, prompt to either search for save file/folder or alternatively create it.
  583.      fi
  584.    elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then
  585.      find_save
  586.      #aufs layers:                 RW (top)      RO1             RO2              PUPMODE
  587.      #ditto, but flash drive:      tmpfs         pup_save.3fs    pup_xxx.sfs      13
  588.      if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then
  589.        #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  590.        #ditto, but flash drive:    tmpfs         pup_save.3fs    pup_xxx.sfs      13
  591.        PUPMODE=13
  592.      else
  593.        echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  594.        PUPMODE=5
  595.      fi
  596.    elif [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ] ; then
  597.      find_bk_folders
  598.      if [ ! -z "$BKFOLDERS" ]; then
  599.        PUPMODE=77  #MULTI-Session CD
  600.      else #First Boot
  601.        find_save
  602.        if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  603.          PUPMODE=13      
  604.        else
  605.          PUPMODE=5
  606.        fi
  607.      fi
  608.      #aufs layers:            RW (top)      RO1             RO2              PUPMODE
  609.      #Multisession cd/dvd:       tmpfs         folders         pup_xxx.sfs      77
  610.    else #[PUPMODE=2 -> full install
  611.      PUPMODE=2
  612.    fi
  613.    #TODO: add option to make initrd anyway even if full install. For now make it regardless:
  614.    if [ "$PUPMODE" = 2 ] && [ 1 -ne 1 ]; then #Full install; then #Full install
  615.      echo "Full install has no initrd"
  616.    else
  617.      mkdir -p "$FAKEROOT/initrd"
  618.      cd $FAKEROOT/initrd
  619.      if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ]
  620.        ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw
  621.      elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then
  622.        ln -s mnt/tmpfs/pup_rw pup_rw
  623.        if [ "$PUPMODE" = 13 ]; then  # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]
  624.          ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1
  625.        elif [ "$PUPMODE" = 77 ]; then
  626.          ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1  #Usually [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ]
  627.        fi
  628.      fi
  629.      #!!!! This code was moved from elsehwere inside this section.
  630.       mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
  631.      mount -o bind  /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
  632.      mkdir $FAKEROOT/mnt
  633.      cd $FAKEROOT/mnt
  634.      ln -s ../initrd/mnt/dev_save
  635.      cd $FAKEROOT
  636.      mount -o bind $SANDBOX_IMG initrd/mnt/tmpfs/pup_rw #not sure if this applies to all pupmodes.    
  637.    fi
  638.  fi
  639. }
  640. function set_fakeroot(){
  641.    unset CLEANUP_SANDBOX_ROOT
  642.    # if SANDBOX_ROOT is set to null then set it in this function
  643.    # if FAKEROOT is null then this implies "/"
  644.    if [ -z ${FAKEROOT+x} ] && [ $FAKEROOT_SET = false ]; then
  645.      FAKEROOT=fakeroot
  646.      CLEANUP_SANDBOX_ROOT=yes
  647.    fi
  648.    if [ ! -z ${SANDBOX_ROOT+x} ] || [ ${#FAKEROOT} -gt 1 ]; then
  649.      
  650.      if [ "${CLEANUP_SANDBOX_ROOT}" = yes ]; then
  651.        SANDBOX_ROOT=/mnt/sb
  652.      else
  653.        FAKEROOT_SET
  654.      fi    
  655.      
  656.  
  657.      if [ ${#SANDBOX_ROOT} -gt 1 ] && [ $FAKEROOT_SET = false ]; then
  658.        FAKEROOT=$SANDBOX_ROOT/$FAKEROOT
  659.        FAKEROOT_SET=true
  660.      elif [ ! -z ${FAKEROOT+x} ]; then
  661.        FAKEROOT_SET=true
  662.      fi
  663.       FAKEROOT_dir="${FAKEROOT%/*}"
  664.      [ -z "${SANDBOX_ROOT}" ] && SANDBOX_ROOT=${FAKEROOT_dir}
  665.      if grep -q $FAKEROOT /proc/mounts; then
  666.        if [ ! "$SANDBOX_ROOT" = /mnt/sb ]; then
  667.            log stop
  668.            dialog --backtitle "rename root" --title "already mounted" \
  669.            --extra-button --extra-label "Rename" --ok-label "Keep" \
  670.            --yesno "FAKEROOTI is already a mount point. Rename Root?" 0 0
  671.            chosen=$?
  672.            log start      
  673.           case "#chosen" in
  674.           1)
  675.             RENAME_ROOT=yes; ;;
  676.           0)
  677.             RENAME_ROOT=no; ;;
  678.           esac
  679.          
  680.        else
  681.          RENAME_ROOT=yes
  682.        fi  
  683.        
  684.        if [ "${RENAME_ROOT}" = yes ]; then    
  685.          FAKEROOT=$(mktemp -d -p ${FAKEROOT%/*}/ ${FAKEROOT##*/}.XXXXXXX)
  686.          SANDBOX_ID=".${FAKEROOT##*.}"
  687.          if [ -z "$SANDBOX_IMG" ]; then
  688.            [ -z "$savebranch" ] && choose_save
  689.            savebranch="$(realpath -m $savebranch)"
  690.            if [ -d  "$savebranch" ]; then
  691.              #TODO: verify this works if savebranch is a mounted directory.
  692.              SANDBOX_IMG="$savebranch"
  693.            else
  694.              [ ! -z "$savebranch"  ] && loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//" )
  695.              if [ ! -z "$loop" ]; then
  696.                SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
  697.              fi
  698.              if [ -z "$SANDBOX_IMG" ] ; then
  699.                SANDBOX_IMG=$FAKEROOT_dir/sandbox_img${SANDBOX_ID}
  700.                mkdir -p $SANDBOX_IMG
  701.              fi
  702.            fi
  703.            rmdir $FAKEROOT
  704.          else
  705.            log stop
  706.            echo "Warning chose to remount over existing mount! $FAKEROOT"
  707.            echo "ctrl-c to quote"
  708.            read -p "Press enter to continue"  
  709.            log start    
  710.          fi
  711.        fi
  712.      else
  713.            echo "This is our first sandbox"
  714.      fi
  715.    else
  716.      echo "Warning sandbox root not defined"
  717.      #[ -z "$FAKEROOT" ] && FAKEROOT=/
  718.    fi
  719.    if [ $CLEANUP_SANDBOX_ROOT = yes ]; then
  720.      if [ ${#del_rules_filter} -eq 0 ]; then
  721.         del_rules_filter+=( $SANDBOX_ROOT"/*" )
  722.         del_rules_filter+=( POLICY_DELETE )
  723.      fi
  724.      if [ ${#umount_rules_filter} -eq 0 ]; then
  725.         umount_rules_filter+=( $SANDBOX_ROOT"/*" )
  726.         umount_rules_filter+=( POLICY_UMOUNT )
  727.      fi    
  728.    fi
  729.    mkdir -p "$SANDBOX_ROOT"
  730.    mkdir -p "$FAKEROOT"
  731. }
  732. function set_sandbox_img(){
  733.     [ -z ${FAKEROOT_dir+x} ] &&  set_fakeroot
  734.     if [ ! -z ${SANDBOX_IMG+x} ]  && [ -z "${SANDBOX_IMG}" ] || [ ! -z ${1+x} ]; then
  735.      SANDBOX_IMG=sandbox_img
  736.      SANDBOX_IMG=${SANDBOX_IMG}${SANDBOX_ID}
  737.      [ ! -z "$FAKEROOT_dir" ] && SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
  738.     elif [ -z "${FAKEROOT_dir}" ] ; then
  739.      SANDBOX_IMG=$FAKEROOT_dir/$SANDBOX_IMG
  740.     fi
  741. }
  742. function set_sandbox_tmpfs(){
  743.     [ -z ${FAKEROOT_dir+x} ] &&  set_fakeroot
  744.     if [ ! -z ${SANDBOX_TMPFS+x} ]  && [ -z "${SANDBOX_TMPFS}" ]; then
  745.      SANDBOX_TMPFS=sandbox_tmpfs
  746.      SANDBOX_TMPFS=${SANDBOX_TMPFS}${SANDBOX_ID}
  747.      [ -z "$FAKEROOT_dir" ] && SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
  748.    elif [ -z "${FAKEROOT_dir}" ] ; then
  749.      SANDBOX_TMPFS=$FAKEROOT_dir/$SANDBOX_TMPFS
  750.    fi
  751. }
  752.  
  753.  
  754. 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: -- "$@")"
  755. eval set --"$options_str"
  756. #set -- $options
  757. #declare -a options=$( $options_str )
  758. eval set --"$options"
  759. while [ $# -gt 0 ]; do
  760.  log stop
  761.  echo "processing args: $@"
  762.  log start
  763.  case $1 in
  764.  -f|--input-file)
  765.     INPUT_FILE=$2
  766.    mount_items "$INPUT_FILE"
  767.    items+="$(get_items -f "$INPUT_FILE")"
  768.    shift 2; ;;      
  769.  -o|--output-file) OUTPUT_FILE=$2; shift 2; ;;
  770.  --no-exit)
  771.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  772.      NO_EXIT="$2"
  773.      [ -z "$NO_EXI" ] && NO_EXIT=true
  774.      shift 2
  775.    else
  776.      NO_EXIT=true
  777.      shift 1
  778.    fi; ;;
  779.  -p|--env-prefix) ENV_PREFIX=$2; shift 2; ;;
  780.  -m|--pmedia) PMEDIA=$2; shift 2; ;;
  781.  -d| --pdrv) PDRV=$2; shift 2; ;;
  782.  -s|--psubdir) PSUBDIR=$2;
  783.    process_psubdir psubdir
  784.    shift 2; ;;
  785.    --maybe-psubdir) PSUBDIR=$2;
  786.    process_psubdir maybe-psubdir    
  787.    shift 2; ;;    
  788.  --distro-specs)
  789.     DISTRO_SPECS=$2;
  790.     [ -f "$DISTRO_SPECS" ] && . "$DISTRO_SPECS"
  791.     shift 2
  792.     ;;
  793.   --boot-config)
  794.       BOOTCONFIG=$2;
  795.     [ -f "$BOOTCONFIG" ] && . "$BOOTCONFIG"
  796.     shift 2
  797.     ;;
  798.   --union-record)  
  799.     LASTUNIONRECORD=$2;
  800.     process_union_record union-record "$LASTUNIONRECORD"
  801.     shift 2; ;;
  802.   -e|--extra-sfs)
  803.     EXTRASFSLIST=$2;
  804.     process_extra_sfs extra-sfs "$EXTRASFSLIST"
  805.     shift 2; ;;
  806.  --aufs)
  807.    items+="$(get_items)"
  808.    shift 1; ;;
  809.  --maybe-aufs)
  810.    [  -z "$items" ] && items+="$(get_items)"
  811.    shift 1; ;;
  812.   -t|--tmpfs)
  813.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  814.      SANDBOX_TMPFS="$2"
  815.      set_sandbox_tmpfs
  816.      shift 2
  817.    else
  818.      SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
  819.      set_sandbox_tmpfs
  820.      shift 1
  821.    fi; ;;  
  822.    -r|--root)
  823.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  824.      SANDBOX_ROOT="$2"
  825.      shift 2
  826.    else
  827.      SANDBOX_ROOT="" #Later we use [ -z ${SANDBOX_ROOT+x} ] to check that this is set
  828.      shift 1
  829.    fi; ;;  
  830.   -f|-n|--fake-root|--new-root)
  831.      if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  832.        FAKEROOT="$2"
  833.        set_fakeroot
  834.        shift 2
  835.      else
  836.        FAKEROOT="" #Later we use [ -z ${FAKEROOT+x} ] to check that this is set
  837.        set_fakeroot
  838.        shift 1
  839.      fi; ;;    
  840.  --psave)
  841.    #!!!!New code. See the -s|--save option of remount_save.sh https://pastebin.com/0ZeU2Prj
  842.    #PSAVE=$2
  843.    #shift 2
  844.    #;;
  845.       if [ -d "$2" ]; then
  846.        SANDBOX_IMG=$2
  847.        savebranch=$2
  848.      else [ -f "$2" ]
  849.        #mnt_sb_immage
  850.        #mount -o loop "$rwbranch" $SANDBOX_IMG;
  851.        savebranch=$1
  852.        loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//")
  853.        if [ ! -z "$loop" ]; then
  854.          SANDBOX_IMG=$(/proc/mounts | grep $loop | cut -d " " -f2)
  855.        else
  856.          SANDBOX_IMG=""
  857.          set_sandbox_img
  858.        fi
  859.        shift 2;
  860.      fi; ;;  
  861.  --pupmode)
  862.    PUPMODE=$2
  863.    shift 2
  864.    ;;
  865.  --rw-layer)
  866.    RW_LAYER=$2
  867.    shift 2
  868.    ;;
  869.  --layer)
  870.    RW_LAYER=$2
  871.    process_layer layer $2
  872.    shift 2
  873.    ;;
  874.  -l|--logfile)
  875.    LOGFILE=$2
  876.    [ -z "$TRACE" ] && TRACE=true
  877.    shift 2
  878.    log init
  879.    ;;  
  880.  -t|--trace)
  881.    TRACE=$2
  882.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  883.      TRACE="$2"
  884.      [ -z "$TRACE" ] && TRACE=true
  885.      shift 2
  886.    else
  887.      TRACE=true
  888.      shift 1
  889.    fi
  890.    log init
  891.    ;;
  892.  -a|--copy-Xauth)
  893.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  894.      XAUTH=$(realpath "$2")
  895.      log stop
  896.      [ -z "$XAUTH" ] && XAUTH=$(realpath "~/.Xauthority")
  897.      shift 2
  898.    else
  899.      log stop
  900.      XAUTH=$(realpath "~/.Xauthority")
  901.      shift 1
  902.    fi
  903.    echo "XAUTH=$XAUTH"
  904.    log start
  905.    ;;
  906.  -u|--bind-X11-sockets)
  907.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  908.      uSocketDir=$(realpath "$2");
  909.      log stop
  910.      [ -z "$uSocketDir" ] && uSocketDir=/tmp/.X11-unix
  911.      shift 2
  912.    else
  913.      log stop
  914.      uSocketDir=/tmp/.X11-unix
  915.      shift 1
  916.    fi
  917.    echo "uSocketDir=$uSocketDir"
  918.    log start
  919.    ;;
  920.  -r|--copy-resolv_conf)
  921.    if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  922.      RESOLV_CONF_PATH=$(realpath "$2")
  923.      log stop
  924.      [ -z "$RESOLV_CONF_PATH" ] && RESOLV_CONF_PATH=/etc/resolv.conf
  925.      shift 2
  926.    else
  927.      log stop
  928.      RESOLV_CONF_PATH=/etc/resolv.conf
  929.      shift 1
  930.    fi
  931.    echo "RESOLV_CONF_PATH=$RESOLV_CONF_PATH"
  932.    log start
  933.    ;;
  934.  --rev-bind) #Bind the fakeroot into a folder (e.g. a samba share)
  935.       unset rev_b_source
  936.      unset rev_b_target
  937.      while true
  938.      do
  939.        if [ $# -lt 1 ]; then
  940.          break
  941.        fi
  942.        case "$1" in
  943.        --)    
  944.  
  945.          if [ ! -z "$rev_b_source" ]; then
  946.            break
  947.          else
  948.          #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.
  949.            shift
  950.            continue
  951.          fi
  952.          ;;
  953.        --rev-bind)
  954.            shift
  955.            continue
  956.            ;;
  957.        -*)
  958.            break
  959.            ;;
  960.        esac
  961.        if [ -z "$rev_b_source" ]; then
  962.          if [ ! -z "$1" ]; then
  963.            rev_b_source="$1"; shift
  964.            continue
  965.          fi        
  966.        elif [ -z "$b_target" ]; then
  967.          if [ ! -z "$1" ]; then
  968.            rev_b_target="$1"; shift
  969.            
  970.            log stop
  971.            
  972.            echo "rev_bind_sources+=( \"$rev_b_source\" )"
  973.            echo "rev_bind_targets+=( \"$rev_b_target\" )"
  974.            
  975.            
  976.            rev_bind_sources+=( "$rev_b_source" )
  977.            rev_bind_targets+=( "$rev_b_target" )
  978.            
  979.            log start
  980.            
  981.            unset rev_b_source
  982.            unset rev_b_target
  983.            shift
  984.            continue
  985.          else
  986.            shift
  987.            continue
  988.          fi      
  989.        else
  990.          shift
  991.          break
  992.        fi
  993.      done
  994. #   fi
  995.    ;;
  996.  --before-chroot)
  997.     BEFORE_CHROOT_CMD="$2";
  998.     shift 2
  999.     ;;
  1000.  --bind)
  1001. #    if [ $# -ge 4 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ] && \
  1002. #[[ "$3" = -j ]] && [[ ! "$4" = --* ]] && [ ! -z "$4" ]; then
  1003. #       bind_source=$(realpath "$2")
  1004. #       bind_target=$(realpath "$2")
  1005. #       bind_sources+=( "$bind_source" )
  1006. #       bind_targets+=( "$bind_target" )
  1007. #       shift 4
  1008. #    else
  1009.      unset b_source
  1010.      unset b_target
  1011.      while true
  1012.      do
  1013.        if [ $# -lt 1 ]; then
  1014.          break
  1015.        fi
  1016.        case "$1" in
  1017.        --)    
  1018.  
  1019.          if [ ! -z "$b_source" ] && [ $# -lt 3 ]; then
  1020.            break
  1021.          else
  1022.          #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.
  1023.            shift
  1024.            continue
  1025.          fi
  1026.          ;;
  1027.        --bind)
  1028.            shift
  1029.            continue
  1030.            ;;      
  1031.        -*)
  1032.        
  1033.            break
  1034.            ;;
  1035.        esac        
  1036.        if [[ $1 = -* ]]; then
  1037.          if [ ! -z "$b_target" ]; then
  1038.            break
  1039.          else
  1040.          #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.
  1041.            shift
  1042.            continue
  1043.          fi
  1044.        fi
  1045.        if [ -z "$b_source" ]; then
  1046.          if [ ! -z "$1" ]; then
  1047.            b_source="$1"; shift
  1048.            continue
  1049.          fi
  1050.        elif [ -z "$b_target" ]; then
  1051.          if [ ! -z "$1" ]; then
  1052.            b_target="$1"; shift
  1053.            log stop
  1054.            
  1055.            echo "bind_sources+=( \"$b_source\" )"
  1056.            echo "bind_targets+=( \"$b_target\" )"            
  1057.            
  1058.            bind_sources+=( "$b_source" )
  1059.            bind_targets+=( "$b_target" )
  1060.            log start
  1061.            
  1062.            unset b_source
  1063.            unset b_target
  1064.            shift
  1065.            continue
  1066.          fi        
  1067.        fi
  1068.        shift
  1069.      done
  1070. #   fi
  1071.    ;;          
  1072.  --)
  1073.    shift 1
  1074.    options2+=( "$@" )
  1075.    break; ;;
  1076.  *)
  1077.     options2+=( "$1" )
  1078.     shift 1; ;;
  1079.  esac
  1080. done
  1081. items="$(echo "$items" | sed -n '/^\s*\(on\)\?\s*$/! p' | sed -n '/^Error: Expected on/! p' | sed -n '/^Use --help on/! p')"
  1082.  
  1083.      log stop
  1084.      read -p "Press enter to continue"
  1085.      log start
  1086.  
  1087. #!!!! Use new code further down to find and mount PDRV
  1088.  
  1089. #!!!!Fake root now set with set_fakeroot() (above) for old code see psandbox_removed.sh
  1090.  
  1091. if [ -z ${SANDBOX_ROOT+x} ] && [ -z ${FAKEROOT+x} ]; then
  1092.  SANDBOX_ROOT="" #Later this will change to SANDBOX_ROOT=/mnt/sb
  1093.  set_fakeroot
  1094.  [ -z $SANDBOX_IMG ] && set_sandbox_img
  1095. fi
  1096.  
  1097. # umount all if we are accidentally killed
  1098. trap 'umountall' 1
  1099.  
  1100. #!!!! Old umountall() function removed. See new function above
  1101.  
  1102.  
  1103. # 0.1 must be root
  1104. if [ $(id -u) -ne 0 ]; then
  1105.  echo "You must be root to use sandbox."
  1106.  exit
  1107. fi
  1108.  
  1109. # 0.2 cannot launch sandbox within sandbox
  1110. if [ "$AUFS_ROOT_ID" != "" ] ; then
  1111.  grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 &&
  1112.    echo "Cannot launch sandbox within sandbox." && exit
  1113. fi
  1114.  
  1115. # 0.3 help
  1116. case "$1" in
  1117.  --help|-h)
  1118.  echo "Usage: ${0##*/}"
  1119.  echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave."
  1120.  exit
  1121. esac
  1122.  
  1123. # 0.4 if not running from terminal but in Xorg, then launch via terminal
  1124. ! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@"
  1125. ! [ -t 0 ] && exit
  1126. # 1. get aufs system-id for the root filesystem
  1127. if [ -z "$AUFS_ROOT_ID" ] ; then
  1128.  AUFS_ROOT_ID=$(
  1129.    awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts
  1130.  )
  1131. fi
  1132.  
  1133.  
  1134. # 3. Ask user to choose the SFS
  1135. #TODO: add quite mode.
  1136. echo "items=$items"
  1137. cat <<EOF
  1138. dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  1139.  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
  1140. EOF
  1141.  
  1142. log stop
  1143. dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  1144.  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
  1145. chosen="$(cat $TMPFILE)"
  1146. log start
  1147. clear
  1148. if [ -z "$chosen" ]; then
  1149.  echo "Cancelled or no SFS is chosen - exiting."
  1150.  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.
  1151. fi
  1152.  
  1153.  
  1154. # 4. convert chosen SFS to robranches
  1155. robranches=""
  1156. for a in $(cat $TMPFILE) ; do
  1157.    #a="$(echo "$a" | sed 's/,$//')" # | sed 's/^'//' | sed 's/'$//' )"
  1158.    echo "a=$a"
  1159.      log stop
  1160.      read -p "Press enter to continue"
  1161.      log start
  1162.    a="$(echo "$a" | sed 's/"//g')" # | sed 's/^'//' | sed 's/'$//' )"
  1163.   robranches=$robranches:$a=ro
  1164.   #TODO, remove line if layer is off in config file.
  1165.   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.
  1166.  
  1167. done
  1168. if [ ! -z "$OUTPUT_FILE" ]; then
  1169.   cp "/tmp/get_items_out" "$OUTPUT_FILE"
  1170.   if [ ! "$NO_EXIT" = true ]; then
  1171.     exit 0
  1172.   fi
  1173. fi
  1174. rm $TMPFILE
  1175.  
  1176. #!!!! New Section Get rw image if not specified (unless pfx=ram?), and mount SANDBOX_IMG if not already mounted and nt a directory.
  1177. # 5. get location of rw image
  1178. [ -z ${savebranch+x} ] && choose_save
  1179. mkdir -p $SANDBOX_IMG
  1180. [ ${#SANDBOX_IMG} -gt 1 ] || echo "Pathlenth too short SANDBOX_IMG='$SANDBOX_IMG'"
  1181. if [ ! -z "$savebranch"  ]; then
  1182.   if [ -f "$savebranch" ]; then
  1183.         loop=$(losetup-FULL -a | grep  "$savebranch"  | sed "s/:.*$//" )
  1184.         if [ ! -z "$loop" ]; then
  1185.           SANDBOX_IMG=$(cat /proc/mounts | grep $loop | cut -d " " -f2)
  1186.         else
  1187.           mount -o loop "$savebranch" $SANDBOX_IMG
  1188.         fi
  1189.   fi
  1190. fi
  1191.  
  1192.  
  1193. #!!!! New code. Flag TMPFS for creation, if in suitable pumode.
  1194. #!!!! TMPFS may already be flagged for creation if suitable option is provided.
  1195.   if [ ! -z "$PUPMODE" ]; then
  1196.     if [ $PUPMODE  -ne 5 ] && [ $PUPMODE  -ne 5 ] && [ $PUPMODE  -ne 13 ] && [ $PUPMODE  -ne 77 ]; then
  1197.       if  [ -z ${SANDBOX_TMPFS+x} ]; then
  1198.         SANDBOX_TMPFS="" #Later we use [ -z ${SANDBOX_TMPFS+x} ] to check that this is set
  1199.       fi
  1200.     fi
  1201.   fi
  1202.  
  1203. #!!!! New find PDRV code
  1204. if [ ! -z "$SANDBOX_ROOT" ]; then
  1205.   DEV_SAVE=$SANDBOX_ROOT/dev_save
  1206.   mkdir -p "$DEV_SAVE"
  1207.   if [ -z "$PDRV" ]; then
  1208.     if [[ "$SANDBOX_IMG" = *"/mnt/"* ]]; then
  1209.       PSUBDIR=${SANDBOX_IMG#/mnt/*/}
  1210.       PDRV=${SANDBOX_IMG%"/$PSUBDIR"}
  1211.       PDRV_real=$(cat /proc/mounts | grep $(realpath $PDRV) | cut -d " " -f1)
  1212.           PSUBDIR_i=${PSUBDIR}
  1213.           PDRV_i=${PDRV}
  1214.           PDRV_real_i=${PDRV_real}      
  1215.       while (true); do
  1216.  
  1217.           if [[ PDRV_real_i = /dev/loop* ]]; then
  1218.             PDRV_real_i=$(losetup-FULL -a | grep "$(basename PDRV_real)")
  1219.             PDRV_real_i=${PDRV_real#*(}
  1220.             PDRV_real_i=${PDRV_real%)}
  1221.             PSUBDIR_i=${PDRV_real_i#/mnt/*/}
  1222.             PDRV_real=$PSUBDIR_i/$PDRV_real
  1223.             PDRV_real_i=${SANDBOX_IMG%"/$PSUBDIR_i"}
  1224.             PDRV_real_i=$(cat /proc/mounts | grep $(realpath $PDRV_real_i) | cut -d " " -f1)
  1225.           elif [[ PDRV_real_i = /dev/* ]]; then
  1226.             PDRV_real=$(blkid | grep $PDRV_real)
  1227.             break
  1228.           else
  1229.             echo "could not identify PDRV_real"
  1230.             break
  1231.           fi
  1232.          
  1233.       done
  1234.     fi
  1235.   fi
  1236. fi
  1237.  
  1238. #(!!!!Removed Section -- old set set_sandbox_tmpfs code -- Se psandbox_removed.sh)
  1239.  
  1240.  
  1241. [ -z $PDRV ] && PDRV=/mnt/home
  1242. if [ -z  "$SANDBOX_IMG" ] || [ ! -z ${SANDBOX_TMPFS+x} ]; then
  1243.   if [ -z "$SANDBOX_TMPFS" ] ; then
  1244.     #SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox
  1245.     set_sandbox_tmpfs
  1246.    
  1247.     #if grep -q $SANDBOX_TMPFS /proc/mounts; then
  1248.     #  #FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
  1249.     #  #SANDBOX_ID=".${FAKEROOT##*.}"
  1250.     #  SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_ID/}${SANDBOX_ID}
  1251.     #  mkdir -p -f SANDBOX_TMPFS
  1252.     #  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.
  1253.     #  rmdir $FAKEROOT
  1254.     #fi
  1255.   fi
  1256.  
  1257.   if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
  1258.     mount -t tmpfs none $SANDBOX_TMPFS;
  1259.   fi
  1260. elif [ ! -z "${SANDBOX_TMPFS}" ]; then
  1261.   if [ ! -z "${SANDBOX_TMPFS}" ] && [ ! -z "$(grep -q ${SANDBOX_TMPFS} /proc/mounts)" ]; then
  1262.     mount -t tmpfs none $SANDBOX_TMPFS;
  1263.   fi
  1264. fi
  1265. if [ -z "$SANDBOX_TMPFS" ]; then
  1266.   SANDBOX_TMPFS=$SANDBOX_IMG
  1267. else
  1268.   if [ $robranches ~= ** ]; then
  1269.     robranches=$SANDBOX_IMG=rr:$robranches
  1270.   fi
  1271. fi
  1272. mkdir -p $FAKEROOT
  1273.  
  1274. #mk_initrd_dir
  1275.  
  1276.  
  1277. ## (!!!Removed Section. See psandbox_removed.sh!!) 6. do the magic - mount the tmpfs first, and then the rest with aufs
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283. # 5. do the magic - mount the rw image first, and then the rest with aufs
  1284. #if mount -o loop "$rwbranch" $SANDBOX_IMG; then
  1285. if [ ${#FAKEROOT} -gt 1 ] && ! grep -q $FAKEROOT /proc/mounts; then
  1286.  
  1287.  
  1288.   echo "mount -t aufs -o \"br:$SANDBOX_TMPFS=rw$robranches\" aufs ${FAKEROOT}"
  1289.   echo "About to mount FAKEROOT at $FAKEROOT"
  1290.   read -p "Press enter to continue"
  1291.  
  1292.     mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT}
  1293.  
  1294.         # 5. record our new aufs-root-id so tools don't hack real filesystem
  1295.         SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #'
  1296.         sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null
  1297.         echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE  
  1298.    
  1299.    
  1300.     # 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp    
  1301.    
  1302.     mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp
  1303.     mkdir -p  "$DEV_SAVE/${PSUBDIR}"
  1304.     mount -o bind  "$PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}"
  1305.    
  1306.     #mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save"
  1307.     mount -o bind  "$DEV_SAVE" "$FAKEROOT/initrd/mnt/dev_save"
  1308.  
  1309.     #Maybe optionally do this based on some input paramater:
  1310.     #Also pull these layers from an array
  1311.     for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  1312.         layer="$(eval 'echo $'$layer_name)"
  1313.       if [ ! -z "$layer" ] ; then
  1314.         mount -o bind  "$layer" "$FAKEROOT/initrd/$layer_name"
  1315.       fi
  1316.     done
  1317.  
  1318.     case "$(uname -a)" in
  1319.     *fatdog*)
  1320.       mkdir -p "$FAKEROOT/aufs"
  1321.       #mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/aufs/dev_save"
  1322.       mkdir -p "$FAKEROOT/aufs/dev_save"
  1323.       mount -o bind  /mnt/home "$FAKEROOT/aufs/dev_save"
  1324.       cd $FAKEROOT
  1325.       #mkdir -p mnt/home
  1326.       cd mnt
  1327.       ln -s home ../aufs/dev_save
  1328.       pup_save="$SANDBOX_IMG"
  1329.       mount -o bind  "$pup_save" "$FAKEROOT/aufs/pup_save"
  1330.       base_sfs=/aufs/pup_ro
  1331.       mount -o bind  "$base_sfs" "$FAKEROOT/aufs/pup_ro"
  1332.       if [ "$SANDBOX_TMPFS" != "$SANDBOX_IMG" ]; then
  1333.          pup_rw="$SANDBOX_TMPFS"
  1334.          mount -o bind  "$pup_rw" "$FAKEROOT/aufs/pup_rw"
  1335.       fi
  1336.       ;;    
  1337.     *) #assume this is puppy
  1338.       mk_initrd_dir
  1339.       #mkdir -p "$FAKEROOT/initrd/mnt/dev_save"
  1340.       #mount -o bind  /mnt/home "$FAKEROOT/initrd/mnt/dev_save"
  1341.       #mkdir $FAKEROOT/mnt
  1342.       #cd $FAKEROOT/mnt
  1343.       #ln -s ../initrd/mnt/dev_save
  1344.       ;;
  1345.     esac
  1346.     mkdir -p $FAKEROOT/mnt/home
  1347.     mount -o rbind /dev $FAKEROOT/dev
  1348.     mount -t sysfs none $FAKEROOT/sys
  1349.     mount -t proc none $FAKEROOT/proc
  1350.     if [ PUPMODE = 2 ] || [[ "$(uname -a)" = *fatdog* ]]; then #Full Install #Maybe don't base this on PUPMODE
  1351.       tmp_des=$FAKEROOT/tmp
  1352.       tmp_source=/tmp
  1353.     else
  1354.       #case "$(uname -a)" in
  1355.       #*fadog*)
  1356.       #
  1357.       #*) #assume this is puppy
  1358.         mkdir -p $FAKEROOT/initrd/mnt/tmpfs
  1359.         tmp_des=$FAKEROOT/initrd/mnt/tmpfs
  1360.         tmp_source=/initrd/mnt/tmpfs
  1361.         cd $FAKEROOT
  1362.       rm tmp
  1363.       ln -s initrd/mnt/tmpfs tmp
  1364.     fi
  1365.     mount -o bind $tmp_source $tmp_des
  1366.  
  1367.     cd $FAKEROOT
  1368.     case "$(uname -a)" in
  1369.     *fatdog*)
  1370.       mkdir -p $FAKEROOT/aufs
  1371.       mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS
  1372.       ;;
  1373.     *) #assume this is puppy
  1374.       mk_initrd_dir
  1375.       #ln -s initrd/mnt/tmpfs tmp  
  1376.       #mkdir -p $FAKEROOT/$SANDBOX_TMPFS
  1377.       #mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox
  1378.       ;;
  1379.     esac
  1380.  
  1381. #    #mkdir -p $FAKEROOT/$SANDBOX_TMPFS
  1382. #    mkdir -p $FAKEROOT/$SANDBOX_IMG
  1383. #    mount -o bind $SANDBOX_IMG $FAKEROOT/$SANDBOX_IMG  # so we can access it within sandbox    
  1384.      cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
  1385.    
  1386.  
  1387.  
  1388.         # 8. optional copy, to enable running sandbox-ed xwin
  1389.         cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
  1390.        
  1391.         # 9. make sure we identify ourself as in sandbox - and we're good to go!
  1392.         echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600
  1393.         sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog
  1394.        
  1395.     if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file
  1396.       if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then
  1397.         #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
  1398.         #and copy_folders()  https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482
  1399.           #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091
  1400.           mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT"
  1401.           #mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT"
  1402.       fi
  1403.     fi
  1404.        
  1405.        
  1406.         echo "Starting sandbox now."
  1407.         log stop
  1408.         if [ $USE_NS ]; then
  1409.             unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT
  1410.         else
  1411.             chroot $FAKEROOT
  1412.         fi
  1413.         log start
  1414.         # 8. done - clean up everything
  1415.         umountall
  1416.         echo "Leaving sandbox."  
  1417.    
  1418. elif [ "${FAKEROOT:-/}" = "/" ]; then
  1419.   #[ -z "$FAKEROOT" ] &&  $FAKEROOT="/"
  1420.   echo "mount -t aufs -o \"remount,br:$SANDBOX_TMPFS=rw$robranches\" aufs  ${FAKEROOT:-/}"
  1421.   echo "Warning!  about to remount rootfs at $FAKEROOT"
  1422.   read -p "Press enter to continue"
  1423.   trap - 1 #Clear traps
  1424.   trap
  1425.   mount -t aufs -o "br:$SANDBOX_TMPFS=rw$robranches" aufs ${FAKEROOT:-/};
  1426.   mkdir -p /dev /sys /proc /tmp #These probably already exist
  1427.   [[ "`mountpoint /dev`"  != *"is a mountpoint"* ]] && mount -t devtmpfs devtmpfs /dev
  1428.   mkdir -p /initrd/mnt/tmpfs
  1429.   [[ "`mountpoint /initrd/mnt/tmpfs`"  != *"is a mountpoint"* ]] && mount -t tmpfs none /initrd/mnt/tmpfs
  1430.   mkdir -p /initrd/mnt/tmpfs/tmp
  1431.   if [[ "`mountpoint /tmp`"  != *"is a mountpoint"* ]]; then
  1432.     if [[ "`mountpoint /initrd/mnt/tmpfs`"  != *"is a mountpoint"* ]]; then
  1433.       mount -o bind /initrd/mnt/tmpfs/tmp /tmp
  1434.     else
  1435.       mount -t tmpfs none /tmp
  1436.     fi
  1437.   fi
  1438. else
  1439.   echo "not implemented for FAKEROOT=${FAKEROOT:-/}}"
  1440.   exit
  1441. fi
  1442.  
Add Comment
Please, Sign In to add comment