diff options
author | Bill Richardson <wfrichar@chromium.org> | 2011-02-14 15:27:54 -0800 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2011-02-14 15:27:54 -0800 |
commit | be69c259e85d01aa648a3bc323587a68d3df31b3 (patch) | |
tree | f39b4ca7b4fd8d19f762664d9f380b412c53527d | |
parent | a8e0f94b94c2181a95a984fbcd8de80c3ca1b8c9 (diff) | |
download | vboot-be69c259e85d01aa648a3bc323587a68d3df31b3.tar.gz |
Moving user_tools/ to its own git repo.
New location is user-recovery-tools.git
BUG=none
TEST=none
TBR=scottz@chromium.org
Change-Id: I6a07307d7d03fc1111c0d378290ed72f32792982
-rw-r--r-- | user_tools/README.txt | 2 | ||||
-rw-r--r-- | user_tools/README_recovery.txt | 84 | ||||
-rwxr-xr-x | user_tools/linux/recovery.sh | 930 |
3 files changed, 0 insertions, 1016 deletions
diff --git a/user_tools/README.txt b/user_tools/README.txt deleted file mode 100644 index 37500652..00000000 --- a/user_tools/README.txt +++ /dev/null @@ -1,2 +0,0 @@ - -The tools under this directory are for the end users of Chromium OS devices. diff --git a/user_tools/README_recovery.txt b/user_tools/README_recovery.txt deleted file mode 100644 index 97f413f8..00000000 --- a/user_tools/README_recovery.txt +++ /dev/null @@ -1,84 +0,0 @@ - -The recovery tool assists the user in creating a bootable USB drive that can -recover a non-functional Chromium OS device. It generally operates in three -steps. - -1. Download a config file from a known URL. This file describes the - available images and where they can be found. - -2. Ask the user to select the appropriate image, download it, and verify - that it matches what the config file describes. - -3. Ask the user to select a USB drive, and write the recovery image to it. - - - - -Here's the format of the config file: - -The config file is a machine-generated, human-readable text file containing -at least two paragraphs or stanzas, which are separated by at least one -blank line. - -* Each line in the file ends with "\n" (LF), not "\r\n" (CRLF). - -* The file shall not contain any tab characters. - -* Lines beginning with '#' are completely ignored and do not count as blank - lines. - -* Non-blank lines must consist of a non-blank key and non-blank value - separated by a '=' with no spaces on either side. The key may not contain - whitespace. The value may contain spaces, but all trailing whitespace is - discarded. - -* The first stanza must contain a key named "recovery_tool_version'. Its - value must match the version of the recovery tool. If the value does not - match, then the key 'recovery_tool_update', if it exists in the first - stanza, should contain a string to display to the user. Regardless, if the - version doesn't match, the recovery tool should exit. - -* The first stanza MAY have platform-specific keys such as - 'recovery_tool_linux_version'. If present, this key is used instead of the - 'recovery_tool_version' key to determine the required recovery tool - version. - -* The current recovery_tool_version value is 0.9.1 - -* The archive shall be in ZIP format. - - -The second and remaining stanzas describe recovery images to put on the USB -drive. Each image stanza must contain, in this order: - -* One and only one of each of these keys: - - name - string to show to the user - zipfilesize - size in bytes of the zipfile - file - the name of the file to extract from the zipfile - filesize - size in bytes of the extracted, uncompressed file - channel - the channel for this image ("beta-channel", - "dev-channel", "pilot-channel", etc.) - -* Zero or more of these keys: - - hwid - the HWID of the device which can use this image (no - entry means "any device") - -* One or both of these keys: - - md5 - md5sum of the zipfile - sha1 - sha1sum of the zipfile - -* One or more of these keys: - - url - where to find the zipfile to download - - -Any other keys are informational only and are not used by the recovery tool. - -If more than one url is provided, then they should be tried, in turn, until -one succeeds. - -At a minimum, the user shall be shown the name, channel, and all hwid values -for each image. diff --git a/user_tools/linux/recovery.sh b/user_tools/linux/recovery.sh deleted file mode 100755 index 56fc255a..00000000 --- a/user_tools/linux/recovery.sh +++ /dev/null @@ -1,930 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# This attempts to guide linux users through the process of putting a recovery -# image onto a removeable USB drive. -# -# We may not need root privileges if we have the right permissions. -# -set -eu - -############################################################################## -# Configuration goes here - -# Where should we do our work? Use 'WORKDIR=' to make a temporary directory, -# but using a persistent location may let us resume interrupted downloads or -# run again without needing to download a second time. -WORKDIR=${WORKDIR:-/tmp/tmp.crosrec} - -# Where do we look for the config file? Note that we can override this by just -# specifying the config file URL on the command line. -CONFIGURL="${1:-https://dl.google.com/dl/edgedl/chromeos/recovery/recovery.conf}" - -# Device to put this stuff on, perhaps the user knows best? -DEVICE="${DEVICE:-}" - -# What version is this script? It must match the 'recovery_tool_version=' value -# in the config file that we'll download. -MYVERSION='0.9.2' - - -############################################################################## -# Some temporary filenames -debug='debug.log' -tmpfile='tmp.txt' -config='config.txt' -version='version.txt' - -############################################################################## -# Various warning messages - -DEBUG() { - echo "DEBUG: $@" >>"$debug" -} - -prompt() { - # builtin echo may not grok '-n'. We should always have /bin/echo, right? - /bin/echo -n "$@" -} - -warn() { - echo "$@" 1>&2 -} - -quit() { - warn "quitting..." - exit 1 -} - -fatal() { - warn "ERROR: $@" - exit 1 -} - -ufatal() { - warn " -ERROR: $@ - -You may need to run this program as a different user. If that doesn't help, try -using a different computer, or ask a knowledgeable friend for help. - -" - exit 1 -} - -gfatal() { - warn " -ERROR: $@ - -You may need to run this program as a different user. If that doesn't help, it -may be a networking problem or a problem with the images provided by Google. -You might want to check to see if there is a newer version of this tool -available, or if someone else has already reported a problem. - -If all else fails, you could try using a different computer, or ask a -knowledgeable friend for help. - -" - exit 1 -} - -############################################################################## -# Identify the external utilities that we MUST have available. -# -# I'd like to keep the set of external *NIX commands to an absolute minimum, -# but I have to balance that against producing mysterious errors because the -# shell can't always do everything. Let's make sure that these utilities are -# all in our $PATH, or die with an error. -# -# This also sets the following global variables to select alternative utilities -# when there is more than one equivalent tool available: -# -# FETCH = name of utility used to download files from the web -# CHECK = command to invoke to generate checksums on a file -# CHECKTYPE = type of checksum generated -# DISKUTIL = set if we have 'diskutil' (for Macs) -# -require_utils() { - local extern - local errors - local tool - local tmp - - extern='awk cat cut dd grep ls mkdir mount readlink sed sync umount unzip wc' - if [ -z "$WORKDIR" ]; then - extern="$extern mktemp" - fi - errors= - - for tool in $extern ; do - if ! type "$tool" >/dev/null 2>&1 ; then - warn "ERROR: need \"$tool\"" - errors=yes - fi - done - - # We also need to a way to fetch files from teh internets. Note that the args - # are different depending on which utility we find. We'll use two variants, - # one to fetch fresh every time and one to try again from where we left off. - FETCH= - if [ -z "$FETCH" ] && tmp=$(type curl 2>/dev/null) ; then - FETCH=curl - fi - if [ -z "$FETCH" ] && tmp=$(type wget 2>/dev/null) ; then - FETCH=wget - fi - if [ -z "$FETCH" ]; then - warn "ERROR: need \"curl\" or \"wget\"" - errors=yes - fi - - # Once we've fetched a file we need to compute its checksum. There are - # multiple possiblities here too. - CHECK= - if [ -z "$CHECK" ] && tmp=$(type md5sum 2>/dev/null) ; then - CHECK="md5sum" - CHECKTYPE="md5" - fi - if [ -z "$CHECK" ] && tmp=$(type sha1sum 2>/dev/null) ; then - CHECK="sha1sum" - CHECKTYPE="sha1" - fi - if [ -z "$CHECK" ] && tmp=$(type openssl 2>/dev/null) ; then - CHECK="openssl" - CHECKTYPE="md5" - fi - if [ -z "$CHECK" ]; then - warn "ERROR: need \"md5sum\" or \"sha1sum\" or \"openssl\"" - errors=yes - fi - - # This utility is on Macs, so use it if we find it. - DISKUTIL= - if type diskutil >/dev/null 2>&1; then - DISKUTIL=diskutil - fi - - if [ -n "$errors" ]; then - ufatal "Some required utilities are missing." - fi -} - -# This retrieves a URL and stores it locally. It uses the global variable -# 'FETCH' to determine the utility (and args) to invoke. -# Args: URL FILENAME [RESUME] -fetch_url() { - local url - local filename - local resume - local err - - url="$1" - filename="$2" - resume="${3:-}" - - DEBUG "FETCH=($FETCH) url=($url) filename=($filename) resume=($resume)" - - if [ "$FETCH" = "curl" ]; then - if [ -z "$resume" ]; then - # quietly fetch a new copy each time - rm -f "$filename" - curl -L -f -s -S -o "$filename" "$url" - else - # continue where we left off, if possible - curl -L -f -C - -o "$filename" "$url" - # If you give curl the '-C -' option but the file you want is already - # complete and the server doesn't report the total size correctly, it - # will report an error instead of just doing nothing. We'll try to work - # around that. - err=$? - if [ "$err" = "18" ]; then - warn "Ignoring spurious complaint" - true - fi - fi - elif [ "$FETCH" = "wget" ]; then - if [ -z "$resume" ]; then - # quietly fetch a new copy each time - rm -f "$filename" - wget -nv -q -O "$filename" "$url" - else - # continue where we left off, if possible - wget -c -O "$filename" "$url" - fi - fi -} - -# This returns a checksum on a file. It uses the global variable 'CHECK' to -# determine the utility (and args) to invoke. -# Args: FILENAME -compute_checksum() { - local filename - - filename="$1" - - DEBUG "CHECK=($CHECK) CHECKTYPE=($CHECKTYPE)" - - if [ "$CHECK" = "openssl" ]; then - openssl md5 < "$filename" - else - $CHECK "$zipfile" | cut -d' ' -f1 - fi -} - - -############################################################################## -# Helper functions to handle the config file and image zipfile. - -# Convert bytes to MB, rounding up to determine storage needed to hold bytes. -roundup() { - local num=$1 - local div=$(( 1024 * 1024 )) - local rem=$(( $num % $div )) - - if [ $rem -ne 0 ]; then - num=$(($num + $div - $rem)) - fi - echo $(( $num / $div )) -} - - -# Die unless the filesystem containing the current directory has enough free -# space. The argument is the number of MB required. -verify_tmp_space() { - local need - local got - need="$1" - - # The output of "df -m ." could take two forms: - # - # Filesystem 1M-blocks Used Available Use% Mounted on - # /some/really/long/path/to/some/where - # 37546 11118 24521 32% / - # - # Filesystem 1048576-blocks Used Available Capacity Mounted on - # /some/short/path 37546 11118 24521 32% / - # - got=$(df -m . | awk '/^\/[^ ]+ +[0-9]/ {print $4} /^ +[0-9]/ {print $3}') - - if [ "$need" -gt "$got" ]; then - fatal " There is not enough free space in ${WORKDIR}" \ -"(it has ${got}MB, we need ${need}MB). - -Please free up some space on that filesystem, or specify a temporary directory -on the commandline like so: - - WORKDIR=/path/to/some/dir $0 -" - fi -} - - -# Each paragraph in the config file should describe a new image. Let's make -# sure it follows all the rules. This scans the config file and returns success -# if it looks valid. As a side-effect, it lists the line numbers of the start -# and end of each stanza in the global variables 'start_lines' and 'end_lines' -# and saves the total number of images in the global variable 'num_images'. -good_config() { - local line - local key - local val - local name - local file - local zipfilesize - local filesize - local url - local md5 - local sha1 - local skipping - local errors - local count - local line_num - - name= - file= - zipfilesize= - filesize= - url= - md5= - sha1= - skipping=yes - errors= - count=0 - line_num=0 - - # global - start_lines= - end_lines= - - while read line; do - line_num=$(( line_num + 1 )) - - # We might have some empty lines before the first stanza. Skip them. - if [ -n "$skipping" ] && [ -z "$line" ]; then - continue - fi - - # Got something... - if [ -n "$line" ]; then - key=${line%=*} - val=${line#*=} - if [ -z "$key" ] || [ -z "$val" ] || [ "$key=$val" != "$line" ]; then - DEBUG "ignoring $line" - continue - fi - - # right, looks good - if [ -n "$skipping" ]; then - skipping= - start_lines="$start_lines $line_num" - fi - - case $key in - name) - if [ -n "$name" ]; then - DEBUG "duplicate $key" - errors=yes - fi - name="$val" - ;; - file) - if [ -n "$file" ]; then - DEBUG "duplicate $key" - errors=yes - fi - file="$val" - ;; - zipfilesize) - if [ -n "$zipfilesize" ]; then - DEBUG "duplicate $key" - errors=yes - fi - zipfilesize="$val" - ;; - filesize) - if [ -n "$filesize" ]; then - DEBUG "duplicate $key" - errors=yes - fi - filesize="$val" - ;; - url) - url="$val" - ;; - md5) - md5="$val" - ;; - sha1) - sha1="$val" - ;; - esac - else - # Between paragraphs. Time to check what we've found so far. - end_lines="$end_lines $line_num" - count=$(( count + 1)) - - if [ -z "$name" ]; then - DEBUG "image $count is missing name" - errors=yes - fi - if [ -z "$file" ]; then - DEBUG "image $count is missing file" - errors=yes - fi - if [ -z "$zipfilesize" ]; then - DEBUG "image $count is missing zipfilesize" - errors=yes - fi - if [ -z "$filesize" ]; then - DEBUG "image $count is missing filesize" - errors=yes - fi - if [ -z "$url" ]; then - DEBUG "image $count is missing url" - errors=yes - fi - if [ "$CHECKTYPE" = "md5" ] && [ -z "$md5" ]; then - DEBUG "image $count is missing required md5" - errors=yes - fi - if [ "$CHECKTYPE" = "sha1" ] && [ -z "$sha1" ]; then - DEBUG "image $count is missing required sha1" - errors=yes - fi - - # Prepare for next stanza - name= - file= - zipfilesize= - filesize= - url= - md5= - sha1= - skipping=yes - fi - done < "$config" - - DEBUG "$count images found" - num_images="$count" - - DEBUG "start_lines=($start_lines)" - DEBUG "end_lines=($end_lines)" - - # return error status - [ "$count" != "0" ] && [ -z "$errors" ] -} - - -# Make the user pick an image to download. On success, it sets the global -# variable 'user_choice' to the selected image number. -choose_image() { - local show - local count - local line - local num - - show=yes - while true; do - if [ -n "$show" ]; then - echo - if [ "$num_images" -gt 1 ]; then - echo "There are $num_images recovery images to choose from:" - else - echo "There is $num_images recovery image to choose from:" - fi - echo - count=0 - echo "0 - <quit>" - # NOTE: making assumptions about the order of lines in each stanza! - while read line; do - if echo "$line" | grep -q '^name='; then - echo - count=$(( count + 1 )) - echo "$line" | sed "s/name=/$count - /" - elif echo "$line" | grep -q '^channel='; then - echo "$line" | sed 's/channel=/ channel: /' - elif echo "$line" | grep -q '^hwid='; then - echo "$line" | sed 's/hwid=/ model: /' - fi - done < "$config" - echo - show= - fi - prompt "Please select a recovery image to download: " - read num - if [ -z "$num" ] || [ "$num" = "?" ]; then - show=yes - elif echo "$num" | grep -q '[^0-9]'; then - echo "Sorry, I didn't understand that." - else - if [ "$num" -lt "0" ] || [ "$num" -gt "$num_images" ]; then - echo "That's not one of the choices." - elif [ "$num" -eq 0 ]; then - quit - else - break; - fi - fi - done - echo - - # global - user_choice="$num" -} - -# Fetch and verify the user's chosen image. On success, it sets the global -# variable 'image_file' to indicate the local name of the unpacked binary that -# should be written to the USB drive. It also sets the global variable -# 'disk_needed' to the minimum capacity of the USB drive required (in MB). -fetch_image() { - local start - local end - local line - local key - local val - local file - local zipfilesize - local filesize - local url - local md5 - local sha1 - local line_num - local zipfile - local err - local sum - - file= - zipfilesize= - filesize= - url= - md5= - sha1= - line_num="0" - - # Convert image number to line numbers within config file. - start=$(echo $start_lines | cut -d' ' -f$1) - end=$(echo $end_lines | cut -d' ' -f$1) - - while read line; do - # Skip to the start of the desired stanza - line_num=$(( line_num + 1 )) - if [ "$line_num" -lt "$start" ] || [ "$line_num" -ge "$end" ]; then - continue; - fi - - # Process the stanza. - if [ -n "$line" ]; then - key=${line%=*} - val=${line#*=} - if [ -z "$key" ] || [ -z "$val" ] || [ "$key=$val" != "$line" ]; then - DEBUG "ignoring $line" - continue - fi - - case $key in - # The descriptive stuff we'll just save for later. - file) - file="$val" - ;; - zipfilesize) - zipfilesize="$val" - ;; - filesize) - filesize="$val" - ;; - md5) - md5="$val" - ;; - sha1) - sha1="$val" - ;; - url) - # Make sure we have enough temp space available. Die if we don't. - verify_tmp_space $(roundup $(( $zipfilesize + $filesize ))) - # Try to download each url until one works. - if [ -n "$url" ]; then - # We've already got one (it's very nice). - continue; - fi - warn "Downloading image zipfile from $val" - warn "" - zipfile=${val##*/} - if fetch_url "$val" "$zipfile" "resumeok"; then - # Got it. - url="$val" - fi - ;; - esac - fi - done < "$config" - - if [ -z "$url" ]; then - DEBUG "couldn't fetch zipfile" - return 1 - fi - - # Verify the zipfile - if ! ls -l "$zipfile" | grep -q "$zipfilesize"; then - DEBUG "zipfilesize is wrong" - return 1 - fi - sum=$(compute_checksum "$zipfile") - DEBUG "checksum is $sum" - if [ "$CHECKTYPE" = "md5" ] && [ "$sum" != "$md5" ]; then - DEBUG "wrong $CHECK" - return 1 - elif [ "$CHECKTYPE" = "sha1" ] && [ "$sum" != "$sha1" ]; then - DEBUG "wrong $CHECK" - return 1 - fi - - # Unpack the file - warn "Unpacking the zipfile" - rm -f "$file" - if ! unzip "$zipfile" "$file"; then - DEBUG "Can't unpack the zipfile" - return 1 - fi - - if ! ls -l "$file" | grep -q "$filesize"; then - DEBUG "unpacked filesize is wrong" - return 1 - fi - - # global - image_file="$file" - disk_needed=$(roundup "$filesize") -} - -############################################################################## -# Helper functions to manage USB drives. - -# Return a list of base device names ("sda sdb ...") for all USB drives -get_devlist() { - local dev - local t - local r - - # Are we on a mac? - if [ -n "$DISKUTIL" ]; then - for dev in $(diskutil list | grep '^/dev'); do - r=$(diskutil info $dev | grep 'Ejectable\: *Yes') || true - t=$(diskutil info $dev | grep 'Protocol\: *USB') || true - if [ "$r" != "" ]; then - if [ "$t" != "" ]; then - echo "$dev" | sed 's,/dev/,,' - fi - fi - done - else - # No, linux, I hope - for dev in $(cat /proc/partitions); do - [ -r "/sys/block/$dev/device/type" ] && - t=$(cat "/sys/block/$dev/device/type") && - [ "$t" = "0" ] && - r=$(cat "/sys/block/$dev/removable") && - [ "$r" = "1" ] && - readlink -f "/sys/block/$dev" | grep -q -i usb && - echo "$dev" || true - done - fi -} - -# Return the raw size in MB of each provided base device name ("sda sdb ...") -get_devsize() { - local dev - local bytes - local sectors - - # Are we on a mac? - if [ -n "$DISKUTIL" ]; then - for dev in $1; do - bytes=$(diskutil info $dev | \ - awk '/\([0-9]+ Bytes\)/' | sed -E 's/.*\(([0-9]+) Bytes\).*/\1/') - echo $(( $bytes / 1024 / 1024)) - done - else - for dev in $1; do - sectors=$(cat "/sys/block/$dev/size") - echo $(( $sectors * 512 / 1024 / 1024 )) - done - fi -} - - -# Return descriptions for each provided base device name ("sda sdb ...") -get_devinfo() { - local dev - local v - local m - local s - local ss - - # Are we on a mac? - if [ -n "$DISKUTIL" ]; then - for dev in $1; do - m=$(diskutil info $dev | grep 'Device \/ Media Name\:' | \ - sed 's/^[^:]*: *//') || true - s=$(diskutil info $dev | grep 'Total Size\:' | \ - sed 's/^[^:]*: *\([^(]*\).*/\1/') || true - echo "/dev/$dev $s $m" - done - else - # No, linux, hopefully - for dev in $1; do - v=$(cat "/sys/block/$dev/device/vendor") && - m=$(cat "/sys/block/$dev/device/model") && - s=$(cat "/sys/block/$dev/size") && ss=$(( $s * 512 / 1000000 )) && - echo "/dev/$dev ${ss}MB $v $m" - done - fi -} - -# Enumerate and descript the specified base device names ("sda sdb ...") -get_choices() { - local dev - local desc - local count - - count=1 - echo "0 - <quit>" - for dev in $1; do - desc=$(get_devinfo "$dev") - echo "" - echo "$count - Use $desc" - count=$(( count + 1 )) - done -} - -# Make the user pick a USB drive to write to. On success, it sets the global -# variable 'user_choice' to the selected device name ("sda", "sdb", etc.) -choose_drive() { - local show - local devlist - local choices - local num_drives - local msg - local num - - show=yes - while true; do - if [ -n "$show" ]; then - devlist=$(get_devlist) - choices=$(get_choices "$devlist") - if [ -z "$devlist" ]; then - num_drives="0" - msg="I can't seem to find a valid USB drive." - else - num_drives=$(echo "$devlist" | wc -l) - if [ "$num_drives" != "1" ]; then - msg="I found $num_drives USB drives." - else - msg="I found $num_drives USB drive." - fi - fi - echo " - -$msg We need one with at least ${disk_needed}MB capacity. - -$choices - -" - show= - fi - prompt "Tell me what to do (or just press Enter to scan again): " - read num - if [ -z "$num" ] || [ "$num" = "?" ]; then - show=yes - elif echo "$num" | grep -q '[^0-9]'; then - echo "Sorry, I didn't understand that." - else - if [ "$num" -lt "0" ] || [ "$num" -gt "$num_drives" ]; then - echo "That's not one of the choices." - elif [ "$num" -eq 0 ]; then - quit - else - break; - fi - fi - done - - # global - user_choice=$(echo $devlist | cut -d' ' -f$num) -} - -# Unmount a partition -unmount_partition() { - if [ -n "$DISKUTIL" ]; then - diskutil unmountDisk "$1" || ufatal "Unable to unmount $1." - else - umount "$1" || ufatal "Unable to unmount $1." - fi -} - -############################################################################## -# Okay, do something... - -# Make sure we have the tools we need -require_utils - -# Need a place to work. We prefer a fixed location so we can try to resume any -# interrupted downloads. -if [ -n "$WORKDIR" ]; then - if [ ! -d "$WORKDIR" ] && ! mkdir "$WORKDIR" ; then - warn "Using temporary directory" - WORKDIR= - fi -fi -if [ -z "$WORKDIR" ]; then - WORKDIR=$(mktemp -d) - # Clean up temporary directory afterwards - trap "cd; rm -rf ${WORKDIR}" EXIT -fi - -cd "$WORKDIR" -warn "Working in $WORKDIR/" -rm -f "$debug" - -# Download the config file to see what choices we have. -warn "Downloading config file from $CONFIGURL" -fetch_url "$CONFIGURL" "$tmpfile" || \ - gfatal "Unable to download the config file" - -# Separate the version info from the images -grep '^recovery_tool' "$tmpfile" > "$version" -grep -v '^#' "$tmpfile" | grep -v '^recovery_tool' > "$config" -# Add one empty line to the config file to terminate the last stanza -echo >> "$config" - -# Make sure that the config file version matches this script version. -tmp=$(grep '^recovery_tool_linux_version=' "$version") || \ - tmp=$(grep '^recovery_tool_version=' "$version") || \ - gfatal "The config file doesn't contain a version string." -filevers=${tmp#*=} -if [ "$filevers" != "$MYVERSION" ]; then - tmp=$(grep '^recovery_tool_update=' "$version"); - msg=${tmp#*=} - warn "This tool is version $MYVERSION." \ - "The config file is for version $filevers." - fatal ${msg:-Please download a matching version of the tool and try again.} -fi - -# Check the config file to be sure it's valid. As a side-effect, this sets the -# global variable 'num_images' with the number of image stanzas read, but -# that's independent of whether the config is valid. -good_config || gfatal "The config file isn't valid." - -# Make the user pick an image to download, or exit. -choose_image - -# Download the user's choice -fetch_image "$user_choice" || \ - gfatal "Unable to download a valid recovery image." - -if [ -n "$DEVICE" ]; then - user_choice="${DEVICE#/dev/}" - dev_desc="${DEVICE}" -else - # Make the user pick a USB drive, or exit. - choose_drive - - # Be sure - dev_desc=$(get_devinfo "$user_choice") -fi - -# Start asking for confirmation -dev_size=$(get_devsize "$user_choice") -if [ "$dev_size" -lt "$disk_needed" ]; then - echo " - -WARNING: This drive seems too small (${dev_size}MB)." \ - "The recovery image is ${disk_needed}MB." -fi -echo " -Is this the device you want to put the recovery image on? - - $dev_desc -" -prompt "You must enter 'YES' (all uppercase) to continue: " -read tmp -if [ "$tmp" != "YES" ]; then - quit -fi - -# Be very sure -echo " - -I'm really going to erase this device. This will permanently ERASE -whatever you may have on that drive. You won't be able to undo it. - - $dev_desc -" - -prompt "If you're sure that's correct, enter 'DoIt' now (case is important): " -read tmp -if [ "$tmp" != "DoIt" ]; then - quit -fi -echo " - -Installing the recovery image - -" - -# Unmount anything on that device. -echo "unmounting..." -for tmp in $(mount | grep ^"/dev/${user_choice}" | cut -d' ' -f1); do - unmount_partition "$tmp" -done - -# Write it. -echo "copying... (this may take several minutes)" - -# Many BSD variants provide both normal /dev/FOO and raw /dev/rFOO devices, -# with the raw path being much faster. If that device exists, we'll use it. -if [ -e /dev/r${user_choice} ]; then - user_choice="r${user_choice}" -fi -dd bs=4194304 of=/dev/${user_choice} if="$image_file" conv=sync || - ufatal "Unable to write the image." -sync - -echo " - -Done. Remove the USB drive and insert it in your Chrome notebook. - -" - -prompt "Shall I remove the temporary files now? [y/n] " -read tmp -case $tmp in - [Yy]*) - cd - \rm -rf ${WORKDIR} - ;; -esac - -exit 0 |