1 1.1 christos #!/bin/sh 2 1.1.1.6 christos 3 1.1 christos # Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4 1.1 christos # 5 1.1.1.6 christos # SPDX-License-Identifier: MPL-2.0 6 1.1.1.6 christos # 7 1.1 christos # This Source Code Form is subject to the terms of the Mozilla Public 8 1.1.1.6 christos # License, v. 2.0. If a copy of the MPL was not distributed with this 9 1.1.1.4 christos # file, you can obtain one at https://mozilla.org/MPL/2.0/. 10 1.1 christos # 11 1.1 christos # See the COPYRIGHT file distributed with this work for additional 12 1.1 christos # information regarding copyright ownership. 13 1.1 christos 14 1.1.1.8 christos set -e 15 1.1.1.8 christos 16 1.1.1.8 christos . ../conf.sh 17 1.1 christos 18 1.1 christos status=0 19 1.1 christos n=0 20 1.1 christos 21 1.1 christos rm -f dig.out.* 22 1.1 christos 23 1.1 christos DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p ${PORT}" 24 1.1 christos 25 1.1.1.8 christos n=$((n + 1)) 26 1.1.1.2 christos echo_i "checking that NSEC wildcard non-existence proof is returned auth ($n)" 27 1.1 christos ret=0 28 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec +norec @10.53.0.1 >dig.out.ns1.test$n || ret=1 29 1.1.1.8 christos grep -i 'a\.wild\.nsec\..*NSEC.*nsec\..*NSEC' dig.out.ns1.test$n >/dev/null || ret=1 30 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 31 1.1.1.8 christos status=$((status + ret)) 32 1.1 christos 33 1.1.1.8 christos n=$((n + 1)) 34 1.1.1.2 christos echo_i "checking that NSEC wildcard non-existence proof is returned non-validating ($n)" 35 1.1 christos ret=0 36 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec @10.53.0.2 >dig.out.ns2.test$n || ret=1 37 1.1.1.8 christos grep -i 'a\.wild\.nsec\..*NSEC.*nsec\..*NSEC' dig.out.ns2.test$n >/dev/null || ret=1 38 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns2.test$n >/dev/null && ret=1 39 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 40 1.1.1.8 christos status=$((status + ret)) 41 1.1 christos 42 1.1.1.8 christos n=$((n + 1)) 43 1.1.1.2 christos echo_i "checking that NSEC wildcard non-existence proof is returned validating ($n)" 44 1.1 christos ret=0 45 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec @10.53.0.3 >dig.out.ns3.test$n || ret=1 46 1.1.1.8 christos grep -i 'a\.wild\.nsec\..*NSEC.*nsec\..*NSEC' dig.out.ns3.test$n >/dev/null || ret=1 47 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns3.test$n >/dev/null || ret=1 48 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 49 1.1.1.8 christos status=$((status + ret)) 50 1.1 christos 51 1.1.1.8 christos n=$((n + 1)) 52 1.1.1.2 christos echo_i "checking that NSEC wildcard non-existence proof is returned validating + CD ($n)" 53 1.1 christos ret=0 54 1.1.1.8 christos $DIG $DIGOPTS +cd a b.wild.nsec @10.53.0.5 >dig.out.ns5.test$n || ret=1 55 1.1.1.8 christos grep -i 'a\.wild\.nsec\..*NSEC.*nsec\..*NSEC' dig.out.ns5.test$n >/dev/null || ret=1 56 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns5.test$n >/dev/null && ret=1 57 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 58 1.1.1.8 christos status=$((status + ret)) 59 1.1.1.8 christos n=$((n + 1)) 60 1.1 christos 61 1.1.1.2 christos echo_i "checking that returned NSEC wildcard non-existence proof validates ($n)" 62 1.1 christos ret=0 63 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec @10.53.0.4 >dig.out.ns4.test$n || ret=1 64 1.1.1.8 christos grep -i 'a\.wild\.nsec\..*NSEC.*nsec\..*NSEC' dig.out.ns4.test$n >/dev/null || ret=1 65 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns4.test$n >/dev/null || ret=1 66 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 67 1.1.1.8 christos status=$((status + ret)) 68 1.1 christos 69 1.1.1.8 christos n=$((n + 1)) 70 1.1.1.2 christos echo_i "checking that NSEC wildcard non-existence proof is returned private, validating ($n)" 71 1.1 christos ret=0 72 1.1.1.8 christos $DIG $DIGOPTS a b.wild.private.nsec @10.53.0.3 >dig.out.ns3.test$n || ret=1 73 1.1.1.8 christos grep -i 'a\.wild\.private\.nsec\..*NSEC.*private\.nsec\..*NSEC' dig.out.ns3.test$n >/dev/null || ret=1 74 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns3.test$n >/dev/null && ret=1 75 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 76 1.1.1.8 christos status=$((status + ret)) 77 1.1 christos 78 1.1.1.8 christos n=$((n + 1)) 79 1.1.1.2 christos echo_i "checking that returned NSEC wildcard non-existence proof for private zone validates ($n)" 80 1.1 christos ret=0 81 1.1.1.8 christos $DIG $DIGOPTS a b.wild.private.nsec @10.53.0.4 >dig.out.ns4.test$n || ret=1 82 1.1.1.8 christos grep -i 'a\.wild\.private\.nsec\..*NSEC.*private\.nsec\..*NSEC' dig.out.ns4.test$n >/dev/null || ret=1 83 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns4.test$n >/dev/null || ret=1 84 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 85 1.1.1.8 christos status=$((status + ret)) 86 1.1 christos 87 1.1.1.8 christos n=$((n + 1)) 88 1.1.1.2 christos echo_i "checking that NSEC3 wildcard non-existence proof is returned auth ($n)" 89 1.1 christos ret=0 90 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec3 +norec @10.53.0.1 >dig.out.ns1.test$n || ret=1 91 1.1.1.8 christos grep -i 'O3TJ8D9AJ54CBTFCQCJ3QK49CH7SF6H9\.nsec3\..*V5DLFB6UJNHR94LQ61FO607KGK12H88A' dig.out.ns1.test$n >/dev/null || ret=1 92 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 93 1.1.1.8 christos status=$((status + ret)) 94 1.1 christos 95 1.1.1.8 christos n=$((n + 1)) 96 1.1.1.2 christos echo_i "checking that NSEC3 wildcard non-existence proof is returned non-validating ($n)" 97 1.1 christos ret=0 98 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec3 @10.53.0.2 >dig.out.ns2.test$n || ret=1 99 1.1.1.8 christos grep -i 'O3TJ8D9AJ54CBTFCQCJ3QK49CH7SF6H9\.nsec3\..*V5DLFB6UJNHR94LQ61FO607KGK12H88A' dig.out.ns2.test$n >/dev/null || ret=1 100 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns2.test$n >/dev/null && ret=1 101 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 102 1.1.1.8 christos status=$((status + ret)) 103 1.1 christos 104 1.1.1.8 christos n=$((n + 1)) 105 1.1.1.2 christos echo_i "checking that NSEC3 wildcard non-existence proof is returned validating ($n)" 106 1.1 christos ret=0 107 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 108 1.1.1.8 christos grep -i 'O3TJ8D9AJ54CBTFCQCJ3QK49CH7SF6H9\.nsec3\..*V5DLFB6UJNHR94LQ61FO607KGK12H88A' dig.out.ns3.test$n >/dev/null || ret=1 109 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns3.test$n >/dev/null || ret=1 110 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 111 1.1.1.8 christos status=$((status + ret)) 112 1.1 christos 113 1.1.1.8 christos n=$((n + 1)) 114 1.1.1.2 christos echo_i "checking that NSEC3 wildcard non-existence proof is returned validating + CD ($n)" 115 1.1 christos ret=0 116 1.1.1.8 christos $DIG $DIGOPTS +cd a b.wild.nsec3 @10.53.0.5 >dig.out.ns5.test$n || ret=1 117 1.1.1.8 christos grep -i 'O3TJ8D9AJ54CBTFCQCJ3QK49CH7SF6H9\.nsec3\..*V5DLFB6UJNHR94LQ61FO607KGK12H88A' dig.out.ns5.test$n >/dev/null || ret=1 118 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns5.test$n >/dev/null && ret=1 119 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 120 1.1.1.8 christos status=$((status + ret)) 121 1.1 christos 122 1.1.1.8 christos n=$((n + 1)) 123 1.1.1.2 christos echo_i "checking that returned NSEC3 wildcard non-existence proof validates ($n)" 124 1.1 christos ret=0 125 1.1.1.8 christos $DIG $DIGOPTS a b.wild.nsec3 @10.53.0.4 >dig.out.ns4.test$n || ret=1 126 1.1.1.8 christos grep -i 'O3TJ8D9AJ54CBTFCQCJ3QK49CH7SF6H9\.nsec3\..*V5DLFB6UJNHR94LQ61FO607KGK12H88A' dig.out.ns4.test$n >/dev/null || ret=1 127 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns4.test$n >/dev/null || ret=1 128 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 129 1.1.1.8 christos status=$((status + ret)) 130 1.1 christos 131 1.1.1.8 christos n=$((n + 1)) 132 1.1.1.2 christos echo_i "checking that NSEC3 wildcard non-existence proof is returned private, validating ($n)" 133 1.1 christos ret=0 134 1.1.1.8 christos $DIG $DIGOPTS a b.wild.private.nsec3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 135 1.1.1.8 christos grep -i 'UDBSP4R8OUOT6HSO39VD8B5LMOSHRD5N\.private\.nsec3\..*NSEC3.*ASDRUIB7GO00OR92S5OUGI404LT27RNU' dig.out.ns3.test$n >/dev/null || ret=1 136 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns3.test$n >/dev/null && ret=1 137 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 138 1.1.1.8 christos status=$((status + ret)) 139 1.1 christos 140 1.1.1.8 christos n=$((n + 1)) 141 1.1.1.2 christos echo_i "checking that returned NSEC3 wildcard non-existence proof for private zone validates ($n)" 142 1.1 christos ret=0 143 1.1.1.8 christos $DIG $DIGOPTS a b.wild.private.nsec3 @10.53.0.4 >dig.out.ns4.test$n || ret=1 144 1.1.1.8 christos grep -i 'UDBSP4R8OUOT6HSO39VD8B5LMOSHRD5N\.private\.nsec3\..*NSEC3.*ASDRUIB7GO00OR92S5OUGI404LT27RNU' dig.out.ns4.test$n >/dev/null || ret=1 145 1.1.1.8 christos grep -i 'flags:.* ad[ ;]' dig.out.ns4.test$n >/dev/null || ret=1 146 1.1 christos if [ $ret != 0 ]; then echo_i "failed"; fi 147 1.1.1.8 christos status=$((status + ret)) 148 1.1 christos 149 1.1.1.3 christos echo_i "checking RFC 4592 responses ..." 150 1.1.1.3 christos 151 1.1.1.8 christos n=$((n + 1)) 152 1.1.1.3 christos echo_i "checking RFC 4592: host3.example. QTYPE=MX, QCLASS=IN ($n)" 153 1.1.1.3 christos ret=0 154 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 host3.example. MX IN >dig.out.ns1.test$n || ret=1 155 1.1.1.8 christos grep '^host3.example..*IN.MX.10 host1.example.' dig.out.ns1.test$n >/dev/null || ret=1 156 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 157 1.1.1.8 christos grep "ANSWER: 1," dig.out.ns1.test$n >/dev/null || ret=1 158 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 159 1.1.1.8 christos status=$((status + ret)) 160 1.1.1.3 christos 161 1.1.1.8 christos n=$((n + 1)) 162 1.1.1.3 christos echo_i "checking RFC 4592: host3.example. QTYPE=A, QCLASS=IN ($n)" 163 1.1.1.3 christos ret=0 164 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 host3.example. A IN >dig.out.ns1.test$n || ret=1 165 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 166 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 167 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 168 1.1.1.8 christos status=$((status + ret)) 169 1.1.1.3 christos 170 1.1.1.8 christos n=$((n + 1)) 171 1.1.1.3 christos echo_i "checking RFC 4592: foo.bar.example. QTYPE=TXT, QCLASS=IN ($n)" 172 1.1.1.3 christos ret=0 173 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 foo.bar.example TXT IN >dig.out.ns1.test$n || ret=1 174 1.1.1.8 christos grep '^foo.bar.example..*IN.TXT."this is a wildcard"' dig.out.ns1.test$n >/dev/null || ret=1 175 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 176 1.1.1.8 christos grep "ANSWER: 1," dig.out.ns1.test$n >/dev/null || ret=1 177 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 178 1.1.1.8 christos status=$((status + ret)) 179 1.1.1.3 christos 180 1.1.1.8 christos n=$((n + 1)) 181 1.1.1.3 christos echo_i "checking RFC 4592: host1.example. QTYPE=MX, QCLASS=IN ($n)" 182 1.1.1.3 christos ret=0 183 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 host1.example MX IN >dig.out.ns1.test$n || ret=1 184 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 185 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 186 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 187 1.1.1.8 christos status=$((status + ret)) 188 1.1.1.3 christos 189 1.1.1.8 christos n=$((n + 1)) 190 1.1.1.3 christos echo_i "checking RFC 4592: host1.example. QTYPE=MX, QCLASS=IN ($n)" 191 1.1.1.3 christos ret=0 192 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 host1.example MX IN >dig.out.ns1.test$n || ret=1 193 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 194 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 195 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 196 1.1.1.8 christos status=$((status + ret)) 197 1.1.1.3 christos 198 1.1.1.8 christos n=$((n + 1)) 199 1.1.1.3 christos echo_i "checking RFC 4592: sub.*.example. QTYPE=MX, QCLASS=IN ($n)" 200 1.1.1.3 christos ret=0 201 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 "sub.*.example." MX IN >dig.out.ns1.test$n || ret=1 202 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 203 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 204 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 205 1.1.1.8 christos status=$((status + ret)) 206 1.1.1.3 christos 207 1.1.1.8 christos n=$((n + 1)) 208 1.1.1.3 christos echo_i "checking RFC 4592: _telnet._tcp.host1.example. QTYPE=SRV, QCLASS=IN ($n)" 209 1.1.1.3 christos ret=0 210 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 _telnet._tcp.host1.example. SRV IN >dig.out.ns1.test$n || ret=1 211 1.1.1.8 christos grep "status: NXDOMAIN" dig.out.ns1.test$n >/dev/null || ret=1 212 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 213 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 214 1.1.1.8 christos status=$((status + ret)) 215 1.1.1.3 christos 216 1.1.1.8 christos n=$((n + 1)) 217 1.1.1.3 christos echo_i "checking RFC 4592: host.subdel.example. QTYPE=A, QCLASS=IN ($n)" 218 1.1.1.3 christos ret=0 219 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 host.subdel.example A IN >dig.out.ns1.test$n || ret=1 220 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 221 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 222 1.1.1.8 christos grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 223 1.1.1.8 christos grep "subdel.example..*IN.NS.ns.example.com." dig.out.ns1.test$n >/dev/null || ret=1 224 1.1.1.8 christos grep "subdel.example..*IN.NS.ns.example.net." dig.out.ns1.test$n >/dev/null || ret=1 225 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 226 1.1.1.8 christos status=$((status + ret)) 227 1.1.1.3 christos 228 1.1.1.8 christos n=$((n + 1)) 229 1.1.1.3 christos echo_i "checking RFC 4592: ghost.*.example. QTYPE=MX, QCLASS=IN ($n)" 230 1.1.1.3 christos ret=0 231 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 "ghost.*.example" MX IN >dig.out.ns1.test$n || ret=1 232 1.1.1.8 christos grep "status: NXDOMAIN" dig.out.ns1.test$n >/dev/null || ret=1 233 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 234 1.1.1.8 christos if [ $ret != 0 ]; then echo_i "failed"; fi 235 1.1.1.8 christos status=$((status + ret)) 236 1.1.1.8 christos 237 1.1.1.8 christos n=$((n + 1)) 238 1.1.1.8 christos echo_i "checking RFC 4592: _foo._udp.bar.example. QTYPE=SRV, QCLASS=IN ($n)" 239 1.1.1.8 christos ret=0 240 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 "_foo._udp.bar.example" SRV IN >dig.out.ns1.test$n || ret=1 241 1.1.1.8 christos grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 242 1.1.1.8 christos grep "ANSWER: 0," dig.out.ns1.test$n >/dev/null || ret=1 243 1.1.1.3 christos if [ $ret != 0 ]; then echo_i "failed"; fi 244 1.1.1.8 christos status=$((status + ret)) 245 1.1.1.3 christos 246 1.1.1.8 christos n=$((n + 1)) 247 1.1.1.5 christos echo_i "check wild card expansions by code point ($n)" 248 1.1.1.5 christos ret=0 249 1.1.1.5 christos i=0 250 1.1.1.8 christos while test $i -lt 256; do 251 1.1.1.8 christos x=$(expr 00$i : '.*\(...\)$' || true) 252 1.1.1.8 christos $DIG $DIGOPTS @10.53.0.1 "\\$x.example" TXT >dig.out.ns1.$x.test$n 253 1.1.1.8 christos if test $i -le 32 -o $i -ge 127; then 254 1.1.1.8 christos grep '^\\'"$x"'\.example\..*TXT.*"this is a wildcard"$' dig.out.ns1.$x.test$n >/dev/null || { 255 1.1.1.8 christos echo_i "code point $x failed" 256 1.1.1.8 christos ret=1 257 1.1.1.8 christos } 258 1.1.1.8 christos # "=34 $=36 (=40 )=41 .=46 ;=59 \=92 @=64 259 1.1.1.8 christos elif test $i -eq 34 -o $i -eq 36 -o $i -eq 40 -o $i -eq 41 -o \ 260 1.1.1.8 christos $i -eq 46 -o $i -eq 59 -o $i -eq 64 -o $i -eq 92; then 261 1.1.1.8 christos case $i in 262 1.1.1.8 christos 34) a='"' ;; 263 1.1.1.8 christos 36) a='$' ;; 264 1.1.1.8 christos 40) a='(' ;; 265 1.1.1.8 christos 41) a=')' ;; 266 1.1.1.8 christos 46) a='\.' ;; 267 1.1.1.8 christos 59) a=';' ;; 268 1.1.1.8 christos 64) a='@' ;; 269 1.1.1.8 christos 92) a='\\' ;; 270 1.1.1.8 christos *) 271 1.1.1.8 christos a='' 272 1.1.1.8 christos echo_i "code point $x failed" 273 1.1.1.8 christos ret=1 274 1.1.1.8 christos ;; 275 1.1.1.8 christos esac 276 1.1.1.8 christos grep '^\\'"$a"'\.example.*.*TXT.*"this is a wildcard"$' dig.out.ns1.$x.test$n >/dev/null || { 277 1.1.1.8 christos echo_i "code point $x failed" 278 1.1.1.8 christos ret=1 279 1.1.1.8 christos } 280 1.1.1.8 christos else 281 1.1.1.8 christos grep '^\\' dig.out.ns1.$x.test$n && { 282 1.1.1.8 christos echo_i "code point $x failed" 283 1.1.1.8 christos ret=1 284 1.1.1.8 christos } 285 1.1.1.8 christos fi 286 1.1.1.8 christos i=$((i + 1)) 287 1.1.1.5 christos done 288 1.1.1.5 christos if [ $ret != 0 ]; then echo_i "failed"; fi 289 1.1.1.8 christos status=$((status + ret)) 290 1.1.1.5 christos 291 1.1 christos echo_i "exit status: $status" 292 1.1 christos [ $status -eq 0 ] || exit 1 293