1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
#!/bin/bash
########################################################################################
# /usr/bin/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/bin/copyiso2usb' used
# to create copyiso2usb.po (which was manually renamed to copyiso2usb.pot)
########################################################################################
# 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)
ThisScript="$0"
if [[ ! ${ThisScript:0:1} = '/' ]] ; then
ThisScript="$(pwd)/$0"
fi
# Exit if not root.
if [[ "$(id -u)" != "0" ]] ; then
exec pkexec "$ThisScript" "$@"
MustBeRoot=$(eval_gettext "Must be root to run \$ThisScript")
ShowMsgExit "$MustBeRoot"
exit 0
fi
#Check to see if running under pkexec, aka policykit and X
pktest=${PKEXEC_UID-"unset"}
if [ ! "unset" = "$pktest" ] ; then
mydisplay=$(strings "/proc/$PPID/environ"|grep ^DISPLAY=)
myxauthority=$(strings "/proc/$PPID/environ"|grep ^XAUTHORITY=)
if [ -n "$mydisplay" ] ; then
export DISPLAY=eval "$mydisplay"
export XAUTHORITY=eval "$myxauthority"
fi
fi
# Set dialog command to use
#dialogcmd="/usr/bin/Xdialog" #Removed after finding errors from things like fontconfig can cause problems.
#displaytest=${DISPLAY-"unset"}
#if [ ! -e /usr/bin/Xdialog ] || [ ! -x /usr/bin/Xdialog ] || [ "unset" = "$displaytest" ] ; then
dialogcmd="/usr/bin/dialog"
#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 $(tree -if /sys/devices|grep usb|grep /block/sd\[a-z\]\$); 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"
}
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
|