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