#!/bin/sh
#(c) Copyright Barry Kauler, Feb. 2017. License GPL v3 (usr/share/doc/legal)
#170523 name change /usr/local/easy_containers/extra-sfss to extra-sfss-ec
#171001 can only select from apps in easy.sfs.
#180407 want to create desktop icons for containerized apps.
#180409 log desktop-icon info, for script ec-fix-desktop. delete container fix.
#180427 support linux capabilities. remove user-namespace. more help.
#180429 allow user-installed apps in containers.
#180524 have patched kernel for cap_sys_mount, extracted from cap_sys_admin. reverted.
#180702 offer Xephyr|Xorg server. offer abstract|pipe|unix socket. 180703
#180723 if xorg started with "-nolisten local" then cannot use abstract socket.
#180930 tweak security settings.
#181002 new Access section. 181006 sound.
#181006 backup icon, may need it, see ec-fix-desktop.
#181008 option to run as zeus in container.
#181009 configuration defaults: /usr/local/easy_containers/templates/defaults/configuration
#181014 need to launch via "urxvt -name eclaunch -iconic ..." which is hidden (see /root/.jwmrc)
#181016 improve find icon for desktop.
#181017 change 181014, use 'empty' instead of urxvt. 181025 typo.
#181028 rename 'repository' folder to 'releases'.
#181029 revert 180429 -- do NOT allow user-installed apps in containers.
#181122 q*.sfs renamed to easy*.sfs, also q_ro to easy_ro, q_sfs to easy_sfs

export TEXTDOMAIN=easy-containers
export OUTPUT_CHARSET=UTF-8

. /etc/rc.d/PUPSTATE
. /etc/DISTRO_SPECS
mkdir -p /tmp/easy_containers

#create a list of apps that could be run in a container...
#171001 can only select from apps in easy.sfs... 180429 allow user-installed apps...
#181029 revert 180429, do NOT allow user-installed apps...
#APPSLIST1="$(grep '^Exec=' /usr/share/applications/*.desktop | cut -f 2 -d '=' | grep -v -E '/| ')"
#xAPPSLIST1="$(grep '^Exec=' /mnt/easy_ro/easy_sfs/usr/share/applications/*.desktop | cut -f 2 -d '=' | grep -v -E '/| ')"
APPSLIST1="$(grep '^Exec=' /mnt/easy_ro/easy_sfs/usr/share/applications/*.desktop | cut -f 2 -d '=' | grep -v -E '/| ')"
#screen out already existing containers...
ls -1 /mnt/${WKG_DEV}/${WKG_DIR}containers > /tmp/easy_containers/current-containers
APPSLIST2="$(echo "$APPSLIST1" | grep -v -w -f /tmp/easy_containers/current-containers | sort)" #180429 sort.
echo "$APPSLIST2" > /tmp/easy_containers/apps-list

#180723 if xorg started with "-nolisten local" then cannot use abstract socket...
XORG_ABSTRACT_ALLOW='true'
grep '^/usr/bin/xinit .*nolisten local' /usr/bin/xwin >/dev/null
[ $? -eq 0 ] && XORG_ABSTRACT_ALLOW='false'

#defaults for the security checkboxes...  #181009
set_defaults_func() {
 EXEin="$1"
 if [ -f /usr/local/easy_containers/templates/${EXEin}/configuration ];then
  . /usr/local/easy_containers/templates/${EXEin}/configuration
 else
  . /usr/local/easy_containers/templates/defaults/configuration
 fi
 #xorg...
 [ "$XORG_ABSTRACT_ALLOW" == "false" ] && [ "$EC_XSOCKET" == "abstract" ] && EC_XSOCKET='unix'
 case "$EC_XSOCKET" in
  abstract)
   echo 'true' > /tmp/easy_containers/chkbx-XSOCKET_ABSTRACT
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_UNIX
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_PIPE
  ;;
  pipe)
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_ABSTRACT
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_UNIX
   echo 'true' > /tmp/easy_containers/chkbx-XSOCKET_PIPE
  ;;
  *) #unix
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_ABSTRACT
   echo 'true' > /tmp/easy_containers/chkbx-XSOCKET_UNIX
   echo 'false' > /tmp/easy_containers/chkbx-XSOCKET_PIPE
  ;;
 esac
 case "$EC_XSERVER" in
  xephyr)
   echo 'false' > /tmp/easy_containers/chkbx-XSERVER_XORG
   echo 'true' > /tmp/easy_containers/chkbx-XSERVER_XEPHYR
  ;;
  *) #xorg
   echo 'true' > /tmp/easy_containers/chkbx-XSERVER_XORG
   echo 'false' > /tmp/easy_containers/chkbx-XSERVER_XEPHYR
  ;;
 esac
 #namespaces...
 echo "$EC_NS_UNSHARE_MOUNT" > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_MOUNT
 echo "$EC_NS_UNSHARE_UTS" > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_UTS
 echo "$EC_NS_UNSHARE_IPC" > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_IPC
 echo "$EC_NS_UNSHARE_NETWORK" > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_NETWORK
 echo "$EC_NS_UNSHARE_PID" > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_PID
 #echo 'true' > /tmp/easy_containers/chkbx-EC_NS_UNSHARE_USER
 #environment... 181008
 echo "$EC_UNSHARE_ENV_VARS" > /tmp/easy_containers/chkbx-EC_UNSHARE_ENV_VARS
 echo "$EC_ENV_ZEUS" > /tmp/easy_containers/chkbx-EC_ENV_ZEUS
 #181002 access...
 echo "$EC_ACCESS_NET" > /tmp/easy_containers/chkbx-EC_ACCESS_NET
 echo "$EC_ACCESS_SND" > /tmp/easy_containers/chkbx-EC_ACCESS_SND
 echo "$EC_ACCESS_FOLDER" > /tmp/easy_containers/chkbx-EC_ACCESS_FOLDER
 echo -n "$EC_ACCESS_FOLDER_PATH" > /tmp/easy_containers/entry-EC_ACCESS_FOLDER_PATH
 lastPATH="$EC_ACCESS_FOLDER_PATH"
 #capabilities...
 echo "$EC_CAP_system" > /tmp/easy_containers/chkbx-EC_CAP_system
 echo "$EC_CAP_file" > /tmp/easy_containers/chkbx-EC_CAP_file
 echo "$EC_CAP_network" > /tmp/easy_containers/chkbx-EC_CAP_network
 echo "$EC_CAP_module" > /tmp/easy_containers/chkbx-EC_CAP_module
 echo "$EC_CAP_resource" > /tmp/easy_containers/chkbx-EC_CAP_resource
 echo "$EC_CAP_mount" > /tmp/easy_containers/chkbx-EC_CAP_mount
} #end set_defaults_func
export -f set_defaults_func
set_defaults_func defaults

#$(gettext 'User-installed packages are a problem, as they will have to be copied into the read-write layer of the container. If, for example, you install Firefox, and choose to run it in a container, all of the installed files of the Firefox package will be copied to the newly-created container. This is done automatically.')

M_close="$(gettext 'Close')"
M_help1="$(gettext 'Easy Containers is a nice GUI for creating and managing the running of apps in containers. Some useful notes:')

$(gettext 'A container is composed of a read-write folder layered on top of easy.sfs. The bottom layer is all of EasyOS, with all the builtin apps. Any one of these apps may be chosen to run in a container, however, currently only apps with a menu-entry are offered in the drop-down list.')

<b>$(gettext 'Important:')</b>
$(gettext 'User-installed packages cannot be containerized. Instead, please use the <b>SFSget package manager</b> to install SFS packages directly to a container.')"
export DLG_HELP1="<window resizable=\"false\" title=\"$(gettext 'Help: Easy Containers')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_help1}\"</label><variable>DLG_HELP1</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELP1</action></button></hbox></vbox></window>"

M_helpcap="$(gettext 'In Easy, the user runs as the <b>root</b> user (administrator), and the same is true in containers. Linux has a feature called <b>capabilities</b>, that can be used to restrict the rights of the root user. Easy has organized them into five categories, for ease-of-use:')

<b>$(gettext 'system')</b>
$(gettext 'Drop system administration permissions.')
<b>$(gettext 'file')</b>
$(gettext 'Prevent execution and modifications to files.')
<b>$(gettext 'network')</b>
$(gettext 'Drop network administration permissions. Note, tick the <i>network Namespace</i> checkbox to disable inheriting host network connection.')
<b>$(gettext 'module')</b>
$(gettext 'Drop kernel module loading/unloading and other admin.')
<b>$(gettext 'resource')</b>
$(gettext 'Drop system resource administration.')
<b>$(gettext 'mount')</b>
$(gettext 'Prevent mount and umount of filesystems.')

Note, for most applications it is OK to tick all of these."
export DLG_HELPcap="<window resizable=\"false\" title=\"$(gettext 'Help: Linux capabilities')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_helpcap}\"</label><variable>DLG_HELPcap</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELPcap</action></button></hbox></vbox></window>"

M_helpns="$(gettext 'Linux namespaces are a mechanism to isolate some functionality of a container from the main system. There are six types:')

<b>$(gettext 'mount')</b>
$(gettext 'Mount points. Recommend do tick this.')
<b>$(gettext 'UTS')</b>
$(gettext 'Hostname and NIS domain name. May be ticked, however, do <i>not</i> tick if choose Pipe Xorg socket, as X apps will not run.')
<b>$(gettext 'IPC')</b>
$(gettext 'Inter Process Communication. Recommend do <i>not</i> tick this, as it will prevent X apps from running.')
<b>$(gettext 'network')</b>
$(gettext 'Network devices, stacks, ports. Tick this for more secure network and Internet connection.')
<b>$(gettext 'PID')</b>
$(gettext 'Process IDs. Ticking this will prevent the container from seeing the host-system PIDs. Recommended to always tick this.')
<b>$(gettext 'user')</b>
$(gettext 'User and group IDs. Easy Containers does not use this, as it was determined to be unnecessary, and even conflicting, with Linux capabilities.')"
export DLG_HELPns="<window resizable=\"false\" title=\"$(gettext 'Help: Linux namespaces')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_helpns}\"</label><variable>DLG_HELPns</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELPns</action></button></hbox></vbox></window>"

M_helpxorg="$(gettext 'The X server is a potential security weakness, as an X app running in a container must use the system X server. The connection is via what is called a <i>socket</i>, and there are three ways of doing it:')

<b>$(gettext 'Unix Domain Socket')</b>
$(gettext 'This uses a path in the main filesystem, /tmp/.X11-unix, which would have to be visible from a container to be used by apps in the container.')

<b>$(gettext 'Abstract')</b>
$(gettext 'This does not require access to /tmp in the main filesystem, however, will not work if the X server started with <i>-nolisten local</i>.')

<b>$(gettext 'Pipe')</b>
$(gettext 'This is setup in the main filesyetm, with the <i>socat</i> utility, to connect TCP port 6000 to the Unix Domain Socket. This will work even if the X server is started with <i>-nolisten tcp -nolisten local</i>. However, Pipe will not work if the <i>mount Namespace</i> is unshared.')

<b>Xorg</b>
$(gettext 'Xorg is the X server used in the main filesystem. It can also be used in containers, with any of the above three socket methods.')

<b>Xephyr</b>
$(gettext 'Xephyr is a nested X server. It will display in its own window, and is the most secure option.')

<b>$(gettext 'Technical notes')</b>
$(gettext 'Xorg commandline start options can be found in /usr/bin/xwin')
$(gettext 'Xephyr commandline start options can be found in /root/Startup/xephyr')"
export DLG_HELPxorg="<window resizable=\"false\" title=\"$(gettext 'Help: X Server')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_helpxorg}\"</label><variable>DLG_HELPxorg</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELPxorg</action></button></hbox></vbox></window>"

M_helpenv="<b>$(gettext 'unshare variables')</b>
$(gettext 'If you type <i>set</i> in a terminal, all of the environment variables will be listed. To reduce the number of these appearing in a container, tick the checkbox.')

<b>user zeus</b>
$(gettext 'Execution in container is as root user, however severely constrained, which is considered secure. However, if you wish, tick this checkbox to run as user <b>zeus</b> in the container, for even more security.')
<b>WARNING: only tick this when creating a new container. Also, some apps may not work.</b>

<b>$(gettext 'network')</b>
$(gettext 'Tick this if you want to have network (and Internet) access from within the container.')

<b>$(gettext 'sound')</b>
$(gettext 'Tick this for sound output from within the container.')

<b>$(gettext 'folder')</b>
$(gettext 'Tick the checkbox, then choose a folder that will have read-write access inside the container. It will be <b>/shared-folder</b> inside the container.')"
export DLG_HELPenv="<window resizable=\"false\" title=\"$(gettext 'Help: Environment & Access')\" icon-name=\"gtk-index\" window_position=\"1\"><vbox><text use-markup=\"true\"><label>\"${M_helpenv}\"</label><variable>DLG_HELPenv</variable></text><hbox><button><label>${M_close}</label><action type=\"closewindow\">DLG_HELPenv</action></button></hbox></vbox></window>"

#          <checkbox><variable>NS_USER</variable><label>user</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_USER</input></checkbox>
#          <checkbox><variable>CAP_mount</variable><label>mount</label><input file>/tmp/easy_containers/chkbx-EC_CAP_mount</input></checkbox>

#181002 chooser for shared folder...
export DLG_CHOOSER="<window title=\"$(gettext 'Easy Containers')\" icon-name=\"gtk-convert\">
 <vbox>
  <text><label>$(gettext 'Choose a folder that will be shared inside container')</label></text>
  <chooser>
   <width>600</width>
   <height>400</height>
   <variable>PATHCHOOSER</variable>
   <default>${lastPATH}</default>
  </chooser>
  <hbox>
   <button ok>
     <action>echo -n \$PATHCHOOSER > /tmp/easy_containers/entry-EC_ACCESS_FOLDER_PATH</action>
     <action>refresh:ACCESS_FOLDER_PATH</action>
     <action function=\"closewindow\">DLG_CHOOSER</action>
   </button>
   <button cancel>
     <action function=\"closewindow\">DLG_CHOOSER</action>
   </button>
  </hbox>
 </vbox>
 <variable>DLG_CHOOSER</variable>
</window>"

#        <action>/usr/local/easy_containers/create-selected \$EC_CREATE</action>

export EC_DLG1="<window title=\"$(gettext "Easy Containers")\" icon-name=\"gtk-convert\">
<vbox>

  <frame $(gettext 'Manage')>
    <hbox>
      <text><label>$(gettext 'Choose container to manage:')</label></text>
      <comboboxtext><variable>EC_MANAGE</variable><input>ls -1 /mnt/${WKG_DEV}/${WKG_DIR}containers</input></comboboxtext>
    </hbox>
    <hbox>
     <text><label>$(gettext 'Load extra SFS files:')</label></text>
     <button><label>$(gettext 'SFS')</label><action>/usr/local/easy_containers/extra-sfss-ec \${EC_MANAGE} </action></button>
    </hbox>
    <hbox>
      <text><label>$(gettext 'Edit configuration file:')</label></text>
      <button><label>$(gettext 'Edit')</label><action>defaulttexteditor /mnt/${WKG_DEV}/${WKG_DIR}containers/\${EC_MANAGE}/configuration & </action></button>
    </hbox>
    <hbox>
      <text><label>$(gettext 'Delete container:')</label></text>
      <button><label>$(gettext 'Delete')</label><action>exit:delete</action></button>
    </hbox>
  </frame>
  
  <frame $(gettext 'Create')>
    
    <frame $(gettext 'Security options')>
     <notebook labels=\"$(gettext 'Simple')|$(gettext 'Expert')\">
      <vbox>
       <hbox>
        <text><label>$(gettext 'Reset security settings to defaults:')</label></text>
        <button>
         <label>Reset</label>
         <action>set_defaults_func \$EC_CREATE</action>
         <action>refresh:ENV_VARS</action>
         <action>refresh:ENV_ZEUS</action>
         <action>refresh:ACCESS_NET</action>
         <action>refresh:ACCESS_SND</action>
         <action>refresh:ACCESS_FOLDER</action>
         <action>refresh:ACCESS_FOLDER_PATH</action>
         <action>refresh:NS_MOUNT</action>
         <action>refresh:NS_UTS</action>
         <action>refresh:NS_IPC</action>
         <action>refresh:NS_NETWORK</action>
         <action>refresh:NS_PID</action>
         <action>refresh:XSERVER_XEPHYR</action>
         <action>refresh:XSERVER_XORG</action>
         <action>refresh:XSOCKET_ABSTRACT</action>
         <action>refresh:XSOCKET_PIPE</action>
         <action>refresh:XSOCKET_UNIX</action>
         <action>refresh:CAP_system</action>
         <action>refresh:CAP_file</action>
         <action>refresh:CAP_network</action>
         <action>refresh:CAP_module</action>
         <action>refresh:CAP_resource</action>
         <action>refresh:CAP_mount</action>
        </button>
       </hbox>
       <text><label>\"  \"</label></text>
       <text><label>more coming soon</label></text>
      </vbox>
      <vbox>
       <hbox>
        <vbox>
         <frame $(gettext 'Environment')>
          <checkbox><variable>ENV_VARS</variable><label>unshare variables</label><input file>/tmp/easy_containers/chkbx-EC_UNSHARE_ENV_VARS</input></checkbox>
          <checkbox><variable>ENV_ZEUS</variable><label>user zeus</label><input file>/tmp/easy_containers/chkbx-EC_ENV_ZEUS</input></checkbox>
         </frame>
         <frame $(gettext 'Access')>
          <checkbox><variable>ACCESS_NET</variable><label>network</label><input file>/tmp/easy_containers/chkbx-EC_ACCESS_NET</input></checkbox>
          <checkbox><variable>ACCESS_SND</variable><label>sound</label><input file>/tmp/easy_containers/chkbx-EC_ACCESS_SND</input></checkbox>
          <hbox>
           <checkbox>
            <variable>ACCESS_FOLDER</variable>
            <label>$(gettext 'folder')</label>
            <input file>/tmp/easy_containers/chkbx-EC_ACCESS_FOLDER</input>
           </checkbox>
           <text><label>\"  \"</label></text>
           <button>
            <input file>/usr/local/lib/X11/mini-icons/mini-folder.xpm</input>
            <action type=\"launch\">DLG_CHOOSER</action>
           </button>
          </hbox>
          <entry>
           <variable>ACCESS_FOLDER_PATH</variable>
           <input file>/tmp/easy_containers/entry-EC_ACCESS_FOLDER_PATH</input>
          </entry>
         </frame>
         <hbox>
          <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELPenv</action></button>
         </hbox>
        </vbox>
        <vbox>
         <frame $(gettext 'Capabilities')>
          <text><label>$(gettext 'Drop:')</label></text>
          <checkbox><variable>CAP_system</variable><label>system</label><input file>/tmp/easy_containers/chkbx-EC_CAP_system</input></checkbox>
          <checkbox><variable>CAP_file</variable><label>file</label><input file>/tmp/easy_containers/chkbx-EC_CAP_file</input></checkbox>
          <checkbox><variable>CAP_network</variable><label>network</label><input file>/tmp/easy_containers/chkbx-EC_CAP_network</input></checkbox>
          <checkbox><variable>CAP_module</variable><label>module</label><input file>/tmp/easy_containers/chkbx-EC_CAP_module</input></checkbox>
          <checkbox><variable>CAP_resource</variable><label>resource</label><input file>/tmp/easy_containers/chkbx-EC_CAP_resource</input></checkbox>
          <hbox>
           <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELPcap</action></button>
          </hbox>
         </frame>
        </vbox>
        <vbox>
         <frame $(gettext 'Namespaces')>
          <text><label>$(gettext 'Unshare:')</label></text>
          <checkbox><variable>NS_MOUNT</variable><label>mount</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_MOUNT</input></checkbox>
          <checkbox><variable>NS_UTS</variable><label>UTS</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_UTS</input></checkbox>
          <checkbox><variable>NS_IPC</variable><label>IPC</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_IPC</input></checkbox>
          <checkbox><variable>NS_NETWORK</variable><label>network</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_NETWORK</input></checkbox>
          <checkbox><variable>NS_PID</variable><label>PID</label><input file>/tmp/easy_containers/chkbx-EC_NS_UNSHARE_PID</input></checkbox>
          <hbox>
           <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELPns</action></button>
          </hbox>
         </frame>
        </vbox>
        <vbox>
         <frame $(gettext 'X server')>
          <radiobutton><variable>XSERVER_XORG</variable><label>Xorg</label><input file>/tmp/easy_containers/chkbx-XSERVER_XORG</input></radiobutton>
          <radiobutton><variable>XSERVER_XEPHYR</variable><label>Xephyr</label><input file>/tmp/easy_containers/chkbx-XSERVER_XEPHYR</input></radiobutton>
         </frame>
         <frame $(gettext 'X socket')>
          <radiobutton><variable>XSOCKET_ABSTRACT</variable><label>Abstract</label><input file>/tmp/easy_containers/chkbx-XSOCKET_ABSTRACT</input></radiobutton>
          <radiobutton><variable>XSOCKET_PIPE</variable><label>Pipe</label><input file>/tmp/easy_containers/chkbx-XSOCKET_PIPE</input></radiobutton>
          <radiobutton><variable>XSOCKET_UNIX</variable><label>Unix</label><input file>/tmp/easy_containers/chkbx-XSOCKET_UNIX</input></radiobutton>
         </frame>
         <hbox>
          <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELPxorg</action></button>
         </hbox>
        </vbox>
       </hbox>
      </vbox>
     </notebook>
    </frame>
    
    
    <text><label>$(gettext 'Choose an application to run in a container:')</label></text>
    <hbox>
      <comboboxtext>
        <variable>EC_CREATE</variable>
        <input file>/tmp/easy_containers/apps-list</input>
        <action>set_defaults_func \$EC_CREATE</action>
        <action>refresh:ENV_VARS</action>
        <action>refresh:ENV_ZEUS</action>
        <action>refresh:ACCESS_NET</action>
        <action>refresh:ACCESS_SND</action>
        <action>refresh:ACCESS_FOLDER</action>
        <action>refresh:ACCESS_FOLDER_PATH</action>
        <action>refresh:NS_MOUNT</action>
        <action>refresh:NS_UTS</action>
        <action>refresh:NS_IPC</action>
        <action>refresh:NS_NETWORK</action>
        <action>refresh:NS_PID</action>
        <action>refresh:XSERVER_XEPHYR</action>
        <action>refresh:XSERVER_XORG</action>
        <action>refresh:XSOCKET_ABSTRACT</action>
        <action>refresh:XSOCKET_PIPE</action>
        <action>refresh:XSOCKET_UNIX</action>
        <action>refresh:CAP_system</action>
        <action>refresh:CAP_file</action>
        <action>refresh:CAP_network</action>
        <action>refresh:CAP_module</action>
        <action>refresh:CAP_resource</action>
        <action>refresh:CAP_mount</action>
      </comboboxtext>
      <button>
        <label>$(gettext 'Create')</label>
        <action>exit:create</action>
      </button>
    </hbox>
  </frame>
  
  <hbox>
    <button><label>$(gettext 'Exit')</label><action>exit:quit</action></button>
    <button><input file>/usr/local/lib/X11/mini-icons/mini-question.xpm</input><action type=\"launch\">DLG_HELP1</action></button>
  </hbox>
</vbox>
</window>"

RETSTRING1="$(gtkdialog --program=EC_DLG1 --center)"
[ $? -ne 0 ] && exit
eval "$RETSTRING1"

if [ "$EXIT" == "delete" ];then
 pupdialog --backtitle "$(gettext 'Easy Containers: delete')" --yesno "$(gettext 'Confirm whether you want to delete. This folder and all of the contents will be deleted:')
 /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_MANAGE}" 0 0
 if [ $? -eq 0 ];then
  #180409 if container currently running, must stop it...
  #note, same code in /usr/bin/wmreboot, etc.
  if [ "$(mount | grep "/containers/${EC_MANAGE}/container")" != "" ];then
   /usr/local/easy_containers/stop-container ${EC_MANAGE}
   sleep 0.5
  fi
  
  rm -rf /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_MANAGE}
  rm -f /usr/share/pixmaps/ec-${EC_MANAGE}48.png 2>/dev/null
  rm -f /usr/share/applications/ec-${EC_MANAGE}.desktop 2>/dev/null
  sync
  
  #180407 remove icon from desktop...
  #remove globicon, got code from /etc/rc.d/functions4puppy4 icon_remove_func()
  echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <UnsetIcon>
   <Path>/usr/sbin/ec-chroot-${EC_MANAGE}</Path>
  </UnsetIcon>
 </env:Body>
</env:Envelope>"  | rox -R
  #pinboard remove...
  echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <PinboardRemove>
   <Path>/usr/sbin/ec-chroot-${EC_MANAGE}</Path>
  </PinboardRemove>
 </env:Body>
</env:Envelope>"  | rox -R
  
  #now update the jwm menu...
  cd /
  fixmenus
  jwm -reload
  pupdialog --timeout 5 --background '#80FF80' --backtitle "$(gettext 'Deleted:') ${EC_DELETE}" --msgbox "$(gettext 'The container has been deleted')" 0 0
 else
  pupdialog --timeout 5 --background '#80C080' --backtitle "$(gettext 'Deletion canceled')" --msgbox "$(gettext 'You have chosen not to delete the container')" 0 0
 fi
fi

if [ "$EXIT" == "create" ];then
 
 #180429 find out if user-installed pkg... #181029 revert...
 M_user1=""
# INBUILTflg="$(echo "$xAPPSLIST1" | grep -w "$EC_CREATE")"
# if [ "$INBUILTflg" == "" ];then
#  M_user1="
#
#\Zb$(gettext 'NOTICE:')\ZB
#$(gettext 'This application is user-installed, not builtin to easy.sfs, hence will not automatically be available in a container.')
#$(gettext 'To remedy this, the application will be copied into the read-write layer, the .session folder, of the new container. The thing to be aware of, is do not erase the session folder, as it will also erase the application.')"
# fi
 
 pupdialog --colors --backtitle "$(gettext 'Easy Containers: create')" --yesno "$(gettext 'Confirm whether you want to create a container. This folder will be created:')
 /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}${M_user1}" 0 0
 if [ $? -eq 0 ];then
  #create skeleton folders/files for container...
  mkdir /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}
  mkdir /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.session #rw layer
  mkdir /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.ro0
  mkdir /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.work
  mkdir /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/container
  echo '#Information for setting up and running the container' > /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  
  #write security options to configuration file...
  echo "
#Connect to X by abstract socket, pipe or unix domain socket (abstract|pipe|unix)..." >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  [ "$XSOCKET_ABSTRACT" == "true" ] && echo "EC_XSOCKET='abstract'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  [ "$XSOCKET_PIPE" == "true" ] && echo "EC_XSOCKET='pipe'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  [ "$XSOCKET_UNIX" == "true" ] && echo "EC_XSOCKET='unix'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "#Use Xorg or Xephyr server (xorg|xephyr)..." >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  [ "$XSERVER_XEPHYR" == "true" ] && echo "EC_XSERVER='xephyr'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  [ "$XSERVER_XORG" == "true" ] && echo "EC_XSERVER='xorg'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  #namespaces...
  echo '
#For security, unshare these namespaces:' >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_NS_UNSHARE_MOUNT='${NS_MOUNT}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_NS_UNSHARE_UTS='${NS_UTS}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_NS_UNSHARE_IPC='${NS_IPC}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_NS_UNSHARE_NETWORK='${NS_NETWORK}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_NS_UNSHARE_PID='${NS_PID}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  #echo "EC_NS_UNSHARE_USER='${NS_USER}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  #environment...
  echo '
#Clear environment variables, except some such as TERM and DISPLAY:' >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_UNSHARE_ENV_VARS='${ENV_VARS}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
echo '#Tick to run as user zeus in container:' >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_ENV_ZEUS='${ENV_ZEUS}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  #181002 access...
  echo '
#Specify what you are allowed to access outside the container:' >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_ACCESS_NET='${ACCESS_NET}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_ACCESS_SND='${ACCESS_SND}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_ACCESS_FOLDER='${ACCESS_FOLDER}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_ACCESS_FOLDER_PATH='${ACCESS_FOLDER_PATH}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  #capabilities...
  echo '
#Drop these Linux capabilities:' >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_system='${CAP_system}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_file='${CAP_file}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_network='${CAP_network}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_module='${CAP_module}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_resource='${CAP_resource}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  echo "EC_CAP_mount='${CAP_mount}'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  
  echo "
#if you want to load another .sfs file, resident in the releases folder of the
#current version of Easy, for example: releases/easy-0.1.6/devx.sfs
#then uncomment this. Glob wildcard accepted, in fact is recommended
#for automatic version updating:
#EASY_LAYER_RO1='devx*.sfs'" >> /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/configuration
  
  #finish creating the container...
  /usr/local/easy_containers/setup-container ${EC_CREATE}
  
#  if [ "$INBUILTflg" == "" ];then #180429  181029 revert.
#   #find pkg list, copy files...
#   FNDfl=''
#   FNDdt="$(grep -l "^Exec=.*${EC_CREATE}$" /usr/share/applications/*.desktop)"
#   [ "$FNDdt" ] && FNDfl="$(grep -l "${FNDdt}" /root/.packages/*.files)" #ex: /root/.packages/firefox-45.9.0esr-r0.files
#   if [ "$FNDfl" == "" ];then
#    pupdialog --timeout 5 --background '#80C080' --backtitle "$(gettext 'Creation canceled')" --msgbox "$(gettext 'Sorry, unable to locate the file-list for the installed package. Aborting.')" 0 0
#    exit
#   else
#    #this is a hack, make sure get all deps...
#    Mpw="$(gettext 'Please wait, copying package into container...')"
#    popup "level=top background=#FFFF80|<big>${Mpw}</big>"
#    for aFL in `find /root/.packages -maxdepth 1 -type f -name '*.files'`
#    do
#     for aFILE in `cat $aFL`
#     do
#      if [ -e "$aFILE" ];then
#       if [ ! -d "$aFILE" ];then
#        aPTH="$(dirname "$aFILE")"
#        mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.session"${aPTH}"
#        cp -a -f --remove-destination "$aFILE" /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.session"${aPTH}"/
#       else
#        mkdir -p /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/.session"${aFILE}"
#       fi
#      fi
#     done
#     sync
#    done
#    killall popup
#   fi
#  fi
  
  #want to modify the jwm menu, to run app in container...
  #first, find the .desktop file...
  DTFILE="$(grep "^Exec=${EC_CREATE}" /usr/share/applications/*.desktop | cut -f 1 -d ':' | head -n 1 | rev | cut -f 1 -d '/' | rev)"
  cp -f /usr/share/applications/${DTFILE} /usr/share/applications/ec-${EC_CREATE}.desktop
  sed -i -e "s%^Exec=[^ ]*%Exec=ec-chroot ${EC_CREATE}%" /usr/share/applications/ec-${EC_CREATE}.desktop
  
  #now modify the icon...
  #170221 pngoverlay wants base and overlay the same size. remove this, just use a standard icon...
  #ICON="$(grep '^Icon=' /usr/share/applications/ec-${EC_CREATE}.desktop | cut -f 2 -d '=')"
  #[ -f "$ICON" ] && fndICON="$ICON"
  #[ ! "$fndICON" ] && [ -f /usr/share/pixmaps/$ICON ] && fndICON="/usr/share/pixmaps/$ICON"
  #[ ! "$fndICON" ] && [ -f /usr/local/lib/X11/mini-icons/$ICON ] && fndICON="/usr/local/lib/X11/mini-icons/$ICON"
  #[ ! "$fndICON" ] && [ -f /usr/local/lib/X11/pixmaps/$ICON ] && fndICON="/usr/local/lib/X11/pixmaps/$ICON"
  #[ ! "$fndICON" ] && fndICON="/usr/local/lib/X11/mini-icons/Executable.xpm" #fallback.
  #IMGTYPE="$(echo -n "$fndICON" | rev | cut -f 1 -d '.' | rev)" #ex: xpm
  #IMGBASE="$(basename "${fndICON}" .${IMGTYPE})"
  #cp -f "$fndICON" /tmp/easy_containers/
  #cd /tmp/easy_containers
  #[ "$IMGTYPE" == "xpm" ] && xpmtoppm ${IMGBASE}.${IMGTYPE} | pnmtopng > ${IMGBASE}.png
  #cp -f /usr/sbin/pngoverlay ./
  #cp -f /usr/local/lib/X11/pixmaps/container-overlay48.png ./
  #sync
  #./pngoverlay ${IMGBASE}.png container-overlay48.png /usr/share/pixmaps/ec-${EC_CREATE}.png
  #sed -i -e "s%^Icon=.*%Icon=ec-${EC_CREATE}.png%" /usr/share/applications/ec-${EC_CREATE}.desktop
  ICON="$(grep '^Icon=' /usr/share/applications/ec-${EC_CREATE}.desktop | cut -f 2 -d '=')" #180407
  sed -i -e "s%^Icon=.*%Icon=container48.png%" /usr/share/applications/ec-${EC_CREATE}.desktop
  
  #180407 want to create desktop icons for containerized apps...
  #note, pre-created (seamonkey, sh0) already on desktop, refer rootfs-skeleton/root/Choices/ROX-Filer/PuppyPin and globicons
  #  these pre-created are from boot/initrd-tree/skeleton, init script copies into wkg-partition.
  #find a free space on desktop...
  #  note, there is free_coord() in /usr/local/easy_containers/frontend_funcs, but just do it roughly here...
  for aY in 128 224 320
  do
   for aX in 672 736
   do
    aPTN="x=\"${aX:0:2}[0-9]\" y=\"${aY:0:2}[0-9]\""
    grep "$aPTN" /root/Choices/ROX-Filer/PuppyPin > /dev/null
    [ $? -ne 0 ] && break 2
   done
  done
  #...aX and aY are free coordinates.
  #globicon...
  #create the icon...
  if [ ! -f /usr/share/pixmaps/ec-${EC_CREATE}48.png ];then
   PWD=`pwd`
   fndICON=''
   [ ! "$ICON" ] && ICON=zzzzzzzz
   [ -f "$ICON" ] && fndICON="$ICON"
   #[ ! "$fndICON" ] && [ -f ${ICON}.png ] && fndICON="${ICON}.png"
   [ ! "$fndICON" ] && fndICON="$(find /usr/share/icons/hicolor/48x48/apps -maxdepth 1 -type f -name "${ICON}*" | head -n 1)" #181016
   [ ! "$fndICON" ] && [ -f /usr/share/pixmaps/$ICON ] && fndICON="/usr/share/pixmaps/$ICON"
   [ ! "$fndICON" ] && [ -f /usr/local/lib/X11/mini-icons/$ICON ] && fndICON="/usr/local/lib/X11/mini-icons/$ICON"
   [ ! "$fndICON" ] && [ -f /usr/local/lib/X11/pixmaps/$ICON ] && fndICON="/usr/local/lib/X11/pixmaps/$ICON"
   [ ! "$fndICON" ] && fndICON="/usr/share/icons/Adwaita/scalable/mimetypes/application-x-executable-symbolic.svg" #fallback.
   IMGTYPE="$(echo -n "$fndICON" | rev | cut -f 1 -d '.' | rev)" #ex: xpm
   IMGBASE="$(basename "${fndICON}" .${IMGTYPE})"
   cp -L -f "$fndICON" /tmp/easy_containers/
   cd /tmp/easy_containers
   if [ "$IMGTYPE" == "xpm" ];then
    #xpmtoppm ${IMGBASE}.${IMGTYPE} | pnmtopng > ${IMGBASE}.png
    xpmtoppm --alphaout=alpha.img ${IMGBASE}.${IMGTYPE} > body.img
    pnmscale -xysize 48 48 alpha.img > alpha48.img
    pnmscale -xysize 48 48 body.img > body48.img
    pnmtopng -alpha=alpha48.img body48.img > ${IMGBASE}.png
   fi
   [ "$IMGTYPE" == "svg" ] && rsvg-convert --width=48 --height=48 --format=png ${IMGBASE}.${IMGTYPE} > ${IMGBASE}.png
   if [ ! -f ${IMGBASE}.png ];then
    rsvg-convert --width=48 --height=48 --format=png /usr/share/icons/Adwaita/scalable/mimetypes/application-x-executable-symbolic.svg > ${IMGBASE}.png
   fi
   cp -f /usr/sbin/pngoverlay ./
   cp -f /usr/local/lib/X11/pixmaps/ec-overlay48.png ./
   sync
   ./pngoverlay ${IMGBASE}.png ec-overlay48.png /usr/share/pixmaps/ec-${EC_CREATE}48.png
   cd $PWD
   #181006 backup icon, may need it, see ec-fix-desktop...
   cp -a -f /usr/share/pixmaps/ec-${EC_CREATE}48.png /mnt/${WKG_DEV}/${WKG_DIR}containers/${EC_CREATE}/
  fi
  #globicons, note, got code from /etc/rc.d/functions4puppy4...
  echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <SetIcon>
   <Path>/usr/sbin/ec-chroot-${EC_CREATE}</Path>
   <Icon>/usr/share/pixmaps/ec-${EC_CREATE}48.png</Icon>
  </SetIcon>
 </env:Body>
</env:Envelope>"  | rox -R
  #now create an icon on desktop...
  #181014 this has stopped working when launch from desktop icon...
  #echo -e "#!/bin/sh\nexec ec-chroot ${EC_CREATE}" > /usr/sbin/ec-chroot-${EC_CREATE}
  #need to launch via "urxvt -name eclaunch -iconic ..." which is hidden (see /root/.jwmrc)
  #181017 now use 'empty' instead of urxvt...
  echo "#!/bin/sh
empty -f ec-chroot ${EC_CREATE}" > /usr/sbin/ec-chroot-${EC_CREATE}
  chmod 755 /usr/sbin/ec-chroot-${EC_CREATE}
  #  note, frontend_funcs has add_pinboard_func(), use code from it...
  echo "<?xml version=\"1.0\"?>
<env:Envelope xmlns:env=\"http://www.w3.org/2001/12/soap-envelope\">
 <env:Body xmlns=\"http://rox.sourceforge.net/SOAP/ROX-Filer\">
  <PinboardAdd>
   <Path>/usr/sbin/ec-chroot-${EC_CREATE}</Path>
   <X>${aX}</X>
   <Y>${aY}</Y>
   <Label>${EC_CREATE}</Label>
   <Args></Args>
  </PinboardAdd>
 </env:Body>
</env:Envelope>"  | rox -R
  
  #180409 log, read by ec-fix-desktop... 180428
  echo "EC_LABEL=${EC_CREATE}
EC_PATH=/usr/sbin/ec-chroot-${EC_CREATE}
EC_ICON=/usr/share/pixmaps/ec-${EC_CREATE}48.png" > /mnt/wkg/containers/${EC_CREATE}/desktop
  
  #now update the jwm menu...
  cd /
  fixmenus
  jwm -reload
  pupdialog --timeout 5 --background '#80FF80' --backtitle "$(gettext 'Creation completed')" --msgbox "$(gettext 'Container created, menu entry created, and icon on the desktop')" 0 0
 else
  pupdialog --timeout 5 --background '#80C080' --backtitle "$(gettext 'Creation canceled')" --msgbox "$(gettext 'You have chosen not to create the container')" 0 0
 fi
fi
