Gilles Peskine | d0a4dc8 | 2020-04-23 17:33:36 +0200 | [diff] [blame] | 1 | ## Common shell functions used by demo scripts programs/*/*.sh. |
| 2 | |
| 3 | ## How to write a demo script |
| 4 | ## ========================== |
| 5 | ## |
| 6 | ## Include this file near the top of each demo script: |
| 7 | ## . "${0%/*}/../demo_common.sh" |
| 8 | ## |
Gilles Peskine | b63e79d | 2020-04-23 18:50:37 +0200 | [diff] [blame] | 9 | ## Start with a "msg" call that explains the purpose of the script. |
| 10 | ## Then call the "depends_on" function to ensure that all config |
| 11 | ## dependencies are met. |
| 12 | ## |
Gilles Peskine | d0a4dc8 | 2020-04-23 17:33:36 +0200 | [diff] [blame] | 13 | ## As the last thing in the script, call the cleanup function. |
| 14 | ## |
| 15 | ## You can use the functions and variables described below. |
| 16 | |
| 17 | set -e -u |
| 18 | |
| 19 | ## $root_dir is the root directory of the Mbed TLS source tree. |
| 20 | root_dir="${0%/*}" |
| 21 | n=4 # limit the search depth |
| 22 | while ! [ -d "$root_dir/programs" ] || ! [ -d "$root_dir/library" ]; do |
| 23 | if [ $n -eq 0 ]; then |
| 24 | echo >&2 "This doesn't seem to be an Mbed TLS source tree." |
| 25 | exit 125 |
| 26 | fi |
| 27 | n=$((n - 1)) |
| 28 | case $root_dir in |
| 29 | .) root_dir="..";; |
| 30 | ..|?*/..) root_dir="$root_dir/..";; |
| 31 | ?*/*) root_dir="${root_dir%/*}";; |
| 32 | /*) root_dir="/";; |
| 33 | *) root_dir=".";; |
| 34 | esac |
| 35 | done |
| 36 | |
| 37 | ## $programs_dir is the directory containing the sample programs. |
| 38 | programs_dir="$root_dir/programs" |
| 39 | |
| 40 | ## msg LINE... |
| 41 | ## msg <TEXT_ORIGIN |
| 42 | ## Display an informational message. |
| 43 | msg () { |
| 44 | if [ $# -eq 0 ]; then |
| 45 | sed 's/^/# /' |
| 46 | else |
| 47 | for x in "$@"; do |
| 48 | echo "# $x" |
| 49 | done |
| 50 | fi |
| 51 | } |
| 52 | |
| 53 | ## run "Message" COMMAND ARGUMENT... |
| 54 | ## Display the message, then run COMMAND with the specified arguments. |
| 55 | run () { |
| 56 | echo |
| 57 | echo "# $1" |
| 58 | shift |
| 59 | echo "+ $*" |
| 60 | "$@" |
| 61 | } |
| 62 | |
| 63 | ## Like '!', but stop on failure with 'set -e' |
| 64 | not () { |
| 65 | if "$@"; then false; fi |
| 66 | } |
| 67 | |
| 68 | ## run_bad "Message" COMMAND ARGUMENT... |
| 69 | ## Like run, but the command is expected to fail. |
| 70 | run_bad () { |
| 71 | echo |
| 72 | echo "$1 This must fail." |
| 73 | shift |
| 74 | echo "+ ! $*" |
| 75 | not "$@" |
| 76 | } |
| 77 | |
Gilles Peskine | 1e18775 | 2020-04-23 17:50:26 +0200 | [diff] [blame] | 78 | ## config_has SYMBOL... |
| 79 | ## Succeeds if the library configuration has all SYMBOLs set. |
| 80 | config_has () { |
| 81 | for x in "$@"; do |
| 82 | "$programs_dir/test/query_compile_time_config" "$x" |
| 83 | done |
| 84 | } |
| 85 | |
Gilles Peskine | b63e79d | 2020-04-23 18:50:37 +0200 | [diff] [blame] | 86 | ## depends_on SYMBOL... |
| 87 | ## Exit if the library configuration does not have all SYMBOLs set. |
| 88 | depends_on () { |
Gilles Peskine | b1ec5cd | 2020-04-26 22:29:57 +0200 | [diff] [blame^] | 89 | m= |
| 90 | for x in "$@"; do |
| 91 | if ! config_has "$x"; then |
| 92 | m="$m $x" |
| 93 | fi |
| 94 | done |
| 95 | if [ -n "$m" ]; then |
Gilles Peskine | b63e79d | 2020-04-23 18:50:37 +0200 | [diff] [blame] | 96 | cat >&2 <<EOF |
Gilles Peskine | b1ec5cd | 2020-04-26 22:29:57 +0200 | [diff] [blame^] | 97 | $0: this demo requires the following |
| 98 | configuration options to be enabled at compile time: |
| 99 | $m |
Gilles Peskine | b63e79d | 2020-04-23 18:50:37 +0200 | [diff] [blame] | 100 | EOF |
| 101 | # Exit with a success status so that this counts as a pass for run_demos.py. |
| 102 | exit |
| 103 | fi |
| 104 | } |
| 105 | |
Gilles Peskine | d0a4dc8 | 2020-04-23 17:33:36 +0200 | [diff] [blame] | 106 | ## Add the names of files to clean up to this whitespace-separated variable. |
| 107 | ## The file names must not contain whitespace characters. |
| 108 | files_to_clean= |
| 109 | |
Gilles Peskine | d9b3209 | 2020-04-26 22:29:12 +0200 | [diff] [blame] | 110 | ## Call this function at the end of each script. |
| 111 | ## It is called automatically if the script is killed by a signal. |
| 112 | cleanup () { |
| 113 | rm -f -- $files_to_clean |
| 114 | } |
| 115 | |
Gilles Peskine | d0a4dc8 | 2020-04-23 17:33:36 +0200 | [diff] [blame] | 116 | |
| 117 | |
| 118 | ################################################################ |
| 119 | ## End of the public interfaces. Code beyond this point is not |
| 120 | ## meant to be called directly from a demo script. |
| 121 | |
Gilles Peskine | d0a4dc8 | 2020-04-23 17:33:36 +0200 | [diff] [blame] | 122 | trap 'cleanup; trap - HUP; kill -HUP $$' HUP |
| 123 | trap 'cleanup; trap - INT; kill -INT $$' INT |
| 124 | trap 'cleanup; trap - TERM; kill -TERM $$' TERM |
Gilles Peskine | 1e18775 | 2020-04-23 17:50:26 +0200 | [diff] [blame] | 125 | |
| 126 | if config_has MBEDTLS_ENTROPY_NV_SEED; then |
| 127 | # Create a seedfile that's sufficiently long in all library configurations. |
| 128 | # This is necessary for programs that use randomness. |
| 129 | # Assume that the name of the seedfile is the default name. |
| 130 | files_to_clean="$files_to_clean seedfile" |
| 131 | dd if=/dev/urandom of=seedfile ibs=64 obs=64 count=1 |
| 132 | fi |