What is ThumbOS? ThumbOS is a CLI (Command line Interpreter) based application used to load bootable ISO or IMG files to a thumbdrive. Sure there are other applications that do the same thing such as gtk-usb-creator and Unetbootin to name a few. What makes Thumbos different? It is as I said a CLI based client. This app has saved my rump more then once. I have been locked out of the desktop due to issues in Mate 1.6 and it allowed me to load out a new image from the raw TTY. Did I mention it is faster then any GUI (Graphical User Interface) based client I have seen?
Loading out Windows 7 using ThumbOS:
CURRENT CHANGE LOG:
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
# title :thumbos
# description :Loads disk images to thumbdrive from the CLI.
# author :theemahn <[email protected]>
# date :07/28/2014
# version :1.0.9
# usage :thumbos --help
# manual :man thumbos
# notes :See change-log below for further information.
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
# Change-log: 1.0.1: Initial Internal Beta release
#
# 1.0.2: Bug fixes
#
# Erase feature added.
#
# Test feature added.
#
# Display ISO and Image info
#
# 1.03 Minor bugfix see comment in code.
#
# Supress errors if end user does not possess a thumbdrive,
# exit graciously.
#
# 1.04 Edited erase routine, NTFS set as default.
#
# Added partition detection function in case user has
# multiple partitions on the thumbdrive.
#
# Added initial ©Microsft Windows support & detection
# routine.
#
# 1.0.5 Adjustment to test function when booting ISO's
#
# Added cpu core(s) & memory size detection
# set VM based on detected hardware.
#
# Added ntfsprogs to dependancy list, direct check on
# mkfs.ntfs Broken symlink: The symlink to mkfs.ntfs is
# wrong. A bug report has been filed.
#
# Added Eyecandy routines borrowed code from repostorm
#
# Added notifications and sound, ThumbOS now talks to you.
#
# 1.0.6 Bug Fix: Columize function info output in wrong column.
#
# 1.0.7 Add more comments to code, we are here to learn right?
#
# Fixed scan function if 2 unknowns are found no output.
#
# Appended detected size MB / GB etc. Calculating disk
# sizes smartly up to 999 Yottabytes.
#
# 1.0.8 Added fix for 0 thumbdrives detected. Report and exit.
#
# Added code for X11 detection in test function.
#
# Wrote Thumbos initial manpages, postscript and pdf
# manuals.
#
# 1.0.9 Adjusted recommended in control file to include:
# gnome-session-canberra, libnotify-bin for sound and
# notifications.
#
# Adjusted Virtual testing function to fallback to qemu on
# KVM acceleration failure.
# 1.1.0 Added Advanced eyecandy fuctions.
# Initiated construction of a GUI (graphical user interface)
#
# 1.1.1 Added dependancy on syslinux-ulils (hybridiso)
#
# 1.1.2 Added udisks | udisks2 to control, Wily support enters
# the mix
#
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- Introduction
- Source code
- Download
Introduction:
First what is Thumbos? As taken from the source code and deb description: Loads disk images to thumbdrive from the CLI. Let's just drop help:
theemahn@JackHammer:~/Music$ thumbos
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒ Thumbos 1.0.5, 03/24/2014 ▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
GNU Thumbos home page: <http://ultimateedition.info/>.
E-mail bug reports to: <[email protected]>.
Be sure to include the word Thumbos somewhere in the Subject: field.
Usage: Thumbos -<-COMMAND> [option]
Mandatory arguments to long options are identical for short options.
possible commands...
-e --erase erases the entire thumbdrive
-l --load load ISO image to thumbdrive
-h --help this help message
-s --scan scans / reports thumbdrive(s) and exits
-t --test test boot device and exit
-v --version dump version info
Thumbos --help [COMMAND] for further information.
theemahn@JackHammer:~/Music$
When I built Ultimate Edition 4.0 and installed it (awesome O/S BTW) i continued to advance it futher by re-building it and fixing idiosyncrasies. I advanced the O/S and went to load it out to a thumbdrive with gtk-usb-creator and it crashed. No error message, just died. I can now see in the logs what happened it segfaulted:
Dec 5 01:20:46 JackHammer udisksd[3561]: Cleaning up mount point /media/theemahn/BLANK (device 8:128 is not mounted)
Dec 5 01:21:02 JackHammer udisksd[3561]: Mounted /dev/sdi at /media/theemahn/BLANK on behalf of uid 1000
Dec 5 01:21:16 JackHammer udisksd[3561]: Mounted /dev/sdk at /media/theemahn/BLANK1 on behalf of uid 1000
Dec 5 01:33:30 JackHammer dbus[1256]: [system] Activating service name='com.ubuntu.USBCreator' (using servicehelper)
Dec 5 01:33:30 JackHammer dbus[1256]: [system] Successfully activated service 'com.ubuntu.USBCreator'
Dec 5 01:33:51 JackHammer udisksd[3561]: Cleaning up mount point /media/theemahn/BLANK (device 8:128 is not mounted)
Dec 5 01:33:51 JackHammer kernel: [21630.118871] sdi:
Dec 5 01:34:12 JackHammer kernel: [21651.275762] ISO 9660 Extensions: Microsoft Joliet Level 3
Dec 5 01:34:12 JackHammer kernel: [21651.278765] ISO 9660 Extensions: RRIP_1991A
Dec 5 01:36:47 JackHammer kernel: [21805.478348] usb-creator-gtk[23647]: segfault at 4 ip 00007fa7efb53d80 sp 00007ffff1e5cec8 error 6 in libdbus-1.so.3.7.4[7fa7efb30000+44000]
Not a dealbreaker, we have unetbootin too right? Wrong, segfault again (something I will have to look into heavily as I aproach the final release of Ultimate Edition 4.0). It is things that happen to me such as the above that causes me to take matters into my own hands. Will those programs be fixed? I'm sure, so why write Thumbos?
- CLI based; to me means when I build O/S's I don't have to leave the comfort of the terminal I can immediately load out an ISO image for testing.
- Diversity
- Speed
- Low overhead
- Features
I'd like to start by covering the features. Thumbos uses as a backend dcfldd, similar to dd aka "disk destroyer" as taken from the wiki:
dcfldd is an enhanced version of dd developed by the U.S. Department of Defense Computer Forensics Lab. It has some useful features for forensic investigators such as:
On-the-fly hashing of the transmitted data.
Progress bar of how much data has already been sent.
Wiping of disks with known patterns.
Verification that the image is identical to the original drive, bit-for-bit.
Simultaneous output to more than one file/disk is possible.
The output can be split into multiple files.
Logs and data can be piped into external applications.
I released this app integrated in Ultimate Edition 3.8 to admin, beta testers, and donors on the Ultimate Edition Test Server and got no feedback, good or bad. Sometimes no news is good news. I have been using this app religiously to load out operating systems and find it to be flawless in design. I have since enhanced it & I have deliberatly tried tossing switches that were incorrect to try and get it to screw up without success. This app in no way shape or form should be taken lightly. The damage it can incure is massive & irreversible, however it will not do so with out your consent.
theemahn@JackHammer:~/Music$ thumbos --help erase
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒ Thumbos 1.0.5, 03/24/2014 ▒
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
GNU Thumbos home page: <http://ultimateedition.info/>.
E-mail bug reports to: <[email protected]>.
Be sure to include the word Thumbos somewhere in the Subject: field.
Usage erase;
Thumbos -e <DEVICE> [quick|secure|full]
Quickly erases the contents of <DEVICE> thumbdrive.
Example: Thumbos --erase sdi secure
If the [full] or [secure] option is used it will wipe the entire drive. This
is a slow process and the information is non-recoverable. Specifing no option
is the same as using the default [Quick] option.
Warning: The contents of the device will be entirely wiped and
unrecoverable using the secure or full option.
Note: The partition number is not necessary as the entire drive will be wiped.
theemahn@JackHammer:~/Music$
It will prompt you in bold red for example: WARNING: this will erase all content on device /dev/sdi. (Y/N)? None the less, I TAKE ZERO RESPOSIBILITY IF YOU HOSE YOUR PORN DRIVE
Lets cover the other features in short order. Low overhead? You can not beat a cli application in resource usage period and goes in hand in hand with speed accordingly. Diversity, is that it is CLI. Optionally directly test the thumbdrive to boot the O/S. I have been also writing a tool to format in android based format called mkfs.android and may eventually enter this program instead, we will see. Enough flapping your gums TheeMahn. Lets drop some source code:
Source Code:
If you are looking to learn programming, my code is heavily commented. I do so to encourage others to learn. I highly discourage you to just copy and paste the source code into a text file and execute it, as it does have dependancies that are not built into any Ultimate Edition minus 3.8. I recommend you download the deb listed at the bottom of this post to satisfy these dependancies:
theemahn@JackHammer:~/Documents/ultimate-edition-thumbos_1.0.2_all/bin$ bashdepends --depends thumbos
bashdepends 1.7.2-1, 10/23/2013
GNU builddeps home page: <http://www.ultimateedition.info/>.
E-mail bug reports to: <[email protected]>.
Be sure to include the word builddeps somewhere in the Subject: field.
Please wait this may take a while depending on the size of the script.
Stripping bash builtin commands.
Externally called commands:
as
blkid
cut
date
dcfldd
expr
file
grep
info
isohybrid
isoinfo
kvm
ls
lsblk
man
qemu-system-x86_64
sed
sfdisk
sync
udevadm
udisks
umount
uniq
wc
which
SCANNING FOR NON-ESSENTIAL / ESSENTIAL PACKAGE(S)...
COMMAND PACKAGE PRIORITY VERSION
________________________________________________________________________________
as binutils optional 2.23.52.20130913-0ubuntu1
blkid util-linux required 2.20.1-5.1ubuntu9
cut coreutils required 8.20-3ubuntu5
date coreutils required 8.20-3ubuntu5
dcfldd dcfldd optional 1.3.4.1-2.1
expr coreutils required 8.20-3ubuntu5
file file standard 5.11-2ubuntu4
grep grep required 2.14-3
info info important 5.1.dfsg.1-4ubuntu1
isohybrid syslinux optional 3
isoinfo genisoimage optional 9
kvm qemu-system-x86 optional 1.5.0+dfsg-3ubuntu5
ls coreutils required 8.20-3ubuntu5
lsblk util-linux required 2.20.1-5.1ubuntu9
man man-db important 2.6.5-2
qemu-system-x86_64 qemu-system-x86 optional 1.5.0+dfsg-3ubuntu5
sed sed required 4.2.2-1ubuntu1
sfdisk util-linux required 2.20.1-5.1ubuntu9
sync coreutils required 8.20-3ubuntu5
udevadm udev extra 204-0ubuntu19
udisks udisks optional 1.0.4-8ubuntu1
umount mount required 2.20.1-5.1ubuntu9
uniq coreutils required 8.20-3ubuntu5
wc coreutils required 8.20-3ubuntu5
which debianutils required 4.4
Please add all red packages to your control file.
Depends: binutils (>=2.23.52.20130913-0ubuntu1), dcfldd (>=1.3.4.1-2.1), syslinux (>=3), genisoimage (>=9), qemu-system-x86 (>=1.5.0+dfsg-3ubuntu5), udev (>=204-0ubuntu19), udisks (>=1.0.4-8ubuntu1)
theemahn@JackHammer:~/Documents/ultimate-edition-thumbos_1.0.2_all/bin$
Bashdepends is another application I wrote for scanning bash scripts for dependancies it is part of the ultimate-edition-code-cleanup package.
The main application /bin/thumbos
- Code: Select all
#!/bin/bash
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
# title :thumbos
# description :Loads disk images to thumbdrive from the CLI.
# author :theemahn <[email protected]>
# date :07/28/2014
# version :1.0.9
# usage :thumbos --help
# manual :man thumbos
# notes :See change-log below for further information.
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
# Change-log: 1.0.1: Initial Internal Beta release
#
# 1.0.2: Bug fixes
#
# Erase feature added.
#
# Test feature added.
#
# Display ISO and Image info
#
# 1.03 Minor bugfix see comment in code.
#
# Supress errors if end user does not possess a thumbdrive,
# exit graciously.
#
# 1.04 Edited erase routine, NTFS set as default.
#
# Added partition detection function in case user has
# multiple partitions on the thumbdrive.
#
# Added initial ©Microsft Windows support & detection
# routine.
#
# 1.0.5 Adjustment to test function when booting ISO's
#
# Added cpu core(s) & memory size detection
# set VM based on detected hardware.
#
# Added ntfsprogs to dependancy list, direct check on
# mkfs.ntfs Broken symlink: The symlink to mkfs.ntfs is
# wrong. A bug report has been filed.
#
# Added Eyecandy routines borrowed code from repostorm ;)
#
# Added notifications and sound, ThumbOS now talks to you.
#
# 1.0.6 Bug Fix: Columize function info output in wrong column.
#
# 1.0.7 Add more comments to code, we are here to learn right?
#
# Fixed scan function if 2 unknowns are found no output.
#
# Appended detected size MB / GB etc. Calculating disk
# sizes smartly up to 999 Yottabytes.
#
# 1.0.8 Added fix for 0 thumbdrives detected. Report and exit.
#
# Added code for X11 detection in test function.
#
# Wrote Thumbos initial manpages, postscript and pdf
# manuals.
#
# 1.0.9 Adjusted recommended in control file to include:
# gnome-session-canberra, libnotify-bin for sound and
# notifications.
#
# Adjusted Virtual testing function to fallback to qemu on
# KVM acceleration failure.
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
PROGNAME="Thumbos"
BUILDDATE="07/28/2014"
VERSION="1.0.9"
# Initiate a few arrays and vars
declare -a USBDRIVE=();
# Vars for obtaining Disk Information can add and remove based on data requested.
# That is just another reason I love arrays.
declare -a ISOINFO=('System id' 'System id' 'Volume id' 'Publisher id' 'Data preparer' 'Volume size');
((blockSize = 4 * 1024 * 1024))
sp="/-\|"
sc=0
# Added in 1.0.7 - Taking a stab at calculating disk sizes smartly up to Yottabyte
# Could easily roll up to a Geopbyte.
# · 1 Bit = Binary Digit
# · 8 Bits = 1 Byte
# · 1024 Bytes = 1 Kilobyte
# · 1024 Kilobytes = 1 Megabyte
# · 1024 Megabytes = 1 Gigabyte
# · 1024 Gigabytes = 1 Terabyte
# · 1024 Terabytes = 1 Petabyte
# · 1024 Petabytes = 1 Exabyte
# · 1024 Exabytes = 1 Zettabyte
# · 1024 Zettabytes = 1 Yottabyte
# · 1024 Yottabytes = 1 Brontobyte
# · 1024 Brontobytes = 1 Geopbyte
# See additional code in function DumpArray to see how I did so using the array
# defined below.
declare -a DISKSIZES=('KB' 'MB' 'GB' 'TB' 'PB' 'EB' 'ZB' 'YB')
#declare -i KBS
# Retrieve number of lines & columns the screen supports.
LINEZ=$(tput lines)
COLUMNZ=$(tput cols)
SPLIT=0
# check to see if notify is installed & if sound is supported.
NOTIFY=$(which notify-send)
SOUND=$(which canberra-gtk-play)
# Declare integer to span eyecandy routine
declare -i RR
RR=0
declare -i TT
TT=0
# Declare integer for whether a drive is detatchable.
declare -i DETACHABLE
# Not required, but optional, no promting for testing etc. if false.
QEMUINSTALLED=$(which qemu)
# set colors so errors etc. stand out.
txtblk='\e[0;30m' # Black - Regular
txtred='\e[0;31m' # Red
txtgrn='\e[0;32m' # Green
txtylw='\e[0;33m' # Yellow
txtblu='\e[0;34m' # Blue
txtpur='\e[0;35m' # Purple
txtcyn='\e[0;36m' # Cyan
txtwht='\e[0;37m' # White
bldblk='\e[1;30m' # Black - Bold
bldred='\e[1;31m' # Red
bldgrn='\e[1;32m' # Green
bldylw='\e[1;33m' # Yellow
bldblu='\e[1;34m' # Blue
bldpur='\e[1;35m' # Purple
bldcyn='\e[1;36m' # Cyan
bldwht='\e[1;37m' # White
unkblk='\e[4;30m' # Black - Underline
undred='\e[4;31m' # Red
undgrn='\e[4;32m' # Green
undylw='\e[4;33m' # Yellow
undblu='\e[4;34m' # Blue
undpur='\e[4;35m' # Purple
undcyn='\e[4;36m' # Cyan
undwht='\e[4;37m' # White
bakblk='\e[40m' # Black - Background
bakred='\e[41m' # Red
badgrn='\e[42m' # Green
bakylw='\e[43m' # Yellow
bakblu='\e[44m' # Blue
bakpur='\e[45m' # Purple
bakcyn='\e[46m' # Cyan
bakwht='\e[47m' # White
txtrst='\e[0m' # Text Reset
# Prerequisite check - mkntfs
MKNTFS=$(which mkntfs)
if ! [ $MKNTFS ]; then
MKNTFS=$(which mkfs.ntfs)
fi
# Direct linking mkfs.ntfs https://bugs.launchpad.net/ubuntu/+source/ntfs-3g/+bug/1158732
# To fix, I wrote a mini howto: http://askubuntu.com/questions/343847/mkfs-ntfs-is-not-found-through-the-ntfs-3g-package-is-installed
# For now, I work around the bug by directly checking for the app.
if [[ -f /sbin/mkfs.ntfs ]]; then
MKNTFS='/sbin/mkfs.ntfs'
fi
if ! [ $MKNTFS ]; then
echo -e "${bldred}Error: mkntfs or mkfs.ntfs program not found!${txtrst}" >&2
exit 1
fi
function Columnize () {
#echo $COLUMNZ
MAINS=$(echo "scale=2; $COLUMNZ-30" | bc)
MAINS=${MAINS%.*}
#echo $MAINS
MAINS=$(expr $MAINS - 2)
MAINS=$(expr $MAINS / 4)
#echo $MAINS
if ! [[ $1 ]]; then
#"#" "DEV" "VENDOR" "LABEL" "TYPE" "SIZE"
printf "%-0s %-1s %-1s %-20s %-26s %-7s %-1s\n" "▒" "#" "DEV" "VENDOR" "LABEL" "TYPE" "SIZE"
else
#MAINS=$(expr $MAINS / 2)
printf "%-0s %-1s %-1s %-20s %-26s %-7s %-1s\n" "▒" $1 $2 $3 $4 $5 $6
fi
}
# Function for outputing to X-11 screen a notification of completion and playing sound.
# The sound file is from the "Optional" ultimate-edition-sound-theme
function Notification () {
X=$( pidof X )
if [[ -f "/usr/share/sounds/Ultimate Edition Sound Scheme/stereo/itisdone.wav" ]]; then
WAVE=1
fi
if [[ $X && $NOTIFY ]]; then
a=$(notify-send "ThumbOS" "$1" -i /usr/share/ultimate_edition/logo.png -t 5000)
else
echo $1
fi
if [[ $SOUND && $WAVE ]]; then
a=$(canberra-gtk-play -i itisdone 2>/dev/null)
fi
}
#Usage: EyeCandy Message
function EyeCandy() {
# Verify a message has been sent to this function otherwise do squat.
# Example: EyeCandy ('Repostorm $REPOVERSION is entering extraction mode.')
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
# ▒ Repostorm 1.7.7 is entering extraction mode. ▒
# ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
STP="$1"
if [[ $STP ]]; then
STRLEN=${#STP}
STRLEN=$(expr $STRLEN + 3)
RR=0; while [ $RR -le $STRLEN ]; do echo -n "▒"; RR=RR+1; done; echo;
echo -e "▒ "$STP" ▒"
RR=0; while [ $RR -le $STRLEN ]; do echo -n "▒"; RR=RR+1; done; echo;
fi
}
# Draws a bar across the screen based on screensize detected (columnz)
function FullBar() {
RR=1; while [ $RR -lt $COLUMNZ ]; do echo -n "▒"; RR=RR+1; done; echo;
}
# Center data passed to function on screen
function Center () {
STP=$1
if [[ $STP ]]; then
STRLEN=${#STP}
CENTER=$(expr $STRLEN / 2)
TCENTER=$(expr $COLUMNZ / 2)
DISTANCE=$(expr $TCENTER - $CENTER)
DISTANCE=$(expr $DISTANCE - 2)
RR=0; while [ $RR -le $DISTANCE ]; do echo -n "▒"; RR=RR+1; done;
echo -n " $STP "
TT=0; while [ $TT -le $DISTANCE ]; do echo -n "▒"; TT=TT+1; done;
CALC=$(expr $RR + $TT + $STRLEN + 2)
if [[ $CALC -lt $COLUMNZ ]]; then
while [ $CALC -lt $COLUMNZ ]; do echo -n "▒"; CALC=CALC+1; done; echo;
fi
fi
# Dubugging:
# echo "STRING LEN: $STRLEN CENTER: $CENTER TOTAL CNTER: $TCENTER RR=$RR TT=$TT COLUMNZ: $COLUMNZ CALC: $CALC DISTANCE: $DISTANCE"
}
# Debugging function to monitor passed arguments.
function CommandLineIntrepreter(){
echo -e "${bldgrn}Number of switches passed: $#"
for var in "$@"
do
array_counter=$(($array_counter + 1))
echo "Switch $array_counter: $var"
done
}
# Virtual machine testing function.
function Virtual {
if ! [[ $DISPLAY ]]; then
echo -e "${bldred}No X11 session detected. Exiting.${txtrst}"
exit 0;
fi
# Declare a few integer varibles
declare -i MEMORY
declare -i DEDICATED
TEMPO=$(cat /proc/meminfo | grep 'MemTotal'|cut -d ':' -f2 | sed 's/ kB//g')
MEMORY=$TEMPO
# See if end user has 3GB or greater memory
if [[ $MEMORY -ge 3096000 ]]; then
# If so set maximum the virtual machine can have.
DEDICATED=2047
else
# Limited resources. Use a quarter the end users memory.
MAINS=$(echo "scale=2; $MEMORY/1000*.25" | bc)
# dump the decimal, we want a raw integer.
DEDICATED=${MAINS%.*}
fi
# Snatch the number of CPU Core(s) the end user has.
CORES=$(cat /proc/cpuinfo | grep "processor" | sed '/model/d' | wc -l)
# Dump data to the end user.
echo -e "${bldgrn}"$MEMORY "memory and "$CORES "CPU core(s) detected.\nUtilizing $DEDICATED MB of memory and $CORES CPU Core(s) to full potential."
# Check for existance of ISO, if so launch VM, enable kvm acceleration.
if [ -e "$1" ]; then
EyeCandy "Thumbos: Testing ISO $1 in a virtual machine.${txtrst}"
A=$(qemu-system-x86_64 -enable-kvm -m $DEDICATED --boot d menu=on cdrom=$1 2>/dev/null)
if ! [[ $A ]]; then
a=$(kvm -m $DEDICATED -smp $CORES -usb -boot d -cdrom $1 -name ThumbOS 2>/dev/null)
fi
else
# Block device?
GREPEDSWITCH=$(echo $1 | grep "dev")
if [[ $GREPPEDSWITCH ]]; then
if [[ -b $1 ]]; then
EyeCandy "Thumbos: Testing Thumbdrive $1 in a virtual machine.${txtrst}"
A=$(qemu-system-x86_64 -enable-kvm -m $DEDICATED --boot d menu=on cdrom=$1 2>/dev/null)
if ! [[ $A ]]; then
a=$(kvm -m $DEDICATED -smp $CORES -usb -boot d -cdrom $1 -name ThumbOS 2>/dev/null)
fi
else
# Lost in space !!! ;)
echo -e "${bldred}Error: Invalid option $1"
Help test $1
exit 0
fi
else
TD='/dev/'$1
if [[ -b $TD ]]; then
EyeCandy "Thumbos: Testing Thumbdrive $TD in a virtual machine.${txtrst}"
A=$(qemu-system-x86_64 -enable-kvm -m $DEDICATED --boot d menu=on cdrom=$TD 2>/dev/null)
if ! [[ $A ]]; then
a=$(kvm -m $DEDICATED -smp $CORES -usb -boot d -cdrom $TD -name ThumbOS 2>/dev/null)
fi
else
# Lost in space !!! ;)
echo -e "${bldred}Error: Invalid option $1"
Help test $1
exit 0
fi
fi
fi
Notification "All operations completed successfully."
}
function DiskImageInfo {
# Set needed varibles, we do not need to check for existance of $1 we
# would not be here if it does not exist
EXTENSION="${1##*.}"
FILENAME="${1%.*}"
BOOTABLE=$(file $1 | grep -m1 "bootable")
# Don't put full trust in utility "file" for ISO's use the right tool
# for the right job if file failed.
if [[ $EXTENSION == 'iso' && $BOOTABLE == '' ]]; then
BOOTABLE=$(isoinfo -i $1 -f -d | grep -m1 "bootable")
fi
# Set Boot Flag
if [[ ${BOOTABLE} ]]; then
BOOTABLE='Yes'
else
BOOTABLE='No'
fi
# Come here my pretty ;)
FullBar
# ISO Image? Dump info defined in Array. Makes it simple to add remove info.
printf '%-15s %s\n' \
"Image File:" "$1"
array_counter=1
for number in ${ISOINFO[@]}
do
TITLEINFO=${ISOINFO[$array_counter]}
GREPINFO=${ISOINFO[$array_counter]}
DISPLAYINFO=$(isoinfo -d -i $1 | grep -m1 "$GREPINFO" | cut -d: -f2 | sed -e 's/^[ \t]*//')
if [[ $DISPLAYINFO && $TITLEINFO ]]; then
printf '%-15s %s\n' \
"$TITLEINFO:" "$DISPLAYINFO"
fi
array_counter=$(($array_counter + 1))
done
# Dump info on boot info as detected, we may need some work here,
# lots of different types of iso's and image files
printf '%-15s %s\n' \
"Bootable:" "$BOOTABLE"
# Thusly inform end user.
if ! [[ $BOOTABLE ]]; then
echo -e "${txtred}Note: This image most likely will not boot. Proceeding.${txtrst}"
fi
WINISO=$(isoinfo -d -i $1 | grep -i "win\|microsoft")
LINUX=$(isoinfo -d -i $1 | grep -i "LINUX")
APPLE=$(isoinfo -d -i $1 | grep -i "APPLE")
FullBar
# Drop additional info if acclible
if [[ $BOOTABLE && $WINISO ]]; then
echo -e "${bldgrn}This is a ©Microsoft Windows bootable ISO and will be treated as such.${txtrst}"
fi
if [[ $BOOTABLE && $LINUX ]]; then
echo -e "${bldgrn}This is a bootable Linux based operating system and will be treated as such.${txtrst}"
fi
if [[ $BOOTABLE && $APPLE ]]; then
echo -e "${bldgrn}This is a bootable Apple/ MAC based operating system and will be treated as such.${txtrst}"
fi
}
# Some eyecandy?
function spin() {
printf "\b${sp:sc++:1}"
((sc==${#sp})) && sc=0
}
function endspin() {
printf "\r%s\n" "$@"
}
function DumpArray () {
# Yank on Devkit to retrieve availible USBDrives, we will process the data later
# 1.0.3 fix for 0 thumbdrives dump to /dev/null to avoid output of errors.
# Open a subshell & parse values.
NUSBDRIVES=$((ls -l /dev/disk/by-id/*usb* | sed 's/^.*\///g' | sed 's/[0-9]*//g' | uniq | wc -l) 2>/dev/null)
USBDRIVE=$((ls -l /dev/disk/by-id/*usb* | sed 's/^.*\///g' | sed 's/[0-9]*//g' | uniq) 2>/dev/null)
# if user has at least one USB drive dump array to screen.
if [[ $NUSBDRIVES ]]; then
echo -e "${undwht}Number of USB drives detected${txtrst}: $NUSBDRIVES"
#Fix for 1.0.8, zero thumbdrives report error.
if [[ $NUSBDRIVES -lt 1 ]]; then
echo -e "${bldred}Error: No thumbdrives detected.${txtrst}"
exit 0;
fi
Columnize
# Old method, left for educational purposes.
# printf '%-1s %-1s %-15s %-25s %-10s %s\n' \
# "#" "DEV" "VENDOR" "LABEL" "TYPE" "SIZE"
FullBar
echo -e -n "${bldgrn}${txtrst}"
array_counter=1
# Stack out a database if you will of detected USB Drives. We will strip out
# Non hackers as we roll. No, I do not want my 1TB external showing up as
# as a thumbdrive.
for number in ${USBDRIVE[@]}
do
TESTVALUE=${USBDRIVE[$array_counter]}
REMOVABLE='2'
REMOVABLE=$(lsblk | grep -m1 $number | cut -d ':' -f2 | cut -d" " -f3)
DETACHABLE=$(udisks --show-info /dev/sdh | grep 'detachable' | cut -d ':' -f2)
# Removable is for debugging at this stage of development.
# Bust out udisks we need raw data on the device(s) in question.
VENDOR=$(udisks --show-info /dev/$number | grep 'vendor' | cut -d":" -f2 | sed 's/ //g')
MODEL=$(udisks --show-info /dev/$number | grep 'model' | cut -d":" -f2 | sed 's/ //g')
if [[ $VENDOR == "" ]]; then
VENDOR=$MODEL
fi
# Still no Vendor?
if ! [[ $VENDOR ]]; then
VENDOR='UNKNOWN'
fi
BYTES=$(udisks --show-info /dev/$number 2>&1 | grep -m1 'size:' | cut -d":" -f2 | sed 's/ //g')
LABEL=$(udisks --show-info /dev/$number | grep 'label:' | cut -d ":" -f2 | sed -e 's/^[ \t]*//')
if [[ $LABEL == "" ]]; then
LABEL=$(ls -l /dev/disk/by-label/ | grep $number | cut -d ":" -f2 | cut -d " " -f2 | sed 's/\\x20/ /g' 2> /dev/null)
fi
if ! [[ $LABEL ]]; then
LABEL="UNKNOWN"
fi
TYPE=$(udisks --show-info /dev/$number | grep 'type:' | cut -d ":" -f2 | sed -e 's/^[ \t]*//' | sed 's/ //g')
if [[ $TYPE == "" ]]; then
TYPE=$(blkid /dev/$number'1' | cut -d " " -f4 | cut -d'"' -f2)
if [[ $TYPE == "" ]]; then
TYPE=$(udevadm info --query=all --name=$number | grep 'ID_PART_TABLE_TYPE' | cut -d '=' -f2)
fi
fi
if ! [[ $TYPE ]]; then
TYPE="UNKNOWN"
fi
# Debugging detected size in bytes.
# echo "BYTES: $BYTES"
SIZE=$BYTES
FORMATTED=$(echo $BYTES | \
sed -r '
:L
s=([0-9]+)([0-9]{3})=\1,\2=
t L')
# IMMEDIATELY convert to KB, the beginning of our scale.
KBS=$(echo "scale=2;${BYTES%/*}/1024"|bc)
# Start with bytes each division of 1024 cycle to next array value MB, GB etc.
for XX in ${DISKSIZES[@]}
do
SIZE=$(echo "scale=2;${SIZE%/*}/1024"|bc)
# Dump the decimal just to see if we have hit the 1024 or less mark.
KBS=$(echo $SIZE | cut -d . -f 1)
# Debugging:
# echo "TESTINGSIZE: $KBS $XX"
if [[ $KBS -lt 1024 && $KBS -gt 1 ]]; then
TRUESIZE="$KBS"$XX
#echo "$KBS $XX"
fi
done
LABEL=$(echo $LABEL | sed "s/ /_/g")
# Test against UNKNOWN VALUES
if ! [[ $TYPE == 'UNKNOWN' || $LABEL == 'UNKNOWN' ]]; then
# Print data in nice Columns, eventually I will re-write this function
# to handle data of any size and include it in code-cleanup application.
if [[ $COLUMNZ -gt 80 ]]; then
Columnize "$array_counter" "$number" "$VENDOR" "$LABEL" "$TYPE" "$TRUESIZE($FORMATTED)"
else
Columnize "$array_counter" "$number" "$VENDOR" "$LABEL" "$TYPE" "$TRUESIZE"
fi
fi
array_counter=$(($array_counter + 1))
done
FullBar
else
# OOPSSY end user does not have a thumbdrive.
echo -e "${bldred}Error: No thumbdrive(s) detected. Exiting...${txtrst}"
exit 0;
fi
}
function copyFile(){
# uncomment below for debugging.
# echo "copyFile RECIEVED 1:$1 2:$2 3:$3 4:$4"
inFile="$1"
outFile="$2"
wholeCurrentSize="$3"
# Size in blocks
size=$(stat --format=%s "$inFile")
((stepNb = size / blockSize + 1))
# Prior existance Remove file.
if [ -f "$outFile" ]; then
rm "$outFile"
fi
# Initiate Copying
i=0
while [ "$i" -lt "$stepNb" ]; do
dd if="$inFile" bs="$blockSize" skip="$i" seek="$i" of="$outFile" count=1 2> /dev/null
((i = i + 1))
# output current copied size
local copiedSize=$(stat --format=%s "$outFile")
((totalCopiedSize = copiedSize + wholeCurrentSize)) || true
((percent = (totalCopiedSize * 100) / totalSize)) || true
echo -en "$percent%\r"
done
return 0
}
function progressCp(){
# uncomment below for debugging.
# echo "progressCp Switches RECEIVED 1:$1 2:$2 3:$3 4:$4"
totalSize=$(du -s "$1" --bytes | awk '{print $1}')
currentSize=0
targetDir="$2"
mkdir -p "$targetDir"
targetDir=$(readlink -f "$targetDir")
cd "$1"
fileList=$(find .)
INDICATOR='='
while read inFile; do
if [ "$inFile" != '.' ]; then
outFile="$targetDir/$inFile"
fileSize=$(stat --format=%s "$inFile")
if [ -d "$inFile" ]; then
mkdir -p "$outFile"
elif [ -f "$inFile" ]; then
if [ "$fileSize" -lt "$blockSize" ]; then
cp "$inFile" "$outFile"
else
copyFile "$inFile" "$outFile" "$currentSize"
fi
else
echo "Error: Unknown type of '$inFile' !" >&2
exit 1
fi
# Mode
#chmod "$(stat --format=%a "$inFile")" "$outFile"
# Progress spinner and precentage
i=1
sp="/-\|"
echo -n ' '
((currentSize = currentSize + fileSize)) || true
((percent = (currentSize * 100) / totalSize)) || true
echo -en "$percent%\r"
fi
done < <(echo "$fileList")
}
function UnmountIso(){
RETURN="$?"
set +o errexit # We need to clean up everything we can
trap - HUP QUIT KILL SEGV PIPE INT TERM EXIT
echo "Syncing..."
cd /
sync
wait 2> /dev/null
sleep 1
echo -e "${bldgrn}Umounting and removing '$1'...${txtrst}"
umount "$1" && rm -rf "$1" || true
echo -e "${bldgrn}Umounting and removing '$2'...${txtrst}"
umount "$2" && rm -rf "$2" || true
}
function STARTTIMER {
# Start the counter, we are off to the races.
STARTM=`date -u "+%s"`
}
function STOPTIMER {
STOPM=`date -u "+%s"`
RUNTIMEM=`expr $STOPM - $STARTM`
if (($RUNTIMEM>59)); then
TTIMEM=`printf "%dm%ds\n" $((RUNTIMEM/60%60)) $((RUNTIMEM%60))`
else
TTIMEM=`printf "%ds\n" $((RUNTIMEM))`
fi
echo "Execution Time: $TTIMEM"
}
function QuickWipeFat() {
#Display initial header
VersionDump
#Verify the switch interpreter, if not provide short help message example.
if [[ $1 == "" ]]; then
DumpArray $1
echo -e "\n${bldred}ERROR: Please specify a device to wipe.${txtrst}"
echo -e "${bldwht}Example: thumbos --erase /dev/sdb${txtrst}"
echo -e "${bldylw}Note: the partition number is unecessary as it will erase the entire drive.${txtrst}"
exit 0;
fi
#Begin scanning for USB Devices.
echo -e "${bldgrn}SCANNING FOR USB DRIVE(S)..."
DETECTED=$(ls -l /dev/disk/by-id/*usb* 2> /dev/null)
#None found?
if ! [[ $DETECTED ]]; then
echo -e "${bldred}No USB drives detected. Exiting.${txtrst}"
exit 0;
fi
if [[ -b /dev/$1 ]]; then
DumpArray $1
else
echo -e "${bldred}Error: Device /dev/$1 is not vaild block device."
echo -e "${bldgrn}Example usage: thumbos --erase sdk full${txtrst}"
exit 0;
fi
NUMERALS=$(echo $2 |grep -o '[0-9]*')
if [[ $NUMERALS ]]; then
echo -e "${bldred}Error: Please provide drive letters only no numerals.${txtrst}"
exit 0;
fi
#Final check. Did the user specify a valid device?
array_counter=1
for number in ${USBDRIVE[@]}
do
REMOVABLE='2'
REMOVABLE=$(lsblk | grep -m1 $number | cut -d ':' -f2 | cut -d" " -f3)
#Debugging - future implementation?
#if [[ $REMOVABLE == 1 ]]; then
if [[ $number == $1 ]]; then
VALIDITY='YES'
fi
#fi
done
if [[ $VALIDITY ]]; then
if [[ $2 == "full" ]]; then
ETYPE='Full'
elif [[ $2 == 'secure' ]]; then
ETYPE='Secure'
else
ETYPE='Quick'
fi
#Verify write premissions to drive
THUMBDRIVE="/dev/"$1
echo -e -n "${txtwht}Verifying write permission of thumbdrive: /dev/$1: ${txtrst}"
if [[ -w ${THUMBDRIVE} ]]; then
echo -e "${bldgrn}Granted.${txtrst}"
else
echo -e "${bldred}Denied."
echo -e "Please run the command sudo thumbos --erase $@"
echo -e "${txtwht}Exiting.${txtrst}"
exit 0
fi
#User has provided valid switches / permission. Drop information and final warning in bold red to standout.
echo -e "${bldgrn}$ETYPE Erase: /dev/$1 thumbdrive?${txtwht}"
while true; do
FullBar
echo -e -n "${bldred}"
read -p "WARNING: this will erase all content on device /dev/$1. (Y/N)? " yn
case $yn in
[Nn]* ) echo -e "${txtrst}"; exit 0;;
[Yy]* ) echo -e "${txtgrn}"
echo "Erasing $1 thumbdrive...";
break;;
* ) echo "Please answer y or n.";;
esac
done
else
echo -e "${bldred}ERROR: $1 is not a valid device.${txtrst}"
exit 0;
fi
STARTTIMER
UNMOUNT=$(umount /dev/$1 2>/dev/null)
case "$ETYPE" in
Full) echo -e "${txtwht}Full wiping drive: $1"; dcfldd if=/dev/zero of=/dev/$1;;
Secure) echo -e "${txtwht}Securely wiping drive: $1"; dcfldd if=/dev/urandom of=/dev/$1 bs=1M;;
*) echo -e "${txtwht}Quickly wiping drive: $1"; QUICK=$(mkfs.msdos -I -n 'Blank' -F 32 /dev/$1);;
esac
echo -e "${txtwht}Syncing..."
sync
echo -e "${txtwht}Refreshing partition ..."
sudo partprobe /dev/$1 2> /dev/null
Notification "All operations completed successfully."
STOPTIMER
}
function Clear() {
# Wipe Thumbdrive
# Debugging switches... Uncomment to see output.
# echo "1:$1 2:$2 3:$3 4:$4"
# exit 0;
# FORCE is an internally called switch to format drive in preparation
# for loading out M$ Windows.
if [[ $2 != "FORCE" ]]; then
# Display initial header
VersionDump
# Verify the switch interpreter, if not provide short help message example.
if [[ $1 == "" ]]; then
DumpArray $1
echo -e "\n${bldred}ERROR: Please specify a device to wipe.${txtrst}"
echo -e "${bldwht}Example: thumbos --erase /dev/sdb${txtrst}"
echo -e "${bldylw}Note: the partition number is unecessary as it will erase the entire drive.${txtrst}"
exit 0;
fi
# Begin scanning for USB Devices.
echo -e "${bldgrn}SCANNING FOR USB DRIVE(S)..."
DETECTED=$(ls -l /dev/disk/by-id/*usb* 2> /dev/null)
# None found?
if ! [[ $DETECTED ]]; then
echo -e "${bldred}No USB drives detected. Exiting.${txtrst}"
exit 0;
fi
if [[ -b /dev/$1 ]]; then
DumpArray $1
else
DumpArray $1
echo -e "${bldred}Error: Device /dev/$1 is not vaild block device."
echo -e "${bldgrn}Example usage: thumbos --erase sdk full${txtrst}"
exit 0;
fi
NUMERALS=$(echo $2 |grep -o '[0-9]*')
if [[ $NUMERALS ]]; then
echo -e "${bldred}Error: Please provide drive letters only no numerals.${txtrst}"
exit 0;
fi
#Final check. Did the user specify a valid device?
array_counter=1
for number in ${USBDRIVE[@]}
do
REMOVABLE='2'
REMOVABLE=$(lsblk | grep -m1 $number | cut -d ':' -f2 | cut -d" " -f3)
#Debugging - future implementation?
#if [[ $REMOVABLE == 1 ]]; then
if [[ $number == $1 ]]; then
VALIDITY='YES'
fi
#fi
done
if [[ $VALIDITY ]]; then
if [[ $2 == "full" ]]; then
ETYPE='Full'
elif [[ $2 == 'secure' ]]; then
ETYPE='Secure'
else
ETYPE='Quick'
fi
#Verify write premissions to drive
THUMBDRIVE="/dev/"$1
echo -e -n "${txtwht}Verifying write permission of thumbdrive: /dev/$1: ${txtrst}"
if [[ -w ${THUMBDRIVE} ]]; then
echo -e "${bldgrn}Granted.${txtrst}"
else
echo -e "${bldred}Denied."
echo -e "Please run the command sudo thumbos --erase $@"
echo -e "${txtwht}Exiting.${txtrst}"
exit 0
fi
#User has provided valid switches / permission. Drop information and final warning in bold red to standout.
echo -e "${bldgrn}$ETYPE Erase: /dev/$1 thumbdrive?${txtwht}"
while true; do
FullBar
echo -e -n "${bldred}"
read -p "WARNING: this will erase all content on device /dev/$1. (Y/N)? " yn
case $yn in
[Nn]* ) echo -e "${txtrst}Exiting..."; exit 0;;
[Yy]* ) echo -en "${txtgrn}"
echo "Erasing $1 thumbdrive...";
break;;
* ) echo "Please answer y or n.";;
esac
done
else
echo -e "${bldred}ERROR: $1 is not a valid device.${txtrst}"
exit 0;
fi
fi
STARTTIMER
# Detect number of partitions currently on thumbdrive.
TOTALPARTS=0
TOTALPARTS=$(parted -s "/dev/$1" print | tail --lines 2 | grep '^\s[0-9]\+\s\+.*$' | awk '{print $1}'| bc)
DISKSIZE=$( sudo parted -s /dev/$1 unit B print | grep "^Disk /dev/$1:" | cut -f 3 -d " " | tr -d B )
# Information overkill, the end user probably does not care
# echo "Disk size detected: $DISKSIZE"
# Unmount Volume(s) - Suppress errors for non-existant volumes
I=0;
if [[ $TOTALPARTS -gt 0 ]]; then
echo -e "${txtwht}$TOTALPARTS existing partitions detected.${txtrst}"
while [ $I -lt $TOTALPARTS ]; do
I=$(($I + 1))
TRUEDEV='/dev/'$1$I
UNMOUNT=$(umount $TRUEDEV 2>/dev/null)
done
else
echo -e "${txtylw}No existing partitions detected.${txtrst}"
fi
#Unmount Success?
if ! [[ $UNMOUNT ]]; then
echo -e "${bldgrn}Device $1 successfully unmounted the $TOTALPARTS partition(s).${txtrst}"
else
echo -e "${bldred}ERROR: $1 can not be unmounted. Are you root?${txtrst}"
exit 0;
fi
I=0;
#DUMP ALL PARTITIONS - Do not assume the enduser is in the United States.
if [[ $TOTALPARTS -gt 0 ]]; then
while [ $I -lt $TOTALPARTS ]; do
I=$(($I + 1))
TRUEDEV='/dev/'$1$I
echo -e "${txtwht}Deleting partition: $TRUEDEV${txtrst}"
sudo parted -s "/dev/$1" rm "$I"
done
else
echo -e "${txtylw}No partitions to delete.${txtrst}"
fi
#Check for non-existant partition table
ERRORCHECK=$(sudo parted -s "/dev/$1" print| grep 'unrecognised disk label')
if [[ $ERRORCHECK ]]; then
echo -e "${bldred}ERROR: No partition table exists at all, attempting to rectify.${txtrst}"
sfdisk /dev/$1 << EOF
;
EOF
sudo dd if=/dev/zero of=/dev/$1 bs=512 count=1
sudo sfdisk -A1 /dev/$1 > /dev/null 2>&1
fi
TRUEDEV='/dev/'$11
#Ensure empty table is reflected to the kernel before proceeding.
echo -e "${bldgrn}Creating a single partition 100% in size."
#Suppress standard output, we don't need to update the fstab for a thumbdrive.
sudo parted -a opt /dev/$1 unit MB mkpart primary 0% 100% > /dev/null 2>&1
sudo sync > /dev/null 2>&1
sudo partprobe $TRUEDEV > /dev/null 2>&1
#Create a single default partition
I=1
TRUEDEV='/dev/'$1$I
#Set default as NTFS
sudo sfdisk -c --change-id /dev/$1 1 07 > /dev/null 2>&1
case "$ETYPE" in
Full) echo -e "${txtwht}Full wiping drive: $1"; dcfldd if=/dev/zero of=/dev/$1;;
Secure) echo -e "${txtwht}Securely wiping drive: $1"; dcfldd if=/dev/urandom of=/dev/$1 bs=1M;;
*) echo -e "${txtwht}Quick formating drive in NTFS Format: $1"; QUICK=$(mkfs.ntfs -Q -L 'ThumbOS' "$TRUEDEV");;
esac
if [[ $QUICK ]]; then
echo -e "${txtwht}Drive $1 successfully formatted.${txtrst}"
fi
echo -e "${txtwht}Syncing...${txtrst}"
sudo sync
echo -e "${txtwht}Setting $TRUEDEV as bootable.${txtrst}"
sudo sfdisk -A1 /dev/$1 > /dev/null 2>&1
echo -e "${txtwht}Refreshing partition ...${txtrst}"
sudo partprobe /dev/$1 2> /dev/null
Notification "All operations completed successfully."
STOPTIMER
}
function WindowsISO {
echo -e "${bldgrn}©Microsoft Windows ISO detected.${txtrst}"
# Debugging Switches
# echo "SENT 1:$1 2:$2 3:$3 4:$4"
# Exclusive internally called switch to force a wipe, we
# already know we have a valid device and user has accepted
# the terms.
Clear $2 FORCE
# Create temporary mount points we will clean up later
isoMountPath="/media/thumbos_iso_$(date +%s)_$$"
partitionMountPath="/media/thumbos_target_$(date +%s)_$$"
STARTTIMER
# Mounting
REALDEV="/dev/$2"1
echo "Mounting $1 ISO..."
mkdir -p "$isoMountPath"
if [ -f "$1" ]; then # ISO
mount -o loop "$1" "$isoMountPath"
else # Real DVD drive (block)
mount "$1" "$isoMountPath"
fi
mkdir -p "$partitionMountPath"
mount "$REALDEV" "$partitionMountPath"
# Calculate needed space
freeSpace=$(df --block-size 1 "$partitionMountPath" | grep "$REALDEV" | awk '{print $4}')
neededSpace=$(du -s "$isoMountPath" --bytes | awk '{print $1}')
neededSpace=$((neededSpace + 1000 * 1000 * 30))
if [ "$neededSpace" -gt "$freeSpace" ]; then
echo -e "${bldred}Error: Not enough free space on '$REALDEV'!${txtrst}" >&2
exit 1
fi
# Copy data
echo "Copying ISO data..."
progressCp "$isoMountPath" "$partitionMountPath"
# boot dir should be lower case
if [ -d "$partitionMountPath/BOOT" ]; then mv "$partitionMountPath/BOOT" "$partitionMountPath/boot"; fi
if [ -d "$partitionMountPath/Boot" ]; then mv "$partitionMountPath/Boot" "$partitionMountPath/boot"; fi
# Install Grub
echo "Installing grub, please wait ..."
grub-install --root-directory="$partitionMountPath" "$REALDEV" > /dev/null 2>&1
uuid=$(blkid -o value -s UUID "$REALDEV")
# grub.cfg
echo "Installing grub.cfg..."
cfgFilename="$partitionMountPath/boot/grub/grub.cfg"
mkdir -p "$(dirname "$cfgFilename")"
echo -n "" > "$cfgFilename"
echo "echo '------------------------------------'" >> "$cfgFilename"
echo "echo '| ThumbOS - Loading... |'" >> "$cfgFilename"
echo "echo '------------------------------------'" >> "$cfgFilename"
echo "insmod ntfs" >> "$cfgFilename"
echo "search --no-floppy --fs-uuid $uuid --set root" >> "$cfgFilename"
echo "chainloader +1" >> "$cfgFilename"
echo "boot" >> "$cfgFilename"
# Cleanup and exit
echo -e "${bldgrn}Cleaning up.${txtrst}"
UnmountIso "$isoMountPath" "$partitionMountPath" 'Cleanup'
STOPTIMER
#Prompt for testing?
if [[ $QEMUINSTALLED ]]; then
while true; do
FullBar
read -p "Would you like to test the drive now in a virtual machine?. (Y/N)? " yn
case $yn in
[Nn]* ) echo -e "${txtrst}"; exit 0;;
[Yy]* ) echo -e "${txtgrn}"
echo "Booting $2...";
break;;
* ) echo "Please answer y or n.";;
esac
done
Virtual $REALDEV
fi
Notification "All operations completed successfully."
}
function Loadit() {
#Display initial header
VersionDump
#Verify the switch interpreter, if not provide short help message example & exit.
if [[ $1 == "" ]]; then
echo -e "\n${bldred}ERROR: Please specify an ISO to load to thumbdrive.${txtrst}"
echo -e "${bldwht}Example: thumbos --load ultimate-edition-4.0-x64.iso sdc${txtrst}"
echo -e "${bldylw}Note: the partition number is unecessary as it will replace the entire drive.${txtrst}"
exit 0;
fi
#display information about selected iso:
if [[ -e $1 ]]; then
DiskImageInfo $1
else
echo -e "${bldred}$1 does not exist. Please specify an ISO to load.${txtrst}"
exit 0;
fi
#Begin scanning for USB Devices.
echo -e "${bldgrn}SCANNING FOR USB DRIVE(S)..."
DETECTED=$(ls -l /dev/disk/by-id/*usb* 2> /dev/null)
#None found?
if [[ $DETECTED == "" ]]; then
echo -e "${bldred}No USB drives detected. Exiting.${txtrst}"
exit 0;
fi
#proper switches provided?
if [[ -e $1 && $2 != "" ]]; then
DumpArray $1
else
DumpArray $1
if [[ -e "$1" ]]; then
if [[ ${USBDRIVE[@]} && $2 == "" ]]; then
echo -e "${bldred}Please provide one of the destinations above.${txtrst}"
echo -e "${bldwht}Example: thumbos --load ultimate-edition-4.0-x64.iso sdc${txtrst}"
echo -e "${bldylw}Note: the partition number is unecessary as it will replace the entire drive.${txtrst}"
exit 0;
fi
else
echo -e "${bldred}$1 does not exist. Please specify an ISO.${txtrst}"
exit 0;
fi
fi
#Scan for partition numbers a no, no.
NUMERALS=$(echo $2 |grep -o '[0-9]*')
if [[ $NUMERALS ]]; then
echo -e "${bldred}Error: Please provide drive letters only no numerals.${txtrst}"
exit 0;
fi
#Final check. Did the user specify a valid device?
array_counter=1
for number in ${USBDRIVE[@]}
do
REMOVABLE='2'
REMOVABLE=$(lsblk | grep -m1 $number | cut -d ':' -f2 | cut -d" " -f3)
#Debugging - future implementation?
#if [[ $REMOVABLE == 1 ]]; then
if [[ $number == $2 ]]; then
VALIDITY='YES'
THUMBDRIVE='/dev/'$2
fi
#fi
done
if [[ $VALIDITY ]]; then
# Verify write premissions to drive
echo -e -n "${txtwht}Verifying write premissions to thumbdrive ${THUMBDRIVE}: ${txtrst}"
if [[ -w ${THUMBDRIVE} ]]; then
echo -e "${bldgrn}Granted.${txtrst}"
else
echo -e "${bldred}Denied."
echo -e "Please run the command sudo thumbos --load $@"
echo -e "${txtwht}Exiting.${txtrst}"
exit 0
fi
# User has provided valid switches. Drop information and warning.
echo -e "${bldgrn}Load: $1 to: $2 thumbdrive?${txtwht}"
while true; do
FullBar
echo -e -n "${bldred}"
read -p "WARNING: this will erase all content on device $2. (Y/N)? " yn
case $yn in
[Nn]* ) echo -e "${txtrst}Exiting ..."; exit 0;;
[Yy]* ) echo -en "${bldgrn}"
echo -e "Dumping $1 to thumbdrive $2...${txtrst}";
break;;
* ) echo "Please answer y or n.";;
esac
done
# Whack the thumbdrive and load it as requested.
# Is drive mounted? If so unmount drive. Suppress errors if not
# mounted.
# Windows Bootable ISO?
if [[ $BOOTABLE && $WINISO ]]; then
WindowsISO $1 $2 $3 $4
fi
# Click the timer, we are starting.
STARTTIMER
DUMPIT=$(umount /dev/$2 2>/dev/null)
# convert image to hybrid bootable image.
isohybrid $1
# Use dcfldd - forensic based version of dd aka "Disk Destroyer"
# we like nice toys.
dcfldd sizeprobe=if statusinterval=10 bs=4M if=$1 of=/dev/$2
# Ensure all data even buffered is written to the disk.
sync
# Set drive active
echo -e "${bldgrn}Setting $2 device as bootable.${txtrst}"
SUPPRESS=$(sfdisk -A /dev/$2 2>/dev/null)
else
echo -e "${bldred}$2 is not a vaild device. Please refer to the table above.${txtrst}"
# Correction in #1.0.3, no sence in syncing or refreshing the
# Partition table if an invaild device was specified. Exit.
exit 0;
fi
echo -e "${txtwht}Syncing..."
sync
echo -e "${txtwht}Refreshing partition ..."
sudo partprobe /dev/$2 2>/dev/null
Notification "All operations completed successfully."
STOPTIMER
#Prompt for testing?
if [[ $QEMUINSTALLED ]]; then
while true; do
FullBar
read -p "Would you like to test the drive now in a virtual machine?. (Y/N)? " yn
case $yn in
[Nn]* ) echo -e "${txtrst}"; exit 0;;
[Yy]* ) echo -e "${txtgrn}"
echo "Booting $2...";
break;;
* ) echo "Please answer y or n.";;
esac
done
Virtual /dev/$2
fi
}
function Help() {
echo "PARAMETER: $1"
if [[ $1 == "" ]];
then
VersionDump
PRAM="ALL"
else
PRAM=$1
fi
case $PRAM in
ALL)
echo -e "
${bldgrn}Usage: $PROGNAME -<-COMMAND> [option]${txtrst}
Mandatory arguments to long options are identical for short options.
possible commands...
-e --erase erases the entire thumbdrive
-l --load load ISO image to thumbdrive
-h --help this help message
-s --scan scans / reports thumbdrive(s) and exits
-t --test test boot device and exit
-v --version dump version info
${bldgrn}$PROGNAME --help [COMMAND] for further information.${txtrst}";;
ALL|e|erase)
echo -e "
${bldwht}Usage erase;${txtrst}
${txtgrn}$PROGNAME -e <DEVICE> [quick|secure|full]${txtrst}
Quickly erases the contents of <DEVICE> thumbdrive.
Example: ${bldgrn}$PROGNAME --erase sdi secure${txtrst}
If the [full] or [secure] option is used it will wipe the entire drive. This
is a slow process and the information is non-recoverable. Specifing no option
is the same as using the default [Quick] option.
${bldred}Warning: The contents of the device will be entirely wiped and
unrecoverable using the secure or full option.${txtrst}
${txtylw}Note: The partition number is not necessary as the entire drive will be wiped.${txtrst}";;
ALL|s|scan)
echo -e "
${bldwht}Usage scan;${txtrst}
${txtgrn}$PROGNAME -s${txtrst}
Scans and reports availible thumbdrive(s).";;
ALL|t|test)
echo -e "
${bldwht}Usage test;${txtrst}
${txtgrn}$PROGNAME -t [DEVICE] | [ISO]${txtrst}
Invokes a virtual machine to boot [DEVICE] or [ISO] image.
Example: thumbos --test ultimate-edition-4.2-x64-lite.iso
Example 2: thumbos --test sdd";;
ALL|l|load)
echo -e "
${bldwht}Usage load;${txtrst}
${txtgrn}$PROGNAME -l <ISONAME> <DEVICE>${txtrst}
Loads selected ISO to selected thumbdrive. Optionally will launch kvm for
testing.
Example: ${bldgrn}thumbos --load utimate-edition-4.0-x64.iso sdi
${bldred}Warning: The contents of the device will be entirely wiped.${txtrst}
${bldylw}Note: the partition number is unecessary as it will replace the entire drive.${txtrst}";;
ALL|v|version)
echo -e "
${bldwht}Usage version;${txtrst}
${txtgrn}$PROGNAME -v${txtrst}
Displays $PROGNAMEs version number and exits.";;
ALL|h|help|\?)
echo -e "
${bldwht}Useage Help [COMMAND];${txtrst}
${txtgrn}$PROGNAME -h [COMMAND]${txtrst}
Displays this message. For futher information $PROGNAME help [COMMAND]
or refer to the manpages.
man $PROGNAME"
echo -e "${txtgrn}"
echo -e "Example: $PROGNAME -h version"
echo -e "${txtwht}Will display help about the command version${txtrst}"
esac
exit 0
}
function VersionDump {
EyeCandy "$PROGNAME $VERSION, $BUILDDATE"
echo -e "GNU $PROGNAME home page: <http://ultimateedition.info/>."
echo -e "E-mail bug reports to: <[email protected]>."
echo -e "Be sure to include the word $PROGNAME somewhere in the Subject: field."
}
# Command line pre-processor use for debugging.
#CommandLineIntrepreter $@
case "$1" in
-s|--scan) VersionDump; DumpArray; exit 0;;
-t|--test) VersionDump; Virtual $2; exit 0;;
-e|--erase) Clear $2 $3 $4; exit 0;;
-l|--load) Loadit $2 $3 $4; exit 0;;
-h|--help|-\?) Help $2; exit 0;;
-v|--version) VersionDump; exit 0;;
*) Help; exit 0;;
esac
Funny how a programmer will spend 10 extra hours writing software just to save 10 minutes tapping keys. I am no exception. Thumbos supports bash autocompletion ie typing thumbos - and tapping the [TAB] key 3 times will yield the availible command switches:
theemahn@JackHammer:~/Music$ thumbos --
--erase --help --load --scan --version
theemahn@JackHammer:~/Music$ thumbos --
Same goes with image files:
theemahn@JackHammer:~/Music$ thumbos --load
Misc ultimate-android-20130222-i386.iso ultimate-edition-4.0-x64.iso
Misc.tar.gz ultimate-edition-3.8-lite-x64-Nov-22-2013-0352.iso ultimate-edition-mk809III-armel-Dec-02-2013-0757.iso
theemahn@JackHammer:~/Music$ thumbos --load
Completion code:
/etc/bash_completion.d/thumbos:
- Code: Select all
# Debian thumbos(8) completion.
have thumbos &&
_thumbos()
{
dashify()
{
local i
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
if [ ${#COMPREPLY[i]} -le 2 ]; then
COMPREPLY[i]=-${COMPREPLY[i]}
else
COMPREPLY[i]=--${COMPREPLY[i]}
fi
done
}
local cur cur_nodash prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
cur_nodash=${cur#-}
prev=${COMP_WORDS[COMP_CWORD-1][COMP_CWORD-2]}
if [ $COMP_CWORD = 1 ]; then
# first parameter on line
case "$cur" in
-s*)
COMPREPLY=( $( compgen -W 'scan' \
$cur_nodash ) )
dashify
return 0
;;
-l*)
COMPREPLY=( $( compgen -W 'load' \
$cur_nodash ) )
dashify
return 0
;;
-*)
COMPREPLY=( $( compgen -W 'erase load scan version help' ${cur_nodash#-} ) )
dashify;
return 0
;;
--*)
COMPREPLY=( $( compgen -W 'erase load scan version help' ${cur_nodash#-} ) )
dashify;
return 0
;;
*)
COMPREPLY=( $( compgen -f $cur ) )
return 0
;;
esac
fi
if [ $COMP_CWORD = 2 ]; then
case "${COMP_WORDS[1]}" in
--l*)
# standard filename completion
COMPREPLY=( $( compgen -f $cur ) )
return 0
;;
-l)
# standard filename completion
COMPREPLY=( $( compgen -f $cur ) )
return 0
;;
--h*)
# complete on list of relevant options
COMPREPLY=( $( compgen -W 'erase help load scan version' ${cur_nodash#-} ) )
#dashify;
return 0
;;
-h)
# complete on list of relevant options
COMPREPLY=( $( compgen -W 'erase load scan help version' ${cur_nodash#-} ) )
#dashify;
return 0
;;
esac
fi
}
complete -F _thumbos thumbos
Download:
I sure hope you enjoy the app, just half as much as I do. I do love it, This app has saved my rump more then once. A few Million PPL know what Thumbos is now. Got to love integration.
TheeMahn