fix sed -i invocations
[unleashed-kayak.git] / usbgen.sh
blob17a028eb5940f8bc6003bec848208c4440ba453f
1 #!/usr/bin/ksh93
4 # CDDL HEADER START
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
21 # CDDL HEADER END
25 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 # Use is subject to license terms.
30 # Generate USB image from iso
33 # Solaris needs /usr/xpg4/bin/ because the tools in /usr/bin are not
34 # POSIX-conformant
35 export PATH=/usr/xpg4/bin:/bin:/usr/bin:/usr/sbin
37 # Make sure all math stuff runs in the "C" locale to avoid problems
38 # with alternative # radix point representations (e.g. ',' instead of
39 # '.' in de_DE.*-locales). This needs to be set _before_ any
40 # floating-point constants are defined in this script).
41 if [[ "${LC_ALL}" != "" ]] ; then
42 export \
43 LC_MONETARY="${LC_ALL}" \
44 LC_MESSAGES="${LC_ALL}" \
45 LC_COLLATE="${LC_ALL}" \
46 LC_CTYPE="${LC_ALL}"
47 unset LC_ALL
49 export LC_NUMERIC=C
51 #######################################################################
52 # usage
53 # Print the usage message.
54 # Input: none
55 # Returns: none
57 #######################################################################
58 function usage
60 print -u2 "\nUsage: "
61 print -u2 "${progname} iso_file usb_image tmpdir"
62 print -u2 "iso_file : The path to an existing iso file."
63 print -u2 "usb_image : The path to usb image to be created."
64 print -u2 "tmpdir : Temporary directy used during usb image " \
65 "creation.\n"
67 print -u2 "If tmpdir does not exist it will be created. If " \
68 "it or subdirectories under tmpdir can not be created " \
69 " an error is generated and this script exits."
73 #######################################################################
74 # get_filesize
75 # Get filesize for the file argv[2] and return it to the
76 # variable defined by argv[1].
77 # Input:
78 # $1 - variable to return filesize in
79 # $2 - file to query
81 # Returns:
82 # $1 - variable to return filesize in
84 # -1 if file does not exist
86 # A non-zero exit code only for internal errors and success
87 # in all other cases
89 #######################################################################
90 function get_filesize
92 set -o errexit
93 nameref filesize_ret="$1" # return filesize into this varable
94 typeset filename="$2" # file to query
95 integer filesize=-1 # temporary integer for "read" below
96 typeset dummy # dummy string
98 if [[ -f "${filename}" ]] ; then
99 ls -lb "${filename}" | \
100 grep "${filename}" | \
101 read dummy dummy dummy dummy filesize dummy
104 (( filesize_ret=filesize ))
105 return 0
110 #######################################################################
111 # cleanup
112 # This function attempst to clean up any resources this script
113 # could generate. Depending on where in the script this function
114 # is involked some resouces may not be there to cleanup, but
115 # that will not adversely effect anything.
117 # This function is not defined using the function keyword
118 # to avoid an exit loop.
120 # Input: none
121 # Returns: none
123 #######################################################################
124 cleanup ()
128 trap "" ERR INT
129 set +o errexit
131 # unmounting, and uninstalling the lofi'ed devices and
132 # cleanup temporary files.
133 IFS=''
135 typeset mount_output="$(mount)"
137 [[ "${mount_output}" == ~(E).*"${usb_path}".* ]] && \
138 umount "${usb_path}"
140 [[ "${mount_output}" == ~(E).*"${iso_path}".* ]] && \
141 umount "${iso_path}"
143 lofiadm "${usb_file}" && \
144 lofiadm -d "${usb_file}"
146 lofiadm "${iso_file}" && \
147 lofiadm -d "${iso_file}"
149 if [[ -d "${iso_path}" ]] ; then
150 rm -rf "${iso_path}"
153 if [[ -d "${usb_path}" ]] ; then
154 rm -rf "${usb_path}"
158 # If the tmpdir did not exist this script could
159 # have created it, so remove it here.
161 if ! ${tmpdir_existed} ; then
162 rm -rf "${tmpdir}"
164 } > /dev/null 2>&1
168 #######################################################################
169 # error_handler
170 # The error_handler for this script. Will cleanup the usb image
171 # that could have been partially created. Then invoke cleanup
172 # to clean up any temporary resouces.
174 # This function is not defined using the function keyword
175 # to avoid an exit loop.
177 # Input: none
178 # Returns: none
180 #######################################################################
181 error_handler ()
183 trap "" ERR INT
184 set +o errexit
186 print -u2 "\nError:\n"
187 print -u2 -r -- "${progname}: $*"
188 cleanup
191 # If an error was encountered while attempting to create
192 # the new usb image file don't leave a possibley partially
193 # constructed one around.
195 if [[ -f "${usb_file}" ]] ; then
196 rm -rf "${usb_file}" > /dev/null 2>&1
199 exit 1
202 # main
203 #######################################################################
204 # main
206 # Input:
207 # iso_file : The path to an existing iso file.
208 # usb_image : The path to usb image to be created.
209 # tmpdir : Temporary directroy used during usb image creation.
211 # If tmpdir does not exist it will be created. If it can not be
212 # created an error is generated and this script exits.
214 # This script must be run as root"
216 # Logic Flow:
217 # Set up error handling.
218 # Confirm input arguments.
219 # Create temporary directories.
220 # Mount up the existing ISO image file.
221 # Compute the size for the new USB image.
222 # Create and mount an empty new USB image.
223 # Copy the contents of the ISO file to the new USB image.
224 # Remove GRUB entries from the USB image which apply only to ISO.
225 # Set the file protections for the new USB image.
227 # Returns:
228 # 1 on failure
229 # 0 on success
231 #######################################################################
232 builtin chmod
233 builtin cp
234 builtin mkdir
235 builtin mv
236 builtin rm
238 typeset -r progname="$0"
239 typeset -r iso_file="$1"
240 typeset -r tmpdir="$3"
241 typeset tmpdir_existed=true
242 typeset -r iso_path="${tmpdir}/iso"
244 typeset -r usb_file="$2"
245 typeset -r usb_path="${tmpdir}/usb"
246 float usb_size # need floating-point for the calculations below
248 typeset isodev
249 typeset devs
250 typeset rdevs
251 typeset s0devs
252 typeset rs0devs
253 typeset rs2devs
256 # Confirm input arguments.
258 if [[ $(id) != ~(E).*uid=0\(root\).* ]]; then
259 print -u2 "Error:\nYou must run this script as root"
260 usage
261 exit 1
264 if (( $# != 3 )) ; then
265 print -u2 "Error:\nImproper arguments"
266 usage
267 exit 1
271 # Set up error handling.
272 # Use set -o errexit to trap errors. However, where possible,
273 # explicitly check command return status for errors.
275 trap "error_handler Error or interrupt encountered. Exiting" ERR INT
276 set -o errexit
279 # Create temporary directories.
281 [[ ! -d $tmpdir ]] && tmpdir_existed=false
282 mkdir -p "${iso_path}"
283 if [[ ! -d "${iso_path}" ]] ; then
284 error_handler "Unable to create or access tmpdir ${iso_path}"
287 mkdir -p "${usb_path}"
288 if [[ ! -d "${usb_path}" ]] ; then
289 error_handler "Unable to create or access tmpdir ${usb_path}"
293 # Mount up the existing ISO image file.
295 isodev="$(lofiadm -a "${iso_file}")" || \
296 error_handler "Failed to lofiadm ${iso_file}"
298 mount -F hsfs "${isodev}" "${iso_path}" || \
299 error_handler "Failed to mount ${isodev} on ${iso_path}"
303 # Compute the size for the new USB image.
304 # Use ISO file size + 20% to account for smaller block size on UFS
305 # and the log. Round to nearest kbyte plus 512
306 # plus 4MB for MBR+SMI label
308 get_filesize "usb_size" "${iso_file}"
309 if (( usb_size == -1 )) ; then
310 error_handler "Failed to get size of file ${iso_file}"
312 (( usb_size=((int( (usb_size * 1.2) / 1024.) * 1024.) + 512) + 4194304 ))
315 # Create and mount an empty new USB image.
317 mkfile -n ${usb_size} "${usb_file}" || \
318 error_handler "Failed to create file ${usb_file}"
320 devs="$(lofiadm -la "${usb_file}")" || \
321 error_handler "Failed to lofiadm file ${usb_file}"
324 # Set rdevs by replacing dsk with rdsk in devs
326 rdevs="${devs/dsk/rdsk}"
327 # for mount
328 s0devs="${devs/p0/s0}"
329 # for newfs and installboot
330 rs0devs="${rdevs/p0/s0}"
331 # for prtvtoc | fmthard
332 rs2devs="${rdevs/p0/s2}"
335 # create Solaris2 partition
337 fdisk -B "${rdevs}"
338 prtvtoc "${rs2devs}" | nawk '
339 /^[^\*]/ { r = $1; for(n = 1; n <= NF; n++) vtoc[r,n] = $n }
340 END {
341 vtoc[0,1] = 0;
342 vtoc[0,2] = 2;
343 vtoc[0,3] = 00;
344 vtoc[0,4] = vtoc[8,6] + 1;
345 vtoc[0,5] = vtoc[2,6] - vtoc[8,6];
346 vtoc[0,6] = vtoc[2,6];
347 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
348 vtoc[0,1], vtoc[0,2], vtoc[0,3], vtoc[0,4], vtoc[0,5], vtoc[0,6]);
349 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
350 vtoc[2,1], vtoc[2,2], vtoc[2,3], vtoc[2,4], vtoc[2,5], vtoc[2,6]);
351 printf("\t%d\t%d\t%02d\t%d\t%d\t%d\n",
352 vtoc[8,1], vtoc[8,2], vtoc[8,3], vtoc[8,4], vtoc[8,5], vtoc[8,6]);
353 }' | fmthard -s- "${rs2devs}"
355 # newfs doesn't ask questions if stdin isn't a tty.
356 newfs "${rs0devs}" </dev/null || \
357 error_handler "Failed to construct the UFS file system ${rs0devs}"
359 mount -o nologging "${s0devs}" "${usb_path}" || \
360 error_handler "Failed to mount construct the UFS file system ${rs0devs}"
363 # Copy the contents of the ISO file to the new USB image.
365 print "Copying ISO contents to USB image..."
366 (cd "${iso_path}"; find . -print | cpio -pmudV "${usb_path}")
369 # install bootblocks
371 installboot -mf "${usb_path}/boot/pmbr" "${usb_path}/boot/gptzfsboot" \
372 "${rs0devs}"
374 # If we get an error hereforth in menu.lst modifications, proceed with a warning
375 trap "" ERR INT
376 set +o errexit
379 # Remove "Hard Disk" GRUB entries from the USB image as they apply only to ISO.
381 nawk '
382 BEGIN { inhard=0 }
383 /^title.*Hard Disk$/ { inhard=1 }
384 /^title/ { if (index($0,"Hard Disk") == 0) inhard=0 }
385 inhard == 0 {print}
386 ' ${usb_path}/boot/grub/menu.lst > ${usb_path}/boot/grub/menu2.lst
387 if [[ $? == 0 ]] ; then
388 mv ${usb_path}/boot/grub/menu2.lst ${usb_path}/boot/grub/menu.lst
389 else
390 print -u2 "Warning: Could not remove \"Hard Disk\" entry from boot menu"
394 # Set the file protections for the new USB image.
396 chmod 444 "${usb_file}"
399 # unmounting, and uninstalling the lofi'ed devices
401 cleanup
403 printf "=== %s completed at %s\n\n" "$0" "$(date)"
405 exit 0