diff --git a/.bin/Scripts/build-ufd b/.bin/Scripts/build-ufd index 3cce38df..f1db1286 100755 --- a/.bin/Scripts/build-ufd +++ b/.bin/Scripts/build-ufd @@ -1,36 +1,413 @@ -#!/bin/bash +#!/usr/bin/env bash # ## Wizard Kit: UFD Build Tool +# +# Based on a template by BASH3 Boilerplate v2.3.0 +# http://bash3boilerplate.sh/#authors +# +# The MIT License (MIT) +# Copyright (c) 2013 Kevin van Zonneveld and contributors +# You are not obligated to bundle the LICENSE file with your b3bp projects as long +# as you leave these references intact in the header comments of your source files. +# Exit on error. Append "|| true" if you expect an error. set -o errexit +# Exit on error inside any functions or subshells. set -o errtrace +# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR set -o nounset +# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip` set -o pipefail +# Turn on traces, useful while debugging but commented out by default +# set -o xtrace -DEST_DEV="$1" -DEST_PARTITION="${DEST_DEV}1" -MAIN_PY="/usr/local/bin/settings/main.py" -LOG_FILE="${HOME}/build-ufd_${DEST_DEV##*/}_$(date +%Y-%m-%d_%H%M_%z).log" -RSYNC_ARGS="-hrtuvS --modify-window=1 --progress" -WD=$(pwd) -EXTRA_DIR="${WD}/Extras" -MAIN_KIT="$(dirname $(find $WD -type d -name '.bin' || true) 2>/dev/null || true)" -LINUX_ISO="$((find $WD -maxdepth 1 -type f -iname '*Linux*iso' 2>/dev/null || echo "__Missing__") | sort -r | head -1)" -WINPE_ISO="$((find $WD -maxdepth 1 -type f -iname '*WinPE*amd64*iso' 2>/dev/null || echo "__Missing__") | sort -r | head -1)" -if [ "${2:-}" == "--silent" ]; then +if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then + __i_am_main_script="0" # false + + if [[ "${__usage+x}" ]]; then + if [[ "${BASH_SOURCE[1]}" = "${0}" ]]; then + __i_am_main_script="1" # true + fi + + __b3bp_external_usage="true" + __b3bp_tmp_source_idx=1 + fi +else + __i_am_main_script="1" # true + [[ "${__usage+x}" ]] && unset -v __usage + [[ "${__helptext+x}" ]] && unset -v __helptext +fi + +# Set magic variables for current file, directory, os, etc. +__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)" +__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" +__base="$(basename "${__file}" .sh)" +__wd="$(pwd)" +__usage_example="Usage: sudo $(basename "${0}") --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path]" +__all_args="" +for a in "${@}"; do + if [[ "${a:0:1}" == "-" ]]; then + __all_args="${__all_args} ${a}" + else + __all_args="${__all_args} \"${a}\"" + fi +done + + +# Define the environment variables (and their defaults) that this script depends on +LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency +NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected + + +### Functions +############################################################################## + +function __b3bp_log () { + local log_level="${1}" + shift + + # shellcheck disable=SC2034 + local color_debug="\x1b[35m" + # shellcheck disable=SC2034 + local color_info="\x1b[32m" + # shellcheck disable=SC2034 + local color_notice="\x1b[34m" + # shellcheck disable=SC2034 + local color_warning="\x1b[33m" + # shellcheck disable=SC2034 + local color_error="\x1b[31m" + # shellcheck disable=SC2034 + local color_critical="\x1b[1;31m" + # shellcheck disable=SC2034 + local color_alert="\x1b[1;33;41m" + # shellcheck disable=SC2034 + local color_emergency="\x1b[1;4;5;33;41m" + + local colorvar="color_${log_level}" + + local color="${!colorvar:-${color_error}}" + local color_reset="\x1b[0m" + + if [[ "${NO_COLOR:-}" = "true" ]] || ( [[ "${TERM:-}" != *"256color"* ]] && [[ "${TERM:-}" != "xterm"* ]] && [[ "${TERM:-}" != "screen"* ]] ) || [[ ! -t 2 ]]; then + if [[ "${NO_COLOR:-}" != "false" ]]; then + # Don't use colors on pipes or non-recognized terminals + color=""; color_reset="" + fi + fi + + # all remaining arguments are to be printed + local log_line="" + + while IFS=$'\n' read -r log_line; do + echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" "${log_level}")${color_reset} ${log_line}" 1>&2 + done <<< "${@:-}" +} + +function emergency () { __b3bp_log emergency "${@}"; exit 1; } +function alert () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && __b3bp_log alert "${@}"; true; } +function critical () { [[ "${LOG_LEVEL:-0}" -ge 2 ]] && __b3bp_log critical "${@}"; true; } +function error () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && __b3bp_log error "${@}"; true; } +function warning () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && __b3bp_log warning "${@}"; true; } +function notice () { [[ "${LOG_LEVEL:-0}" -ge 5 ]] && __b3bp_log notice "${@}"; true; } +function info () { [[ "${LOG_LEVEL:-0}" -ge 6 ]] && __b3bp_log info "${@}"; true; } +function debug () { [[ "${LOG_LEVEL:-0}" -ge 7 ]] && __b3bp_log debug "${@}"; true; } + +function help () { + echo "" 1>&2 + echo " ${*}" 1>&2 + echo "" 1>&2 + echo " ${__usage:-No usage available}" 1>&2 + echo "" 1>&2 + + if [[ "${__helptext:-}" ]]; then + echo " ${__helptext}" 1>&2 + echo "" 1>&2 + fi + + exit 1 +} + + +### Parse commandline options +############################################################################## + +# Commandline options. This defines the usage page, and is used to parse cli +# opts & defaults from. The parsing is unforgiving so be precise in your syntax +# - A short option must be preset for every long option; but every short option +# need not have a long option +# - `--` is respected as the separator between options and arguments +# - We do not bash-expand defaults, so setting '~/app' as a default will not resolve to ${HOME}. +# you can use bash variables to work around this (so use ${HOME} instead) + +# shellcheck disable=SC2015 +[[ "${__usage+x}" ]] || read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered + OPTIONS: + -u --ufd-device [arg] Device to which the kit will be applied + -m --main-kit [arg] Path to the Main Kit + -l --linux-iso [arg] Path to the Linux ISO + -w --winpe-iso [arg] Path to the WinPE ISO + + -e --extra-dir [arg] Path to the Extra folder (optional) + -h --help This page + + ADVANCED: + -d --debug Enable debug mode + -v --verbose Enable verbose mode + -F --force Bypass all confirmation messages. USE WITH EXTREME CAUTION! +EOF + +# shellcheck disable=SC2015 +[[ "${__helptext+x}" ]] || read -r -d '' __helptext <<-'EOF' || true # exits non-zero when EOF encountered + Paths can be relative to the current working directory or absolute +EOF + +# Translate usage string -> getopts arguments, and set $arg_ defaults +while read -r __b3bp_tmp_line; do + if [[ "${__b3bp_tmp_line}" =~ ^- ]]; then + # fetch single character version of option string + __b3bp_tmp_opt="${__b3bp_tmp_line%% *}" + __b3bp_tmp_opt="${__b3bp_tmp_opt:1}" + + # fetch long version if present + __b3bp_tmp_long_opt="" + + if [[ "${__b3bp_tmp_line}" = *"--"* ]]; then + __b3bp_tmp_long_opt="${__b3bp_tmp_line#*--}" + __b3bp_tmp_long_opt="${__b3bp_tmp_long_opt%% *}" + fi + + # map opt long name to+from opt short name + printf -v "__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}" '%s' "${__b3bp_tmp_opt}" + printf -v "__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt}" '%s' "${__b3bp_tmp_long_opt//-/_}" + + # check if option takes an argument + if [[ "${__b3bp_tmp_line}" =~ \[.*\] ]]; then + __b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg + __b3bp_tmp_init="" # it has an arg. init with "" + printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "1" + elif [[ "${__b3bp_tmp_line}" =~ \{.*\} ]]; then + __b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg + __b3bp_tmp_init="" # it has an arg. init with "" + # remember that this option requires an argument + printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2" + else + __b3bp_tmp_init="0" # it's a flag. init with 0 + printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "0" + fi + __b3bp_tmp_opts="${__b3bp_tmp_opts:-}${__b3bp_tmp_opt}" + fi + + [[ "${__b3bp_tmp_opt:-}" ]] || continue + + if [[ "${__b3bp_tmp_line}" =~ (^|\.\ *)Default= ]]; then + # ignore default value if option does not have an argument + __b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" + + if [[ "${!__b3bp_tmp_varname}" != "0" ]]; then + __b3bp_tmp_init="${__b3bp_tmp_line##*Default=}" + __b3bp_tmp_re='^"(.*)"$' + if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then + __b3bp_tmp_init="${BASH_REMATCH[1]}" + else + __b3bp_tmp_re="^'(.*)'$" + if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then + __b3bp_tmp_init="${BASH_REMATCH[1]}" + fi + fi + fi + fi + + if [[ "${__b3bp_tmp_line}" =~ (^|\.\ *)Required\. ]]; then + # remember that this option requires an argument + printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2" + fi + + printf -v "arg_${__b3bp_tmp_opt:0:1}" '%s' "${__b3bp_tmp_init}" +done <<< "${__usage:-}" + +# run getopts only if options were specified in __usage +if [[ "${__b3bp_tmp_opts:-}" ]]; then + # Allow long options like --this + __b3bp_tmp_opts="${__b3bp_tmp_opts}-:" + + # Reset in case getopts has been used previously in the shell. + OPTIND=1 + + # start parsing command line + set +o nounset # unexpected arguments will cause unbound variables + # to be dereferenced + # Overwrite $arg_ defaults with the actual CLI options + while getopts "${__b3bp_tmp_opts}" __b3bp_tmp_opt; do + [[ "${__b3bp_tmp_opt}" = "?" ]] && help "Invalid use of script: ${*} " + + if [[ "${__b3bp_tmp_opt}" = "-" ]]; then + # OPTARG is long-option-name or long-option=value + if [[ "${OPTARG}" =~ .*=.* ]]; then + # --key=value format + __b3bp_tmp_long_opt=${OPTARG/=*/} + # Set opt to the short option corresponding to the long option + __b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}" + printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}" + OPTARG=${OPTARG#*=} + else + # --key value format + # Map long name to short version of option + __b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${OPTARG//-/_}" + printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}" + # Only assign OPTARG if option takes an argument + __b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt}" + printf -v "OPTARG" '%s' "${@:OPTIND:${!__b3bp_tmp_varname}}" + # shift over the argument if argument is expected + ((OPTIND+=__b3bp_tmp_has_arg_${__b3bp_tmp_opt})) + fi + # we have set opt/OPTARG to the short value and the argument as OPTARG if it exists + fi + __b3bp_tmp_varname="arg_${__b3bp_tmp_opt:0:1}" + __b3bp_tmp_default="${!__b3bp_tmp_varname}" + + __b3bp_tmp_value="${OPTARG}" + if [[ -z "${OPTARG}" ]] && [[ "${__b3bp_tmp_default}" = "0" ]]; then + __b3bp_tmp_value="1" + fi + + printf -v "${__b3bp_tmp_varname}" '%s' "${__b3bp_tmp_value}" + debug "cli arg ${__b3bp_tmp_varname} = (${__b3bp_tmp_default}) -> ${!__b3bp_tmp_varname}" + done + set -o nounset # no more unbound variable references expected + + shift $((OPTIND-1)) + + if [[ "${1:-}" = "--" ]] ; then + shift + fi +fi + + +### Automatic validation of required option arguments +############################################################################## + +for __b3bp_tmp_varname in ${!__b3bp_tmp_has_arg_*}; do + # validate only options which required an argument + [[ "${!__b3bp_tmp_varname}" = "2" ]] || continue + + __b3bp_tmp_opt_short="${__b3bp_tmp_varname##*_}" + __b3bp_tmp_varname="arg_${__b3bp_tmp_opt_short}" + [[ "${!__b3bp_tmp_varname}" ]] && continue + + __b3bp_tmp_varname="__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt_short}" + printf -v "__b3bp_tmp_opt_long" '%s' "${!__b3bp_tmp_varname}" + [[ "${__b3bp_tmp_opt_long:-}" ]] && __b3bp_tmp_opt_long=" (--${__b3bp_tmp_opt_long//_/-})" + + help "Option -${__b3bp_tmp_opt_short}${__b3bp_tmp_opt_long:-} requires an argument" +done + + +### Cleanup Environment variables +############################################################################## + +for __tmp_varname in ${!__b3bp_tmp_*}; do + unset -v "${__tmp_varname}" +done + +unset -v __tmp_varname + + +### Externally supplied __usage. Nothing else to do here +############################################################################## + +if [[ "${__b3bp_external_usage:-}" = "true" ]]; then + unset -v __b3bp_external_usage + return +fi + + +### Signal trapping and backtracing +############################################################################## + +function __b3bp_cleanup_before_exit () { + if [[ "$EUID" -eq 0 ]]; then + for d in Dest Linux WinPE; do + if [[ -d "/mnt/${d}" ]]; then + umount "/mnt/${d}" || true + rmdir "/mnt/${d}" || true + fi + done + fi + if [[ "${?}" != "0" ]]; then + info "Sources unmounted" + fi + if [[ ${arg_F:-} == 0 && "${SILENT:-False}" == "False" ]]; then + read -r -p "Press Enter to exit... " ignored_var 2>&1 + fi +} +trap __b3bp_cleanup_before_exit EXIT + +# requires `set -o errtrace` +__b3bp_err_report() { + local error_code + error_code=${?} + error "Error in ${__file} in function ${1} on line ${2}" + exit ${error_code} +} +# Uncomment the following line for always providing an error backtrace +trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR + + +### Command-line argument switches (like -d for debugmode, -h for showing helppage) +############################################################################## + +# debug mode +if [[ "${arg_d:?}" = "1" ]]; then + set -o xtrace + LOG_LEVEL="7" + # Enable error backtracing + trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR +fi + +# verbose mode +if [[ "${arg_v:?}" = "1" ]]; then + set -o verbose +fi + + +### Validation. Error out if the things required for your script are not present +############################################################################## + +if [[ "${arg_F:?}" == 1 ]]; then SILENT="True" else SILENT="False" fi -# COLORS -CLEAR="\e[0m" -RED="\e[31m" -GREEN="\e[32m" -YELLOW="\e[33m" -BLUE="\e[34m" +if [[ "${arg_h:?}" == 1 ]]; then + help "${__usage_example}" +else + # Print warning line + [[ "${arg_u:-}" ]] || echo " -u or --ufd-device is required" + [[ "${arg_m:-}" ]] || echo " -m or --main-kit is required" + [[ "${arg_l:-}" ]] || echo " -l or --linux-iso is required" + [[ "${arg_w:-}" ]] || echo " -w or --winpe-iso is required" + + # Bail if necessary + [[ "${arg_u:-}" ]] || help "${__usage_example}" + [[ "${arg_l:-}" ]] || help "${__usage_example}" + [[ "${arg_m:-}" ]] || help "${__usage_example}" + [[ "${arg_w:-}" ]] || help "${__usage_example}" +fi +[[ "${LOG_LEVEL:-}" ]] || emergency "Cannot continue without LOG_LEVEL. " + + +### More functions +############################################################################## + +function abort () { + local abort_message="Aborted" + [[ "${1:-}" ]] && abort_message="${1}" || true + error "${abort_message}" + #echo -e "${YELLOW}${abort_message}${CLEAR}" + exit 1 +} -# Functions function ask() { if [[ "${SILENT}" == "True" ]]; then echo -e "${1:-} Yes ${BLUE}(Silent)${CLEAR}" @@ -46,86 +423,83 @@ function ask() { done } -die () { - echo "$@" >&2 - echo "" - read -p "Press Enter to exit... " -r - exit 1 -} + +### Runtime +############################################################################## + +# VARIABLES +DEST_DEV="${arg_u}" +DEST_PAR="${DEST_DEV}1" +LOG_FILE="${HOME}/build-ufd_${DEST_DEV##*/}_$(date +%Y-%m-%d_%H%M_%z).log" +MAIN_PY="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/settings/main.py" +RSYNC_ARGS="-hrtuvS --modify-window=1 --progress" +MAIN_KIT="$(realpath "${arg_m:-}" 2>/dev/null || true)" +LINUX_ISO="$(realpath "${arg_l:-}" 2>/dev/null || true)" +WINPE_ISO="$(realpath "${arg_w:-}" 2>/dev/null || true)" +EXTRA_DIR="$(realpath "${arg_e:-}" 2>/dev/null || true)" + +# COLORS +CLEAR="\e[0m" +RED="\e[31m" +GREEN="\e[32m" +YELLOW="\e[33m" +BLUE="\e[34m" # Load main.py settings -if [ ! -f "$MAIN_PY" ]; then - echo -e "${RED}ERROR${CLEAR}: $MAIN_PY not found." - die "Aborted." +if [ ! -f "${MAIN_PY}" ]; then + echo -e "${RED}ERROR${CLEAR}: ${MAIN_PY} not found." + abort fi while read line; do - if echo "$line" | egrep -q "^\w+='"; then - line="$(echo "$line" | sed -r 's/[\r\n]+//')" - eval "$line" + if echo "${line}" | egrep -q "^\w+='"; then + line="$(echo "${line}" | sed -r 's/[\r\n]+//')" + eval "${line}" fi -done < "$MAIN_PY" +done < "${MAIN_PY}" if [ -z ${KIT_NAME_FULL+x} ]; then # KIT_NAME_FULL is not set, assume main.py missing or malformatted - echo -e "${RED}ERROR${CLEAR}: failed to load settings from $MAIN_PY" - die "Aborted." + echo -e "${RED}ERROR${CLEAR}: failed to load settings from ${MAIN_PY}" + abort fi UFD_LABEL="${KIT_NAME_SHORT}_LINUX" # Check if root if [[ "$EUID" -ne 0 ]]; then echo -e "${RED}ERROR${CLEAR}: This script must be run as root." - die "Aborted." + abort fi # Check if in tmux if ! tmux list-session 2>/dev/null | grep -q "build-ufd"; then # Reload in tmux - tmux new-session -s "build-ufd" "${0:-}" $* + eval tmux new-session -s "build-ufd" "${0:-}" ${__all_args} + SILENT="True" # avoid two "Press Enter to exit..." prompts exit 0 fi # Header -echo -e "${GREEN}$KIT_NAME_FULL${CLEAR}: UFD Build Tool" +echo -e "${GREEN}${KIT_NAME_FULL}${CLEAR}: UFD Build Tool" echo "" -# Dest and Sources Check -abort="False" -if [ ! -b "$DEST_DEV" ]; then - echo -e "${RED}ERROR${CLEAR}: Device $DEST_DEV not found." - abort="True" -fi -if [ ! -f "$LINUX_ISO" ]; then - echo -e "${RED}ERROR${CLEAR}: Linux ISO not found." - abort="True" -fi -if [ ! -f "$WINPE_ISO" ]; then - echo -e "${RED}ERROR${CLEAR}: WinPE ISO not found." - abort="True" -fi -if [ ! -d "$MAIN_KIT" ]; then - echo -e "${RED}ERROR${CLEAR}: Wizard Kit directory not found." - abort="True" -fi -if [ ! -d "$EXTRA_DIR" ]; then - # Warn but don't abort - echo -e "${YELLOW}WARNING${CLEAR}: $EXTRA_DIR not found." - echo "" - EXTRA_DIR='__None__' -fi -if [ "$abort" == "True" ]; then - echo "" - die "Aborted." +# Verify sources +[[ -b "${DEST_DEV}" ]] || abort "${DEST_DEV} is not a valid device." +[[ -d "${MAIN_KIT}/.bin" ]] || abort "Invalid Main Kit, ${MAIN_KIT}/.bin not found." +[[ -e "${LINUX_ISO}" ]] || abort "Linux ISO not found." +[[ -e "${WINPE_ISO}" ]] || abort "WinPE ISO not found." +if [[ ! -z "${arg_e:-}" ]]; then + [[ -d "${EXTRA_DIR}" ]] || abort "Extra Dir not found." fi -# Display Job Settings +# Print Info echo -e "${BLUE}Sources${CLEAR}" -echo "Main Kit: $MAIN_KIT" -echo "Linux ISO: $LINUX_ISO" -echo "WinPE ISO: $WINPE_ISO" -echo "Extras: $EXTRA_DIR" +echo "Main Kit: ${MAIN_KIT}" +echo "Linux ISO: ${LINUX_ISO}" +echo "WinPE ISO: ${WINPE_ISO}" +echo "Extra Dir: ${EXTRA_DIR:-(Not Specified)}" echo "" echo -e "${BLUE}Destination${CLEAR}" -lsblk -n -o NAME,LABEL,SIZE,MODEL,SERIAL $DEST_DEV +lsblk -n -o NAME,LABEL,SIZE,MODEL,SERIAL "${DEST_DEV}" +echo "" # Ask before starting job echo "" @@ -135,81 +509,84 @@ if ask "Is the above information correct?"; then echo "All data will be DELETED from the disk and partition(s) listed above." echo -e "This is irreversible and will lead to ${RED}DATA LOSS.${CLEAR}" if ! ask "Asking again to confirm, is this correct?"; then - die "Aborted." + abort fi else - die "Aborted." + abort fi # Start Build echo "" echo -e "${GREEN}Building Kit${CLEAR}" -touch "$LOG_FILE" -tmux split-window -dl 10 tail -f "$LOG_FILE" +touch "${LOG_FILE}" +tmux split-window -dl 10 tail -f "${LOG_FILE}" # Format echo "Formatting drive..." -parted "$DEST_DEV" -s -- mklabel msdos mkpart primary fat32 1MiB -1s >> "$LOG_FILE" 2>&1 -parted "$DEST_DEV" set 1 boot on >> "$LOG_FILE" 2>&1 -mkfs.vfat -F 32 -n "$UFD_LABEL" "$DEST_PARTITION" >> "$LOG_FILE" 2>&1 +parted "${DEST_DEV}" -s -- mklabel msdos mkpart primary fat32 1MiB -1s >> "${LOG_FILE}" 2>&1 +parted "${DEST_DEV}" set 1 boot on >> "${LOG_FILE}" 2>&1 +mkfs.vfat -F 32 -n "${UFD_LABEL}" "${DEST_PAR}" >> "${LOG_FILE}" 2>&1 # Mount sources and dest echo "Mounting sources and destination..." -mkdir /mnt/{Dest,Linux,WinPE} -p >> "$LOG_FILE" 2>&1 -mount $DEST_PARTITION /mnt/Dest >> "$LOG_FILE" 2>&1 -mount "$LINUX_ISO" /mnt/Linux -r >> "$LOG_FILE" 2>&1 -mount "$WINPE_ISO" /mnt/WinPE -r >> "$LOG_FILE" 2>&1 +mkdir /mnt/{Dest,Linux,WinPE} -p >> "${LOG_FILE}" 2>&1 +mount ${DEST_PAR} /mnt/Dest >> "${LOG_FILE}" 2>&1 +mount "${LINUX_ISO}" /mnt/Linux -r >> "${LOG_FILE}" 2>&1 +mount "${WINPE_ISO}" /mnt/WinPE -r >> "${LOG_FILE}" 2>&1 # Copy files echo "Copying Linux files..." -rsync ${RSYNC_ARGS} /mnt/Linux/* /mnt/Dest/ >> "$LOG_FILE" 2>&1 +rsync ${RSYNC_ARGS} /mnt/Linux/* /mnt/Dest/ >> "${LOG_FILE}" 2>&1 echo "Copying WinPE files..." -rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot,bootmgr{,.efi},en-us,sources} /mnt/Dest/ >> "$LOG_FILE" 2>&1 -rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Microsoft /mnt/Dest/EFI/ >> "$LOG_FILE" 2>&1 -rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Boot/* /mnt/Dest/EFI/Microsoft/ >> "$LOG_FILE" 2>&1 -rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot/{BCD,boot.sdi},bootmgr} /mnt/Dest/sources/ >> "$LOG_FILE" 2>&1 +rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot,bootmgr{,.efi},en-us,sources} /mnt/Dest/ >> "${LOG_FILE}" 2>&1 +rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Microsoft /mnt/Dest/EFI/ >> "${LOG_FILE}" 2>&1 +rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Boot/* /mnt/Dest/EFI/Microsoft/ >> "${LOG_FILE}" 2>&1 +rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot/{BCD,boot.sdi},bootmgr} /mnt/Dest/sources/ >> "${LOG_FILE}" 2>&1 echo "Copying Main Kit..." -rsync ${RSYNC_ARGS} "$MAIN_KIT/" "/mnt/Dest/$KIT_NAME_FULL/" >> "$LOG_FILE" 2>&1 -if [ "$EXTRA_DIR" != "__None__" ]; then +rsync ${RSYNC_ARGS} "${MAIN_KIT}/" "/mnt/Dest/${KIT_NAME_FULL}/" >> "${LOG_FILE}" 2>&1 + +if [[ ! -z "${EXTRA_DIR:-}" ]]; then echo "Copying Extra files..." - rsync ${RSYNC_ARGS} "$EXTRA_DIR"/* /mnt/Dest/ >> "$LOG_FILE" 2>&1 + rsync ${RSYNC_ARGS} "${EXTRA_DIR}"/* /mnt/Dest/ >> "${LOG_FILE}" 2>&1 fi # Install syslinux echo "Copying Syslinux files..." -rsync ${RSYNC_ARGS} /usr/lib/syslinux/bios/*.c32 /mnt/Dest/arch/boot/syslinux/ >> "$LOG_FILE" 2>&1 -syslinux --install -d /arch/boot/syslinux/ $DEST_PARTITION >> "$LOG_FILE" 2>&1 +rsync ${RSYNC_ARGS} /usr/lib/syslinux/bios/*.c32 /mnt/Dest/arch/boot/syslinux/ >> "${LOG_FILE}" 2>&1 +syslinux --install -d /arch/boot/syslinux/ ${DEST_PAR} >> "${LOG_FILE}" 2>&1 echo "Unmounting destination..." -umount /mnt/Dest >> "$LOG_FILE" 2>&1 +umount /mnt/Dest >> "${LOG_FILE}" 2>&1 +rmdir /mnt/Dest >> "${LOG_FILE}" 2>&1 sync echo "Installing Syslinux MBR..." -dd bs=440 count=1 if=/usr/lib/syslinux/bios/mbr.bin of=$DEST_DEV >> "$LOG_FILE" 2>&1 +dd bs=440 count=1 if=/usr/lib/syslinux/bios/mbr.bin of=${DEST_DEV} >> "${LOG_FILE}" 2>&1 sync # Cleanup echo "Hiding boot files..." -echo "drive s: file=\"$DEST_PARTITION\"" > /root/.mtoolsrc +echo "drive s: file=\"${DEST_PAR}\"" > /root/.mtoolsrc echo 'mtools_skip_check=1' >> /root/.mtoolsrc -for item in boot{,mgr,mgr.efi} efi en-us images isolinux sources "$KIT_NAME_FULL"/{.bin,.cbin}; do - yes | mattrib +h "S:/$item" >> "$LOG_FILE" 2>&1 || true +for item in boot{,mgr,mgr.efi} efi en-us images isolinux sources "${KIT_NAME_FULL}"/{.bin,.cbin}; do + yes | mattrib +h "S:/${item}" >> "${LOG_FILE}" 2>&1 || true done sync # Unmount Sources echo "Unmounting sources..." -umount /mnt/{Linux,WinPE} -R >> "$LOG_FILE" 2>&1 +for d in Linux WinPE; do + umount "/mnt/${d}" >> "${LOG_FILE}" 2>&1 || true + rmdir "/mnt/${d}" >> "${LOG_FILE}" 2>&1 || true +done # Close progress pane -pkill -f "tail.*$LOG_FILE" +pkill -f "tail.*${LOG_FILE}" # Done echo "" echo "Done." echo "" -read -p "Press Enter to exit..." -r exit 0 - diff --git a/.bin/Scripts/build_kit.ps1 b/.bin/Scripts/build_kit.ps1 index 87787566..0fe123c5 100644 --- a/.bin/Scripts/build_kit.ps1 +++ b/.bin/Scripts/build_kit.ps1 @@ -14,6 +14,8 @@ $System32 = "{0}\System32" -f $Env:SystemRoot Push-Location "$WD" $Host.UI.RawUI.BackgroundColor = "black" $Host.UI.RawUI.ForegroundColor = "white" +#Enable TLS 1.2 +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ## Functions ## @@ -76,21 +78,21 @@ if ($MyInvocation.InvocationName -ne ".") { $Path = $Temp # 7-Zip - DownloadFile -Path $Path -Name "7z-installer.msi" -Url "http://www.7-zip.org/a/7z1701.msi" - DownloadFile -Path $Path -Name "7z-extra.7z" -Url "http://www.7-zip.org/a/7z1701-extra.7z" + DownloadFile -Path $Path -Name "7z-installer.msi" -Url "http://www.7-zip.org/a/7z1801.msi" + DownloadFile -Path $Path -Name "7z-extra.7z" -Url "http://www.7-zip.org/a/7z1801-extra.7z" # ConEmu - $Url = "https://github.com/Maximus5/ConEmu/releases/download/v17.11.09/ConEmuPack.171109.7z" + $Url = "https://github.com/Maximus5/ConEmu/releases/download/v18.02.06/ConEmuPack.180206.7z" DownloadFile -Path $Path -Name "ConEmuPack.7z" -Url $Url # Notepad++ - $Url = "https://notepad-plus-plus.org/repository/7.x/7.5.2/npp.7.5.2.bin.minimalist.7z" + $Url = "https://notepad-plus-plus.org/repository/7.x/7.5.5/npp.7.5.5.bin.minimalist.7z" DownloadFile -Path $Path -Name "npp.7z" -Url $Url # Python - $Url = "https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-win32.zip" + $Url = "https://www.python.org/ftp/python/3.6.4/python-3.6.4-embed-win32.zip" DownloadFile -Path $Path -Name "python32.zip" -Url $Url - $Url = "https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-amd64.zip" + $Url = "https://www.python.org/ftp/python/3.6.4/python-3.6.4-embed-amd64.zip" DownloadFile -Path $Path -Name "python64.zip" -Url $Url # Python: psutil diff --git a/.bin/Scripts/build_pe.ps1 b/.bin/Scripts/build_pe.ps1 index 61d43bf4..80fce4f0 100644 --- a/.bin/Scripts/build_pe.ps1 +++ b/.bin/Scripts/build_pe.ps1 @@ -18,6 +18,8 @@ $Host.UI.RawUI.BackgroundColor = "Black" $Host.UI.RawUI.ForegroundColor = "White" $HostSystem32 = "{0}\System32" -f $Env:SystemRoot $DISM = "{0}\DISM.exe" -f $Env:DISMRoot +#Enable TLS 1.2 +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ## Functions ## function Ask-User ($text = "Kotaero") { @@ -128,38 +130,37 @@ if ($MyInvocation.InvocationName -ne ".") { ## Download Tools ## $ToolSources = @( # 7-Zip - @("7z-installer.msi", "http://www.7-zip.org/a/7z1701.msi"), - @("7z-extra.7z", "http://www.7-zip.org/a/7z1701-extra.7z"), + @("7z-installer.msi", "http://www.7-zip.org/a/7z1801.msi"), + @("7z-extra.7z", "http://www.7-zip.org/a/7z1801-extra.7z"), # Blue Screen View @("bluescreenview64.zip", "http://www.nirsoft.net/utils/bluescreenview-x64.zip"), @("bluescreenview32.zip", "http://www.nirsoft.net/utils/bluescreenview.zip"), # ConEmu - @("ConEmuPack.7z", "https://github.com/Maximus5/ConEmu/releases/download/v17.11.09/ConEmuPack.171109.7z"), + @("ConEmuPack.7z", "https://github.com/Maximus5/ConEmu/releases/download/v18.02.06/ConEmuPack.180206.7z"), # Fast Copy - @("fastcopy64.zip", "http://ftp.vector.co.jp/69/76/2323/FastCopy340_x64.zip"), - @("fastcopy32.zip", "http://ftp.vector.co.jp/69/76/2323/FastCopy340.zip"), + @("fastcopy64.zip", "http://ftp.vector.co.jp/69/93/2323/FastCopy341_x64.zip"), + @("fastcopy32.zip", "http://ftp.vector.co.jp/69/93/2323/FastCopy341.zip"), # HWiNFO - @("hwinfo64.zip", "http://app.oldfoss.com:81/download/HWiNFO/hw64_560.zip"), - @("hwinfo32.zip", "http://app.oldfoss.com:81/download/HWiNFO/hw32_560.zip"), + @("hwinfo.zip", "http://app.oldfoss.com:81/download/HWiNFO/hwi_574.zip"), # Killer Network Drivers @( "killerinf.zip", ("http://www.killernetworking.com"+(FindDynamicUrl "http://www.killernetworking.com/driver-downloads/item/killer-drivers-inf" "Download Killer-Ethernet").replace('&', '&')) ), # Notepad++ - @("npp_amd64.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.2/npp.7.5.2.bin.minimalist.x64.7z"), - @("npp_x86.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.2/npp.7.5.2.bin.minimalist.7z"), + @("npp_amd64.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.5/npp.7.5.5.bin.minimalist.x64.7z"), + @("npp_x86.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.5/npp.7.5.5.bin.minimalist.7z"), # NT Password Editor @("ntpwed.zip", "http://cdslow.org.ru/files/ntpwedit/ntpwed07.zip"), # Prime95 - @("prime95_64.zip", "http://www.mersenne.org/ftp_root/gimps/p95v294b5.win64.zip"), - @("prime95_32.zip", "http://www.mersenne.org/ftp_root/gimps/p95v294b5.win32.zip"), + @("prime95_64.zip", "http://www.mersenne.org/ftp_root/gimps/p95v294b8.win64.zip"), + @("prime95_32.zip", "http://www.mersenne.org/ftp_root/gimps/p95v294b7.win32.zip"), # ProduKey @("produkey64.zip", "http://www.nirsoft.net/utils/produkey-x64.zip"), @("produkey32.zip", "http://www.nirsoft.net/utils/produkey.zip"), # Python - @("python64.zip", "https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-amd64.zip"), - @("python32.zip", "https://www.python.org/ftp/python/3.6.3/python-3.6.3-embed-win32.zip"), + @("python64.zip", "https://www.python.org/ftp/python/3.6.4/python-3.6.4-embed-amd64.zip"), + @("python32.zip", "https://www.python.org/ftp/python/3.6.4/python-3.6.4-embed-win32.zip"), # Python: psutil @( "psutil64.whl", @@ -295,14 +296,14 @@ if ($MyInvocation.InvocationName -ne ".") { Write-Host "Extracting: HWiNFO" try { $ArgumentList = @( - "e", "$Temp\hwinfo64.zip", "-o$Build\bin\amd64\HWiNFO", + "e", "$Temp\hwinfo.zip", "-o$Build\bin\amd64\HWiNFO", "-aoa", "-bso0", "-bse0", "-bsp0", "HWiNFO64.exe") Start-Process -FilePath $SevenZip -ArgumentList $ArgumentList -NoNewWindow -Wait $ArgumentList = @( - "e", "$Temp\hwinfo32.zip", "-o$Build\bin\x86\HWiNFO", + "e", "$Temp\hwinfo.zip", "-o$Build\bin\x86\HWiNFO", "-aoa", "-bso0", "-bse0", "-bsp0", "HWiNFO32.exe") Start-Process -FilePath $SevenZip -ArgumentList $ArgumentList -NoNewWindow -Wait - Remove-Item "$Temp\hwinfo*" + # Remove-Item "$Temp\hwinfo.zip" Move-Item "$Build\bin\amd64\HWiNFO\HWiNFO64.exe" "$Build\bin\amd64\HWiNFO\HWiNFO.exe" -Force Move-Item "$Build\bin\x86\HWiNFO\HWiNFO32.exe" "$Build\bin\x86\HWiNFO\HWiNFO.exe" -Force } diff --git a/.bin/Scripts/functions/common.py b/.bin/Scripts/functions/common.py index 189e8bf5..173dd2c8 100644 --- a/.bin/Scripts/functions/common.py +++ b/.bin/Scripts/functions/common.py @@ -571,8 +571,12 @@ def wait_for_process(name, poll_rate=3): sleep(poll_rate) running = False for proc in psutil.process_iter(): - if re.search(r'^{}'.format(name), proc.name(), re.IGNORECASE): - running = True + try: + if re.search(r'^{}'.format(name), proc.name(), re.IGNORECASE): + running = True + except psutil._exceptions.NoSuchProcess: + # Assuming process closed during iteration + pass sleep(1) # global_vars functions diff --git a/.bin/Scripts/functions/data.py b/.bin/Scripts/functions/data.py index 964eb965..b7306a9d 100644 --- a/.bin/Scripts/functions/data.py +++ b/.bin/Scripts/functions/data.py @@ -150,6 +150,10 @@ def cleanup_transfer(dest_path): except Exception: pass +def fix_path_sep(path_str): + """Replace non-native and duplicate dir separators, returns str.""" + return re.sub(r'(\\|/)+', lambda s: os.sep, path_str) + def is_valid_wim_file(item): """Checks if the provided os.DirEntry is a valid WIM file, returns bool.""" valid = bool(item.is_file() and REGEX_WIM_FILE.search(item.name)) @@ -378,7 +382,7 @@ def list_source_items(source_obj, rel_path=None): raise # Strip non-root items - items = [re.sub(r'(\\|/)', os.sep, i.strip()) + items = [fix_path_sep(i.strip()) for i in items.stdout.decode('utf-8', 'ignore').splitlines()] if rel_path: items = [i.replace(rel_path, '') for i in items] @@ -473,7 +477,7 @@ def scan_source(source_obj, dest_path, rel_path='', interactive=True): def get_source_item_obj(source_obj, rel_path, item_path): """Check if the item exists and return a SourceItem object if it does.""" item_obj = None - item_path = re.sub(r'(\\|/)', os.sep, item_path) + item_path = fix_path_sep(item_path) if source_obj.is_dir(): item_obj = SourceItem( name = item_path, diff --git a/.bin/Scripts/functions/update.py b/.bin/Scripts/functions/update.py index afaa59bd..6825f9ba 100644 --- a/.bin/Scripts/functions/update.py +++ b/.bin/Scripts/functions/update.py @@ -412,16 +412,13 @@ def update_hwinfo(): kill_process(exe) # Download - download_to_temp('HWiNFO32.zip', SOURCE_URLS['HWiNFO32']) - download_to_temp('HWiNFO64.zip', SOURCE_URLS['HWiNFO64']) + download_to_temp('HWiNFO.zip', SOURCE_URLS['HWiNFO']) # Extract files - extract_temp_to_bin('HWiNFO32.zip', 'HWiNFO') - extract_temp_to_bin('HWiNFO64.zip', 'HWiNFO') + extract_temp_to_bin('HWiNFO.zip', 'HWiNFO') # Cleanup - remove_from_temp('HWiNFO32.zip') - remove_from_temp('HWiNFO64.zip') + remove_from_temp('HWiNFO.zip') def update_produkey(): # Stop running processes @@ -757,17 +754,13 @@ def update_treesizefree(): # Download download_to_temp( - 'treesizefree.zip.gz', SOURCE_URLS['TreeSizeFree']) + 'treesizefree.zip', SOURCE_URLS['TreeSizeFree']) # Extract files - ## NOTE: When downloaded using requests it is a .zip.gz? - source = r'{}\treesizefree.zip.gz'.format(global_vars['TmpDir']) - extract_generic(source, global_vars['TmpDir']) extract_temp_to_cbin('treesizefree.zip', 'TreeSizeFree') # Cleanup remove_from_temp('treesizefree.zip') - remove_from_temp('treesizefree.zip.gz') def update_xmplay(): # Stop running processes diff --git a/.bin/Scripts/mount-raw-image b/.bin/Scripts/mount-raw-image new file mode 100755 index 00000000..e738c445 --- /dev/null +++ b/.bin/Scripts/mount-raw-image @@ -0,0 +1,32 @@ +#!/bin/bash +# +## Wizard Kit: RAW image mounting tool + +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +LOOPDEV="$(losetup -f)" + +function usage { + echo "Usage: $(basename "$0") [image]" + echo " e.g. $(basename "$0") HDD.dd" +} + +if [[ -f "${1:-}" ]]; then + sudo losetup -P "${LOOPDEV}" "${1:-}" + sleep 1 + if [[ -b "${LOOPDEV}p1" ]]; then + # losetup detected partitions + for dev in "${LOOPDEV}p"*; do + udevil mount -o ro "${dev}" || true + done + else + # losetup did not detect partitions, attempt whole image + udevil mount -o to "${LOOPDEV}" || true + fi +else + usage + exit 1 +fi diff --git a/.bin/Scripts/settings/launchers.py b/.bin/Scripts/settings/launchers.py index 7d52cd51..fa65c06e 100644 --- a/.bin/Scripts/settings/launchers.py +++ b/.bin/Scripts/settings/launchers.py @@ -294,8 +294,8 @@ LAUNCHERS = { 'Intel RST (Current Release)': { 'L_TYPE': 'Executable', 'L_PATH': '_Drivers\Intel RST', - 'L_ITEM': 'SetupRST_15.8.exe', - 'L_7ZIP': 'SetupRST_15.8.exe', + 'L_ITEM': 'SetupRST_15.9.exe', + 'L_7ZIP': 'SetupRST_15.9.exe', }, 'Intel RST (Previous Releases)': { 'L_TYPE': 'Folder', diff --git a/.bin/Scripts/settings/sources.py b/.bin/Scripts/settings/sources.py index b9adf614..2e3a7566 100644 --- a/.bin/Scripts/settings/sources.py +++ b/.bin/Scripts/settings/sources.py @@ -2,29 +2,28 @@ SOURCE_URLS = { 'AIDA64': 'http://download.aida64.com/aida64engineer595.zip', - 'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1800920044/AcroRdrDC1800920044_en_US.exe', + 'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1801120035/AcroRdrDC1801120035_en_US.exe', 'AdwCleaner': 'https://toolslib.net/downloads/finish/1-adwcleaner/', 'Autoruns': 'https://download.sysinternals.com/files/Autoruns.zip', - 'BleachBit': 'https://download.bleachbit.org/beta/1.17/BleachBit-1.17-portable.zip', + 'BleachBit': 'https://download.bleachbit.org/BleachBit-2.0-portable.zip', 'BlueScreenView32': 'http://www.nirsoft.net/utils/bluescreenview.zip', 'BlueScreenView64': 'http://www.nirsoft.net/utils/bluescreenview-x64.zip', 'Caffeine': 'http://www.zhornsoftware.co.uk/caffeine/caffeine.zip', 'ClassicStartSkin': 'http://www.classicshell.net/forum/download/file.php?id=3001&sid=9a195960d98fd754867dcb63d9315335', 'Du': 'https://download.sysinternals.com/files/DU.zip', 'ERUNT': 'http://www.aumha.org/downloads/erunt.zip', - 'Everything32': 'https://www.voidtools.com/Everything-1.4.1.877.x86.zip', - 'Everything64': 'https://www.voidtools.com/Everything-1.4.1.877.x64.zip', - 'FastCopy32': 'http://ftp.vector.co.jp/69/76/2323/FastCopy340.zip', - 'FastCopy64': 'http://ftp.vector.co.jp/69/76/2323/FastCopy340_x64.zip', - 'Firefox uBO': 'https://addons.mozilla.org/firefox/downloads/file/764482/ublock_origin-1.14.18-an+fx.xpi?src=dp-btn-primary', - 'HWiNFO32': 'http://app.oldfoss.com:81/download/HWiNFO/hw32_560.zip', - 'HWiNFO64': 'http://app.oldfoss.com:81/download/HWiNFO/hw64_560.zip', + 'Everything32': 'https://www.voidtools.com/Everything-1.4.1.895.x86.zip', + 'Everything64': 'https://www.voidtools.com/Everything-1.4.1.895.x64.zip', + 'FastCopy32': 'http://ftp.vector.co.jp/69/93/2323/FastCopy341.zip', + 'FastCopy64': 'http://ftp.vector.co.jp/69/93/2323/FastCopy341_x64.zip', + 'Firefox uBO': 'https://addons.cdn.mozilla.net/user-media/addons/607454/ublock_origin-1.15.10-an+fx.xpi?filehash=sha256%3A30b258803fd6cd988c5ba479f2f6ff5b4e9b40110c81e3421a6867b20ec718a6', + 'HWiNFO': 'http://app.oldfoss.com:81/download/HWiNFO/hwi_574.zip', 'HitmanPro32': 'https://dl.surfright.nl/HitmanPro.exe', 'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe', - 'IOBit_Uninstaller': 'https://portableapps.com/redirect/?a=IObitUninstallerPortable&t=http%3A%2F%2Fdownloads.portableapps.com%2Fportableapps%2Fiobituninstallerportable%2FIObitUninstallerPortable_7.2.0.11.paf.exe', - 'Intel SSD Toolbox': r'https://downloadmirror.intel.com/27330/eng/Intel%20SSD%20Toolbox%20-%20v3.4.9.exe', + 'IOBit_Uninstaller': 'https://portableapps.com/redirect/?a=IObitUninstallerPortable&t=http%3A%2F%2Fdownloads.portableapps.com%2Fportableapps%2Fiobituninstallerportable%2FIObitUninstallerPortable_7.3.0.13.paf.exe', + 'Intel SSD Toolbox': r'https://downloadmirror.intel.com/27527/eng/Intel%20SSD%20Toolbox%20-%20v3.5.1.exe', 'KVRT': 'http://devbuilds.kaspersky-labs.com/devbuilds/KVRT/latest/full/KVRT.exe', - 'NotepadPlusPlus': 'https://notepad-plus-plus.org/repository/7.x/7.5.2/npp.7.5.2.bin.minimalist.7z', + 'NotepadPlusPlus': 'https://notepad-plus-plus.org/repository/7.x/7.5.5/npp.7.5.5.bin.minimalist.7z', 'Office Deployment Tool 2013': 'https://download.microsoft.com/download/6/2/3/6230F7A2-D8A9-478B-AC5C-57091B632FCF/officedeploymenttool_x86_4827-1000.exe', 'Office Deployment Tool 2016': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_8529.3600.exe', 'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip', @@ -33,7 +32,7 @@ SOURCE_URLS = { 'RKill': 'https://www.bleepingcomputer.com/download/rkill/dl/10/', 'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip', 'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent', - 'Samsung Magician': 'http://downloadcenter.samsung.com/content/SW/201710/20171019164455812/Samsung_Magician_Installer.exe', + 'Samsung Magician': 'http://downloadcenter.samsung.com/content/SW/201801/20180123130636806/Samsung_Magician_Installer.exe', 'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe', 'TestDisk': 'https://www.cgsecurity.org/testdisk-7.1-WIP.win.zip', 'TreeSizeFree': 'https://www.jam-software.com/treesize_free/TreeSizeFree-Portable.zip', @@ -44,7 +43,7 @@ SOURCE_URLS = { 'XMPlay Game': 'http://support.xmplay.com/files/12/xmp-gme.zip?v=515637', 'XMPlay RAR': 'http://support.xmplay.com/files/16/xmp-rar.zip?v=409646', 'XMPlay WAModern': 'http://support.xmplay.com/files/10/WAModern.zip?v=207099', - 'XMPlay': 'http://support.xmplay.com/files/20/xmplay3823.zip?v=115916', + 'XMPlay': 'http://support.xmplay.com/files/20/xmplay383.zip?v=298195', 'XYplorerFree': 'https://www.xyplorer.com/download/xyplorer_free_noinstall.zip', 'aria2': 'https://github.com/aria2/aria2/releases/download/release-1.33.1/aria2-1.33.1-win-32bit-build1.zip', } @@ -66,15 +65,15 @@ VCREDIST_SOURCES = { '64': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe', }, '2017': { - '32': 'https://download.visualstudio.microsoft.com/download/pr/11100229/78c1e864d806e36f6035d80a0e80399e/VC_redist.x86.exe', - '64': 'https://download.visualstudio.microsoft.com/download/pr/11100230/15ccb3f02745c7b206ad10373cbca89b/VC_redist.x64.exe', + '32': 'https://download.visualstudio.microsoft.com/download/pr/100349138/88b50ce70017bf10f2d56d60fcba6ab1/VC_redist.x86.exe', + '64': 'https://download.visualstudio.microsoft.com/download/pr/100349091/2cd2dba5748dc95950a5c42c2d2d78e4/VC_redist.x64.exe', }, } NINITE_SOURCES = { 'Bundles': { - 'Runtimes.exe': '.net4.7-air-java8-silverlight', - 'Legacy.exe': '.net4.7-7zip-air-chrome-firefox-java8-silverlight-vlc', - 'Modern.exe': '.net4.7-7zip-air-chrome-classicstart-firefox-java8-silverlight-vlc', + 'Runtimes.exe': '.net4.7.1-air-java8-silverlight', + 'Legacy.exe': '.net4.7.1-7zip-air-chrome-firefox-java8-silverlight-vlc', + 'Modern.exe': '.net4.7.1-7zip-air-chrome-classicstart-firefox-java8-silverlight-vlc', }, 'Audio-Video': { 'AIMP.exe': 'aimp', @@ -154,7 +153,7 @@ NINITE_SOURCES = { }, 'Runtimes': { 'Adobe Air.exe': 'air', - 'dotNET.exe': '.net4.7', + 'dotNET.exe': '.net4.7.1', 'Java 8.exe': 'java8', 'Shockwave.exe': 'shockwave', 'Silverlight.exe': 'silverlight', @@ -195,7 +194,8 @@ RST_SOURCES = { #SetupRST_13.x.exe : Broken, doesn't support > .NET 4.5 'SetupRST_14.0.exe': 'https://downloadmirror.intel.com/25091/eng/SetupRST.exe', 'SetupRST_14.8.exe': 'https://downloadmirror.intel.com/26759/eng/setuprst.exe', - 'SetupRST_15.8.exe': 'https://downloadmirror.intel.com/27147/eng/SetupRST.exe', + 'SetupRST_15.8.exe': 'https://downloadmirror.intel.com/27442/eng/SetupRST.exe', + 'SetupRST_15.9.exe': 'https://downloadmirror.intel.com/27400/eng/SetupRST.exe', } diff --git a/.linux_items/include/airootfs/etc/skel/.config/i3/config b/.linux_items/include/airootfs/etc/skel/.config/i3/config index dbbdee82..de3c6fa8 100644 --- a/.linux_items/include/airootfs/etc/skel/.config/i3/config +++ b/.linux_items/include/airootfs/etc/skel/.config/i3/config @@ -19,9 +19,9 @@ new_float normal hide_edge_borders none # Pulse Audio controls -bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% #increase sound volume -bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% #decrease sound volume -bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # mute sound +bindsym XF86AudioRaiseVolume exec --no-startup-id amixer set Master 5%+ #increase sound volume +bindsym XF86AudioLowerVolume exec --no-startup-id amixer set Master 5%- #decrease sound volume +bindsym XF86AudioMute exec --no-startup-id amixer set Master toggle # mute sound # alt+tab navi bindsym Mod1+Tab workspace next diff --git a/.linux_items/include/airootfs/etc/skel/.config/i3status/config b/.linux_items/include/airootfs/etc/skel/.config/i3status/config index d36294a4..605e517c 100644 --- a/.linux_items/include/airootfs/etc/skel/.config/i3status/config +++ b/.linux_items/include/airootfs/etc/skel/.config/i3status/config @@ -16,7 +16,7 @@ order += "wireless _first_" order += "ethernet _first_" order += "cpu_usage" order += "battery all" -order += "volume master" +#order += "volume master" order += "tztime local" #order += "tztime utc" @@ -55,7 +55,7 @@ battery all { volume master { format = " %volume" format_muted = " muted" - device = "pulse" + device = "default" } tztime local { diff --git a/.linux_items/include/airootfs/etc/skel/.config/openbox/rc.xml b/.linux_items/include/airootfs/etc/skel/.config/openbox/rc.xml index 5ecc2eee..43656613 100644 --- a/.linux_items/include/airootfs/etc/skel/.config/openbox/rc.xml +++ b/.linux_items/include/airootfs/etc/skel/.config/openbox/rc.xml @@ -347,6 +347,21 @@ oblogout + + + amixer set Master 5%+ + + + + + amixer set Master 5%- + + + + + amixer set Master toggle + + 1 diff --git a/.linux_items/include/airootfs/etc/skel/.config/volumeicon/volumeicon b/.linux_items/include/airootfs/etc/skel/.config/volumeicon/volumeicon new file mode 100644 index 00000000..26c840b8 --- /dev/null +++ b/.linux_items/include/airootfs/etc/skel/.config/volumeicon/volumeicon @@ -0,0 +1,25 @@ +[Alsa] +card=default + +[Notification] +show_notification=true +notification_type=0 + +[StatusIcon] +stepsize=5 +onclick=urxvt -e 'alsamixer' +theme=Default +use_panel_specific_icons=false +lmb_slider=true +mmb_mute=false +use_horizontal_slider=false +show_sound_level=false +use_transparent_background=false + +[Hotkeys] +up_enabled=false +down_enabled=false +mute_enabled=false +up=XF86AudioRaiseVolume +down=XF86AudioLowerVolume +mute=XF86AudioMute diff --git a/.linux_items/include/airootfs/etc/skel/.xinitrc b/.linux_items/include/airootfs/etc/skel/.xinitrc index 918fc507..ccca956a 100755 --- a/.linux_items/include/airootfs/etc/skel/.xinitrc +++ b/.linux_items/include/airootfs/etc/skel/.xinitrc @@ -11,7 +11,7 @@ sleep 1s conky -d nm-applet & cbatticon & -pasystray & +volumeicon & connect-to-network & (sleep 5s && killall dunst) & $HOME/.urxvt_default_res & diff --git a/.linux_items/packages/aur b/.linux_items/packages/aur index ae607f33..c2178d63 100644 --- a/.linux_items/packages/aur +++ b/.linux_items/packages/aur @@ -1,13 +1,11 @@ aic94xx-firmware bash-pipes -gtk-theme-arc-git hfsprogs i3lock-fancy-git mprime nvme-cli openbox-patched papirus-icon-theme -pasystray smartmontools-svn testdisk-wip ttf-font-awesome-4 diff --git a/.linux_items/packages/dependencies b/.linux_items/packages/dependencies index 02b90822..7b6da316 100644 --- a/.linux_items/packages/dependencies +++ b/.linux_items/packages/dependencies @@ -5,10 +5,15 @@ curl dos2unix git hwloc +lhasa +libbsd libewf +ntfs-3g openssh p7zip +pango progsreiserfs refind-efi rsync +subversion syslinux diff --git a/.linux_items/packages/live b/.linux_items/packages/live index a6798b79..be997510 100644 --- a/.linux_items/packages/live +++ b/.linux_items/packages/live @@ -1,6 +1,7 @@ aic94xx-firmware alsa-utils antiword +arc-gtk-theme bash-pipes bc bluez @@ -22,7 +23,6 @@ firefox gnome-keyring gparted gsmartcontrol -gtk-theme-arc-git hardinfo hexedit hfsprogs @@ -53,10 +53,7 @@ openbox-patched otf-font-awesome-4 p7zip papirus-icon-theme -pasystray -pavucontrol progsreiserfs -pulseaudio python python-psutil python-requests @@ -87,6 +84,7 @@ veracrypt vim virtualbox-guest-modules-arch virtualbox-guest-utils +volumeicon wd719x-firmware wimlib xf86-input-libinput diff --git a/Build Kit.cmd b/Build Kit.cmd index 45d444bc..58272a45 100644 --- a/Build Kit.cmd +++ b/Build Kit.cmd @@ -9,6 +9,7 @@ call :CheckFlags %* :PrepNewKit rem Copy base files to a new folder OUT_KIT +robocopy /e .kit_items OUT_KIT robocopy /e .bin OUT_KIT\.bin robocopy /e .cbin OUT_KIT\.cbin copy LICENSE.txt OUT_KIT\LICENSE.txt diff --git a/Build Linux b/Build Linux index a0600d74..26e70919 100755 --- a/Build Linux +++ b/Build Linux @@ -32,7 +32,7 @@ fi function ask() { while :; do - read -p "$1 " -r answer + read -p "$1 [Y/N] " -r answer if echo "$answer" | egrep -iq '^(y|yes|sure)$'; then return 0 elif echo "$answer" | egrep -iq '^(n|no|nope)$'; then @@ -71,20 +71,26 @@ function load_settings() { ## Answer: https://stackoverflow.com/a/13864829 ## Answer by: https://stackoverflow.com/users/1633643/lionel ## Answer edit: https://stackoverflow.com/users/-1/community + _main_path="$BUILD_DIR/main.py" if [ ! -z ${KIT_NAME_FULL+x} ]; then # KIT_NAME_FULL is set return 0 # Skip loading settings from main.py fi - # Copy settings - if [[ ! -e "$BUILD_DIR/main.py" ]] || ask "Overwrite main.py?"; then - cp -bv "$ROOT_DIR/.bin/Scripts/settings/main.py" "$BUILD_DIR/main.py" - dos2unix "$BUILD_DIR/main.py" - fi + if [[ "${1:-}" == "--edit" ]]; then + # Copy settings + if [[ ! -e "$BUILD_DIR/main.py" ]] || ask "Overwrite main.py?"; then + cp -bv "$ROOT_DIR/.bin/Scripts/settings/main.py" "$BUILD_DIR/main.py" + dos2unix "$BUILD_DIR/main.py" + fi - # Edit settings - read -p "Press Enter to open settings... " -r - "$EDITOR" "$BUILD_DIR/main.py" + # Edit settings + read -p "Press Enter to open settings... " -r + "$EDITOR" "$BUILD_DIR/main.py" + else + # Load settings from $LIVE_DIR + _main_path="$LIVE_DIR/airootfs/usr/local/bin/settings/main.py" + fi # Load settings while read line; do @@ -92,7 +98,7 @@ function load_settings() { line="$(echo "$line" | sed -r 's/[\r\n]+//')" eval "$line" fi - done < "$BUILD_DIR/main.py" + done < "$_main_path" } function copy_live_env() { @@ -122,10 +128,20 @@ function run_elevated() { prog="$1" shift if which sudo >/dev/null 2>&1; then - sudo "$prog" $* + if ! sudo "$prog" $*; then + echo "ERROR: Failed to run '$prog'" + if ask "Retry?"; then + sudo "$prog" $* + fi + fi else echo -n "Root " - su -c "export REAL_USER=$USER && '$prog' $*" + if ! su -c "export REAL_USER=$USER && '$prog' $*"; then + echo "ERROR: Failed to run '$prog'" + if ask "Retry?"; then + su -c "export REAL_USER=$USER && '$prog' $*" + fi + fi fi } @@ -263,7 +279,7 @@ function update_repo() { curl -LsfO https://aur.archlinux.org/cgit/aur.git/snapshot/$p.tar.gz tar xf $p.tar.gz pushd $p >/dev/null - makepkg -s --noconfirm + makepkg -d popd >/dev/null mv -n $p/*xz "$REPO_DIR"/ done < "$ROOT_DIR/.linux_items/packages/aur" @@ -315,6 +331,7 @@ function build_iso() { echo "Reverting permissions..." chown $REAL_USER:$REAL_USER "$LIVE_DIR" -R + chown $REAL_USER:$REAL_USER "$OUT_DIR" -R } function build_full() { @@ -328,7 +345,7 @@ function build_full() { cleanup fix_kit_permissions install_deps - load_settings + load_settings --edit update_repo copy_live_env update_live_env @@ -360,7 +377,7 @@ case ${1:-} in ;; -p|--prep-live-env) - load_settings + load_settings --edit copy_live_env update_live_env echo Done diff --git a/LICENSE.txt b/LICENSE.txt index 8e17b045..d02f5a6e 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2017 Alan Mason +Copyright (c) 2018 Alan Mason Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 8eaf3c34..37c7f431 100644 --- a/README.md +++ b/README.md @@ -116,31 +116,19 @@ There's a `build-ufd` script which does the following: * Boot to a Live Linux ISO built following the instructions above. * You can apply it to a UFD using [rufus](https://rufus.akeo.ie/) for physical systems. * Virtual machines should be able to use the Linux ISO directly. -* Put the Linux ISO, the WinPE ISO, and the Main Kit folder _(usually "OUT_KIT")_ in the same directory. - * "OUT_KIT" will be renamed on the UFD using `$KIT_NAME_FULL` +* Mount the device(s) or network share(s) that contain the Linux ISO, WinPE ISO, and Main Kit folder. +* Connect the UFD but don't mount it. +* Get the device name of the UFD. + * You can use $ `inxi -Dxx` or $ `lsblk --fs` to help. +* $ `sudo build-ufd --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path]` + * **2nd Warning**: All data will be erased from the UFD resulting in **DATA LOSS**. + * NOTE: The Main Kit folder will be renamed on the UFD using `$KIT_NAME_FULL` * `$KIT_NAME_FULL` defaults to "Wizard Kit" but can be changed in `main.py` - * "OUT_KIT" can be renamed in the source folder. - * The script searched for the ".bin" folder and uses it's parent folder as the Main Kit source. - * Additional files/folders can be included by putting them in a folder named "Extras". - * These files/folders will be copied to the root of the UFD. + * You can include extra items by using the `--extra-dir` option + * _(e.g. $ `sudo build-ufd --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path] --extra-dir [path]`)_ * To include images for the WinPE Setup section, put the files in "Extras/images". * WinPE Setup will recognize ESD, WIM, and SWM2 images. * The filenames should be "Win7", "Win8", or "Win10" - * The final layout should be similar to this: _(assuming it's mounted to "/Sources")_ - * **(Required)** `/Sources/OUT_KIT` - * **(Required)** `/Sources/WK-Linux-2018-01-01-x86_64.iso` - * **(Required)** `/Sources/WK-WinPE-2018-01-01-amd64.iso` - * _(Optional)_ `/Sources/Extras/Essential Windows Updates` - * _(Optional)_ `/Sources/Extras/images/Win7.wim` - * _(Optional)_ `/Sources/Extras/images/Win8.wim` - * _(Optional)_ `/Sources/Extras/images/Win10.esd` -* Connect the UFD but don't mount it. -* Mount the device, or connect to the share, with the ISOs and Main Kit folder. -* $ `cd /Sources` _(replace with real path to source files)_ -* Get the device name of the UFD. - * You can use $ `lsblk --fs` or $ `inxi -Dxx` to help. -* $ `sudo build-ufd /dev/sdX` _(replace `/dev/sdX` with the desired device)_ - * **2nd Warning**: All data will be erased from the UFD resulting in **DATA LOSS**. ## Notes ## 1. PowerShell 6.0 on Windows 7 is not supported by the build script.