#! /bin/bash
#
# Copyright 2022 Nio Wiklund
#
# GPLv3: GNU GPL version 3
# <http://gnu.org/licenses/gpl.html>.
#
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
#-----------------------------------------------------------------------------
# author sudodus alias nio-wiklund at launchpad
#
# date        editor   comment
# 2016-10-21  sudodus  created dus 'do usb stuff'
# 2016-11-14  sudodus  version 0.0.2
# 2016-12-29  sudodus  version 12.0.0 - mkusb-dus version 12
# 2016-12-31  sudodus  removed 'double dus' in two window titles
# 2016-12-31  sudodus  version 12.0.1
# 2017-01-23  sudodus  function p_cal1: sudo password better at start
# 2017-01-25  sudodus  dus no longer asks for usb-pack-efi but
#                      dus-persistent does, and with improved logic
# 2017-01-25  sudodus  version 12.0.2
# 2017-01-31  sudodus  dus-persistent: label=usbboot for partition #3
# 2017-01-31  sudodus  version 12.0.3
# 2017-02-11  sudodus  modified p_checkpoint: 'src_orig='
#                      to make it easy to change the source file
#                      guidus.desktop and mkusb.desktop: added %f
#                      mkusb-start: "$@" to transfer source file as parameter
# 2017-02-11  sudodus  version 12.0.4
# 2017-02-11  sudodus  deb preinst & postinst to upgrade from 'pre-12' versions
# 2017-02-11  sudodus  version 12.0.5
# 2017-03-15  sudodus  mkusb-select: made to print versions directly with -v
#                      mkusb.8: The manual made up to date
# 2017-03-15  sudodus  version 12.0.6
# 2017-03-16  sudodus  mkusb.8: modified
# 2017-03-16  sudodus  version 12.0.7
# 2017-03-29  sudodus  dus-live, dus-persistent, mkusb-11 modified
# 2017-03-29  sudodus  version 12.0.8
# 2017-04-02  sudodus  p_list_drives: skipping floppy: grep -v -e ^zram -e ^fd
# 2017-04-02  sudodus  version 12.0.9
# 2017-04-27  sudodus  p_source: lsblk -Jo ... --> pcalx lsblk -Po ... 
# 2017-04-27  sudodus  version 12.1.0
# 2017-04-30  sudodus  dus-persistent: fixes for 17.04
# 2017-04-30  sudodus  version 12.1.1
# 2017-05-01  sudodus  dus-persistent: fix for 17.04 modified (not for 12.04)
# 2017-05-01  sudodus  version 12.1.2
# 2017-05-05  sudodus  p_persistent: suggest to select an iso file for dus-persistent
#                      or try to clone if an image file.
# 2017-05-05  sudodus  version 12.1.3
# 2017-05-05  sudodus  ${source/.iso} --> ${source%.iso}   # fixes for some
#                      ${source/.img} --> ${source%.img}   # unusual file names
#                      ${source/.img.[gx]z} --> ${source%.img.[gx]z}
# 2017-05-05  sudodus  version 12.1.4
#                      backup and restore: debugged and improved a lot
#                      by testing extensively in a persistent pendrive
# 2017-05-10  sudodus  version 12.1.5
# 2017-05-16  sudodus  dus-persistent: function menu_package_installer: ask to
#                      update & upgrade only installed systems (not live)
# 2017-05-16  sudodus  version 12.1.6
# 2017-05-18  sudodus  dus: p_need_pck mkfs.vfat "package dosfstools" (for debian)
# 2017-05-18  sudodus  version 12.1.7
# 2017-05-19  sudodus  dus: separate function usage called directly if '-h'
# 2017-05-19  sudodus  dus: function p_checkpoint: --defaultno for the 'dialog' menu
# 2017-05-19  sudodus  dus: function p_chk_programs: improved logic to ask for
# 2017-05-19  sudodus  zenity and dialog in text mode 
# 2017-05-19  sudodus  version 12.1.8
# 2017-05-21  sudodus  checking for 'overlay': device name for live root clonezilla
# 2017-05-21  sudodus  version 12.1.9
# 2017-05-29  sudodus  dus modified for knoppix in
# 2017-05-29  sudodus  function  p_list_drives and function p_ldr 
# 2017-05-29  sudodus  version 12.2.0
# 2017-05-31  sudodus  dus-persistent: tweaks to work with "9w-debian-wheezy"
# 2017-06-01  sudodus  dus: p_need_pck_s mkfs.ntfs "package ntfs-3g" (for debian)
# 2017-06-01  sudodus  version 12.2.1
# 2017-06-07  sudodus  p_cal1, p_call, p_calx: no sudo when running as root
# 2017-06-07  sudodus  dus-persistent: tweaks to work with "9w-debian-jessie"
# 2017-06-07  sudodus  version 12.2.2
# 2017-06-23  sudodus  dus-persistent: tweaks for debian 9 (currently 'stretch')
# 2017-06-23  sudodus  version 12.2.3
# 2017-06-28  sudodus  mkusb-bas alias mkusb version 7.4.3:
# 2017-06-28  sudodus   tweaked to recognize and run from TahrPup
# 2017-06-28  sudodus   FINAL WARNING ---> Final checkpoint
# 2017-06-28  sudodus  version 12.2.4
# 2017-06-28  sudodus  version 12.2.4
# 2017-07-22  sudodus  mkusb-start: bugfixes to make it work correctly with mkusb-11
#                      if [ "$@" != "" ] --> if [ "$*" != "" ]
#                      logical variable nopsw introduced
# 2017-07-22  sudodus  version 12.2.5
# 2017-08-27  sudodus  dus-persistent: tweaks to work with extix debian
# 2017-08-27  sudodus  version 12.2.6
# 2017-08-27  sudodus  dus-persistent: function partitioner: 'grubimg' added
#                      extracting from the file 'grub.img.xz' to clone head
#                      and partitions 2 and 3 with grub for BIOS mode when
#                      running in an installed system in UEFI mode
# 2017-08-27  sudodus  version 12.2.7
# 2017-09-21  sudodus  dus-live: function partition_msdos_fat: extracting
#                      from the file 'grub4win.img.xz' to clone the head
#                      and the partition with grub for BIOS mode when
#                      running in an installed system in UEFI mode
# 2017-09-21  sudodus  version 12.2.8
# 2017-10-02  sudodus  dus-persistent: removed redundant 'echo' output about 'grubimg'
# 2017-10-02  sudodus  version 12.2.9
# 2018-03-10  sudodus  dus dus-persistent mkusb-start:
#                      zenity window sizes fixed for Ubuntu Bionic
# 2018-03-10  sudodus  version 12.3.0
# 2018-04-22  sudodus  dus:
#                      zenity window sizes fixed for Ubuntu Bionic (more)
# 2018-04-22  sudodus  version 12.3.1
# 2018-05-28  sudodus  dus-home-backup and dus-home-restore in starter menu
#                      and mkusb-backup-n-restore-home symbolic link
# 2018-05-28  sudodus  version 12.3.2
# 2019-10-11  sudodus  p_starter: text mode read command updated
#                      dus-persistent: upefi for debian buster
# 2019-10-11  sudodus  version 12.3.3
# 2019-10-23  sudodus  dus-persistent: added delays at 'tweak 3 grub.cfg'
# 2019-10-23  sudodus  version 12.3.4
# 2019-11-01  sudodus  p_target: warning if target size>sizwarn (now 128 GB)
# 2019-11-01  sudodus  version 12.3.5
# 2019-11-02  sudodus  p_target: warning if target size >= sizwarn (now 60 GB)
#                      black and white warning text
# 2019-11-02  sudodus  version 12.3.6-1ubuntu1
# 2019-11-02  sudodus  p_target: warning if target size >= sizwarn (now 60 GB)
#                      red warning text
# 2019-11-02  sudodus  version 12.3.6-1ubuntu2
# 2019-11-09  sudodus  dus-persistent: new menuentry with toram nopersistent
# 2019-11-09  sudodus  grub.cfg: new menuentry with toram nopersistent
# 2019-11-09  sudodus  version 12.3.7
# 2019-11-16  sudodus  modifications for nvme drives (alongside mmcblk)
# 2019-11-16  sudodus  version 12.3.8
# 2019-12-09  sudodus  dus: new functions p_langC p_langR that set and reset
#                      the environment variables LANG and LC_ALL which are
#                      used when the local language creates problems
# 2019-12-09  sudodus  version 12.3.9
# 2020-02-06  sudodus  p_lisdz: quoting array variables, kudos to 
# Jonathan Starnes's patch in https://bugs.launchpad.net/mkusb/+bug/1731359
# 2020-02-06  sudodus  version 12.4.0
# 2020-02-07  sudodus  dus-persistent & dus-restore: parted set partition type FAT32
# 2020-02-07  sudodus  version 12.4.1
# 2020-02-09  sudodus  p_menudz: wider menus for zenity and dialog
#                      p_target: red warning about size also for dialog and text
#                      p_list: line 1294: redirected error output to /dev/null
#                      mkusb-select: added menu entry for mkusb-plug
# 2020-02-09  sudodus  version 12.4.2
# 2020-03-03  sudodus  mkusb-plug: mkusb-sedd: puer: select label depending on
#                      Ubuntu version (to cater for 'writable' in Focal Fossa)
# 2020-03-03  sudodus  version 12.4.3
# 2020-03-14  sudodus  dus-persistent: grub-n-iso: label for persistence in
#                      focal fossa 'writable'
# 2020-03-14  sudodus  version 12.4.4
# 2020-04-16  sudodus  backup and restore: 'live-rw' --> 'writable' and
#                      getcnt and getdrw: fix to work with mmcblk devices
# 2020-04-17  sudodus  backup and restore: minor bugfixes after testing
# 2020-04-18  sudodus  debian/control: depends: mkusb-common (>= 12.4.5)
#                      debian/update-control: depends updated 'automatically'
# 2020-04-18  sudodus  version 12.4.5
# 2020-04-28  sudodus  grub.cfg and dus-persistent: menu_entry_1:
#                      tweaks for boot option 'maybe-ubiquity'
#                      to manage language setting
# 2020-04-28  sudodus  version 12.4.6
# 2020-04-29  sudodus  grub.cfg and dus-persistent: menu_entry_1:
#                      to manage 'fsck.mode=skip' to check the live system
#                      integrity in presistent live menu entries
# 2020-04-28  sudodus  version 12.4.7
# 2020-05-03  sudodus  mkusb-plug: mkusb-sedd: puer: relies on automatic
#                      creation of partition for persistence by Ubuntu
# 2020-05-03  sudodus  version 12.4.9
# 2020-05-09  sudodus  dus-persistent: grub-n-iso:
#                      'grub-graph-prefix' to improve grub menu with the
#                      grub background file 'mkusb-grub-bg_800x600.png'
# 2020-05-09  sudodus  version 12.5.0
#                      dus-persistent: probe_source: recognizing
#                      Sparky Linux as Debian respin
# 2020-05-09  sudodus  version 12.5.1
# 2020-05-14  sudodus  manage two usb-pack-efi versions:
#                      added p_usb_pack_manage and p_usb_pack_toggle
#                      call p_usb_pack_manage from p_starter and p_setting
#                      dus-persistent: grub_n_iso:
#                      removed verbosity for extraction of usb-pack_efi
# 2020-05-14  sudodus  dus: p_usb_pack_manage and dus-persistent:
# 2020-05-14  sudodus  version 12.5.2
# 2020-05-16  sudodus  separate usb-pack_efi files for grub 2.02 and grub 2.04
#                      usb-pack_efi-x.tar.gz --> usb-pack_efi-x.tar.xz
#                      and corresponding grub-x.img.xz for better compression
#                      plus several tweaks with logical statements
#                      Improved help text in dus-persistent:
#                      "The image file 'grub.img.xz' is not found.
#                       - Please install the package 'usb-pack-efi' -
#                       or if it is installed, select it in the settings menu."
# 2020-05-16  sudodus  version 12.5.3
# 2020-05-19  sudodus  p_usb_pack_toggle: changed default 0 --> 1
#                      grub.cfg: changed logic detecting rmmod tpm and bootmode
#                      and changed text colours
#                      grub-graph-prefix: changed text colours
#                      mkusb-grub-bg_800x600.png: background with 'water-mark' 
# 2020-05-19  sudodus  version 12.5.4
# 2020-05-23  sudodus  dus-persistent: at tweak 3: setting search by UUID failed
#                      p_setting: new test for usb-pack-efi
# 2020-05-23  sudodus  version 12.5.5
# 2020-05-27  sudodus  dus-persistent: Silently select grub.img and usb-pack-efi,
#                      when running in an installed system in UEFI mode
#                      p_setting: activate p_usb-pack-manage when using grub-0.img.xz
# 2020-05-28  sudodus  p_winsel: select method to make Windows installer, the old
#                      method or the new mkusb-tow imported from mkusb-plug
# 2020-05-28  sudodus  version 12.5.6
# 2020-05-30  sudodus  dus-persistent: find_distr, chk4uefi:
#                      recognizing Sparky Linux as Debian respin when running
#                      p_chk_programs: using 'p_want_pck_s mkusb-tow ...'
#                      p_need_pck pv --> p_want_pck pv
#                      p_want_pck watch-flush
#                      dus-live & dus-persistent: using watch-flush via
#                      wf_prep & wf_cleanup
# 2020-05-30  sudodus  version 12.5.7
# 2020-06-28  sudodus  dus-wipe:
#                      added p_zentest, wf_prep, wf_cleanup to use watch-flush
# 2020-06-28  sudodus  version 12.5.8
#                      dus-live: mkcmd_runcmd: size also when cloning from block device
#                      watch-flush: fix if dirtorig = 0 to avoid division by zero
# 2020-09-06  sudodus  version 12.5.9
#                      dus-persistent: grub-n-iso: --no-same-owner added to tar command
#                      tar -xf "$mkusb_sdir"/usb-pack_efi.tar.xz --directory "$targ1"
#                      To make 'usb-pack-efi' work with secure boot with fix
#                      for the boothole bug there are new versions of the files
#                      usb-pack_efi-2.02.tar.xz and usb-pack_efi-2.04.tar.xz
# 2020-09-09  sudodus  version 12.6.0
# 2020-09-12  sudodus  if grubimg, do not extract from usb-pack_efi.tar.xz
#                      use the same image as grub-2.02.img.xz and grub-2.04.img.xz
#                      (not now, maybe later simplify the logic for grubimg)
# 2020-09-12  sudodus  version 12.6.1
# 2020-09-18  sudodus  dus & dus-*; variable font and window size of zenity
#                      new function: p_zensize where msiz percent sets the size
# 2020-09-18  sudodus  version 12.6.2
# 2020-09-23  sudodus  mkusb-plug: mkusb-sedd: puer, puer0:
#                      Workaround because of bug:
#                      https://bugs.launchpad.net/bugs/1895329 
# 2020-09-23  sudodus  version 12.6.3
# 2020-09-25  sudodus  added manual size for zenity font and window: p_zensize,
#                      new function p_zen_siz_select, new file "$HOME/.mkusb/fontsave",
#                      p_starter (new menu entry to manage the size of zenity windows
#                      and xterm console).
#                      dus-persistent & dus-home-backup: p_zensize
#                      mkusb-start & guidus.desktop: variable font in xterm
# 2020-09-25  sudodus  version 12.6.4
# 2020-10-02  sudodus  p_restore: removed <span ... because it does not work
# 2020-10-19  sudodus  dus-persistent: probe_source: usb-pack_efi auto-set for 20.10
#                      mkusb-plug:
#                      mkusb-sedd: puer, puer0: Workaround reverted
#                      (bug-fix for https://bugs.launchpad.net/bugs/1895329)
#                      srctst: Cannot to create data partition for version 20.10
# 2020-10-19  sudodus  version 12.6.5
# 2020-09-21  sudodus  dus-live: gpt_fix: added "-e 'Problem:'" to first grep command
# 2020-09-21  sudodus  mkusb-plug:
#                       mkusb-sedd: new functions gpt_fix, gpt_zap
#                        datp: using gpt_fix, gpt_zap (and partprobe)
#                       get_action and scrtst: no longer check to exclude 20.10
# 2020-09-21  sudodus  version 12.6.6
# 2021-01-08  sudodus  guidus: skip parameter if %f is '%f' (for hippo hirsute)
# 2021-01-08  sudodus  version 12.6.7
# 2021-01-22  sudodus  dus-live: mkcmd_runcmd:
#                      ... wait for the buffered data to get flushed ...
# 2021-01-22  sudodus  version 12.6.8
# 2021-02-03  sudodus  dus-persistent:
#                      grub_n_iso & probe_source: identifying 20.04.2 & 21.04
#                      probe_source: usb-pack_efi auto-set for 21.04
# 2021-02-03  sudodus  version 12.6.9
# 2021-07-29  sudodus  dus: p_checkpoint: full lsblk output to zenity
# 2021-07-29  sudodus  version 12.7.0
# 2021-08-18  sudodus  dus-persistent: probe_source:
#                      upefi [from now] always default for debian
# 2021-08-18  sudodus  version 12.7.1
# 2021-11-17  sudodus  quoted grep 'patterns'
# 2021-11-22  sudodus  version 12.7.2
# 2022-04-10  sudodus  control0: mkusb-plug: Recommends: pv, exfat-utils, exfatprogs
# 2022-04-10  sudodus  version 12.7.3
# 2022-04-19  sudodus  dus-persistent:
#                      apparmor.service.d/30_live_mode.conf: ConditionPathExists=
# 2022-04-19  sudodus  version 12.7.4
# 2022-05-02  sudodus  dus-persistent: probe_source: upefi=true and grubimg=true
#                      for newer than 20.04 iso files or 21.04 host systems
# 2022-05-02  sudodus  version 12.7.5
# 2022-05-11  sudodus  Added early version of dus-iso2usb (grub-n-iso) script.
#                      Not yet called by dus, only for testing in text mode.
# 2022-05-11  sudodus  version 22.0.1 (year based: 2022 ---> 22)
# 2022-05-15  sudodus  dus-iso2usb: added optional parameter #6 'boot-flag'
#                      in readparams, addparts
#                      plus extra warnings when large target drives
# 2022-05-15  sudodus  version 22.0.2
# 2022-05-17  sudodus  dus-iso2usb: copyiso: sleep to settle down to get syslbl
#                      dus (itself): new functions p_toolsel and p_seti2u
#                      to prepare settings for the script dus-iso2usb
# 2022-05-17  sudodus  version 22.0.3
# 2022-05-20  sudodus  p_seti2u: fixed other settings when msdos and/or boot-flag selected
# 2022-05-20  sudodus  version 22.0.4
# 2022-05-20  sudodus  dus-iso2usb: add_parts: if statement for boot-flag
#                      also when live-only (alias not persistent)
# 2022-05-20  sudodus  version 22.0.5
# 2022-05-23  sudodus  dus-iso2usb: read_params: warning and question
#                      if the source is not an Ubuntu [flavour] iso file
#                      p_zentest and p_checkpoint added (to dus-iso2usb)
#                      p_toolsel: p_clean and return after call of dus-iso2usb
#                      p_checkpoint: extra question 'Are you sure ?' in text mode
# 2022-05-23  sudodus  version 22.0.6
# 2022-06-03  sudodus  p_toolsel: cleaner return after p_live and p_persistent
#                      dus-iso2usb: read_params, p_checkpoint:
#                      fine-tuned output to terminal window
# 2022-06-03  sudodus  version 22.0.7
# 2022-06-09  sudodus  dus.8 (and mkusb.8) for man dus & man mkusb updated
# 2022-08-26  sudodus  dus-iso2usb: syslbl="Not Ubuntu 19." when not Ubuntu
# 2022-08-26  sudodus  version 22.0.8
# 2022-09-03  sudodus  upgrade of mkusb-nox:
#                      1. made more convenient for isotesting with SSD drives
#                      which are seen as ATA even when connected via USB
#                      2. pv replaced by dd options (takes care of sync too)
#                      status=progress oflag=dsync and bs modified to 1M
#                      3. discouraging text when creating Windows installer
#                      4. protecting source when a block device (bugfix)
# 2022-09-03  sudodus  version 22.0.9
# 2022-09-08  sudodus  mkusb-nox: added inverse video and lsblk output to help
#                      identify the target device
# 2022-09-08  sudodus  mkusb-nox version 22.1.0
# 2022-09-13  sudodus  dus-iso2usb: redbacks when errors causing exit
# 2022-09-13  sudodus  p_toolsel: print command line for dus-iso2usb
# 2022-09-13  sudodus  version 22.1.1
# 2022-09-14  sudodus  1. several fixes of zenity window sizes
#                      2. p_ldr: set livedrive in system made by dus-iso2usb
#                         which is a grub-n-iso system with isodevice
#                      3. copyright updated
# 2022-09-14  sudodus  version 22.1.2
# 2022-10-22  sudodus  p_source: added p_sniff with sub-functions for crude
#                      estimate of possible mkusb tools/methods to create
#                      persistent live drive from the selected iso file
# 2022-10-22  sudodus  version 22.2.0
# 2022-10-22  sudodus  minor bugfixes detected after p_sniff was added
#                      p_toolsel: correct letters "(i/l/q)" for text mode,
#                                 that is when "$manager" == "t"
#                      p_sniff: zenity window when "$manager" == "z"
#                               and dialog paused when "$manager" == "d"
# 2022-10-22  sudodus  version 22.2.1
# 2022-10-23  sudodus  minor bugfixes detected after p_sniff was added
#                      p_snff: sudo --> p_calx
# 2022-10-23  sudodus  version 22.2.2
# 2022-10-23  sudodus  p_sniff: return when source not an iso file
# 2022-10-23  sudodus  version 22.2.3
# 2022-10-25  sudodus  p_sniff: added kaisen to array dist_plug
#                      waiting for more edits, so not yet uploaded ...
# 2022-12-24  sudodus  version 22.2.4
# 2023-02-07  sudodus  dus-iso2usb:
#                      increased size of partition for iso file 5G --> 7G
# 2023-02-07  sudodus  version 23.0.1
# 2023-04-21  sudodus  dus-iso2usb: read_params, tweak_grub:
#                      check for 'layerfs' in grub in the iso file,
#                      when found modify the linux-line to match the
#                      boot structure of the new installer
# 2023-04-21  sudodus  version 23.1.0
# 2023-04-21  sudodus  dus-persistent: probe_source, grub_n_iso tweak 5:
#                      check for 'layerfs' in grub in the iso file,
#                      when found modify the linux-line to match the
#                      boot structure of the new installer
# 2023-04-21  sudodus  version 23.1.1
# 2023-05-13  sudodus  dus-iso2usb: read_params: minor fix to improve output
#                      when target drive size >= 128GB
# 2023-05-13  sudodus  version 23.1.2
# 2023-06-12  sudodus  p_snff & p_sniff: Modifications to show that only
#                      mkusb-plug works well to make persistent live drives
#                      with Debian 12 (drives by dus-persistent work only
#                      in UEFI mode)
# 2023-06-12  sudodus  version 23.1.3
# 2023-06-14  sudodus  dus-persistent: partitioner:
#                       if [ "$part_type" == "gpt" ] then use template to avoid
#                       mismatch with grub versions > 2.04 (only workaround, new
#                       version of grub should be added to mkusb)
#                      p_sniff: Modification to show that also dus-persistent
#                       works well to make persistent live drives with Debian 12
# 2023-06-14  sudodus  version 23.1.4
#                      p_usb_pack_manage: or (not and) condition for updating
#                       usb-pack and grub image (fixing old bug)
# 2023-06-14  sudodus  version 23.1.5

version="${0##*/} 23.1.5"

inversvid="\0033[7m"
resetvid="\0033[0m"
redback="\0033[1;37;41m"
greenback="\0033[1;37;42m"
blueback="\0033[1;37;44m"
logoansi="\0033[38;5;0;48;5;148m"
logorgb="'#afd700'"
ans=
pff=
cmf=
source=
par_org=
src_orig=
list01=
target=
livedrive=
sdrive=
infstb=false
separator='-------------------------------------------------------------------------------'
curdir="$(pwd)"
curlang="$LANG"
curlc_all="$LC_ALL"
#LANG=C
#LC_ALL=C
manager=
want_pck=
choice="$curdir"
sizwarn=60  # GB -- warning if target has this size or bigger

fontsave="$HOME/.mkusb/fontsave"  # setting for zenity window size and font
fontchar=auto
declare -i fontsize=0
mfnt=
msiz=
zniff=false

# workaround for non ascii characters in path/filename: works but not used
# echo "$cmdline"|grep -P "[\x80-\xFF]" && nonascii=true || nonascii=false

lng0=$LANG
lca0=$LC_ALL

########################################################################

function p_langR { LANG=$lng0; LC_ALL=$lca0; }
########################################################################

function p_langC { LANG=C; LC_ALL=C; }
########################################################################

function about {

btitle="About $version"

message=\
"Version: $version

<b><span bgcolor=$logorgb>dus - Do USB Stuff</span></b>
author - sudodus alias Nio Wiklund
https://help.ubuntu.com/community/mkusb

Copyright 2014-2022 Nio Wiklund
GPLv3: GNU GPL version 3
http://gnu.org/licenses/gpl.html

This is free software: you are free to use, change and redistribute it.

There is NO WARRANTY, to the extent permitted by law."

if [ "$manager" == "z" ]
then
 zenity --info --title="$btitle" \
  --width=$((msiz * 360 / 100)) --height=$((msiz * 480 / 100)) \
  --text="<span font='$mfnt'>$message</span>" 2> /dev/null
 if ! test -s /usr/share/man/man8/dus.8.gz
 then
  zenity --info --title="About 'man dus'" --text=\
"<span font='$mfnt'>Install dus from the PPA to get the manual page, 'man dus'.
See https://help.ubuntu.com/community/mkusb</span>" 2> /dev/null
 fi
else
 message=${message/<*>/dus - Do USB Stuff}
 echo "$message"
 if ! test -s /usr/share/man/man8/dus.8.gz
 then
  echo "
Install dus from the PPA to get the manual page, 'man dus'.
See https://help.ubuntu.com/community/mkusb" 2> /dev/null
 fi
 if [ "$manager" == "d" ]
 then
  read -p "
Press Enter to continue"
 else
  echo ""
 fi
fi
}
########################################################################

function usage {

 dtok=${0##*/}
 echo "Usage:"
 echo "---- Make USB or memory card install drive from ISO or image file ---"
 echo "$dtok"
 echo "$dtok file.iso"
 echo "$dtok \"quote file name (1) with special characters.iso\""
 echo "$dtok file.img"
 echo "$dtok file.img.gz"
 echo "$dtok file.img.xz"
 echo "$dtok file.tar       # if an mkusb tarfile for Windows"
 echo "---- Clone a device (typically a CD drive or USB drive) -------------"
 echo "$dtok /dev/sr0       # example of CD drive"
 echo "---- Wipe or restore a USB drive or memory card ---------------------"
 echo "$dtok"
 echo "---- Options --------------------------------------------------------"
 echo "$dtok -d [file.iso]  # dialog (text mode menus)"
 echo "$dtok -t [file.iso]  # plain text mode interface"
 echo "$dtok -h             # usage text"
 echo "$dtok -v             # version"
 exit
}
########################################################################

function p_chk_param {

# put parameters through , $@

# print version on demand

if [ "$1" == "-v" ]
then
 echo "$version"
 exit
fi 

# to force dialog or text

if [ "$1" == "-z" ]
then
 if [ "$manager" == "z" ]
 then
  manager=z
 fi
 shift
elif [ "$1" == "-d" ]
then
 if [ "$manager" == "z" ] || [ "$manager" == "d" ]
 then
  manager=d
 fi
 shift
elif [ "$1" == "-t" ]
then
 manager=t
 shift
fi
if [ "$manager" == "" ]
then
 manager=t
 echo "manager=$manager  # text, simple text, no menus available"
# read -p "Press ENTER to continue " ans
fi

#echo "'parameter 1'=$1 (is it a suitable source?)
#ls -l  $1"
#ls -l "$1"

# usage text

if [ $# -gt 1 ] || [ "$1" == "-h" ]
then
 usage
fi

# check usage mode and input file extension

if [ $# -eq 0 ]
then
# echo "p_chk_param: no command line parameter for the source file or device"
 return
elif [ "${1%.iso}.iso" != "$1" ] && \
     [ "${1%.img}.img" != "$1" ] && \
     [ "${1%.img.gz}.img.gz" != "$1" ] && \
     [ "${1%.img.xz}.img.xz" != "$1" ] && \
     [ "${1/.tar}.tar" != "$1" ]
then
 if [ "${1%/*}" == "/dev" ] || test -b "$1"
 then
  echo "Clone a device ... :"
 else
  echo "$1 is neither an iso file nor an img.{gz,xz} file"
  exit
 fi
elif ! test -s "$1"
then
 echo "$1 is not a file that can be used"
 exit
fi

source="$1"
src_orig="$1"
}
########################################################################

function p_need_pck {

which "$1" > /dev/null
if [ "$?" != "0" ]
then
 if [ "$2" != "" ]
 then 
  s_cmnt="'$2'"
 else
  s_cmnt=
 fi
 need_pck="$need_pck
$1 $s_cmnt"
fi
}
########################################################################

function p_want_pck {

which "$1" > /dev/null
if [ "$?" != "0" ]
then
 if [ "$2" != "" ]
 then 
  s_cmnt="'$2'"
 else
  s_cmnt=
 fi
 want_pck="$want_pck
$1 $s_cmnt"
elif [ "$1" == "zenity" ] && [ "$par_org" != "-d" ]
then
 p_zentest || p_want_pck dialog
elif [ "$1" == "dialog" ]
then
 manager=d
fi
}
########################################################################

function p_need_pck_s {

p_calx which "$1" > /dev/null
if [ "$?" != "0" ]
then
 if [ "$2" != "" ]
 then 
  s_cmnt="'$2'"
 else
  s_cmnt=
 fi
 need_pck="$need_pck
$1 $s_cmnt"
fi
}
########################################################################

function p_want_pck_s {

p_calx which "$1" > /dev/null
if [ "$?" != "0" ]
then
 if [ "$2" != "" ]
 then 
  s_cmnt="'$2'"
 else
  s_cmnt=
 fi
 want_pck="$want_pck
$1 $s_cmnt"
elif [ "$1" == "zenity" ] && [ "$par_org" != "-d" ]
then
 p_zentest || p_want_pck dialog
elif [ "$1" == "dialog" ]
then
 manager=d
fi
}
#######################################################################

function p_zentest {

zenity --info --title="$version - zenity-test" --timeout 1 \
--width=420 --height=150 \
--text="<span font='11'>Checking if zenity works in this environment</span>" > /dev/null 2>&1
exitnr=$?
if [ $exitnr -eq 0 ] || [ $exitnr -eq 5 ]
then
 manager=z
 p_zensize
else
 return 1
fi
}
#######################################################################

function p_zensize {

fontchar=auto
fontsize=0

hpix=$(xrandr | grep -m1 ' connected'|sed -e 's/x.*//' -e 's/.* //')
#echo "hpix=$hpix"
hsiz=$(xrandr | grep ' connected'|grep -om1 ' [0-9]*mm '|grep -o '[0-9]*')
vsiz=$(xrandr | grep ' connected'|grep -om1 ' [0-9]*mm$'|grep -o '[0-9]*')
#echo "hsiz=$hsiz"
if test -s "$fontsave"
then
 read fontchar < "$fontsave"
 if [ "$fontchar" != "auto" ]
 then
  fontsize="$fontchar"
 fi
fi
if [ "$hpix" == "" ]   || [ "$hsiz" == "" ]  || [ "$vsiz" == "" ] \
|| [ "$hpix" == "0" ]  || [ "$hsiz" == "0" ] || [ "$vsiz" == "0" ] \
|| [ $fontsize -gt 0 ] && [ $fontsize -le 11 ]
then
 mf100=1100
elif [ $fontsize -gt 11 ]
then
 mf100=$((fontsize * 100))
elif [ "$vsiz" -lt "160" ]
then
 mf100=1100
elif [ "$vsiz" -lt "200" ]
then
 mf100=$((19*12*hpix/hsiz))
else
 #psiz=$((100*hsiz/hpix))
 mf100=$((19*16*hpix/hsiz))
fi
mfnt=$((mf100/100))
#echo "mfnt=$mfnt"
msiz=$((mf100/11))
}
########################################################################

function p_zen_siz_select {

which zenity > /dev/null
if [ $? -ne 0 ]
then
 fontchar="auto"
 return 0
fi

mkdir -p "$HOME/.mkusb/"
fontsave="$HOME/.mkusb/fontsave"
fontchar=

if test -s "$fontsave"
then
 read fontchar < "$fontsave"
else
 fontchar="auto"
fi

if [ "$fontchar" == "auto" ]
then
 lauto=true
 lfix=false
else
 lauto=false
 lfix=true
fi

declare -a menuls=( \
$lauto a "Automatic size of zenity windows and font" \
$lfix f "Fixed size of zenity windows and fonts" );

title1="$version - set zenity size"
title2="Please select a font size for zenity matching
the default font in the desktop environment"

ans=$(zenity --list --radiolist \
 --width=$((msiz * 600 / 100)) --height=$((msiz * 280 / 100)) \
 --title="$title1" \
 --cancel-label="Quit" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --column="selected" --column="hotkey" --column="Setting mode of zenity size" \
 "${menuls[@]}" \
 2> /dev/null)

if [ "$ans" == "a" ]
then
 fontchar="auto"
elif [ "$ans" == "f" ]
then
 fontsize="$fontchar"
 title1="$version - select font size"
 if [ $fontsize -gt 33 ]
 then
  fontdefault="33"
 elif [ $fontsize -gt 11 ]
 then
  fontdefault="$fontsize"
 else
  fontdefault="11"
 fi
 fontchar=$(zenity --scale \
 --title="$title1" --cancel-label="Use default" \
 --text="<span font='$mfnt'>$title2</span>" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --value=$fontdefault \
 --min-value=11 \
 --max-value=33 \
 2> /dev/null)

fi
echo "$fontchar" > "$fontsave"
p_zensize
if [ "$fontchar" == "auto" ]
then
 echo "$mfnt" >> "$fontsave"
fi
}
#######################################################################

function p_clean {

echo "p_clean:"
if [ "$choice" == "" ]
then
 source="$src_orig"
else
 source="$choice"
fi
target=
for i in /tmp/dus.*
do
 if test -d "$i"
 then
  p_calx bash -c "umount $i* 2> /dev/null"
 fi
done
sleep 0.3
p_calx rm -rf "$pff" "$cmf" /tmp/dus.*
ans=
}
#######################################################################

function p_usb_pack_toggle {

# use parameter $1 to pre-select item

if [ "$1" == "0" ]
then
 log0=true
 log1=false
 chr0=on
 chr1=off
else
 log0=false
 log1=true
 chr0=off
 chr1=on
fi

title1="$version - select version of usb-pack_efi.tar.xz"
title2="usb-pack: select 0 for the old version or 1 for the new version"
helptext="Move between items with the 'arrow up/down' keys
Press the 'space bar' to select high-lighted item"

if [ "$manager" == "z" ]
then
  upever=$(zenity --list --radiolist \
  --separator=" " \
  --width=$((msiz * 800 / 100)) --height=$((msiz * 280 / 100)) \
  --title="$title1" --cancel-label="Use default" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --column="selected" --column="version" --column="$title2" \
  "$log0" 0 "usb-pack_efi-0.tar.xz: good for most old cases (even 32-bit in UEFI)" \
  "$log1" 1 "usb-pack-efi-1.tar.xz: good for most current cases (default)" \
 2> /dev/null)
elif [ "$manager" == "d" ]
then
  upever=$(dialog \
  --backtitle "$title1" \
  --title "$title2" \
  --cancel-label "Use default" \
  --radiolist "$helptext" 0 0 0 \
  0 "usb-pack_efi-0.tar.xz: good for most old cases (even 32-bit in UEFI)" "$chr0" \
  1 "usb-pack-efi-1.tar.xz: good for most current cases (default)" "$chr1" \
  3>&1 1>&2 2>&3 3>&-)
else
  read -p "Select version of 'usb-pack_efi.tar.xz'. Enter 0 or 1
0 - usb-pack_efi-0.tar.xz: good for most old cases (even 32-bit in UEFI)
1 - usb-pack-efi-1.tar.xz: good for most current cases (default)
Enter 0 or 1: " upever
fi
if [ "$upever" != "0" ]
then
  upever=1
fi
#  echo "upever=$upever"
p_calx ln -sf usb-pack_efi-"$upever".tar.xz usb-pack_efi.tar.xz
p_calx ln -sf grub-"$upever".img.xz grub.img.xz
echo -e "$greenback 'usb-pack_efi-$upever.tar.xz' activated $resetvid"
}
#######################################################################

function p_usb_pack_manage {


cd /usr/share/mkusb/

if ! ( test -e usb-pack_efi-2.02.tar.xz && test -e usb-pack_efi-2.04.tar.xz && \
       test -e grub-2.02.img.xz && test -e grub-2.04.img.xz )
then
  if [ "$manager" == "z" ]
  then
   zenity --info --title="$version - install 'usb-pack-efi'" \
   --width=$((msiz * 500 / 100)) --height=$((msiz * 150 / 100)) \
   --text="<span font='$mfnt'>Please install the package 'usb-pack-efi'</span>" > /dev/null 2>&1
  fi
 echo -e "$redback Please install the package 'usb-pack-efi' $resetvid"
 return 1
fi

grver=$(grub-install --version|sed -e 's/.* //' -e 's/-.*//')
echo -e "$inversvid grub version: $grver $resetvid"
if [ "$grver" \< "2.04" ]
then
 if ! diff usb-pack_efi-2.02.tar.xz usb-pack_efi-1.tar.xz > /dev/null 2>&1
 then
 sudo ln -sf usb-pack_efi-2.02.tar.xz usb-pack_efi-1.tar.xz
 fi
 if ! diff grub-2.02.img.xz grub-1.img.xz > /dev/null 2>&1
 then
 sudo ln -sf grub-2.02.img.xz grub-1.img.xz
 fi

elif ! diff usb-pack_efi-2.04.tar.xz usb-pack_efi-1.tar.xz > /dev/null 2>&1 || \
     ! diff grub-2.04.img.xz grub-1.img.xz > /dev/null 2>&1 
then
 if [ "$grver" \> "2.04" ]
 then
  echo "Warning: grub version > 2.04. Maybe problems with usb-pack_efi"
 fi 
 sudo ln -sf usb-pack_efi-2.04.tar.xz usb-pack_efi-1.tar.xz
 sudo ln -sf grub-2.04.img.xz grub-1.img.xz
fi

if test -e usb-pack_efi-0.tar.xz && test -e usb-pack_efi-1.tar.xz
then
 if test -e usb-pack_efi.tar.xz
 then
  if diff usb-pack_efi-0.tar.xz usb-pack_efi.tar.xz > /dev/null 2>&1
  then
   echo -e "$blueback 'usb-pack_efi-0.tar.xz': good except for new cases e.g. secure boot $resetvid"
   p_usb_pack_toggle 0
  elif diff usb-pack_efi-1.tar.xz usb-pack_efi.tar.xz > /dev/null 2>&1
  then
   echo -e "$blueback 'usb-pack_efi-1.tar.xz': good for new cases e.g. secure boot, but $resetvid
$blueback may not work for old cases e.g. 32-bit systems in UEFI mode $resetvid"
   p_usb_pack_toggle 1
  fi
 else
  p_usb_pack_toggle
 fi
elif test -e usb-pack_efi.tar.xz
then
  if [ "$manager" == "z" ]
  then
   zenity --info --title="$version - maybe reinstall 'usb-pack-efi'" \
   --width=$((msiz * 600 / 100)) --height=$((msiz * 150 / 100)) \
   --text="<span font='$mfnt'>The installed package 'usb-pack-efi' is not a complete current version.
It would be a good idea to <b> reinstall 'usb-pack-efi' </b> now.</span>" > /dev/null 2>&1
  fi
  echo -e "$blueback The installed package 'usb-pack-efi' is not a complete current version. $resetvid
$blueback It would be a good idea to $inversvid reinstall 'usb-pack-efi' $resetvid$blueback now. $resetvid"
else
  if [ "$manager" == "z" ]
  then
   zenity --info --title="$version - install 'usb-pack-efi'" \
   --width=$((msiz * 500 / 100)) --height=$((msiz * 150 / 100)) \
   --text="<span font='$mfnt'>Please install the package 'usb-pack-efi'</span>" > /dev/null 2>&1
  fi
 echo -e "$redback Please install the package 'usb-pack-efi' $resetvid"
 return 1
fi
}
#######################################################################

function p_menudz {

# select what to do

 if [ "$manager" == "d" ]
 then
  ans=$(dialog \
  --colors \
  --no-collapse \
  --backtitle "$version - $title1" \
  --title "$title2" \
  --menu "$titled" 13 64 0 \
  "${menuln[@]}" \
  3>&1 1>&2 2>&3 3>&-)
  if [ $? -ne 0 ]
  then
   ans=q
  fi
 elif [ "$manager" == "z" ]
 then
  ans=$(zenity --list \
  --width=$((msiz * 700 / 100)) --height=$((msiz * 400 / 100)) \
  --title="$version - $title1" \
  --cancel-label="Quit" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --column="hotkey" --column="$title2" \
  "${menuln[@]}" \
  2> /dev/null)
  if [ $? -ne 0 ]
  then
   ans=q
  fi
  ans=${ans:0:1}  # fix for buggy(?) zenity --list in trusty
#  echo "ans=$ans"
 fi
}

#######################################################################

function p_starter {

# select what to do

ans=
while [ "$ans" == "" ]
do
title1="Install / Backup / Restore / Wipe"
title2="Move between items with the arrow keys"
if [ "$manager" == "z" ]
then
 declare -a menuln=( \
i "Install (make a boot device)" \
s "restore to a Standard storage device" \
w "Wipe a device (drive)" \
b "Backup persistent live home" \
r "Restore persistent live home" \
u "manage USB-pack-EFI" \
z "manage Zenity window and font size" \
a "About" \
q "Quit (exit from ${0##*/})");
else
 declare -a menuln=( \
i "Install (make a boot device)" \
s "restore to a Standard storage device" \
w "Wipe a device (drive)" \
b "Backup persistent live home" \
r "Restore persistent live home" \
u "manage USB-pack-EFI" \
a "About" \
q "Quit (exit from ${0##*/})");

fi
 p_menudz
 titled=""
 if [ "$manager" == "t" ]
 then
  ans=
  while [ "$ans" == "" ]
  do
   read -p "
Install (make a boot device)
restore to Standard storage devuce
Wipe a device
Backup persistent live home
Restore persistent live home
manage USB-pack-EFI
About
Quit (exit from ${0##*/})
(i/s/w/b/r/u/a/q) " ans
  done 
 fi

# find what to do

 ask_for_zenity="$redback${0##*/} needs the program package zenity $resetvid
$inversvid Please install it to backup/restore persistent live home $resetvid"

 if [ "$ans" == "i" ]
 then
  p_install
 elif [ "$ans" == "s" ]
 then
  p_restore
 elif [ "$ans" == "b" ]
 then
  p_need_pck zenity
  if [ "$need_pck" != "" ]
  then
   echo -e "$ask_for_zenity"
   rm -f "$pff"
   exit
  fi
  dus-home-backup
  ans=
 elif [ "$ans" == "r" ]
 then
  p_need_pck zenity
  if [ "$need_pck" != "" ]
  then
   echo -e "$ask_for_zenity"
   rm -f "$pff"
   exit
  fi
  dus-home-restore
  ans=
 elif [ "$ans" == "u" ]
 then
  p_usb_pack_manage
  cd "$curdir"
  ans=
 elif [ "$ans" == "w" ]
 then
  p_wipe
 elif [ "$ans" == "z" ]
 then
  p_zen_siz_select
  ans=
 elif [ "$ans" == "a" ]
 then
  about
  ans=
 elif [ "$ans" == "q" ]
 then
  echo "clean if necessary and quit"
  exit
 else
  ans=
 fi
done

}
#######################################################################

function p_install {

ans=
#while [ "$ans" == "" ]
while [ "$ans" != "q" ]
do
 title1="Cloning, live linux, windows / Persistent live"
 title2="Move between items with the arrow keys"
 declare -a menuln=( \
  c "Cloning iso file, [compressed] image file or device" \
  l "'Live-only' or linux installer from iso file" \
  p "'Persistent live' - only Debian and Ubuntu" \
  w "extracting Windows installer" \
  q "Quit");
 p_menudz
 titled=""
 if [ "$manager" == "t" ]
 then
  read -p "Cloning,live-only,windows / Persistent-live / Quit (c/l/p/w/q) " ans
 fi

 if [ "$ans" == "c" ]
 then
  echo "-----  p_install: cloning ..."
  p_live
 elif [ "$ans" == "l" ]
 then
  p_toolsel live-only
 elif [ "$ans" == "w" ]
 then
  p_winsel
 elif [ "$ans" == "p" ]
 then
#  p_persistent
  p_toolsel persistent
 elif [ "$ans" == "q" ]
 then
  ans=
  echo "clean if necessary and return"
  return
 else
  ans=
 fi
done
p_clean
}
########################################################################

function p_winsel {

echo "-----  p_winsel: extracting Windows installer  -----"
ans=
#while [ "$ans" == "" ]
while [ "$ans" != "q" ]
do
 title1="Extract installer for Windows 7-11"
 title2="Move between items with the arrow keys"
 declare -a menuln=( \
  n "New version, works also with huge Windows iso files" \
  o "Old version, works also in 32-bit linux" \
  q "Quit");
 p_menudz
 titled=""
 if [ "$manager" == "t" ]
 then
  read -p "New version, works also with huge Windows iso files /
Old version, works also in 32-bit linux /
Quit
(n/o/q) " ans
 fi

 if [ "$ans" == "o" ]
 then
  p_live
 elif [ "$ans" == "n" ]
 then
 zniff=true
 p_source
 if [ $? -eq 1 ]
 then
  rm -f "$pff"
  return
 fi
 p_target
 if [ $? -eq 0 ]
 then
  echo "$separator"
  tmpcmd=$(mktemp)
  echo mkusb-tow "$source" "$target" > "$tmpcmd"
  echo "echo $separator" >> "$tmpcmd"
  chmod +x "$tmpcmd"
  p_calx "$tmpcmd" && p_chk_result || echo "bad password"
  rm  "$tmpcmd"
 fi
 elif [ "$ans" == "q" ]
 then
  ans=
  echo "clean if necessary and return"
  return
 else
  ans=
 fi
done
p_clean
 
 
}
########################################################################

function p_toolsel {

# $1 is true or false (persistent)

echo -e "$inversvid p_toolsel starts here ...$resetvid"
perst="$1"
ans=
#while [ "$ans" == "" ]
while [ "$ans" != "q" ]
do
 title1="Select method/tool"
 title2="Move between items with the arrow keys"
 if [ "$perst" == "persistent" ]
 then
  declare -a menuln=( \
   i "'dus-Iso2usb', grub-n-iso method" \
   p "'dus-Persistent', classic dus method" \
   q "Quit");
  p_menudz
  titled=""
  if [ "$manager" == "t" ]
  then
   read -p "'dus-Iso2usb', grub-n-iso method /
'dus-Persistent', classic dus method /
Quit
(i/p/q) " ans
  fi
 else
  perst=live-only
  declare -a menuln=( \
   i "'dus-Iso2usb', grub-n-iso method" \
   l "'dus-Live', cloning method" \
   q "Quit");
  p_menudz
  titled=""
  if [ "$manager" == "t" ]
  then
   read -p "'dus-Iso2usb', grub-n-iso method /
'dus-Live', cloning method /
Quit
(i/l/q) " ans
  fi
 fi

 if [ "$ans" == "p" ]
 then
  p_persistent
  rm -f "$pff"
  return
 elif [ "$ans" == "l" ]
 then
  echo "-----  cloning ..."
  p_live
  rm -f "$pff"
  return
 elif [ "$ans" == "i" ]
 then
  echo "-----  p_iso2usb:  use grub-n-iso method -----"
  zniff=true
  p_source
 fi
 if [ $? -eq 1 ]
 then
  rm -f "$pff"
  return
 fi
 p_target
 if [ $? -eq 0 ]
 then
  echo "$separator"
  tmpcmd=$(mktemp)
  
# put menu here to select pt and grv (perst should already be selected)

  p_seti2u

  echo -e "$inversvid p_toolsel after p_seti2u $resetvid"
  echo "pt=$pt"
  echo "grv=$grv"
  echo "flg=$flg"
  if [ "$grv" == "grub-2.0.6" ] && [ "$pt" == "msdos" ]
  then
   ans=
   echo -e "$redback Use old grub version with msdos partition table $resetvid"
   return
  fi 
  if [ "$pt" == "gpt" ] || [ "grv" == "grub-2.0.6" ]
  then
   if [ "$flg" == "boot-flag" ]
   then
    ans=
    echo -e "$redback Do not set 'boot-flag' with '$pt' or '$grv' $resetvid"
    return
   fi
  fi 
  echo -en "${blueback}dus-iso2usb "
           echo -e "$source $target $pt $grv $perst $flg$resetvid"
  echo dus-iso2usb "$source $target $pt $grv $perst $flg" > "$tmpcmd"
  echo "echo $separator" >> "$tmpcmd"
  chmod +x "$tmpcmd"
  p_calx "$tmpcmd" && p_chk_result || echo "bad password"
  rm  "$tmpcmd"
  p_clean
  return
 elif [ "$ans" == "q" ]
 then
  ans=
  echo "clean if necessary and return"
  return
 else
  ans=
 fi
done
p_clean
}
########################################################################

function p_source {

if [ "$manager" == "z" ] && [ "$src_orig" == "" ]
then
 source=
# stmp=$(lsblk -Jo name,label|grep -m1 casper-rw|cut -d \" -f 4|sed -e s/5$/4/ -e s#^#/dev/#)
# stmp=$(lsblk -Jo name,fstype|grep iso9660|cut -d \" -f 4|grep -m1 4$|sed s#^#/dev/#)
 stmp=$(p_calx lsblk -Po name,fstype|grep 'iso9660'|cut -d \" -f 2|grep -m1 '4$'|sed s#^#/dev/#)
# if [ "$stmp" == "" ]
# then
#  stmp=$(lsblk -Jo name,fstype|grep iso9660|cut -d \" -f 4|head -n1|sed s#^#/dev/#)
# fi
 if [ "$stmp" != "" ]
 then
  sname="$(p_calx lsblk -no label $stmp|head -n1)"

  p_langC
  zenity --title="$version - Select source device" \
  --width=$((msiz * 790 / 100)) --height=$((msiz * 400 / 100)) \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --question --text="<span font='$mfnt'><b>ISO 9660 partition found. Quick choice possible.</b>
Answer <b>No</b>, if you intend to install <b>to</b> the drive with <b>$stmp</b>.
<tt><small>
$(p_calx lsblk -lo model,name,size,fstype,label,mountpoint|grep -e '^[^ ]' -e 'iso9660')
</small></tt>
Do you want to install <b>$sname</b>
from the device <b>$stmp</b> ?</span>" \
 2>/dev/null
  if [ $? -eq 0 ]
  then
   source="$stmp"
   echo "source device: $stmp '$sname'"
  fi
  p_langR
 fi
 
 if [ "$source" == "" ]
 then
  source=$(zenity --file-selection \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --title "$version - Select source file" \
  --filename="$choice" --file-filter={*.i[sm][og]*,*.iso,*.img,*.img.?z,s[dr]?,mmc*,*} \
  2> /dev/null)
 fi
 if [ "$source" == "" ]
 then
  echo "No file or bad file"
  rm -f "$pff"
  return 1
 fi
elif [ "$source" == "" ] || ! ( test -s "$source" || test -b "$source" ) || test -d "$source"
then
 echo -e "$inversvid
+-------------------------------------------------------------+
|     It is easier to select source file as a parameter,      |
|     when using dialog menus or a simple text interface.     |
+-------------------------------------------------------------+
|     Examples:                                               |
|     cd Downloads        # where you find source files       |
|     dus debian.iso      # autoselect zenity, dialog, text   |
|     dus -t ubuntu.iso   # simple text                       |
|     dus -d ubuntu.iso   # dialog menus                      |
+-------------------------------------------------------------+
|     However, there is a good file selector using zenity.    |
|     dus [-z]            # zenity menus (when available)     |
+-------------------------------------------------------------+$resetvid"

 read -p "Select source file " source
 if [ "$source" == "" ] || ! ( test -s "$source" || test -b "$source" ) || test -d "$source"
 then
  echo "No file or bad file"
  rm -f "$pff"
  return 1
 fi
fi
p_sniff "$source"
choice="$source"
}
########################################################################

function p_checkpoint {

# $text string with high-lights

 ans=
 q_chk="Final checkpoint, go ahead?"
 q_ch2="Final checkpoint:
are you ready?"
  
 echo -e "$1"
 action="${1/\\*7m}"
 action="${action/\\*0m}"
 action=$(echo "$action"|sed "s#^'/.*/#'#")
 blklist=$(lsblk -o MODEL,NAME,FSTYPE,LABEL,SIZE "$target")
 lsblk -lo MODEL,NAME,FSTYPE,LABEL,SIZE "$target"
 trgtxt=$(lsblk -o NAME,SIZE,MODEL -d "$target")
 trgtx1=$(echo "$trgtxt"|head -n1)
 trgtx2=$(echo "$trgtxt"|tail -n1)
 trgtxt="${trgtxt,,}"
 if [ "$manager" == "z" ]
 then
  ans=$(zenity --list --radiolist \
  --width=$((msiz * 780 / 100)) --height=$((msiz * 480 / 100)) \
  --title="$version - $q_chk" --cancel-label="Stop" --ok-label="Go" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --text="Source: '$source'
Target: '$target'
<tt>
$blklist
</tt>" \
  --column="Go/Stop" --column="$action" --column="$trgtxt"\
  true Stop "No, I am not sure yet" \
  false Go  "Yes, I want to go ahead" \
  2> /dev/null)
  if [ $? -ne 0 ]
  then
   ans=n
  fi
 elif [ "$manager" == "d" ]
 then
  action="$trgtx1\n$trgtx2\n$action\n\Z1***** $q_chk *****\Zn"
  ans=$(dialog --no-collapse \
 --backtitle "$version - $q_chk" \
 --cancel-label "Stop" --ok-label "Go" --colors \
 --defaultno \
 --radiolist "$action" 0 0 0 \
 Stop "\Z1No, I am not sure yet\Zn" on \
 Go   "Yes, I want to go ahead" off \
 3>&1 1>&2 2>&3 3>&-)
  if [ $? -ne 0 ]
  then
   ans=n
  fi
 else
  echo -en "$redback $q_chk (g/N) $resetvid"
  read ans
  if [ "$ans" == "g" ]
  then
   echo -en "$redback Are you sure ? (y/N) $resetvid"
   read an2
   if [ "$an2" != "y" ]
   then
    return 1
   fi
  fi
 fi
 
 if [ "$ans" == "Go" ]
 then
  ans=g
 elif [ "$ans" == "Stop" ]
 then
  ans=n
 fi
 if [ "$ans" == "g" ]
 then
  return 0
 else
  if [ "$manager" == "z" ]
  then
   src_orig=
  fi
  return 1
 fi
}
########################################################################

function p_chk_result {

btitle="Check the result (scroll if possible), press Enter to finish"
btext="The target device is unmounted and you can unplug it.
The system might not see the current partition table of the
target device unless you re-plug it."
if [ "$manager" == "z" ]
then
 if [ "$1" != "not_here_when_z" ]
 then
  zenity --info \
  --width=$((msiz * 460 / 100)) --height=$((msiz * 280 / 100)) \
  --title="$version - check the result" \
  --text="<span font='$mfnt'><b>$btitle</b>

$btext</span>" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  2> /dev/null
 fi
else
 echo "$btest
"
 read -p "$btitle "
fi

if [ "$manager" == "d" ]
then
# fix to avoid overwriting previous output when using dialog in xterm
 ps -A|grep 'xterm$' > /dev/null
 if [ $? -eq 0 ]
 then
  LINES=$(tput lines)
#  echo "LINES=$LINES"
  str=
  for (( i=2; i<=$LINES ; i++ ))
  do
   str="${str}\n${i}"
  done
  echo -en "$str"
#  read -p "temp-check"
 fi
fi
}
########################################################################

function p_cal1 {

if [ "$USER" != "root" ]
then
 sudostr="live system or temporary superuser permissions"
 for i in 1 2 3
 do
  if [ "$i" == "1" ]
  then
   sudo -n echo "$sudostr" 2> /dev/null
  else
   sudo -n echo "$sudostr" > /dev/null 2> /dev/null
  fi
  if [ $? -ne 0 ]
  then
   if [ "$1" == "-z" ]
   then
    zenity --password --title "$version - sudo" \
    --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
    2> /dev/null \
    |sudo -S echo "$sudostr" 2> /dev/null
   elif [ "$1" == "-d" ]
   then
    echo "o/ dialog"
    ans=$(dialog --backtitle "$version - enter password" \
    --insecure --passwordbox "Enter (sudo) password" 0 0 \
    3>&1 1>&2 2>&3 3>&-)
    echo "$ans" \
    |sudo -S echo "$sudostr" 2> /dev/null
   else
#   3 attempts to enter password built into standard sudo
    sudo echo "$sudostr" 2> /dev/null
    if [ $? -ne 0 ]
    then
     exit
    fi
   fi
  fi
 done

 if [ $? -ne 0 ]
 then
  echo "${0##*/}: bad sudo password"
  exit
 fi
fi
}
########################################################################

function p_call {

if [ "$USER" == "root" ]
then
 "$1" "pff:$pff"
else
 sudostr="live system or temporary superuser permissions"
 for i in 1 2 3
 do
  if [ "$i" == "1" ]
  then
   sudo -n echo "$sudostr" 2> /dev/null
  else
   sudo -n echo "$sudostr" > /dev/null 2> /dev/null
  fi
  if [ $? -ne 0 ]
  then
   if [ "$manager" == "z" ]
   then
    zenity --password --title "$version - sudo" \
    --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
    2> /dev/null \
    |sudo -S echo "$sudostr" 2> /dev/null
   elif [ "$manager" == "d" ]
   then
    echo "o/ dialog"
    ans=$(dialog --backtitle "$version - enter password" \
    --insecure --passwordbox "Enter (sudo) password" 0 0 \
    3>&1 1>&2 2>&3 3>&-)
    echo "$ans" \
    |sudo -S echo "$sudostr" 2> /dev/null
    ans=
   else
    sudo echo "$sudostr"
   fi
  fi
  sudo -nH "$1" "pff:$pff"
  ans=$?
  if [ "$ans" == "0" ]
  then
   break
  fi
 done

 if [ $ans -ne 0 ]
 then
  return 1
 fi
fi
}
########################################################################

function p_calx {

if [ "$USER" == "root" ]
then
 "$@"
else
 sudostr="live system or temporary superuser permissions"
 for i in 1 2 3
 do
  if [ "$i" == "1" ]
  then
   sudo -n echo "$sudostr" 2> /dev/null
  else
   sudo -n echo "$sudostr" > /dev/null 2> /dev/null
  fi
  if [ $? -ne 0 ]
  then
   if [ "$manager" == "z" ]
   then
    zenity --password --title "$version - sudo" \
    --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
    2> /dev/null \
    |sudo -S echo "$sudostr" 2> /dev/null
   elif [ "$manager" == "d" ]
   then
    echo "o/ dialog"
    ans=$(dialog --backtitle "$version - enter password" \
    --insecure --passwordbox "Enter (sudo) password" 0 0 \
    3>&1 1>&2 2>&3 3>&-)
    echo "$ans" \
    |sudo -S echo "$sudostr" 2> /dev/null
    ans=
   else
    sudo echo "$sudostr" 2> /dev/null
   fi
  fi
  sudo -nH "$@"
  ans=$?
  if [ "$ans" == "0" ]
  then
   break
  fi
 done

 if [ $ans -ne 0 ]
 then
  return 1
 fi
fi
}
########################################################################

function p_live {

pff=$(mktemp --tmpdir dus.XXXXXXXXXX)
echo "-----  p_live: cloning Linux or extracting Windows  -----"
p_source
if [ $? -eq 1 ]
then
 rm -f "$pff"
 return
fi
p_target
if [ $? -eq 0 ]
then
 p_checkpoint "$inversvid Clone/extract $resetvid system from the source
'$source'
to the target device (drive) '$target'"
 if [ $? -eq 0 ]
 then
  echo "$source" > "$pff" 
  echo "$target" >> "$pff" 
  cat "$pff"
  echo "-----"
  p_call dus-live && p_chk_result || echo "bad password"
 fi
fi
p_clean
}
########################################################################

function p_persistent {

pff=$(mktemp --tmpdir dus.XXXXXXXXXX)
echo "-----  p_persistent:  make persistent live drive -----"
zniff=true
p_source
if [ $? -eq 1 ]
then
 rm -f "$pff"
 return
fi
if test -s "$source"
then
 if [ "${source%.iso}.iso" != "$source" ]
 then
  tmpstr="dus-persistent wants input from an 'iso' file or a device -- try again"
  if [ "${source%.img}.img" != "$source" ]
  then
   tmpstr="$tmpstr
 '${source##*/}'
 tip: Try to clone this image file (or select an iso file for dus-persistent)"
  fi
  /bin/echo -e "$redback $tmpstr $resetvid"
  if [ "$manager" == "z" ]
  then
   zenity --info --title="$version - Bad file extension, not '.iso'" \
   --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
   --text="<span font='$mfnt'>$tmpstr</span>" 2> /dev/null
  else
   read -p "Press Enter to continue"
  fi
  src_orig=
  return
 fi
fi

p_target
if [ $? -eq 0 ]
then
 p_setting
 p_checkpoint "Prepare $inversvid persistent live $resetvid system from
'$source'
to the target device (drive) '$target'"
 if [ $? -eq 0 ]
 then
  echo "$source" > "$pff" 
  echo "$target" >> "$pff" 
  echo "$percent" >> "$pff"
  echo "settings=$settings" >> "$pff"
  cat "$pff"
  echo "-----"
  p_call dus-persistent && p_chk_result not_here_when_z || echo "bad password"
 fi
fi
p_clean
}
########################################################################

function p_wipe {

ans=
while [ "$ans" == "" ]
do
 title1="wipe: 1 (first) Mibibyte / Whole device"
 title2="Move between items with the arrow keys"
 declare -a menuln=( \
  1 "wipe 1 (the first) Mibibyte" \
  w "wipe the Whole device (very slow)" \
  q "Quit");
 p_menudz
 if [ "$manager" == "t" ]
 then
  read -p "wipe-1-MiB/wipe-whole-device/quit (1/w/q) " ans
 fi
 
 if [ "$ans" == "1" ]
 then
  p_wips 1
 elif [ "$ans" == "w" ]
 then
  p_wips w
 elif [ "$ans" == "q" ]
 then
  ans=
  echo "clean if necessary and return"
  return
 else
  ans=
 fi
done
p_clean
}
########################################################################

function p_restore {

pff=$(mktemp --tmpdir dus.XXXXXXXXXX)

p_target
if [ $? -eq 0 ]
then
 if [ "$manager" == "z" ]
 then
  label=$(zenity --entry \
  --text="Enter label for the FAT32 file system (max 11 characters)" \
  --width=$((msiz * 420 / 100)) --height=$((msiz * 320 / 100)) \
  --title="$version - Enter label" --cancel-label="No label" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  2> /dev/null)
 elif [ "$manager" == "d" ]
 then
  label=$(dialog --backtitle "$version - Enter label" \
   --inputbox "Enter label for the FAT32 file system (max 11 characters)" 0 0 \
   3>&1 1>&2 2>&3 3>&-)
 else
  read -p "Enter label (max 11 characters) " label
 fi
 p_checkpoint "Restore $inversvid $target $resetvid
to an MSDOS partition table and a
partition with a FAT32 file system"
 if [ $? -eq 0 ]
 then
  echo "restore $target" "$label" | tr -s ' ' '\n' > "$pff" 
  cat "$pff"
  echo "-----"
  p_call dus-restore && p_chk_result || echo "bad password"
 fi
fi
p_clean
}
########################################################################

function p_wips {

pff=$(mktemp --tmpdir dus.XXXXXXXXXX)

if [ "$1" == "1" ]
then
 token=wipe-1
 echo "wipe the first Mibibyte"
elif [ "$1" == "w" ]
then
 token=wipe-whole-device
 echo "wipe the whole device - it can take very long time"
else
 echo "p_wipe: error"
 return
fi

p_target
if [ $? -eq 0 ]
then
 p_checkpoint "Preparing to wipe $inversvid $target $resetvid"
 if [ $? -eq 0 ]
 then
  echo "$token $target" | tr -s ' ' '\n' > "$pff" 
  cat "$pff"
  echo "-----"
  p_call dus-wipe && p_chk_result || echo "bad password"
 fi
fi
p_clean
}

########################################################################

function p_list_drives {

p_langC
rm -f "$byid" "$list00"
byid=$(mktemp --tmpdir dus.XXXXXXXXXX)
list00=$(mktemp --tmpdir dus.XXXXXXXXXX)
> "$list00"

for i in $(lsblk -o name,type -d|grep 'disk'|grep -v -e '^zram' -e '^fd' -e '^cloop'|cut -d ' ' -f1)
do
 ls -l /dev/disk/by-id |grep "$i$" | grep 'nvme-[A-Z]' > /dev/null
 if [ $? -eq 0 ]
 then
  ls -l /dev/disk/by-id |grep "$i$" | grep -m1 'nvme-[A-Z]' |tr -s ' ' '\t' \
   |cut -f9,11|sed -e 's#../../##' |tr '\n' '\t'
 else
   ls -l /dev/disk/by-id |grep -v '^wwn'| grep -m1 "$i$" |tr -s ' ' '\t' \
   |cut -f9,11|sed -e 's#../../##' |tr '\n' '\t'
 fi
 lsblk -o size -dn "/dev/$i"
done > "$byid"
#echo "byid:"
#cat "$byid"

#Isav1=$IFS
#IFS=$'\t'
#while read model name size
#do
# echo "\"$name\" \"$model\" \"$size\""
#done < "$byid"
#IFS=Isav1
#echo "p_list_drives: after mini-read-loop"

Isav1=$IFS
IFS=$'\t'
while read model name size
do
 bus="${model%%-*}"
 model="${model#*-}"
 model="${model%_*}"
 if [ "$bus" == "usb" ] || [ "${bus:0:3}" == "mmc" ]
 then
  hotplug="USB or memory card"
 else
  hotplug="built-in device"
 fi

 if [ "$manager" == "z" ]
 then
#     prepare for zenity

#  echo "name=$name model=$model size=$size bus=$bus hotplug=$hotplug"

  echo "\"$name\" \"$model\" \"$size\" \"$bus\" \"$hotplug\"" >> "$list00"

 else
#     prepare string for dialog (and text)

  moddum='                              '
  model="${model:0:30}"
  modlen=${#model}
  modpad="${moddum:modlen}"

  sizdum='      '
  sizlen=${#size}
  sizpad="${sizdum:sizlen}"

  echo "$name  $model$modpad $size$sizpad $bus  $hotplug" >> "$list00"
 fi
done < "$byid"
IFS=$Isav1

#echo "p_list_drives:"
#echo "list00:"
#cat "$list00"
#echo "manager=$manager"
#read -p "p_list_drives: checking, press Enter to continue "

#sort -k5 "$list00" > "$list01"  # depends on locale
> "$list01"
grep "built-in device" "$list00" > "$list01"
grep "USB or memory card" "$list00" >> "$list01"

sleep 0.3
rm "$byid" "$list00"
p_langR
}
########################################################################

function p_list {

#p_ldr
p_sdr
list01=$(mktemp --tmpdir dus.XXXXXXXXXX)
p_list_drives
plghead="Dev  Target name/model              Size   Bus  Kind of device    "
hotplug=$(grep "USB or memory card" "$list01")
cldplug=$(grep "built-in device" "$list01")
sleep 0.3
rm "$list01"

if [ "$sdrive" != "" ]
then
 hotplug=$(echo "$hotplug"|grep -v "${sdrive##*/}")
 cldplug=$(echo "$cldplug"|grep -v "${sdrive##*/}")
fi
if [ "$livedrive" != "not_found" ]
then
 hotplug=$(echo "$hotplug"|grep -v "${livedrive##*/}")
 cldplug=$(echo "$cldplug"|grep -v "${livedrive##*/}")
fi

echo "$separator"
echo "Available drives (mass storage devices)"
echo -e "$inversvid$plghead$resetvid"
cldlist=$(echo "$cldplug"|sed 's/ .*//')
hotlist=$(echo "$hotplug"|sed 's/ .*//')
for i in $cldlist
do
 for j in $(grep '^UUID' /etc/fstab 2>/dev/null|tr '=' ' '|cut -d ' ' -f2); \
  do lsblk -o NAME,UUID /dev/[^f]d[a-z][1-9]* /dev/mmcblk?p?* /dev/nvme?n?p?* \
   2> /dev/null grep -m1 "$j";done|grep "$i" >/dev/null
 if [ $? -ne 0 ]
 then
  echo "$cldplug" | grep "$i"
 fi
done
#echo "$separator"
#echo "USB drives and memory cards"
for i in $hotlist
do
 for j in $(grep '^UUID' /etc/fstab 2>/dev/null|tr '=' ' '|cut -d ' ' -f2); \
  do lsblk -o NAME,UUID /dev/[^f]d[a-z][1-9]* /dev/mmcblk?p?* /dev/nvme?n?p?* \
   2>/dev/null|grep -m1 "$j";done|grep "$i" >/dev/null
 if [ $? -ne 0 ]
 then
  ptmp=$(echo "$hotplug" | grep "$i")
  echo -e "$inversvid$ptmp$resetvid"
 fi
done
}
########################################################################

function p_lisdz {

list0=$(mktemp --tmpdir dus.XXXXXXXXXX)
list01=$(mktemp --tmpdir dus.XXXXXXXXXX)
list02=$(mktemp --tmpdir dus.XXXXXXXXXX)
list03=$(mktemp --tmpdir dus.XXXXXXXXXX)

p_list_drives

#echo "list01:"
#cat "$list01"
#echo "sdrive=$sdrive"
#echo "dollar {sdrive##*/}=${sdrive##*/}"
if [ "$sdrive" != "" ]
then
 grep -v "${sdrive##*/}" "$list01" > "$list02"
else
 cp "$list01" "$list02"
fi
#echo "list02:"
#cat "$list02"
#read -p "p_lisdz: after check of source drive "
#sync
#sleep 0.3
#echo "livedrive=$livedrive"
#echo "dollar {livedrive##*/}=${livedrive##*/}"
if [ "$livedrive" != "" ] && [ "$livedrive" != "not_found" ]
then
 grep -v "${livedrive##*/}" "$list02" > "$list03"
else
 cp "$list02" "$list03"
fi
#echo "list03:"
#cat "$list03"
#read -p "p_lisdz: after check of live drive "

lsbl3="$(cat "$list03")"
#echo "lsbl3=
#$lsbl3"
#read -p "p_lisdz: after check of live drive "

Isav2=$IFS
IFS=' '
if [ "$manager" == "z" ]
then
 tfstb="$(echo "$lsbl3"|cut -d \" -f 2|tr '\n' ' ')"
else
 tfstb=$(echo "$lsbl3"|cut -d " " -f 1|tr '\n' ' ')
fi
IFS=$Isav2

#echo "tfstb=
#$tfstb"
#echo "manager=$manager"
#read -p "p_lisdz: after creating tfstb "

Isav3=$IFS
IFS=' '
for j in $tfstb
do
# echo "$j ##### ska vara 'dollar j' #####"
 p_fstb "$j"
 if $infstb
 then
  echo "Drive with a partition in fstab: /dev/$j"
  lsbl3="$(echo "$lsbl3"|grep -v "$j")"
 fi
done
IFS=$Isav3
l_bl3="${#lsbl3}"

#echo "lsbl3=
#$lsbl3"
#echo "l_bl3=$l_bl3"
#read -p "----- end of this test output, press Enter to continue #####"

if [ $l_bl3 -lt 3 ]
then
 tmpstr="No suitable target device found"
 echo -e "$redback $tmpstr $resetvid"
 if [ "$manager" == "z" ]
 then
  zenity --info --text="<span font='$mfnt'>$tmpstr</span>" \
  --title="$version - no target" --width=$((msiz * 260 / 100)) \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  2> /dev/null
 elif [ "$manager" == "d" ]
 then
  read -p "Press Enter to continue "
 fi
 return
fi

if [ "$manager" == "d" ]
then
echo "$lsbl3" | \
 sed -e 's/  */\t/'| \
 sed -e 's/$/\toff/' -e 's/\t/\n/g' > "$list0"

#cat "$list0"

typeset -a listd[@]
i=0
Isave=$IFS
IFS=$'\n'
while read line
do
 listd[$i]="$line"
 i=$((i+1))
done < "$list0"
i=$((i-1))
listd[$i]=on

#echo "${listd[@]}"

elif [ "$manager" == "z" ]
then

#lsblk -o name,model,size,tran,hotplug,type -x hotplug -J | \ #####
echo "$lsbl3" | \
cut -d \" -f 2,4,6,8,10|sed -e 's/"/\n/g' > "$list0"

typeset -a lst1[@]
typeset -a lst2[@]
i=0
Isave=$IFS
IFS=$'\n'
while read line
do
 lst1[$i]="$line"
 i=$((i+1))
done < "$list0"

cands=$((i/5))
echo "cands=$cands"
cat "$list0"
#echo "${lst1[@]}"

i=0
n=0
for (( k=0; k<$cands ; k++ ))
do
 for (( j=0; j<6 ; j++ ))
 do
  if [ $j -eq 0 ]
  then
   lst2[$n]=false
  else
   lst2[$n]=${lst1[$i]}
   i=$((i+1))
  fi
  n=$((n+1))
 done
done
n=$((n-6))
lst2[$n]=true
IFS=$'\n'

#echo "${lst2[@]}"

fi

title1="$version - Select target device"
title2="Select target device from this list"

if [ "$manager" == "d" ]
then
 title3="\Z4${title2}:\Zn
Move between items with the arrow up/down keys
Press the 'space bar' to make the selection"
 trg=$(dialog \
 --backtitle "$title1" --colors \
 --no-shadow \
 --radiolist "$title3" 0 0 0 \
 "${listd[@]}" \
 3>&1 1>&2 2>&3 3>&-)
elif [ "$manager" == "z" ]
then
 trg=$(zenity --list --radiolist \
 --width=$((msiz * 800 / 100)) --height=$((msiz * 320 / 100)) \
 --title="$title1" --cancel-label="Quit" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --column="Select" --column="Device" --column="Target name/model" \
 --column="Size" --column="Bus" --column="Kind of device" \
 "${lst2[@]}" \
 2> /dev/null)
fi

#if [ "$target" != "" ]
#then
# target="/dev/$target"
#else
# target=
#fi

rm "$list0" "$list01" "$list02" "$list03"
}
########################################################################

function p_ldr {

#echo "p_ldr starts here"
ltest0=$(grep -m 1 " / " /etc/mtab|cut -d ' ' -f 1)
if [ "$ltest0" == "/cow" ] || [ "$ltest0" == "aufs" ] || \
   [ "$ltest0" == "rootfs" ] || [ "$ltest0" == "overlay" ]
then
 ltest1=$(grep -m 1 ' /isodevice' /etc/mtab|cut -d ' ' -f 1)
 if [ "$ltest1" != "" ]
 then
  livedrive=$ltest1
 else
  ltest1=$(grep -m 1 ' /cdrom' /etc/mtab|cut -d ' ' -f 1)  # ubuntu live
  if [ "$ltest1" != "" ]
  then
   if [ "$ltest1" == "/dev/loop0" ]  # ubuntu live grub-n-iso
   then
    isodevs=$(lsblk -lo name,label|grep isodevice | wc -l)
    if [ $isodevs -gt 1 ]
    then
     echo -ne "$redback isodevices: "
     lsblk -lo name,label|grep isodevice|cut -d ' ' -f 1 | tr '\n' ' '
     echo -e "assuming the first one is on the live drive $resetvid"
    else
     echo -n "isodevice: "
     lsblk -lo name,label|grep isodevice|cut -d ' ' -f 1
    fi
    livedrive="/dev/$(lsblk -lo name,label|grep -m1 isodevice|cut -d ' ' -f 1)"
   else
    livedrive=$ltest1  # ubuntu normal live
   fi
  else
   ltest1=$(grep -m 1 ' /livecd' /etc/mtab|cut -d ' ' -f 1)
   if [ "$ltest1" != "" ]
   then
    livedrive=$ltest1
   else
    ltest1=$(grep -m 1 ' iso9660' /etc/mtab|grep -v -e ' /media' -e ^/dev/cloop|grep -v ' /mnt'|cut -d ' ' -f 1)
    if [ "$ltest1" != "" ]
    then
     livedrive=$ltest1
    else
#     ltest1=$(grep -m 1 ' iso9660' /etc/mtab|grep ' /mnt-system'|cut -d ' ' -f 1)  # knoppix
     ltest1=$(grep -m 1 ' /mnt-system' /etc/mtab|cut -d ' ' -f 1)  # knoppix
     if [ "$ltest1" != "" ]
     then
      livedrive=$ltest1
     else
      livedrive=$(df 2>/dev/null|grep -m 1 " /$" |cut -d ' ' -f 1)  # mageia
      if [ "$ltest1" != "" ] && test -b "/dev$ltest1"
      then
       livedrive=$ltest1
      else
       ltest1=$(lvm pvdisplay 2> /dev/null |grep 'PV Name'|sed 's/.* //'|cut -d ' ' -f 1)  # fedora
       ltest2=$(df 2>/dev/null|grep -m 1 " /$" |sed 's/ .*//')
       if [ "$ltest1" != "" ] && [ "$ltest2" == "/dev/mapper/fedora-root" ]
       then
        livedrive=$ltest1
        if ! test -b "/dev$livedrive"
        then
         livedrive="not_found"
        fi
       fi
      fi
     fi
    fi
   fi
  fi
 fi
elif [ "${ltest0/\/dev\/[^f]d}" != "" ] \
  && [ "${ltest0/\/dev\/mmcblk}" != "" ] \
  && [ "${ltest0/\/dev\/nvme}" != "" ]
then
 livedrive=$(df 2>/dev/null|grep -m 1 '/$' |cut -d ' ' -f 1)
else
 livedrive=$(df 2>/dev/null|grep -m 1 " /$" |cut -d ' ' -f 1)
 if ! test -b "$livedrive"
 then
  livedrive="not_found"
 fi
fi
l_ldrv=${#livedrive}
l_m1=$((l_ldrv - 1 ))
l_m2=$((l_ldrv - 2 ))
l_m3=$((l_ldrv - 3 ))
#echo "$l_ldrv"
if test -b "${livedrive:0:$l_m3}"
then
 livedrive="${livedrive:0:$l_m3}"
elif test -b "${livedrive:0:$l_m2}"
then
 livedrive="${livedrive:0:$l_m2}"
elif test -b "${livedrive:0:$l_m1}"
then
 livedrive="${livedrive:0:$l_m1}"
fi
#echo ltest0=$ltest0
#echo ltest1=$ltest1
#echo ltest2=$ltest2
#echo livedrive=$livedrive
}
########################################################################

function p_fstb {

#echo "dollar1=$1"
Isav4=$IFS
IFS=$'\n'
for k in $(grep '^UUID' /etc/fstab 2>/dev/null|tr '=' ' '|cut -d ' ' -f2)
do
 lsblk -o NAME,UUID /dev/[^f]d[a-z][1-9]* /dev/mmcblk?p?* /dev/nvme?n?p?* 2> /dev/null|grep -m1 "$k"
done|grep ^"$1" >/dev/null
if [ $? -eq 0 ]
then
 infstb=true
else
 infstb=false
fi
ISF=$Isav4
#echo "infstb=$infstb"
}
########################################################################

function p_sdr {

#echo "p_sdr: livedrive=$livedrive"
#echo "p_sdr: source=$source ####################  @@@@@@@@@@@@@@@@"
if [ "$source" != "" ] && test -s "$source" && test -f "$source" || test -b "$source"
then
 if test -b "$source"
 then
  sdrive="$source"
 else
  sdrive=$(df "$source"|tail -n1|sed 's/ .*//')
 fi
# echo "sdrive=$sdrive" 
 if test -b "$sdrive"
 then
  l_sdrv=${#sdrive}
  l_m1=$((l_sdrv - 1 ))
  l_m2=$((l_sdrv - 2 ))
  l_m3=$((l_sdrv - 3 ))
# echo "l_sdrv=$l_sdrv"
  if test -b "${sdrive:0:$l_m3}"
  then
   sdrive="${sdrive:0:$l_m3}"
  elif test -b "${sdrive:0:$l_m2}"
  then
   sdrive="${sdrive:0:$l_m2}"
  elif test -b "${sdrive:0:$l_m1}"
  then
  sdrive="${sdrive:0:$l_m1}"
  fi
 else
  sdrive="$livedrive"
 fi
# read -p "sdrive=$sdrive, press Enter to continue" 
elif test -b "$source"
then
echo "source=$source"
 sdrive="$source"
 df -h|grep "$source" > /dev/null && p_calx bash -c "umount $source* 2> /dev/null"
 df -h|grep "$source"
 if [ $? -eq 0 ]
 then
  mount |grep "$source"|grep 'iso9660'
  if [ $? -ne 0 ]
  then
   echo -e "$redback The source device could not be unmounted $resetvid"
   p_clean
   exit
  fi
 fi
fi
}
########################################################################

function p_target {

p_sdr
if [ "$sdrive" != "" ]
then
 echo "Drive that contains source file: $sdrive"
fi
#p_ldr
if [ "$livedrive" != "not_found" ]
then
 echo "Live drive, that is booted from: $livedrive"
else
 echo "Live drive not found"
fi
if [ "$manager" == "z" ] || [ "$manager" == "d" ]
then
 p_lisdz
else
 p_list
 echo    "Example: add 'sdx':  /dev/sdx"
 read -p "Select target device /dev/" trg
fi

target="/dev/$trg"

hpl=$(ls -l /dev/disk/by-id|grep -m1 "${trg}$"|tr -s ' ' '\t'|cut -f 9|cut -b 1-3)
#echo "hpl=$hpl"
if [ "$hpl" == "usb" ] || [ "$hpl" == "mmc" ]
then
 hpl=1
else
 hpl=0
fi

p_fstb "$trg"
echo "p_target: target=$target"

isblk=false
if [ "$target" != "" ]
then
 test -b $target && isblk=true
fi

if [ "$target" == "" ] || ! $isblk
then
 echo "No target device or bad target device"
 rm -f "$pff"
 return 1
elif [ "${target##*/}" == "${livedrive##*/}" ]
then
 echo "This device is busy because it is the live drive (booted from)"
 rm -f "$pff"
 return 1
elif [ "${target##*/}" == "${sdrive##*/}" ]
then
 echo "This device is busy because it contains the source file (to install from)"
 rm -f "$pff"
 return 1
elif $infstb
then
 echo "This device is busy because in /etc/fstab"
 rm -f "$pff"
 return 1
elif [ "$hpl" == "0" ]
then
 pls_chk="Please check again!"
 tell_risk="'$target' is not a USB drive or memory card. $pls_chk"
 ask_risk="Do you really want to overwrite this target device?"
 if [ "$manager" == "z" ]
 then
  zenity --title="$version - $pls_chk" \
  --width=$((msiz * 520 / 100)) \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --question --text="<span font='$mfnt'>$tell_risk

$ask_risk</span>" \
 2>/dev/null
  if [ $? -ne 0 ]
  then
   rm -f "$pff"
   return 1
  fi
 elif [ "$manager" == "d" ]
 then
  dialog \
  --colors \
  --no-collapse \
  --backtitle "$version - $pls_chk" \
  --yesno "$tell_risk\n\n$ask_risk" 14 72 \
  3>&1 1>&2 2>&3 3>&-
  if [ $? -ne 0 ]
  then
   rm -f "$pff"
   return 1
  fi
 else
  echo -e "$inversvid $tell_risk $resetvid"
  read -p "$ask_risk (y/N) " ans
  if [ "$ans" != "y" ]
  then
   rm -f "$pff"
   return 1
  fi
 fi
fi

# check for size of target and warn if big

p_langC
sizbyt=$(lsblk -dbno size "$target")
p_langR
sizgb=$(((sizbyt+500000000)/1000000000))
#echo "target=$target  sizbyt=$sizbyt  sizgb=$sizgb"

echo "target drive size = $sizgb GB"

if [ "$sizgb" -ge "$sizwarn" ]
then
 pls_chk="Please check again!"
 if [ "$manager" == "z" ]
 then
  tell_risk="<span fgcolor='#cc0000'>'$target' drive size = $sizgb GB. $pls_chk</span>"
 elif [ "$manager" == "d" ]
 then
  tell_risk="\Z1'$target' drive size = $sizgb GB. $pls_chk\Zn"
 else
  tell_risk="$redback'$target' drive size = $sizgb GB. $pls_chk $resetvid"
 fi
 ask_risk="Do you really want to overwrite this target device?"
 if [ "$manager" == "z" ]
 then
  zenity --title="$version - $pls_chk" \
  --width=$((msiz * 520 / 100)) \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --question --text="<span font='$mfnt'>$tell_risk

$ask_risk</span>" \
 2>/dev/null
  if [ $? -ne 0 ]
  then
   rm -f "$pff"
   return 1
  fi
 elif [ "$manager" == "d" ]
 then
  dialog \
  --colors \
  --no-collapse \
  --backtitle "$version - $pls_chk" \
  --yesno "$tell_risk\n\n$ask_risk" 14 72 \
  3>&1 1>&2 2>&3 3>&-
  if [ $? -ne 0 ]
  then
   rm -f "$pff"
   return 1
  fi
 else
  echo -e "$inversvid $tell_risk $resetvid"
  read -p "$ask_risk (y/N) " ans
  if [ "$ans" != "y" ]
  then
   rm -f "$pff"
   return 1
  fi
 fi
fi

df -h|grep "$target" > /dev/null && p_calx bash -c "umount $target* 2> /dev/null"
df -h|grep "$target"
if [ $? -eq 0 ]
then
 echo -e "$redback The target device could not be unmounted $resetvid"
 p_clean
 exit
fi
}
########################################################################

function p_seti2u {

# settings for persistence

title1="$version - settings for 'dus-iso2usb'"
title2="'Tick a box' to make a custom selection"

if [ "$manager" == "d" ]
then
 helptext="Move between items with the arrow up/down keys
Press the 'space bar' to make a custom selection"

 settings=$(dialog \
 --backtitle "$title1" \
 --title "$title2" \
 --checklist "$helptext" 0 0 0 \
 msdos "MSDOS partition table (default GPT)" off \
 grold "grub 2.0.4 & 2.0.2    (default grub 2.0.6)" off \
 bflag "boot-flag             (default no boot flag)" off \
 3>&1 1>&2 2>&3 3>&-)
elif [ "$manager" == "z" ]
then
 settings=$(zenity --list --checklist \
 --separator=" " \
 --width=$((msiz * 760 / 100)) --height=$((msiz * 280 / 100)) \
 --title="$title1" --cancel-label="Use defaults" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --column="selected" --column="when ticked" --column="$title2" \
 false msdos "MSDOS partition table (default GPT)" \
 false grold "grub 2.0.4 & 2.0.2    (default grub 2.0.6)" \
 false bflag "boot-flag             (default no boot flag)" \
 2> /dev/null)
fi

if [ "$manager" == "t" ]
then
 read -p "Select 'MSDOS' partition table - default GPT?               (y/N) " a_dos
 read -p "Select 'grub 2.0.4 & 2.0.2'    - default grub 2.0.6?         (y/N) " a_grv
 read -p "Select 'boot-flag'             - default no boot flag)? (y/N) " a_flg

 if [ "$a_dos" == "y" ];then pt="msdos";       else pt="gpt" ; fi
 if [ "$a_grv" == "y" ];then grv="grub-2.0.4"; else grv="grub-2.0.6"; fi
 if [ "$a_flg" == "y" ];then flg="boot-flag";  else flg=; fi

settings="$pt $grv $flg"

else
 settings="${settings// /,}"
 echo "settings=$settings"
 pt=$(<<< "$settings" grep -o 'msdos' ) || pt="gpt"
 grv=$(<<< "$settings" grep -o 'grold' ) || grv="grub-2.0.6"
 if [ "$grv" == "grold" ];then grv="grub-2.0.4"; fi
 flg=$(<<< "$settings" grep -o 'bflag' ) || flg=
 if [ "$flg" == "bflag" ];then flg="boot-flag"; fi
fi
# fix other settings when boot-flag selected
if [ "$flg" == "boot-flag" ]
then
 echo -e "$blueback fixing other settings to match 'boot-flag'$resetvid"
 pt="msdos"
 grv="grub-2.0.4"
elif [ "$pt" == "msdos" ]
then
 echo -e "$blueback setting 'grub.2.0.4' to match 'msdos' partition table $resetvid"
 grv="grub-2.0.4"
fi

#echo "pt=$pt"
#echo "grv=$grv"
#echo "flg=$flg"
}
########################################################################

function p_setting {

# settings for persistence

title1="$version - persistent live drive settings"
title2="'Tick a box' to make a custom selection"

if [ "$manager" == "d" ]
then
 helptext="Move between items with the arrow up/down keys
Press the 'space bar' to make a custom selection"

 settings=$(dialog \
 --backtitle "$title1" \
 --title "$title2" \
 --checklist "$helptext" 0 0 0 \
 msdos "MSDOS partition table (default GPT)" off \
 upefi "usb-pack-efi          (default grub from ISO file)" off \
 d-n-i "download and install  (default DISPLAY when security updates)" off \
 3>&1 1>&2 2>&3 3>&-)
elif [ "$manager" == "z" ]
then
 settings=$(zenity --list --checklist \
 --separator=" " \
 --width=$((msiz * 800 / 100)) --height=$((msiz * 280 / 100)) \
 --title="$title1" --cancel-label="Use defaults" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --column="selected" --column="when ticked" --column="$title2" \
 false msdos "MSDOS partition table (default GPT)" \
 false upefi "usb-pack-efi          (default grub from ISO file)" \
 false d-n-i "Download and Install  (default DISPLAY when security updates)" \
 2> /dev/null)
fi
# -space for persistence -----------------------------------------------

title1="$version - select space for persistence (percent)"
title2="Please select the percentage of the available space for persistence.
The rest of the space will be used for storage (usbdata)."
persdefault=50

if [ "$manager" == "d" ]
then
 text="The dialog shows the current value as a bar (like the gauge dialog). Tabs or arrow keys move the cursor between the buttons and the value. When the cursor is on the value, you can edit it by:

left/right cursor movement: to select a digit to modify
+/-  characters:            to increment/decrement the digit by one
0 through 9:                to set the digit to the given value

Some keys are also recognized in all cursor positions:
home/end:         set the value to its maximum or minimum
pageup/pagedown:  increment the value so that the slider moves one step

$title2"

#--rangebox text height width min-value max-value default-value
 percent=$(dialog \
 --backtitle "$title1" \
 --no-collapse \
 --rangebox \
 "$text" 16 76 1 100 50 \
 3>&1 1>&2 2>&3 3>&-)
elif [ "$manager" == "z" ]
then
 percent=$(zenity --scale \
 --title="$title1" --cancel-label="Use default" \
 --text="<span font='$mfnt'>$title2</span>" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 --value=$persdefault \
 --min-value=1 \
 --max-value=100 \
 2> /dev/null)
fi

if [ "$manager" == "t" ]
then
 read -p "Select 'MSDOS' partition table - default GPT?               (y/N) " a_dos
 read -p "Select 'usb-pack-efi' - default grub from iso file?         (y/N) " a_upe
 read -p "Select 'download and install' security update - default NO? (y/N) " a_dni
 read -p "Enter 'percentage' for persistence - default 50  (enter: 1 - 100) " percent
 settings=
 if [ "$a_dos" == "y" ];then settings="$settings msdos"; fi
 if [ "$a_upe" == "y" ];then settings="$settings upefi"; fi
 if [ "$a_dni" == "y" ];then settings="$settings d-n-i"; fi

 if [ "$percent" == "" ]; then
   echo "blank percentage, using default (50%)"; percent=50
 else
  re='^[0-9]+$'
  if ! [[ $percent =~ $re ]];then
   echo "not an integer number 1 - 100, using default (50%)"; percent=50
  elif [ $percent -lt 1 ] || [ $percent -gt 100 ];then
   echo "not an integer number 1 - 100, using default (50%)"; percent=50
  fi
 fi
fi

if [ "$percent" == "" ]
then
 percent=$persdefault
fi

if [ "$(find /usr/share/mkusb/ -name 'usb-pack_efi*')" != "" ]
then
 if ! ( test -e /usr/share/mkusb/usb-pack_efi-0.tar.xz && \
        test -e /usr/share/mkusb/usb-pack_efi-1.tar.xz && \
        test -e /usr/share/mkusb/usb-pack_efi.tar.xz && \
        test -e /usr/share/mkusb/grub-0.img.xz && \
        test -e /usr/share/mkusb/grub-1.img.xz && \
        test -e /usr/share/mkusb/grub.img.xz ) || \
        diff /usr/share/mkusb/{grub.img.xz,grub-0.img.xz}
 then
  p_usb_pack_manage
  cd "$curdir"
  if [ $? -ne 0 ]
  then
   p_clean
   exit
  fi
 fi
fi

settings="${settings// /,}"
echo "settings=$settings"
echo "percent=$percent"
}
########################################################################

function p_chk_programs {

# check for various programs and suggest installation if not found

par_org="$1"
need_pck=
want_pck=
s_pers="a persistent live drive"
s_win="a windows installer"

p_need_pck_s parted
p_need_pck_s gdisk
p_need_pck_s mkfs.vfat "package dosfstools"
p_need_pck_s mkfs.ntfs "package ntfs-3g"
p_need_pck lsblk "package util-linux"
p_need_pck df "package coreutils"
p_need_pck_s mount
p_need_pck gzip
p_need_pck xz "package xz-utils"
# p_need_pck xterm
p_want_pck pv
p_want_pck find "package findutils; only to make $s_pers"
p_want_pck rsync "to make $s_pers or $s_win"
p_want_pck tar "to make $s_pers or $s_win"
p_want_pck watch-flush "package mkusb-common; to show flushing of buffers"
p_want_pck_s mkusb-tow "package mkusb-common; to make $s_win"
p_want_pck mkusb-common "to make $s_pers and to get a good GUI experience"
# p_want_pck usb-pack-efi "only to make $s_pers"

if [ "$1" != "-t" ]
then
 if [ "${TERM:0:5}" == "xterm" ] || [ "$TERM" != "linux" ] || [ "$DISPLAY" != "" ]
 then
#  echo "dus thinks it runs in *graphics* mode, and checks for zenity"
  p_want_pck zenity "to get GUI menus"
  which zenity > /dev/null || p_want_pck dialog "to get text menus"
 else
  echo "dus thinks it runs in *text* mode, and does not check for zenity"
  echo "dus checks for dialog"
  p_want_pck dialog "to get text menus"
 fi
fi

if [ "$1" == "-d" ]
then
 p_want_pck dialog "to get text menus"
fi

if [ "$distr" == "opensuse" ]
then
 p_want_pck_s grub2-install "grub-i386-pc: to make $s_pers or $s_win"
else
 p_want_pck_s grub-install "grub-pc: to make $s_pers or $s_win"
fi

if [ "$want_pck" != "" ]
then
 echo -e "$blueback${0##*/} wants the program(s) $want_pck $resetvid"
 echo -e "$inversvid Please install the corresponding package(s) $resetvid"
 rm -f "$pff"
 if [ "$manager" == "d" ]
 then
  dlay=8
  read -t "$dlay" -p "Press Enter to continue, or wait $dlay seconds "
 fi
fi
if [ "$need_pck" != "" ]
then
 echo -e "$redback${0##*/} needs the program(s) $need_pck $resetvid"
 echo -e "$inversvid Please install the corresponding package(s) $resetvid"
 rm -f "$pff"
 exit
fi
}
########################################################################

function p_welcome {

w_tmp=
i_tmp=
if [ "$want_pck" != "" ]
then
 w_tmp="${0##*/} wants the program(s) <span fgcolor='#2252a0'>$want_pck</span>"
 i_tmp="Please install the corresponding package(s)"
fi
 welcome="<b><span bgcolor=$logorgb>- Do USB Stuff -</span>

Welcome and Notice about Overwriting</b>

<span fgcolor='#cc0000'>The target device will be completely overwritten</span>

$w_tmp
$i_tmp"
 zenity --info \
  --width=$((msiz * 350 / 100)) --height=$((msiz * 280 / 100)) \
 --title="$title0" \
 --text="<span font='$mfnt'>$welcome</span>" \
 --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
 2> /dev/null
}
########################################################################

function p_sniff {

# some basic tests

if [ $# -ne 1 ]
then
 echo "Usage: p_sniff <file.iso>"
 exit
fi

if ! test -e "$1"
then
 echo "p_sniff: '$1' is not a file" > /dev/stderr
 return
elif test -b "$1"
then
 echo "'$1' is a block device" > /dev/stderr
 return
elif [[ "${1,,}" =~ '.img' ]]
then
 echo "'$1' is an image file"
 return
elif ! [[ "${1,,}" =~ '.iso' ]]
then
 echo "'$1' is not an iso file" > /dev/stderr
 return
fi

# arrays showing which distros can be managed by the mkusb tools/methods
# in order to create persistent live system (and windows installer)

dist_dus_p=( ubuntu \
 'Debian.GNU.Linux.Live.1[01]' 'Debian.GNU.Linux.12' \
  bodhi elementary mint "linux.lite" lxle parrot sparky zorin )
dist_dus_iu=( ubuntu )
dist_plug=( ubuntu debian kaisen "kali[^a-z]" neon mint lmde q4os rescatux solyd sparky supergamer )
dist_clon=( opensuse knoppix endless "kali[^a-z]" )
dist_win=( windows )
dist_tot=( ${dist_dus_p[@]} ${dist_dus_iu[@]} ${dist_plug[@]} ${dist_clon[@]} ${dist_win[@]} )

# other variables

sniftot=true
inversvid="\0033[7m"
resetvid="\0033[0m"
totaltxt="<b>Cloning</b> works with most linux distros to make <b>live-only</b> system.

Crude estimate of possible mkusb tools/methods for persistent live Linux system:
"

snif_txt0="${blueback}Crude estimate of possible mkusb tools/methods to create$resetvid
${blueback}persistent live drive from the selected iso file:$resetvid
$inversvid $1 $resetvid"

# prepare testing 

echo -e "$snif_txt0"
q_snff
p_snff "$1"

# test and write to console

t_dus_p "$1"
t_dus_iu "$1"
t_plug "$1"
t_clon "$1"
t_win "$1"

if $sniftot
then
 snif_txt1="p_sniff <b>cannot tell</b> how to make persistent live system,
see details at the following links:
https://help.ubuntu.com/community/mkusb/gui#Linux_distros_where_mkusb_works
https://help.ubuntu.com/community/mkusb/minp/details"
 z_snff "$snif_txt1"
fi
echo -e \
"$blueback------------------------------------------------------------------$resetvid"

# output to zenity window

if $zniff
then
 if [ "$manager" == "z" ]
 then
 totaltxt="Selected iso file:
<b>$1</b>

$totaltxt"
 zenity --info --title="$version - possible mkusb tools/methods" \
  --window-icon="/usr/share/icons/hicolor/48x48/apps/mkusb.png" \
  --width=$((msiz * 760 / 100)) --height=$((msiz * 320 / 100)) \
  --text="$totaltxt" \
  2> /dev/null
 elif [ "$manager" == "d" ]
 then
  read -p "Press Enter to continue"
 fi
fi
}
########################################################################

function t_dus_p {

sniff=true
	
for i in ${dist_dus_p[@]}
do
 fnam="${1,,}"
 fnam="${fnam##*/}"
 if [[ "$fnam" =~ "${i##*\.}" ]] && [[ "$fnam" =~ "${i%\.*}" ]]
 then
  z_snff "Works with <b>dus-persistent</b> according to name"
  sniff=false
  sniftot=false
  break
 fi
done

if $sniff
then
 for i in ${dist_dus_p[@]}
 do
  tmpstr=$(echo "$snifstr" | grep -i "$i")
  if [ "$tmpstr" != "" ]
  then
   if ! [[ "${tmpstr,,}" =~ "lmde" ]]
   then
    z_snff "Works with <b>dus-persistent</b> according to content"
    sniff=false
    sniftot=false
    break
   fi
  fi
 done
fi
}
#####################

function t_dus_iu {

sniff=true
	
for i in ${dist_dus_iu[@]}
do
 fnam="${1,,}"
 fnam="${fnam##*/}"
 if [[ "$fnam" =~ "$i" ]]
 then
  z_snff "Works with <b>dus-iso2usb</b> according to name"
  sniff=false
  sniftot=false
break
 fi
done

if $sniff
then
 for i in ${dist_dus_iu[@]}
 do
  tmpstr=$(echo "$snifstr" | grep -i "$i")
  if [ "$tmpstr" != "" ]
  then
   z_snff "Works with <b>dus-iso2usb</b> according to content"
   sniff=false
   sniftot=false
   break
  fi
 done
fi
}
#####################

function t_plug {

sniff=true
	
for i in ${dist_plug[@]}
do
 fnam="${1,,}"
 fnam="${fnam##*/}"
 if [[ "$fnam" =~ "${i##*\.}" ]] && [[ "$fnam" =~ "${i%\.*}" ]]
 then
  z_snff "Persistent live by <b>mkusb-plug</b> according to name"
  sniff=false
  sniftot=false
  break
 fi
done

if $sniff
then
 for i in ${dist_plug[@]}
 do
  tmpstr=$(echo "$snifstr" | grep -i "$i")
  if [ "$tmpstr" != "" ]
  then
   z_snff "Persistent live with <b>mkusb-plug</b> according to content"
   sniff=false
   sniftot=false
   break
  fi
 done
fi
}
#####################

function t_clon {

sniff=true
	
for i in ${dist_clon[@]}
do
 fnam="${1,,}"
 fnam="${fnam##*/}"
 if [[ "$fnam" =~ "${i##*\.}" ]] && [[ "$fnam" =~ "${i%\.*}" ]]
 then
  z_snff "Persistent live by <b>cloning</b> according to name"
  sniff=false
  sniftot=false
  break
 fi
done

if $sniff
then
 for i in ${dist_clon[@]}
 do
  tmpstr=$(echo "$snifstr" | grep -i "$i")
  if [ "$tmpstr" != "" ]
  then
   z_snff "Persistent live by <b>cloning</b> according to content"
   sniff=false
   sniftot=false
   break
  fi
 done
fi
}
#####################

function t_win {

#sniff=true
	
for i in ${dist_win[@]}
do
 fnam="${1,,}"
 fnam="${fnam##*/}"
 if [[ "$fnam" =~ "$i" ]]
 then
  totaltxt=
  z_snff "Only <b>Windows installer</b> can be created according to name"
  sniff=false
  sniftot=false
  zniff=true
  break
 fi
done

if $sniff
then
 for i in ${dist_win[@]}
 do
  tmpstr=$(echo "$snifstr" | grep -i "$i")
  if [ "$tmpstr" != "" ] && \
  ! [[ "${tmpstr,,}" =~ "menuentry" ]] &&
  ! [[ "${tmpstr,,}" =~ "ntpasswd:" ]] &&
  ! [[ "${tmpstr,,}" =~ "# ms" ]] &&
  ! [[ "${tmpstr,,}" =~ "windows_efi" ]]
  then
   z_snff "Only <b>Windows installer</b> can be created according to content"
   sniff=false
   sniftot=false
   zniff=true
   break
  fi
 done
fi
}
########################################################################

function p_snff {

lptst=$(mktemp -d)
snif_fil0=$(mktemp)
snif_fil1=$(mktemp)

p_calx bash -c "mount -o loop \"$1\" \"$lptst\" > /dev/null 2> /dev/null"
if [ $? -eq 0 ]
then
 find "$lptst" -type f -name '*.cfg' -exec grep -i  -e 'menuentry' \
 -e 'menu title' -e 'label' -e 'windows' {} \; > "$snif_fil0"
 grep "^.*$" "$lptst"/.disk/info >> "$snif_fil0" 2>/dev/null
 for i in ${dist_tot[@]}
 do
  grep -i "$i" "$snif_fil0" | head -n1 >> "$snif_fil1"
 done
 snifstr="$(cat "$snif_fil1")"
 echo "$snifstr"
 p_calx umount "$lptst"
else
 echo "p_sniff: could not mount '$1'" > /dev/stderr
fi
rmdir "$lptst"
rm "$snif_fil0"
rm "$snif_fil1"
}
########################################################################

function q_snff {

filtot0=$(mktemp)
filtot1=$(mktemp)

for i in ${dist_tot[@]}
do
 echo "$i" >> "$filtot0"
done
sort "$filtot0" | grep -v -e ubuntu -e debian | uniq > "$filtot1"
echo "ubuntu
debian" > "$filtot0"
cat "$filtot1" >> "$filtot0"
dist_tot=( $(cat "$filtot0") )
#echo ${dist_tot[@]}

rm "$filtot0" "$filtot1"
}
########################################################################

function z_snff {

totaltxt="$totaltxt
$1"
snif_text="${1/\<b\>/$inversvid }"
snif_text="${snif_text/\<\/b\>/ $resetvid}"
echo -e "$snif_text"
}
########################################################################

#     main

########################################################################

if [ "$1" == "-v" ]
then
 echo "$version"
 exit
elif [ "$1" == "-h" ]
then
 echo "$version"
 usage
fi 

echo -e "$inversvid $version $resetvid"

p_cal1 $1
p_chk_programs "$1"
p_chk_param "$@"
p_langC
p_ldr
p_sdr
p_langR

# Welcome and Notice about Overwriting 

title0="$version - Do USB Stuff"

if [ "$manager" == "d" ]
then
 welcome="                     \Zb- Do USB Stuff -
           Welcome and Notice about Overwriting\Zn
     \Z1The target device will be completely overwritten\Zn"
 titled="$welcome"
elif [ "$manager" == "z" ]
then
 p_welcome
elif [ "$manager" == "t" ]
then
 welcome="$inversvid
+------------------------  Do USB Stuff  -------------------------+
|              Welcome and Notice about Overwriting               |
|       $resetvid$redback The target device will be completely overwritten $resetvid$inversvid        |
+------------------------  quit with (q)  ------------------------+$resetvid"

 /bin/echo -e "$welcome"
fi

#echo "source=$source"

# start general menu or if parameter with source file, start install menu


if [ "$source" == "" ]
then
 p_starter
elif [ "${source%.iso}.iso" != "$source" ]
then
 p_live
else
 p_install
fi

LANG="$curlang"
LC_ALL="$curlc_all"
