#!/usr/bin/env bash # # TROUBLESHOOTING # - To enable verbose algorithm/implementation debugging, use ./build -DDEBUG # - If you see 'undefined reference to `clock_gettime'', try ./build -lrt instead # # BUGS # masterpassword@lyndir.com # # AUTHOR # Maarten Billemont # cd "${BASH_SOURCE%/*}" shopt -s extglob set -e ### CONFIGURATION # Targets to build. if [[ $targets ]]; then read -ra targets <<< "$targets" else # Default targets. # Modify here or override using targets='mpw mpw-bench' ./build targets=( mpw # C CLI version of Master Password. #mpw-bench # C CLI Master Password benchmark utility. ) fi ### DEPENDENCIES fetch() { if hash wget 2>/dev/null; then wget -O "${1##*/}" "$1" elif hash curl 2>/dev/null; then curl "$1" > "${1##*/}" fi } unpack() { if [[ $1 = *.tar.gz || $1 = *.tgz ]]; then tar -xvzf "$1" elif [[ $1 = *.tar.bz2 || $1 = *.tbz2 ]]; then tar -xvjf "$1" elif [[ $1 = *.tar ]]; then tar -xvf "$1" else echo 2>&1 "Don't know how to unpack: $1" fi printf 'Verifying package: %s, against digest: %s...' "$1" "$2" [[ $(openssl sha < "$1") = $2 ]] || { printf ' mismatch!\n' echo 2>&1 "Downloaded package doesn't match digest." exit 1 } printf ' OK!\n' files=( !("$1") ) if [[ -d $files ]] && (( ${#files[@]} == 1 )); then mv "$files"/* . rmdir "$files" fi } fetchSource() ( source .source if [[ $pkg && -e "${pkg##*/}" ]]; then files=( !("${pkg##*/}") ) [[ -e $files ]] || { echo echo "Unpacking: ${PWD##*/}, using package..." unpack "${pkg##*/}" "$pkg_sha" } elif [[ $git ]] && hash git 2>/dev/null; then [[ -e .git ]] || { echo echo "Fetching: ${PWD##*/}, using git..." git clone "$svn" . printf '%s' "$(git describe --always)" > "${PWD##*/}-version" } elif [[ $svn ]] && hash git 2>/dev/null && [[ -x "$(git --exec-path)/git-svn" ]]; then [[ -e .git ]] || { echo echo "Fetching: ${PWD##*/}, using git-svn..." git svn clone --prefix=origin/ --stdlayout "$svn" . printf '%s' "$(git describe --always)" > "${PWD##*/}-version" } elif [[ $svn ]] && hash svn 2>/dev/null; then [[ -e .svn ]] || { echo echo "Fetching: ${PWD##*/}, using svn..." svn checkout "$svn/trunk" . printf 'r%s' "$(svn info | awk '/^Revision:/{ print $2 }')" > "${PWD##*/}-version" } elif [[ $pkg ]]; then files=( !("${pkg##*/}") ) [[ -e $files ]] || { echo echo "Fetching: ${PWD##*/}, using package..." fetch "$pkg" unpack "${pkg##*/}" "$pkg_sha" } else echo >&2 "error: Missing git-svn or svn." echo >&2 "error: Please install either or manually check out the sources" echo >&2 "error: from: $home" echo >&2 "error: into: $PWD" exit 1 fi ) depend() { echo echo "Checking dependency: $1..." [[ -e "lib/$1/.built" ]] && return pushd "lib/$1" fetchSource echo echo "Configuring dependency: $1..." if [[ -e configure.ac ]]; then if [[ ! -e configure ]]; then # create configure using autotools. if ! hash aclocal || ! hash automake; then echo >&2 "Need autotools to build $1. Please install automake and autoconf." exit 1 fi aclocal autoheader autoconf mkdir -p config.aux automake --add-missing fi fi if [[ -e configure ]]; then ./configure fi echo echo "Building dependency: $1..." if [[ -e Makefile ]]; then if ! hash make; then echo >&2 "Need make to build $1. Please install GNU make." exit 1 fi make date > .built else echo >&2 "error: Don't know how to build: $1" exit 1 fi popd } ### MPW mpw() { depend scrypt echo echo "Building target: $target..." CFLAGS=( # include paths -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" ) LDFLAGS=( # library paths -L"." -L"lib/scrypt" # link libraries -l"crypto" # scrypt "lib/scrypt/scrypt-crypto_aesctr.o" "lib/scrypt/scrypt-sha256.o" "lib/scrypt/scrypt-crypto_scrypt-nosse.o" "lib/scrypt/scrypt-memlimit.o" "lib/scrypt/scrypt-scryptenc_cpuperf.o" "lib/scrypt/scrypt-scryptenc.o" ) cc "${CFLAGS[@]}" -c types.c -o types.o "$@" cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw.c -o mpw "$@" echo "done! Now run ./install or use ./mpw" } ### MPW-BENCH mpw-bench() { depend scrypt depend bcrypt echo echo "Building target: $target..." CFLAGS=( # include paths -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" -I"lib/bcrypt" ) LDFLAGS=( # library paths -L"." -L"lib/scrypt" -L"lib/bcrypt" # libraries -l"crypto" # scrypt "lib/scrypt/scrypt-crypto_aesctr.o" "lib/scrypt/scrypt-sha256.o" "lib/scrypt/scrypt-crypto_scrypt-nosse.o" "lib/scrypt/scrypt-memlimit.o" "lib/scrypt/scrypt-scryptenc_cpuperf.o" "lib/scrypt/scrypt-scryptenc.o" # bcrypt "lib/bcrypt/crypt_blowfish.o" "lib/bcrypt/crypt_gensalt.o" "lib/bcrypt/wrapper.o" "lib/bcrypt/x86.o" ) cc "${CFLAGS[@]}" -c types.c -o types.o "$@" cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw-bench.c -o mpw-bench "$@" echo "done! Now use ./mpw-bench" } ### TARGETS cc() { if hash llvm-gcc 2>/dev/null; then llvm-gcc "$@" elif hash gcc 2>/dev/null; then gcc -std=gnu99 "$@" elif hash clang 2>/dev/null; then clang "$@" else echo >&2 "Need a compiler. Please install GCC or LLVM." exit 1 fi } echo "Will build targets: ${targets[*]}..." for target in "${targets[@]}"; do "$target" "$@" done