(BWDIC!) Allow `source' in `call'ed macros..
[s-mailx.git] / cc-test.sh
blob2b582e1015eac6d895959a91f301f804eef2b1a4
1 #!/bin/sh -
2 #@ Usage: ./cc-test.sh [--check-only [s-nail-binary]]
4 SNAIL=./s-nail
5 ARGS='-n# -Sstealthmua -Snosave -Sexpandaddr=restrict -Sdotlock-ignore-error'
6 CONF=./make.rc
7 BODY=./.cc-body.txt
8 MBOX=./.cc-test.mbox
10 MAKE="${MAKE:-`command -v make`}"
11 awk=${awk:-`command -v awk`}
12 cat=${cat:-`command -v cat`}
13 cksum=${cksum:-`command -v cksum`}
14 rm=${rm:-`command -v rm`}
15 sed=${sed:-`command -v sed`}
16 grep=${grep:-`command -v grep`}
18 ## -- >8 -- 8< -- ##
20 export SNAIL ARGS CONF BODY MBOX MAKE awk cat cksum rm sed grep
22 # NOTE! UnixWare 7.1.4 gives ISO-10646-Minimum-European-Subset for
23 # nl_langinfo(CODESET), then, so also overwrite ttycharset.
24 # (In addition this setup allows us to succeed on TinyCore 4.4 that has no
25 # other locales than C/POSIX installed by default!)
26 LC=en_US.UTF-8
27 LC_ALL=${LC} LANG=${LC}
28 ttycharset=UTF-8
29 export LC_ALL LANG ttycharset
31 # Problem: force $SHELL to be a real shell. It seems some testing environments
32 # use nologin(?), but we need a real shell for command execution
33 if { echo ${SHELL} | ${grep} nologin; } >/dev/null 2>&1; then
34 echo >&2 '$SHELL seems to be nologin, overwriting to /bin/sh!'
35 SHELL=/bin/sh
36 export SHELL
39 ESTAT=0
41 usage() {
42 echo >&2 "Usage: ./cc-test.sh [--check-only [s-nail-binary]]"
43 exit 1
46 CHECK_ONLY=
47 [ ${#} -gt 0 ] && {
48 [ "${1}" = --check-only ] || usage
49 [ ${#} -gt 2 ] && usage
50 [ ${#} -eq 2 ] && SNAIL="${2}"
51 [ -x "${SNAIL}" ] || usage
52 CHECK_ONLY=1
55 # cc_all_configs()
56 # Test all configs TODO doesn't cover all *combinations*, stupid!
57 cc_all_configs() {
58 < ${CONF} ${awk} '
59 BEGIN {
60 NOTME["WANT_AUTOCC"] = 1
61 NOTME["WANT_DEBUG"] = 1
62 NOTME["WANT_NOEXTMD5"] = 1
63 NOTME["WANT_NOALLOCA"] = 1
64 NOTME["WANT_DEVEL"] = 1
65 NOTME["WANT_NYD2"] = 1
66 i = 0
68 /^[[:space:]]*WANT_/ {
69 sub(/^[[:space:]]*/, "")
70 # This bails for UnixWare 7.1.4 awk(1), but preceeding = with \
71 # does not seem to be a compliant escape for =
72 #sub(/=.*$/, "")
73 $1 = substr($1, 1, index($1, "=") - 1)
74 if (NOTME[$1])
75 next
76 data[i++] = $1
78 END {
79 # Doing this completely sequentially and not doing make distclean in
80 # between runs should effectively result in lesser compilations.
81 # It is completely dumb nonetheless... TODO
82 for (j = 1; j < i; ++j) {
83 for (k = 1; k < j; ++k)
84 printf data[k] "=1 "
85 for (k = j; k < i; ++k)
86 printf data[k] "=0 "
87 printf "WANT_AUTOCC=1\n"
89 for (j = 1; j < i; ++j) {
90 for (k = 1; k < j; ++k)
91 printf data[k] "=0 "
92 for (k = j; k < i; ++k)
93 printf data[k] "=1 "
94 printf "WANT_AUTOCC=1\n"
96 # With debug
97 for (j = 1; j < i; ++j) {
98 for (k = 1; k < j; ++k)
99 printf data[k] "=1 "
100 for (k = j; k < i; ++k)
101 printf data[k] "=0 "
102 printf "WANT_AUTOCC=1\n"
103 printf "WANT_DEBUG=1\n"
105 for (j = 1; j < i; ++j) {
106 for (k = 1; k < j; ++k)
107 printf data[k] "=0 "
108 for (k = j; k < i; ++k)
109 printf data[k] "=1 "
110 printf "WANT_AUTOCC=1\n"
111 printf "WANT_DEBUG=1\n"
114 printf "CONFIG=NULL WANT_AUTOCC=0\n"
115 printf "CONFIG=NULL WANT_AUTOCC=1\n"
116 printf "CONFIG=NULLI WANT_AUTOCC=0\n"
117 printf "CONFIG=NULLI WANT_AUTOCC=1\n"
118 printf "CONFIG=MINIMAL WANT_AUTOCC=0\n"
119 printf "CONFIG=MINIMAL WANT_AUTOCC=1\n"
120 printf "CONFIG=MEDIUM WANT_AUTOCC=0\n"
121 printf "CONFIG=MEDIUM WANT_AUTOCC=1\n"
122 printf "CONFIG=NETSEND WANT_AUTOCC=0\n"
123 printf "CONFIG=NETSEND WANT_AUTOCC=1\n"
124 printf "CONFIG=MAXIMAL WANT_AUTOCC=0\n"
125 printf "CONFIG=MAXIMAL WANT_AUTOCC=1\n"
126 printf "CONFIG=DEVEL WANT_AUTOCC=0\n"
127 printf "CONFIG=DEVEL WANT_AUTOCC=1\n"
128 printf "CONFIG=ODEVEL WANT_AUTOCC=0\n"
129 printf "CONFIG=ODEVEL WANT_AUTOCC=1\n"
131 ' | while read c; do
132 printf "\n\n##########\n$c\n"
133 printf "\n\n##########\n$c\n" >&2
134 sh -c "${MAKE} ${c}"
135 t_all
136 done
137 ${MAKE} distclean
140 # cksum_test()
141 # Read mailbox $2, strip non-constant headers and MIME boundaries, query the
142 # cksum(1) of the resulting data and compare against the checksum $3
143 cksum_test() {
144 tid=${1} f=${2} s=${3}
145 printf "${tid}: "
146 csum="`${sed} -e '/^From /d' -e '/^Date: /d' \
147 -e '/^ boundary=/d' -e '/^--=-=/d' < \"${f}\" \
148 -e '/^\[-- Message/d' | ${cksum}`";
149 if [ "${csum}" = "${s}" ]; then
150 printf 'ok\n'
151 else
152 ESTAT=1
153 printf 'error: checksum mismatch (got %s)\n' "${csum}"
157 have_feat() {
159 echo 'feat' |
160 MAILRC=/dev/null "${SNAIL}" ${ARGS} |
161 ${grep} ${1}
162 ) >/dev/null 2>&1
165 # t_behave()
166 # Basic (easily testable) behaviour tests
167 t_behave() {
168 # Test for [d1f1a19]
169 ${rm} -f "${MBOX}"
170 printf 'echo +nix\nset folder=/\necho +nix\nset nofolder\necho +nix\nx' |
171 MAILRC=/dev/null "${SNAIL}" ${ARGS} > "${MBOX}"
172 cksum_test behave:001 "${MBOX}" '4214021069 15'
174 # POSIX: setting *noprompt*/prompt='' shall prevent prompting TODO
175 # TODO for this to be testable we need a way to echo a variable
176 # TODO or to force echo of the prompt
178 __behave_ifelse
180 # FIXME __behave_alias
182 # FIXME __behave_mlist
184 have_feat SSL/TLS && have_feat S/MIME && __behave_smime
187 __behave_ifelse() {
188 # Nestable conditions test
189 ${rm} -f "${MBOX}"
190 ${cat} <<- '__EOT' | MAILRC=/dev/null "${SNAIL}" ${ARGS} > "${MBOX}"
191 if 0
192 echo 1.err
193 else
194 echo 1.ok
195 endif
196 if 1
197 echo 2.ok
198 else
199 echo 2.err
200 endif
201 if $dietcurd
202 echo 3.err
203 else
204 echo 3.ok
205 endif
206 set dietcurd=yoho
207 if $dietcurd
208 echo 4.ok
209 else
210 echo 4.err
211 endif
212 if $dietcurd == 'yoho'
213 echo 5.ok
214 else
215 echo 5.err
216 endif
217 if $dietcurd != 'yoho'
218 echo 6.err
219 else
220 echo 6.ok
221 endif
222 # Nesting
223 if faLse
224 echo 7.err1
225 if tRue
226 echo 7.err2
227 if yEs
228 echo 7.err3
229 else
230 echo 7.err4
231 endif
232 echo 7.err5
233 endif
234 echo 7.err6
235 else
236 echo 7.ok7
237 if YeS
238 echo 7.ok8
239 if No
240 echo 7.err9
241 else
242 echo 7.ok9
243 endif
244 echo 7.ok10
245 else
246 echo 7.err11
247 if yeS
248 echo 7.err12
249 else
250 echo 7.err13
251 endif
252 endif
253 echo 7.ok14
254 endif
255 if r
256 echo 8.ok1
257 if R
258 echo 8.ok2
259 else
260 echo 8.err2
261 endif
262 echo 8.ok3
263 else
264 echo 8.err1
265 endif
266 if s
267 echo 9.err1
268 else
269 echo 9.ok1
270 if S
271 echo 9.err2
272 else
273 echo 9.ok2
274 endif
275 echo 9.ok3
276 endif
277 # `elif'
278 if $dietcurd == 'yohu'
279 echo 10.err1
280 elif $dietcurd == 'yoha'
281 echo 10.err2
282 elif $dietcurd == 'yohe'
283 echo 10.err3
284 elif $dietcurd == 'yoho'
285 echo 10.ok1
286 if $dietcurd == 'yohu'
287 echo 10.err4
288 elif $dietcurd == 'yoha'
289 echo 10.err5
290 elif $dietcurd == 'yohe'
291 echo 10.err6
292 elif $dietcurd == 'yoho'
293 echo 10.ok2
294 if $dietcurd == 'yohu'
295 echo 10.err7
296 elif $dietcurd == 'yoha'
297 echo 10.err8
298 elif $dietcurd == 'yohe'
299 echo 10.err9
300 elif $dietcurd == 'yoho'
301 echo 10.ok3
302 else
303 echo 10.err10
304 endif
305 else
306 echo 10.err11
307 endif
308 else
309 echo 10.err12
310 endif
311 # integer conversion, <..>..
312 set dietcurd=10
313 if $dietcurd < 11
314 echo 11.ok1
315 if $dietcurd > 9
316 echo 11.ok2
317 else
318 echo 11.err2
319 endif
320 if $dietcurd == 10
321 echo 11.ok3
322 else
323 echo 11.err3
324 endif
325 if $dietcurd >= 10
326 echo 11.ok4
327 else
328 echo 11.err4
329 endif
330 if $dietcurd <= 10
331 echo 11.ok5
332 else
333 echo 11.err5
334 endif
335 if $dietcurd >= 11
336 echo 11.err6
337 else
338 echo 11.ok6
339 endif
340 if $dietcurd <= 9
341 echo 11.err7
342 else
343 echo 11.ok7
344 endif
345 else
346 echo 11.err1
347 endif
348 set dietcurd=Abc
349 if $dietcurd < aBd
350 echo 12.ok1
351 if $dietcurd > abB
352 echo 12.ok2
353 else
354 echo 12.err2
355 endif
356 if $dietcurd == aBC
357 echo 12.ok3
358 else
359 echo 12.err3
360 endif
361 if $dietcurd >= AbC
362 echo 12.ok4
363 else
364 echo 12.err4
365 endif
366 if $dietcurd <= ABc
367 echo 12.ok5
368 else
369 echo 12.err5
370 endif
371 if $dietcurd >= abd
372 echo 12.err6
373 else
374 echo 12.ok6
375 endif
376 if $dietcurd <= abb
377 echo 12.err7
378 else
379 echo 12.ok7
380 endif
381 else
382 echo 12.err1
383 endif
384 if $dietcurd =@ aB
385 echo 13.ok
386 else
387 echo 13.err
388 endif
389 if $dietcurd =@ bC
390 echo 14.ok
391 else
392 echo 14.err
393 endif
394 if $dietcurd !@ aB
395 echo 15.err
396 else
397 echo 15.ok
398 endif
399 if $dietcurd !@ bC
400 echo 15.err
401 else
402 echo 15.ok
403 endif
404 if $dietcurd =@ Cd
405 echo 16.err
406 else
407 echo 16.ok
408 endif
409 if $dietcurd !@ Cd
410 echo 17.ok
411 else
412 echo 17.err
413 endif
414 set diet=abc curd=abc
415 if $diet == $curd
416 echo 18.ok
417 else
418 echo 18.err
419 endif
420 set diet=abc curd=abcd
421 if $diet != $curd
422 echo 19.ok
423 else
424 echo 19.err
425 endif
426 # 1. Shitty grouping capabilities as of today
427 unset diet curd ndefined
428 if [ [ false ] || [ false ] || [ true ] ] && [ [ false ] || [ true ] ] && \
429 [ yes ]
430 echo 20.ok
431 else
432 echo 20.err
433 endif
434 if [ [ [ [ 0 ] || [ 1 ] ] && [ [ 1 ] || [ 0 ] ] ] && [ 1 ] ] && [ yes ]
435 echo 21.ok
436 else
437 echo 21.err
438 endif
439 if [ [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] ]
440 echo 22.ok
441 else
442 echo 22.err
443 endif
444 if [ [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] || [ [ 1 ] ] ]
445 echo 23.ok
446 else
447 echo 23.err
448 endif
449 if [ [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] || [ [ 1 ] ] || [ 1 ] ] && [ no ]
450 echo 24.err
451 else
452 echo 24.ok
453 endif
454 if [ [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] || [ [ 1 ] ] || [ 1 ] ] \
455 && [ no ] || [ yes ]
456 echo 25.ok
457 else
458 echo 25.err
459 endif
460 if [ [ [ [ [ [ [ 1 ] ] && [ 1 ] ] && [ 1 ] ] && [ 1 ] ] ] && [ 1 ] ]
461 echo 26.ok
462 else
463 echo 26.err
464 endif
465 if [ [ [ [ [ [ [ 1 ] ] && [ 1 ] ] && [ 1 ] ] && [ 1 ] ] ] && [ 0 ] ]
466 echo 27.err
467 else
468 echo 27.ok
469 endif
470 if [ [ [ [ [ [ [ 1 ] ] && [ 1 ] ] && [ 0 ] ] && [ 1 ] ] ] && [ 1 ] ]
471 echo 28.err
472 else
473 echo 28.ok
474 endif
475 if [ [ [ [ [ [ [ 0 ] ] && [ 1 ] ] && [ 1 ] ] && [ 1 ] ] ] && [ 1 ] ]
476 echo 29.err
477 else
478 echo 29.ok
479 endif
480 if [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] && [ 0 ]
481 echo 30.err
482 else
483 echo 30.ok
484 endif
485 if [ 1 ] || [ 0 ] || [ 0 ] || [ 0 ] && [ 1 ]
486 echo 31.ok
487 else
488 echo 31.err
489 endif
490 if [ 0 ] || [ 0 ] || [ 0 ] || [ 1 ] && [ 0 ]
491 echo 32.err
492 else
493 echo 32.ok
494 endif
495 if [ 0 ] || [ 0 ] || [ 0 ] || [ 1 ] && [ 1 ]
496 echo 33.ok
497 else
498 echo 33.err
499 endif
500 if [ 0 ] || [ 0 ] || [ 0 ] || [ 1 ] && [ 0 ] || [ 1 ] && [ 0 ]
501 echo 34.err
502 else
503 echo 34.ok
504 endif
505 if [ 0 ] || [ 0 ] || [ 0 ] || [ 1 ] && [ 0 ] || [ 1 ] && [ 1 ]
506 echo 35.ok
507 else
508 echo 35.err
509 endif
510 set diet=yo curd=ho
511 if [ [ $diet == 'yo' ] && [ $curd == 'ho' ] ] && [ $ndefined ]
512 echo 36.err
513 else
514 echo 36.ok
515 endif
516 set ndefined
517 if [ [ $diet == 'yo' ] && [ $curd == 'ho' ] ] && [ $ndefined ]
518 echo 37.ok
519 else
520 echo 37.err
521 endif
522 # 2. Shitty grouping capabilities as of today
523 unset diet curd ndefined
524 if [ false || false || true ] && [ false || true ] && yes
525 echo 40.ok
526 else
527 echo 40.err
528 endif
529 if [ [ [ 0 || 1 ] && [ 1 || 0 ] ] && 1 ] && [ yes ]
530 echo 41.ok
531 else
532 echo 41.err
533 endif
534 if [ 1 || 0 || 0 || 0 ]
535 echo 42.ok
536 else
537 echo 42.err
538 endif
539 if [ 1 || 0 || 0 || 0 || [ 1 ] ]
540 echo 43.ok
541 else
542 echo 43.err
543 endif
544 if [ 1 || 0 || 0 || 0 || [ 1 ] || 1 ] && no
545 echo 44.err
546 else
547 echo 44.ok
548 endif
549 if [ 1 || 0 || 0 || 0 || 1 || [ 1 ] ] && no || [ yes ]
550 echo 45.ok
551 else
552 echo 45.err
553 endif
554 if [ [ [ [ [ [ 1 ] && 1 ] && 1 ] && 1 ] ] && [ 1 ] ]
555 echo 46.ok
556 else
557 echo 46.err
558 endif
559 if [ [ [ [ [ [ 1 ] && 1 ] && 1 ] && [ 1 ] ] ] && 0 ]
560 echo 47.err
561 else
562 echo 47.ok
563 endif
564 if [ [ [ [ [ [ [ 1 ] ] && 1 ] && 0 ] && [ 1 ] ] ] && 1 ]
565 echo 48.err
566 else
567 echo 48.ok
568 endif
569 if [ [ [ [ [ [ 0 ] && 1 ] && 1 ] && 1 ] ] && 1 ]
570 echo 49.err
571 else
572 echo 49.ok
573 endif
574 if 1 || 0 || 0 || 0 && 0
575 echo 50.err
576 else
577 echo 50.ok
578 endif
579 if 1 || 0 || 0 || 0 && 1
580 echo 51.ok
581 else
582 echo 51.err
583 endif
584 if 0 || 0 || 0 || 1 && 0
585 echo 52.err
586 else
587 echo 52.ok
588 endif
589 if 0 || 0 || 0 || 1 && 1
590 echo 53.ok
591 else
592 echo 53.err
593 endif
594 if 0 || 0 || 0 || 1 && 0 || 1 && 0
595 echo 54.err
596 else
597 echo 54.ok
598 endif
599 if 0 || 0 || 0 || 1 && 0 || 1 && 1
600 echo 55.ok
601 else
602 echo 55.err
603 endif
604 set diet=yo curd=ho
605 if [ $diet == 'yo' && $curd == 'ho' ] && $ndefined
606 echo 56.err
607 else
608 echo 56.ok
609 endif
610 if $diet == 'yo' && $curd == 'ho' && $ndefined
611 echo 57.err
612 else
613 echo 57.ok
614 endif
615 set ndefined
616 if [ $diet == 'yo' && $curd == 'ho' ] && $ndefined
617 echo 57.ok
618 else
619 echo 57.err
620 endif
621 if $diet == 'yo' && $curd == 'ho' && $ndefined
622 echo 58.ok
623 else
624 echo 58.err
625 endif
626 if [ [ [ [ [ [ $diet == 'yo' && $curd == 'ho' && $ndefined ] ] ] ] ] ]
627 echo 59.ok
628 else
629 echo 59.err
630 endif
631 # Some more en-braced variables
632 set diet=yo curd=ho
633 if ${diet} == ${curd}
634 echo 70.err
635 else
636 echo 70.ok
637 endif
638 if ${diet} != ${curd}
639 echo 71.ok
640 else
641 echo 71.err
642 endif
643 if $diet == ${curd}
644 echo 72.err
645 else
646 echo 72.ok
647 endif
648 if ${diet} == $curd
649 echo 73.err
650 else
651 echo 73.ok
652 endif
653 # Unary !
654 if ! 0 && ! ! 1 && ! ! ! ! 2 && 3
655 echo 80.ok
656 else
657 echo 80.err
658 endif
659 if ! 0 && ! [ ! 1 ] && ! [ ! [ ! [ ! 2 ] ] ] && 3
660 echo 81.ok
661 else
662 echo 81.err
663 endif
664 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ 2 ] ] ] ] ] && 3
665 echo 82.ok
666 else
667 echo 82.err
668 endif
669 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ 2 ] ] ] ] ] && ! 3
670 echo 83.err
671 else
672 echo 83.ok
673 endif
674 if [ ! 0 ] && [ ! [ ! 1 ] ] && ! [ [ ! [ ! [ ! [ 2 ] ] ] ] ] && ! 3
675 echo 84.err
676 else
677 echo 84.ok
678 endif
679 if [ ! 0 ] && ! [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ 2 ] ] ] ] ] && 3
680 echo 85.err
681 else
682 echo 85.ok
683 endif
684 if ! [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ 2 ] ] ] ] ] && 3
685 echo 86.err
686 else
687 echo 86.ok
688 endif
689 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ 2 ] ] ] ] ] || 3
690 echo 87.ok
691 else
692 echo 87.err
693 endif
694 if [ ! 0 ] && [ ! ! [ ! ! 1 ] ] && [ ! ! [ ! ! [ ! ! [ ! ! [ 2 ] ] ] ] ]
695 echo 88.ok
696 else
697 echo 88.err
698 endif
699 # Unary !, odd
700 if ! 0 && ! ! 1 && ! ! ! 0 && 3
701 echo 90.ok
702 else
703 echo 90.err
704 endif
705 if ! 0 && ! [ ! 1 ] && ! [ ! [ ! [ 0 ] ] ] && 3
706 echo 91.ok
707 else
708 echo 91.err
709 endif
710 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ [ 0 ] ] ] ] ] && 3
711 echo 92.ok
712 else
713 echo 92.err
714 endif
715 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! ! [ ! [ ! 0 ] ] ] ] && ! 3
716 echo 93.err
717 else
718 echo 93.ok
719 endif
720 if [ ! 0 ] && [ ! [ ! 1 ] ] && ! [ ! [ ! [ ! [ ! 0 ] ] ] ] && 3
721 echo 94.ok
722 else
723 echo 94.err
724 endif
725 if [ ! 0 ] && ! [ ! [ ! 1 ] ] && [ ! ! [ ! [ ! [ ! [ 0 ] ] ] ] ] && 3
726 echo 95.err
727 else
728 echo 95.ok
729 endif
730 if ! [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! ! 0 ] ] ] ] && 3
731 echo 96.err
732 else
733 echo 96.ok
734 endif
735 if [ ! 0 ] && [ ! [ ! 1 ] ] && [ ! [ ! [ ! [ ! [ ! 0 ] ] ] ] ] || 3
736 echo 97.ok
737 else
738 echo 97.err
739 endif
740 if [ ! 0 ] && [ ! ! [ ! ! 1 ] ] && [ ! ! [ ! ! [ ! ! [ ! [ 0 ] ] ] ] ]
741 echo 98.ok
742 else
743 echo 98.err
744 endif
745 __EOT
746 cksum_test behave:if-normal "${MBOX}" '557629289 631'
748 if have_feat REGEX; then
749 ${rm} -f "${MBOX}"
750 ${cat} <<- '__EOT' | MAILRC=/dev/null "${SNAIL}" ${ARGS} > "${MBOX}"
751 set dietcurd=yoho
752 if $dietcurd =~ '^yo.*'
753 echo 1.ok
754 else
755 echo 1.err
756 endif
757 if $dietcurd =~ '^yoho.+'
758 echo 2.err
759 else
760 echo 2.ok
761 endif
762 if $dietcurd !~ '.*ho$'
763 echo 3.err
764 else
765 echo 3.ok
766 endif
767 if $dietcurd !~ '.+yoho$'
768 echo 4.ok
769 else
770 echo 4.err
771 endif
772 if [ $dietcurd !~ '.+yoho$' ]
773 echo 5.ok
774 else
775 echo 5.err
776 endif
777 if ! [ $dietcurd =~ '.+yoho$' ]
778 echo 6.ok
779 else
780 echo 6.err
781 endif
782 if ! ! [ $dietcurd !~ '.+yoho$' ]
783 echo 7.ok
784 else
785 echo 7.err
786 endif
787 if ! [ ! [ $dietcurd !~ '.+yoho$' ] ]
788 echo 8.ok
789 else
790 echo 8.err
791 endif
792 if [ ! [ ! [ $dietcurd !~ '.+yoho$' ] ] ]
793 echo 9.ok
794 else
795 echo 9.err
796 endif
797 if ! [ ! [ ! [ $dietcurd !~ '.+yoho$' ] ] ]
798 echo 10.err
799 else
800 echo 10.ok
801 endif
802 if ! ! ! $dietcurd !~ '.+yoho$'
803 echo 11.err
804 else
805 echo 11.ok
806 endif
807 if ! ! ! $dietcurd =~ '.+yoho$'
808 echo 12.ok
809 else
810 echo 12.err
811 endif
812 if ! [ ! ! [ ! [ $dietcurd !~ '.+yoho$' ] ] ]
813 echo 13.ok
814 else
815 echo 13.err
816 endif
817 set diet=abc curd='^abc$'
818 if $diet =~ $curd
819 echo 14.ok
820 else
821 echo 14.err
822 endif
823 set diet=abc curd='^abcd$'
824 if $diet !~ $curd
825 echo 15.ok
826 else
827 echo 15.err
828 endif
829 __EOT
830 cksum_test behave:if-regex "${MBOX}" '439960016 81'
834 __behave_smime() { # FIXME add test/ dir, unroll tests therein, regular enable!
835 printf 'behave:s/mime: .. generating test key and certificate ..\n'
836 ${cat} <<-_EOT > ./t.conf
837 [ req ]
838 default_bits = 1024
839 default_keyfile = keyfile.pem
840 distinguished_name = req_distinguished_name
841 attributes = req_attributes
842 prompt = no
843 output_password =
845 [ req_distinguished_name ]
846 C = GB
847 ST = Over the
848 L = rainbow
849 O = S-nail
850 OU = S-nail.smime
851 CN = S-nail.test
852 emailAddress = test@localhost
854 [ req_attributes ]
855 challengePassword =
856 _EOT
857 openssl req -x509 -nodes -days 3650 -config ./t.conf \
858 -newkey rsa:1024 -keyout ./tkey.pem -out ./tcert.pem >/dev/null 2>&1
859 ${rm} -f ./t.conf
860 ${cat} ./tkey.pem ./tcert.pem > ./tpair.pem
862 printf "behave:s/mime:sign/verify: "
863 echo bla |
864 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
865 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
866 -Ssmime-sign -Sfrom=test@localhost \
867 -s 'S/MIME test' ./VERIFY
868 # TODO CHECK
869 printf 'verify\nx\n' |
870 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
871 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
872 -Ssmime-sign -Sfrom=test@localhost \
873 -Sbatch-exit-on-error -R \
874 -f ./VERIFY >/dev/null 2>&1
875 if [ $? -eq 0 ]; then
876 printf 'ok\n'
877 else
878 ESTAT=1
879 printf 'error: verification failed\n'
880 ${rm} -f ./VERIFY ./tkey.pem ./tcert.pem ./tpair.pem
881 return
883 ${rm} -rf ./VERIFY
885 # (signing +) encryption / decryption
886 ${cat} <<-_EOT > ./tsendmail.sh
887 #!/bin/sh -
888 (echo 'From S-Postman Thu May 10 20:40:54 2012' && ${cat}) > ./ENCRYPT
889 _EOT
890 chmod 0755 ./tsendmail.sh
892 printf "behave:s/mime:encrypt+sign/decrypt+verify: "
893 echo bla |
894 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
895 -Ssmime-force-encryption \
896 -Ssmime-encrypt-recei@ver.com=./tpair.pem \
897 -Ssendmail=./tsendmail.sh \
898 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
899 -Ssmime-sign -Sfrom=test@localhost \
900 -s 'S/MIME test' recei@ver.com
901 # TODO CHECK
902 printf 'decrypt ./DECRYPT\nfi ./DECRYPT\nverify\nx\n' |
903 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
904 -Ssmime-force-encryption \
905 -Ssmime-encrypt-recei@ver.com=./tpair.pem \
906 -Ssendmail=./tsendmail.sh \
907 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
908 -Ssmime-sign -Sfrom=test@localhost \
909 -Sbatch-exit-on-error -R \
910 -f ./ENCRYPT >/dev/null 2>&1
911 if [ $? -eq 0 ]; then
912 printf 'ok\n'
913 else
914 ESTAT=1
915 printf 'error: decryption+verification failed\n'
917 ${sed} -e '/^X-Decoding-Date/d' \
918 -e \
919 '/^Content-Disposition: attachment; filename="smime.p7s"/,/^-- /d' \
920 < ./DECRYPT > ./ENCRYPT
921 cksum_test ".. checksum of decrypted content" "./ENCRYPT" '82649489 454'
923 ${rm} -f ./DECRYPT
924 printf "behave:s/mime:encrypt/decrypt: "
925 echo bla |
926 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
927 -Ssmime-force-encryption \
928 -Ssmime-encrypt-recei@ver.com=./tpair.pem \
929 -Ssendmail=./tsendmail.sh \
930 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
931 -Sfrom=test@localhost \
932 -s 'S/MIME test' recei@ver.com
933 printf 'decrypt ./DECRYPT\nx\n' |
934 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
935 -Ssmime-force-encryption \
936 -Ssmime-encrypt-recei@ver.com=./tpair.pem \
937 -Ssendmail=./tsendmail.sh \
938 -Ssmime-ca-file=./tcert.pem -Ssmime-sign-cert=./tpair.pem \
939 -Sfrom=test@localhost \
940 -Sbatch-exit-on-error -R \
941 -f ./ENCRYPT >/dev/null 2>&1
942 if [ $? -eq 0 ]; then
943 printf 'ok\n'
944 else
945 ESTAT=1
946 printf 'error: decryption failed\n'
947 # FALLTHRU
949 ${sed} -e '/^X-Decoding-Date/d' \
950 < ./DECRYPT > ./ENCRYPT
951 cksum_test ".. checksum of decrypted content" "./ENCRYPT" '2694938815 239'
953 ${rm} -f ./tsendmail.sh ./ENCRYPT ./DECRYPT \
954 ./tkey.pem ./tcert.pem ./tpair.pem
957 # t_content()
958 # Some basic tests regarding correct sending of mails, via STDIN / -t / -q,
959 # including basic MIME Content-Transfer-Encoding correctness (quoted-printable)
960 # Note we unfortunately need to place some statements without proper
961 # indentation because of continuation problems
962 t_content() {
963 ${rm} -f "${BODY}" "${MBOX}"
965 # MIME encoding (QP) stress message body
966 printf \
967 'Ich bin eine DÖS-Datäi mit sehr langen Zeilen und auch '\
968 'sonst bin ich ganz schön am Schleudern, da kannste denke '\
969 "wasde willst, gelle, gelle, gelle, gelle, gelle.\r\n"\
970 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst \r\n"\
971 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 1\r\n"\
972 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 12\r\n"\
973 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 123\r\n"\
974 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 1234\r\n"\
975 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 12345\r\n"\
976 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 123456\r\n"\
977 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 1234567\r\n"\
978 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 12345678\r\n"\
979 "Ich bin eine DÖS-Datäi mit langen Zeilen und auch sonst 123456789\r\n"\
980 "Unn ausserdem habe ich trailing SP/HT/SP/HT whitespace \r\n"\
981 "Unn ausserdem habe ich trailing HT/SP/HT/SP whitespace \r\n"\
982 "auf den zeilen vorher.\r\n"\
983 "From am Zeilenbeginn und From der Mitte gibt es auch.\r\n"\
984 ".\r\n"\
985 "Die letzte Zeile war nur ein Punkt.\r\n"\
986 "..\r\n"\
987 "Das waren deren zwei.\r\n"\
988 " \r\n"\
989 "Die letzte Zeile war ein Leerschritt.\n"\
990 "=VIER = EQUAL SIGNS=ON A LINE=\r\n"\
991 "Prösterchen.\r\n"\
992 ".\n"\
993 "Die letzte Zeile war nur ein Punkt, mit Unix Zeilenende.\n"\
994 "..\n"\
995 "Das waren deren zwei. ditto.\n"\
996 "Prösterchen.\n"\
997 "Unn ausseerdem habe ich trailing SP/HT/SP/HT whitespace \n"\
998 "Unn ausseerdem habe ich trailing HT/SP/HT/SP whitespace \n"\
999 "auf den zeilen vorher.\n"\
1000 "ditto.\n"\
1001 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.\n"\
1002 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.1"\
1003 "\n"\
1004 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.12"\
1005 "\n"\
1006 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.12"\
1007 "3\n"\
1008 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.12"\
1009 "34\n"\
1010 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.12"\
1011 "345\n"\
1012 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende.12"\
1013 "3456\n"\
1014 "QP am Zeilenende über soft-nl hinweg\n"\
1015 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende."\
1016 "ö123\n"\
1017 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende."\
1018 "1ö23\n"\
1019 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende."\
1020 "12ö3\n"\
1021 "Ich bin eine ziemlich lange, steile, scharfe Zeile mit Unix Zeilenende."\
1022 "123ö\n"\
1023 "=VIER = EQUAL SIGNS=ON A LINE=\n"\
1024 " \n"\
1025 "Die letzte Zeile war ein Leerschritt.\n"\
1026 ' '\
1027 > "${BODY}"
1029 # MIME encoding (QP) stress message subject
1030 SUB="Äbrä Kä?dä=brö Fü?di=bus? \
1031 adadaddsssssssddddddddddddddddddddd\
1032 ddddddddddddddddddddddddddddddddddd\
1033 ddddddddddddddddddddddddddddddddddd\
1034 dddddddddddddddddddd Hallelulja? Od\
1035 er?? eeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
1036 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\
1037 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee f\
1038 fffffffffffffffffffffffffffffffffff\
1039 fffffffffffffffffffff ggggggggggggg\
1040 ggggggggggggggggggggggggggggggggggg\
1041 ggggggggggggggggggggggggggggggggggg\
1042 ggggggggggggggggggggggggggggggggggg\
1043 gggggggggggggggg"
1045 # Three tests for MIME encodign and (a bit) content classification.
1046 # At the same time testing -q FILE, < FILE and -t FILE
1048 # TODO Note: because of our weird putline() handling in <-> collect.c
1049 ${rm} -f "${MBOX}"
1050 < "${BODY}" MAILRC=/dev/null \
1051 "${SNAIL}" -nSstealthmua -Sexpandaddr -a "${BODY}" -s "${SUB}" "${MBOX}"
1052 cksum_test content:001-0 "${MBOX}" '3310338268 6375'
1054 ${rm} -f "${MBOX}"
1055 < "${BODY}" MAILRC=/dev/null \
1056 "${SNAIL}" ${ARGS} -Snodot -a "${BODY}" -s "${SUB}" "${MBOX}"
1057 cksum_test content:001 "${MBOX}" '62505451 6374'
1059 ${rm} -f "${MBOX}"
1060 < /dev/null MAILRC=/dev/null \
1061 "${SNAIL}" ${ARGS} -a "${BODY}" -s "${SUB}" \
1062 -q "${BODY}" "${MBOX}"
1063 cksum_test content:002 "${MBOX}" '3310338268 6375'
1065 ${rm} -f "${MBOX}"
1066 ( echo "To: ${MBOX}" && echo "Subject: ${SUB}" && echo &&
1067 ${cat} "${BODY}"
1068 ) | MAILRC=/dev/null "${SNAIL}" ${ARGS} -Snodot -a "${BODY}" -t
1069 cksum_test content:003 "${MBOX}" '62505451 6374'
1071 # Test for [260e19d] (Juergen Daubert)
1072 ${rm} -f "${MBOX}"
1073 echo body | MAILRC=/dev/null "${SNAIL}" ${ARGS} "${MBOX}"
1074 cksum_test content:004 "${MBOX}" '3729232114 11'
1076 # Sending of multiple mails in a single invocation
1077 ${rm} -f "${MBOX}"
1078 ( printf "m ${MBOX}\n~s subject1\nE-Mail Körper 1\n~.\n" &&
1079 printf "m ${MBOX}\n~s subject2\nEmail body 2\n~.\n" &&
1080 echo x
1081 ) | MAILRC=/dev/null "${SNAIL}" ${ARGS}
1082 cksum_test content:005 "${MBOX}" '773028641 184'
1084 ## $BODY CHANGED
1086 # "Test for" [d6f316a] (Gavin Troy)
1087 ${rm} -f "${MBOX}"
1088 printf "m ${MBOX}\n~s subject1\nEmail body\n~.\nfi ${MBOX}\np\nx\n" |
1089 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1090 -Spipe-text/plain="${cat}" > "${BODY}"
1091 ${sed} -e 1d < "${BODY}" > "${MBOX}"
1092 cksum_test content:006 "${MBOX}" '654030565 45'
1094 # "Test for" [c299c45] (Peter Hofmann) TODO shouldn't end up QP-encoded?
1095 # TODO Note: because of our weird putline() handling in <-> collect.c
1096 ${rm} -f "${MBOX}"
1097 LC_ALL=C ${awk} 'BEGIN{
1098 for(i = 0; i < 10000; ++i)
1099 printf "\xC3\xBC"
1100 #printf "\xF0\x90\x87\x90"
1101 }' |
1102 MAILRC=/dev/null "${SNAIL}" -nSstealthmua -Sexpandaddr \
1103 -s TestSubject "${MBOX}"
1104 cksum_test content:007-0 "${MBOX}" '2747333583 61729'
1106 ${rm} -f "${MBOX}"
1107 LC_ALL=C ${awk} 'BEGIN{
1108 for(i = 0; i < 10000; ++i)
1109 printf "\xC3\xBC"
1110 #printf "\xF0\x90\x87\x90"
1111 }' |
1112 MAILRC=/dev/null "${SNAIL}" ${ARGS} -s TestSubject "${MBOX}"
1113 cksum_test content:007 "${MBOX}" '3343002941 61728'
1115 ## Test some more corner cases for header bodies (as good as we can today) ##
1118 ${rm} -f "${MBOX}"
1119 echo |
1120 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1121 -s 'a̲b̲c̲d̲e̲f̲h̲i̲k̲l̲m̲n̲o̲r̲s̲t̲u̲v̲w̲x̲z̲a̲b̲c̲d̲e̲f̲h̲i̲k̲l̲m̲n̲o̲r̲s̲t̲u̲v̲w̲x̲z̲' \
1122 "${MBOX}"
1123 cksum_test content:008 "${MBOX}" '3872015771 288'
1125 # Single word (overlong line split -- bad standard! Requires injection of
1126 # artificial data!! Bad can be prevented by using RFC 2047 encoding)
1127 ${rm} -f "${MBOX}"
1128 i=`LC_ALL=C ${awk} 'BEGIN{for(i=0; i<92; ++i) printf "0123456789_"}'`
1129 echo | MAILRC=/dev/null "${SNAIL}" ${ARGS} -s "${i}" "${MBOX}"
1130 cksum_test content:009 "${MBOX}" '2048460448 1631'
1132 # Combination of encoded words, space and tabs of varying sort
1133 ${rm} -f "${MBOX}"
1134 echo | MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1135 -s "1Abrä Kaspas1 2Abra Katä b_kaspas2 \
1136 3Abrä Kaspas3 4Abrä Kaspas4 5Abrä Kaspas5 \
1137 6Abra Kaspas6 7Abrä Kaspas7 8Abra Kaspas8 \
1138 9Abra Kaspastäb4-3 10Abra Kaspas1 _ 11Abra Katäb1 \
1139 12Abra Kadabrä1 After Tab after Täb this is NUTS" \
1140 "${MBOX}"
1141 cksum_test content:010 "${MBOX}" '1272213842 504'
1143 # Overlong multibyte sequence that must be forcefully split
1144 # todo This works even before v15.0, but only by accident
1145 ${rm} -f "${MBOX}"
1146 echo | MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1147 -s "✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄\
1148 ✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄\
1149 ✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄✄" \
1150 "${MBOX}"
1151 cksum_test content:011 "${MBOX}" '2972351879 572'
1153 # Trailing WS
1154 ${rm} -f "${MBOX}"
1155 echo |
1156 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1157 -s "1-1 B2 B3 B4 B5 B6 B\
1158 1-2 B2 B3 B4 B5 B6 B\
1159 1-3 B2 B3 B4 B5 B6 B\
1160 1-4 B2 B3 B4 B5 B6 B\
1161 1-5 B2 B3 B4 B5 B6 B\
1162 1-6 B2 B3 B4 B5 B6 " \
1163 "${MBOX}"
1164 cksum_test content:012 "${MBOX}" '2467265470 210'
1166 # Leading and trailing WS
1167 ${rm} -f "${MBOX}"
1168 echo |
1169 MAILRC=/dev/null "${SNAIL}" ${ARGS} \
1170 -s " 2-1 B2 B3 B4 B5 B6 B\
1171 1-2 B2 B3 B4 B5 B6 B\
1172 1-3 B2 B3 B4 B5 B6 B\
1173 1-4 B2 B3 B4 B5 B6 " \
1174 "${MBOX}"
1175 cksum_test content:013 "${MBOX}" '4119922611 149'
1177 # Quick'n dirty RFC 2231 test; i had more when implementing it, but until we
1178 # have a (better) test framework materialize a quick shot
1179 ${rm} -f "${MBOX}"
1180 : > "ma'ger.txt"
1181 : > "mä'ger.txt"
1182 : > 'diet\ is \curd.txt'
1183 : > diet \"is\" curd.txt
1184 : > höde-tröge.txt
1185 : > höde__tröge__müde__dätte__hätte__vülle__gülle__äse__äße__säuerliche__kräuter__österliche__grüße__mäh.txt
1186 : > höde__tröge__müde__dätte__hätte__vuelle__guelle__aese__aesse__sauerliche__kräuter__österliche__grüße__mäh.txt
1187 : > hööööööööööööööööö_nöööööööööööööööööööööö_düüüüüüüüüüüüüüüüüüü_bäääääääääääääääääääääääh.txt
1188 : > ✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆.txt
1189 echo bla |
1190 MAILRC=/dev/null "${SNAIL}" ${ARGS} -Snodot \
1191 -a "ma'ger.txt" -a "mä'ger.txt" \
1192 -a 'diet\\\ is\ \\curd.txt' -a diet \"is\" curd.txt \
1193 -a höde-tröge.txt \
1194 -a höde__tröge__müde__dätte__hätte__vülle__gülle__äse__äße__säuerliche__kräuter__österliche__grüße__mäh.txt \
1195 -a höde__tröge__müde__dätte__hätte__vuelle__guelle__aese__aesse__sauerliche__kräuter__österliche__grüße__mäh.txt \
1196 -a hööööööööööööööööö_nöööööööööööööööööööööö_düüüüüüüüüüüüüüüüüüü_bäääääääääääääääääääääääh.txt \
1197 -a ✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆.txt \
1198 "${MBOX}"
1199 ${rm} -f "ma'ger.txt" "mä'ger.txt" 'diet\ is \curd.txt' \
1200 diet \"is\" curd.txt höde-tröge.txt \
1201 höde__tröge__müde__dätte__hätte__vülle__gülle__äse__äße__säuerliche__kräuter__österliche__grüße__mäh.txt \
1202 höde__tröge__müde__dätte__hätte__vuelle__guelle__aese__aesse__sauerliche__kräuter__österliche__grüße__mäh.txt \
1203 hööööööööööööööööö_nöööööööööööööööööööööö_düüüüüüüüüüüüüüüüüüü_bäääääääääääääääääääääääh.txt \
1204 ✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆✆.txt
1205 cksum_test content:14 "${MBOX}" '1106643854 2453'
1206 # `resend' test
1207 printf "Resend ${BODY}\nx\n" |
1208 MAILRC=/dev/null "${SNAIL}" ${ARGS} -f "${MBOX}"
1209 cksum_test content:14-2 "${MBOX}" '1106643854 2453'
1211 ${rm} -f "${BODY}" "${MBOX}"
1214 t_all() {
1215 if have_feat DEVEL; then
1216 ARGS="${ARGS} -Smemdebug"
1217 export ARGS
1219 t_behave
1220 t_content
1223 if [ -z "${CHECK_ONLY}" ]; then
1224 cc_all_configs
1225 else
1226 t_all
1229 [ ${ESTAT} -eq 0 ] && echo Ok || echo >&2 'Errors occurred'
1231 exit ${ESTAT}
1232 # s-sh-mode