From 144525ecde395b581e5929d3c174921df170d617 Mon Sep 17 00:00:00 2001 From: Dave Hodgins Date: Thu, 3 Oct 2013 12:19:14 -0400 Subject: Add actual script file --- copyiso2usb | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100755 copyiso2usb diff --git a/copyiso2usb b/copyiso2usb new file mode 100755 index 0000000..19127bc --- /dev/null +++ b/copyiso2usb @@ -0,0 +1,323 @@ +#!/bin/bash +######################################################################################## +# /usr/sbin/copyiso2usb +######################################################################################## +# Usage: copyiso2usb [isofile] +# Installs needed packages if missing - dcfldd cdialog udisks mlocate +# Runs locate command if needed mmlocate.db doesn't exist, or is more than 24 hours +# old, or requested. +# Uses the locate command to find iso images, presented in a selection dialog, unless +# a file name is passed as the only argument. +# Lists usb drives in a selection dialog +# Checks that the iso will fit on the selected drive +# Confirms that the command should be run +# Copies the iso image to the usb drive. +# +# Note for maintainers 'xgettext -d copyiso2usb -L Shell /usr/sbin/copyiso2usb' used +# to create copyiso2usb.po (which was manually renamed to copyiso2usb.pot) +# +# If installing manually, also suggest installing Xdialog and runnning +# 'ln -s /usr/bin/consolehelper /usr/sbin/copyiso2usb' +######################################################################################## +# Author: David W. Hodgins - Mageia Qa team +# 2013-06-02 Initial writing +# 2013-06-04 Added iso as arg, fix for no partition table on usb stick, Thanks barjac. +# 2013-08-22 Converted to use gettext for translations +######################################################################################## +set -u # Show usage of unset variables as an error, to help catch typos. +# Obtain translations for all static messages (message with vars translated when needed) +. /usr/bin/gettext.sh +TEXTDOMAIN=copyiso2usb +export TEXTDOMAIN +TEXTDOMAINDIR=/usr/share/locale/ +export TEXTDOMAINDIR +Newline="\n" +TitleString=$(gettext "Copy iso image to usb drive") +SelectISO=$(gettext "Select iso image to be copied to a usb drive") +NoISOFound=$(eval_gettext "No iso images found.\${Newline}\${Newline}If an iso has been recently downloaded, please run /etc/cron.daily/mlocate.cron\${Newline}so that this script can find them using the locate command.") +NoUSBDrives=$(eval_gettext "No usb drives found.\${Newline}\${Newline}Please insert a usb drive, and then rerun this script.") +SelectUSBDrive=$(gettext "Select usb drive to copy the iso image to") +CopyCancelled=$(gettext "Copy cancelled. Exiting.") +Waitmlocate=$(gettext "Running /etc/cron.daily/mlocate.cron. Please wait for 'rc=0' before continuing.") +WaitCopy=$(gettext "Copying iso to usb drive. Please wait for 'rc=0' before continuing.") +FileNameTemp=$(mktemp -p /tmp "${0##*/}".XXXXXX) + +# Set dialog command to use +dialogcmd="/usr/bin/Xdialog" +displaytest=${DISPLAY-"unset"} +if [ ! -e /usr/bin/Xdialog ] || [ ! -x /usr/bin/Xdialog ] || [ "unset" = "$displaytest" ] ; then + dialogcmd="/usr/bin/dialog" +fi + +ThisScript="$0" +if [[ ! ${ThisScript:0:1} = '/' ]] ; then + ThisScript="$(pwd)/$0" +fi + +# Function to get window size +GetDisplaySize() { + IFS=$':, ' + read label MaxLines MaxColumns<<<"$($dialogcmd --print-maxsize --output-fd 1 2>&1)" + unset IFS + MenuHeight=$(( MaxLines - 5 )) +} + +GetDisplaySize + +# Function to list all usb drives +listusbdrives () { + for block in /sys/devices/pci*/*/usb*/*/*/host*/target*/*/block/sd*; do + device=${block##*/} # strip last slash and everything before it. + printf '%s\n' "$device" + done +} + +menuitem=0 +MenuText="" +DisplayMenu() { + GetDisplaySize + $dialogcmd --backtitle "$TitleString" --title "copyiso2usb" --menu "$DisplayText" "$MaxLines" "$MaxColumns" "$MenuHeight" $MenuText 2>$FileNameTemp +} + +DisplayInfo() { + GetDisplaySize + $dialogcmd --backtitle "$TitleString" --title "copyiso2usb" --msgbox "$DisplayText" "$MaxLines" "$MaxColumns" +} + +RunCommandX() { + GetDisplaySize + printf '%s\n\n' "$DisplayText" >$FileNameTemp + ( printf '%s\n' "$@" ; eval "$@" ; result=$? ; printf '%s\n' "rc=$result" ) >>$FileNameTemp & + $dialogcmd --backtitle "$TitleString" \ + --title "copyiso2usb" \ + --tailbox "$FileNameTemp" "$MaxLines" "$MaxColumns" + rm -f "$FileNameTemp" +} + +RunCommand() { + if [[ "$dialogcmd" = "/usr/bin/dialog" ]] ; then + printf '%s\n\n' "$DisplayText" + eval "$@" + result=$? + printf '%s\n' "rc=$result" + else + RunCommandX "$@" + fi +} + +ShowMsgExit() { + DisplayText="$@" + DisplayInfo + exit 0 +} + +# Function to install missing packages +InstallPackageIfFileMissing() { +# Install command, if it isn't already available + if [ ! -x "$1" ] ; then + Command="$1" + Package="$2" + CmdNotFoundInstalling=$(eval_gettext "\$Command command not found. Installing \$Package") + DisplayText="$CmdNotFoundInstalling" + RunCommand "urpmi --auto $2" + result=$? + if (($result)) ; then + FailedExiting=$(eval_gettext "urpmi failed. Return code was \$result. Exiting.") + ShowMsgExit "$FailedExiting" + exit 1 + fi + fi +} + +# Function to convert size to human readable format +declare -a SpaceUnits=( B KB MB GB TB PB ) +declare -i SpaceUnitsIndex +declare -i SpaceInt +setspaceunits () { + SpaceUnitsIndex=0 + (( Size *= 100 )) # add two decimal places + while [ "$Size" -ge 102400 ] ; do + let Size="$Size"/1024 + (( SpaceUnitsIndex++ )) + done + SpaceString="$Size" + StringLength=${#SpaceString} + let Intlength="$StringLength - 2" + StringLeft=${SpaceString:0:$Intlength} + StringRight=${SpaceString:$Intlength} + SpaceString="$StringLeft.$StringRight${SpaceUnits[$SpaceUnitsIndex]}" + if [ "$Size" -gt 100 ] ; then + SpaceString="$SpaceString"s + else + SpaceString="$SpaceString " + fi + printf '%s' "$SpaceString" +} + +# Exit if not root. +if [[ "$(id -u)" != "0" ]] ; then + MustBeRoot=$(eval_gettext "Must be root to run \$ThisScript") + ShowMsgExit "$MustBeRoot" + exit 0 +fi + +InstallPackageIfFileMissing /usr/bin/dcfldd dcfldd +InstallPackageIfFileMissing /usr/bin/dialog cdialog +InstallPackageIfFileMissing /usr/bin/udisks udisks +InstallPackageIfFileMissing /etc/cron.daily/mlocate.cron mlocate + +if="" +if [[ $# -eq 1 && -r "$1" ]] ; then + if="$1" +fi + +runmlocate="no" +if [ -z "$if" ] ; then + if [ ! -s /var/lib/mlocate/mlocate.db ] ; then + runmlocate="yes" + else + dbdatetext=$(stat /var/lib/mlocate/mlocate.db|grep Modify) + dbdate="${dbdatetext#* }" # strip upto and including first space + dbdatesecondssince1970=$(date -u -d "$dbdate" "+%s") + currentsecondscince1970=$(date -u "+%s") + dbageseconds=$(( $currentsecondscince1970 - $dbdatesecondssince1970 )) + if (("$dbageseconds" > "86400")) ; then # 86400 seconds is one day + runmlocate="yes" + else + mlocateAsk=$(eval_gettext "mlocate.db is \${dbageseconds} seconds old (it's used to locate iso files), would you like it updated?") + $dialogcmd --backtitle "$TitleString" \ + --title "copyiso2usb" \ + --yesno "$mlocateAsk" "$MaxLines" "$MaxColumns" + Selected=$? + if (( ! $Selected)) ; then + runmlocate="yes" + fi + fi + fi +fi + + +if [[ "$runmlocate" == "yes" ]] ; then + DisplayText="${Waitmlocate}" + RunCommand "/etc/cron.daily/mlocate.cron" +fi + +IFS=$'\n' +isolist=($(locate -eiq .iso|grep -i iso$)) +unset IFS +if [ "${#isolist[@]}" == 0 ] ; then + ShowMsgExit "$NoISOFound" + exit 2 +fi + +for i in "${isolist[@]}" ; do + isolistshow="${i// /_}" # Show spaces in file names as underscores + MenuText="$MenuText $menuitem ${isolistshow}" + (( menuitem++ )) +done + +if [[ $# -eq 1 && -r "$1" ]] ; then + if="$1" +else + DisplayText="$SelectISO" + DisplayMenu + Selected=$(<$FileNameTemp) + rm -f "$FileNameTemp" + if [[ "${Selected}" == "" ]] ; then + exit 3 # Cancel selected + fi + if="${isolist[$Selected]}" +fi + +shopt -s nullglob +usbdrives=($(listusbdrives)) + +if [ "${#usbdrives[@]}" == 0 ] ; then + ShowMsgExit "$NoUSBDrives" + exit 4 +fi + +menuitem=0 +MenuText="" + +for dev in "${usbdrives[@]}" ; do + IFS=$'\n' + udisksinfo=($(udisks --show-info /dev/$dev |grep -e size -e label -e vendor -e model -e serial)) + unset IFS + Size=${udisksinfo[0]##*: } + read -rd '' Size <<< "$Size" + usbsize[$menuitem]="$Size" + SizeString=$(setspaceunits) + Label=${udisksinfo[2]##*: } + Vendor=${udisksinfo[3]##*: } + Model=${udisksinfo[4]##*: } + Serial=${udisksinfo[5]##*: } + if [[ "${Label}" == "" ]] ; then + udisksinfo=($(udisks --show-info /dev/${dev}1 |grep -e label)) + Label=${udisksinfo[0]##*:} + fi + Mountpoint="" + read mntdev Mountpoint rest<<<"$(grep ^/dev/$dev /proc/mounts)" + read -rd '' SizeString <<< "$SizeString" # Remove leading/trailing spaces + SizeString="${SizeString// /_}" # Translate any embedded spaces to underscores + Label="" + read -rd '' Label <<< "$Label" + if [[ "${Label}" == "" ]] ; then + if [ -e "/dev/${dev}1" ] ; then + IFS=$'\n' + udisksinfo=($(udisks --show-info /dev/${dev}1 |grep -m 1 label)) + unset IFS + Label=${udisksinfo[0]##*:} + fi + fi + read -rd '' Label <<< "$Label" + Label="${Label// /_}" + read -rd '' Vendor <<< "$Vendor" + Vendor="${Vendor// /_}" + read -rd '' Model <<< "$Model" + Model="${Model// /_}" + read -rd '' Serial <<< "$Serial" + Serial="${Serial// /_}" + read -rd '' Mountpoint <<< "$Mountpoint" + Mountpoint="${Mountpoint// /_}" + if [[ ! "${Mountpoint}" == "" ]] ; then + Mountpoint="---MOUNTED_at_${Mountpoint}" + fi + MenuText="$MenuText $menuitem ${dev}.${SizeString}.${Label}.${Vendor}.${Model}.${Serial}${Mountpoint}" + (( menuitem++ )) +done +DisplayText="$SelectUSBDrive" +DisplayMenu +Selected=$(<$FileNameTemp) +rm -f "$FileNameTemp" + +if [[ "${Selected}" == "" ]] ; then + exit 5 # Cancel selected +fi + +of="${usbdrives[$Selected]}" +ofsize="${usbsize[$Selected]}" +ddcmd="dcfldd sizeprobe=if statusinterval=5 if='""$if""' of=/dev/$of bs=1M" + +read label IsoSize rest<<<"$(stat $if|grep Size)" +if (( $IsoSize > $ofsize )) ; then + TooBig=$(eval_gettext "ISO size is \$IsoSize bytes. Selected USB stick only has room for \$ofsize bytes. Copy cancelled. Exiting.") + ShowMsgExit "$TooBig" + exit 7 +fi + +ConfirmRun=$(eval_gettext "About to run\${Newline}\${ddcmd}\${Newline}Please select yes to confirm, or no to cancel.\${Newline}NOTE: When it runs, please wait for 'rc=0' before continuing.") +$dialogcmd --backtitle "$TitleString" \ + --title "copyiso2usb" \ + --yesno "$ConfirmRun" "$MaxLines" "$MaxColumns" +Selected=$? + +if (($Selected)) ; then + ShowMsgExit "$CopyCancelled" + exit 7 +fi + +DisplayText="$WaitCopy" +RunCommand "${ddcmd} 2>&1" +exit 0 + -- cgit v1.2.1