]> diplodocus.org Git - nmh/commitdiff
Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/nmh into nmh
authorLyndon Nerenberg <lyndon@orthanc.ca>
Thu, 31 Jan 2013 03:58:16 +0000 (19:58 -0800)
committerLyndon Nerenberg <lyndon@orthanc.ca>
Thu, 31 Jan 2013 03:58:16 +0000 (19:58 -0800)
107 files changed:
.gitignore
Makefile.am
config/config.c
configure.ac
docs/COMPLETION-ZSH
docs/README.developers
docs/contrib/build_nmh
docs/historical/mh-6.8.5/doc/.null [deleted file]
docs/pending-release-notes
h/fmt_compile.h
h/mh.h
h/mhcachesbr.h
h/nmh.h
h/prototypes.h
m4/iconv.m4 [new file with mode: 0644]
man/mh-profile.man
man/mhbuild.man
man/mhn.man
man/msh.man
mts/smtp/smtp.c
sbr/arglist.c [new file with mode: 0644]
sbr/discard.c
sbr/fmt_compile.c
sbr/fmt_rfc2047.c
sbr/fmt_scan.c
sbr/folder_delmsgs.c
sbr/geteditor.c [new file with mode: 0644]
sbr/m_convert.c
sbr/m_getfld.c
sbr/m_msgdef.c [deleted file]
sbr/readconfig.c
sbr/seq_read.c
sbr/smatch.c
test/bad-input/test-header
test/common.sh.in
test/folder/test-sortm
test/format/test-rightjustify [new file with mode: 0755]
test/getcwidth.c [new file with mode: 0644]
test/inc/test-inc-scanout
test/inc/test-pop
test/mhbuild/test-utf8-body
test/mhparam/test-mhparam
test/mhshow/test-msg-buffer-boundaries [new file with mode: 0755]
test/scan/test-scan
test/scan/test-scan-multibyte
test/sequences/test-out-of-range [new file with mode: 0755]
uip/ali.c
uip/anno.c
uip/ap.c
uip/burst.c
uip/comp.c
uip/conflict.c
uip/dist.c
uip/distsbr.c
uip/dp.c
uip/flist.c
uip/fmtdump.c
uip/folder.c
uip/forw.c
uip/forwsbr.c
uip/inc.c
uip/install-mh.c
uip/mark.c
uip/mhbuild.c
uip/mhbuildsbr.c
uip/mhcachesbr.c
uip/mhlist.c
uip/mhlsbr.c
uip/mhn.c
uip/mhoutsbr.c
uip/mhparam.c
uip/mhparse.c
uip/mhpath.c
uip/mhshow.c
uip/mhshowsbr.c
uip/mhstore.c
uip/mhstoresbr.c
uip/mhtest.c
uip/msgchk.c
uip/msh.c
uip/mshcmds.c
uip/new.c
uip/packf.c
uip/pick.c
uip/picksbr.c
uip/post.c
uip/prompter.c
uip/rcvdist.c
uip/rcvpack.c
uip/rcvstore.c
uip/rcvtty.c
uip/refile.c
uip/repl.c
uip/replsbr.c
uip/rmf.c
uip/rmm.c
uip/scan.c
uip/scansbr.c
uip/send.c
uip/sendsbr.c
uip/show.c
uip/slocal.c
uip/sortm.c
uip/viamail.c
uip/whatnowproc.c
uip/whatnowsbr.c
uip/whom.c

index 74b6aad338873f187d7ec81dace7acfb0b7deea0..af04fac2f15bd4b796ac7dee3f728523e509452f 100644 (file)
@@ -24,6 +24,8 @@
 /sbr/dtimep.c
 /cscope.files
 /cscope.out
+/cscope.in.out
+/cscope.po.out
 
 # Removed by distclean:
 .deps/
@@ -101,6 +103,7 @@ a.out.dSYM/
 /test/fakepop
 /test/getfullname
 /test/getfqdn
+/test/getcwidth
 
 # Removed by mostlyclean:
 *.o
index 27ffdfbb14311aface874238f45020d338e31e5e..c1c90d035f7855af52c33e9028de78b651f6bc07 100644 (file)
@@ -52,6 +52,7 @@ TESTS = test/ali/test-ali test/anno/test-anno \
        test/format/test-dp test/format/test-fmtdump \
        test/format/test-localmbox test/format/test-myname \
        test/format/test-myhost test/format/test-mymbox \
+       test/format/test-rightjustify \
        test/forw/test-forw-digest test/forw/test-forw-format \
        test/inc/test-deb359167 test/inc/test-eom-align \
        test/inc/test-inc-scanout test/inc/test-msgchk \
@@ -61,8 +62,8 @@ TESTS = test/ali/test-ali test/anno/test-anno \
        test/mhlist/test-mhlist test/mhmail/test-mhmail \
        test/mhparam/test-mhparam test/mhpath/test-mhpath \
        test/mhshow/test-cte-binary test/mhshow/test-qp \
-       test/mhshow/test-subpart test/mhstore/test-mhstore \
-       test/new/test-basic \
+       test/mhshow/test-subpart test/mhshow/test-msg-buffer-boundaries \
+       test/mhstore/test-mhstore test/new/test-basic \
        test/pick/test-pick test/pick/test-stderr \
        test/post/test-post-aliases test/post/test-post-basic \
        test/post/test-post-multiple test/post/test-post-bcc \
@@ -76,13 +77,15 @@ TESTS = test/ali/test-ali test/anno/test-anno \
        test/repl/test-multicomp test/repl/test-repl \
        test/scan/test-scan test/scan/test-scan-multibyte \
        test/sequences/test-flist test/sequences/test-mark \
+       test/sequences/test-out-of-range \
        test/slocal/test-slocal \
        test/whatnow/test-attach-detach test/whatnow/test-cd \
        test/whatnow/test-ls test/whom/test-whom \
        test/cleanup ## The "cleanup" test should always be last.
 
 check_SCRIPTS = test/common.sh
-check_PROGRAMS = test/getfullname test/getfqdn test/fakepop test/fakesmtp
+check_PROGRAMS = test/getfullname test/getfqdn test/fakepop test/fakesmtp \
+                test/getcwidth
 DISTCHECK_CONFIGURE_FLAGS = DISABLE_SETGID_MAIL=1
 
 ##
@@ -97,7 +100,7 @@ clean-local:
 ##
 ## Stuff that should be cleaned via "make maintainer-clean"
 ##
-MAINTAINERCLEANFILES = cscope.files cscope.out
+MAINTAINERCLEANFILES = cscope.files cscope.out cscope.in.out cscope.po.out
 
 ##
 ## And our own superclean, to get everything left by maintainer-clean.
@@ -210,6 +213,27 @@ man_MANS = man/ali.1 man/anno.1 man/ap.8 man/burst.1 man/comp.1 \
           man/sendfiles.1 man/show.1 man/slocal.1 man/sortm.1 man/unseen.1 \
           man/whatnow.1 man/whom.1
 
+##
+## Sources for our man pages
+##
+man_SRCS = man/ali.man man/anno.man man/ap.man man/burst.man man/comp.man \
+          man/conflict.man man/dist.man man/dp.man man/flist.man \
+          man/flists.man man/fmtdump.man man/fnext.man man/folder.man \
+          man/folders.man man/forw.man man/fprev.man man/inc.man \
+          man/install-mh.man man/mark.man man/mh-alias.man \
+          man/mh-chart-gen.sh man/mh-draft.man man/mh-format.man \
+          man/mh-mail.man man/mh-profile.man man/mh_profile.man \
+          man/mh-sequence.man man/mh-tailor.man man/mhbuild.man man/mhl.man \
+          man/mhlist.man man/mhmail.man man/mhn.man man/mhparam.man \
+          man/mhpath.man man/mhshow.man man/mhstore.man man/msgchk.man \
+          man/msh.man man/mts.conf.man man/new.man man/next.man man/nmh.man \
+          man/packf.man man/pick.man man/post.man man/prev.man \
+          man/prompter.man man/rcvdist.man man/rcvpack.man \
+          man/rcvstore.man man/rcvtty.man man/refile.man man/repl.man \
+          man/rmf.man man/rmm.man man/scan.man man/send.man \
+          man/sendfiles.man man/show.man man/slocal.man man/sortm.man \
+          man/unseen.man man/whatnow.man man/whom.man
+
 ##
 ## Files we need to include in the distribution which aren't found by
 ## Automake using the automatic rules
@@ -218,28 +242,11 @@ EXTRA_DIST = config/version.sh sbr/sigmsg.awk etc/mts.conf.in \
             etc/mhn.defaults.sh etc/sendfiles $(MHNSEARCHPROG) DATE MACHINES \
             docs/ChangeLog_MH-3_to_MH-6.6 \
             docs/ChangeLog_MH-6.7.0_to_MH-6.8.4.html \
-            man/ali.man man/anno.man man/ap.man man/burst.man man/comp.man \
-            man/conflict.man man/dist.man man/dp.man man/flist.man \
-            man/flists.man man/fmtdump.man man/fnext.man man/folder.man \
-            man/folders.man man/forw.man man/fprev.man man/inc.man \
-            man/install-mh.man man/mark.man man/mh-alias.man \
-            man/mh-chart-gen.sh man/mh-draft.man man/mh-format.man \
-            man/mh-mail.man man/mh-profile.man man/mh_profile.man \
-            man/mh-sequence.man man/mh-tailor.man man/mhbuild.man man/mhl.man \
-            man/mhlist.man man/mhmail.man man/mhn.man man/mhparam.man \
-            man/mhpath.man man/mhshow.man man/mhstore.man man/msgchk.man \
-            man/msh.man man/mts.conf.man man/new.man man/next.man man/nmh.man \
-            man/packf.man man/pick.man man/post.man man/prev.man \
-            man/prompter.man man/rcvdist.man man/rcvpack.man \
-            man/rcvstore.man man/rcvtty.man man/refile.man man/repl.man \
-            man/rmf.man man/rmm.man man/scan.man man/send.man \
-            man/sendfiles.man man/show.man man/slocal.man man/sortm.man \
-            man/unseen.man man/whatnow.man man/whom.man \
             test/README test/fakesendmail $(TESTS) test/inc/deb359167.mbox \
             test/inc/fromline.txt test/inc/msgheader.txt test/inc/filler.txt \
             test/inc/md5sums test/mhmail/attachment.txt \
             test/post/test-post-common.sh uip/mhmail \
-            SPECS/nmh.spec SPECS/build-nmh-cygwin
+            SPECS/nmh.spec SPECS/build-nmh-cygwin $(man_SRCS)
 
 ##
 ## These are all of the definitions for each of the programs listed above.
@@ -372,7 +379,7 @@ uip_mhtest_SOURCES = uip/mhtest.c uip/mhparse.c uip/mhcachesbr.c \
 uip_mhtest_LDADD = $(LDADD) $(TERMLIB)
 
 uip_post_SOURCES = uip/post.c uip/aliasbr.c
-uip_post_LDADD = mts/libmts.a $(LDADD) $(SASLLIB)
+uip_post_LDADD = mts/libmts.a $(LDADD) $(SASLLIB) $(TLSLIB)
 
 uip_rcvdist_SOURCES = uip/rcvdist.c uip/distsbr.c
 uip_rcvdist_LDADD = $(LDADD) $(ICONVLIB)
@@ -467,7 +474,8 @@ uninstall-hook:
 ##
 ## Our rules to build our internal libraries (libmh.a, libmts.a)
 ##
-sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/base64.c \
+sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/arglist.c \
+                     sbr/base64.c \
                      sbr/brkstring.c sbr/check_charset.c sbr/client.c \
                      sbr/closefds.c sbr/concat.c sbr/context_del.c \
                      sbr/context_find.c sbr/context_foil.c sbr/context_read.c \
@@ -480,7 +488,8 @@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/base64.c \
                      sbr/folder_free.c sbr/folder_pack.c \
                      sbr/folder_read.c sbr/folder_realloc.c sbr/gans.c \
                      sbr/getans.c sbr/getanswer.c sbr/getarguments.c \
-                     sbr/getcpy.c sbr/getfolder.c sbr/getpass.c \
+                     sbr/getcpy.c sbr/geteditor.c sbr/getfolder.c \
+                     sbr/getpass.c \
                      sbr/fmt_addr.c sbr/fmt_compile.c sbr/fmt_new.c \
                      sbr/fmt_rfc2047.c sbr/fmt_scan.c sbr/lock_file.c \
                      sbr/m_atoi.c sbr/m_backup.c sbr/m_convert.c \
@@ -499,16 +508,14 @@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/base64.c \
                      sbr/showfile.c sbr/signals.c sbr/smatch.c \
                      sbr/snprintb.c sbr/ssequal.c sbr/strcasecmp.c \
                      sbr/strindex.c sbr/trimcpy.c sbr/uprf.c sbr/vfgets.c \
-                     sbr/fmt_def.c sbr/m_msgdef.c sbr/mf.c sbr/utils.c \
+                     sbr/fmt_def.c sbr/mf.c sbr/utils.c \
                      sbr/m_mktemp.c sbr/getansreadline.c config/config.c \
                      config/version.c
 
 sbr_libmh_a_CPPFLAGS = -I./sbr -DNMHETCDIR='"$(sysconfdir)"' \
                -DMAILSPOOL='"$(mailspool)"' \
                -DSENDMAILPATH='"$(sendmailpath)"' -DNMHBINDIR='"$(bindir)"' \
-               -DNMHLIBDIR='"$(libdir)"' \
-               -DDEFAULT_EDITOR='"$(editorpath)"' \
-               -DDEFAULT_PAGER='"$(pagerpath)"'
+               -DNMHLIBDIR='"$(libdir)"'
 
 sbr_libdtimep_a_SOURCES = sbr/dtimep.l
 sbr_libdtimep_a_CFLAGS = $(sbr_libmh_a_CPPFLAGS) \
@@ -537,8 +544,6 @@ man/man.sed: Makefile
        @echo 's,%mandir%,$(mandir),g' >> $@
        @echo 's,%mailspool%,$(mailspool),g' >> $@
        @echo 's,%sendmailpath%,$(sendmailpath),g' >> $@
-       @echo 's,%default_editor%,$(editorpath),g' >> $@
-       @echo 's,%default_pager%,$(pagerpath),g' >> $@
        @echo 's,%manext1%,$(manext1),g' >> $@
        @echo 's,%manext5%,$(manext5),g' >> $@
        @echo 's,%manext7%,$(manext7),g' >> $@
@@ -550,7 +555,7 @@ man/man.sed: Makefile
        @echo '/%mhl_reply%/r $(top_srcdir)/etc/mhl.reply' >> $@
        @echo ' s,%mhl_reply%,,g' >> $@
 
-man/mh-chart.man:
+man/mh-chart.man: $(man_SRCS)
        $(srcdir)/man/mh-chart-gen.sh > $@
 
 .man.$(manext1):
@@ -594,14 +599,6 @@ rpm: dist
          -ba SPECS/nmh.spec
 .PHONY: rpm
 
-##
-## A target to build information needed by cscope
-##
-cscope:
-       echo "-I $(srcdir)/h -I $(srcdir)/sbr -I $(srcdir)/uip -I $(srcdir)/mts/smtp" > cscope.files
-       find $(srcdir) \( -name docs -prune \) -o \( -name \*.c -o -name \*.l \) -print | grep -v dtimep.c >> cscope.files
-.PHONY: cscope
-
 
 ##
 ## Use GNU gcov to find the coverage of the test suite.
index 72da2cd97c6ab1f9e222d84b7e97761545d8ae80..02265c0a6befb8457041cec19a3f4f7d93162cef 100644 (file)
@@ -83,9 +83,9 @@ try_it:
  */
 
 struct swit anoyes[] = {
-    { "no", 0 },
-    { "yes", 0 },
-    { NULL, 0 }
+    { "no", 0, 0 },
+    { "yes", 0, 1 },
+    { NULL, 0, 0 }
 };
 
 /* 
@@ -318,14 +318,6 @@ char *whatnowproc = nmhbindir (/whatnow);
 
 char *whomproc = nmhbindir (/whom);
 
-/*
- * This is the editor invoked by the various message
- * composition programs.  It SHOULD be a full screen
- * editor, such as vi or emacs, but any editor will work.
- */
-
-char *defaulteditor = DEFAULT_EDITOR;
-
 /* 
  * This is the global nmh alias file.  It is somewhat obsolete, since
  * global aliases should be handled by the Mail Transport Agent (MTA).
index c51e65bc9131273a5dbdbe336066e1f0353b6666..1aea372a9822261d18bac28c13459fefb0cc3093 100644 (file)
@@ -3,12 +3,12 @@ dnl configure.ac -- autoconf template for nmh
 dnl
 
 dnl Move this up a bit
-AC_PREREQ([2.61])
+AC_PREREQ([2.68])
 
 AC_INIT([nmh], m4_normalize(m4_include([VERSION])), [nmh-workers@nongnu.org])
 AC_CONFIG_SRCDIR([h/nmh.h])
 AC_CONFIG_HEADER([config.h])
-AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
+AM_INIT_AUTOMAKE([-Wall color-tests foreign serial-tests subdir-objects 1.12])
 
 AC_CANONICAL_HOST
 
@@ -27,8 +27,6 @@ dnl --------------------------
 dnl Do you want to debug nmh?
 AC_ARG_ENABLE([debug],
   AS_HELP_STRING([--enable-debug],[enable nmh code debugging]))
-dnl The old redundant --enable-nmh-debug is deprecated and undocumented.
-AS_IF([test x"$enable_nmh_debug" = x"yes"], [enable_debug=yes])
 
 dnl Do you want to disable use of locale functions
 AH_TEMPLATE([LOCALE],
@@ -56,12 +54,6 @@ AS_IF([test x"$with_tls" != x -a x"$with_tls" != x"no"],[
       AC_DEFINE([TLS_SUPPORT], [1], [Support TLS for session encryption.])dnl
       tls_support=yes],[tls_support=no])
 
-dnl What should be the default editor?
-AC_ARG_WITH([editor],
-  AS_HELP_STRING([--with-editor=EDITOR],[specify the default editor]))
-
-AS_IF([test -n "$with_editor"], [editorpath="$with_editor"])
-
 dnl Set the backup prefix
 AC_ARG_WITH([hash-backup],
   AS_HELP_STRING([--with-hash-backup],[use # as the backup prefix (default: ,)]))
@@ -77,26 +69,24 @@ AS_CASE(["$host_os"],
   [freebsd*|openbsd*|darwin*], [default_locktype="flock"; default_locking=FLOCK_LOCKING],
   [default_locktype="dot"; default_locking=DOT_LOCKING])
 
-AC_ARG_WITH(locking,
+AC_ARG_WITH([locking],
   AS_HELP_STRING([--with-locking=@<:@dot|fcntl|flock|lockf@:>@],
   [specify the file locking method]))
 
-if test x"$with_locking" = x"dot"; then
-  LOCKTYPE="dot"
-  AC_DEFINE(DOT_LOCKING, 1, [Define to use dot based file locking.])dnl
-elif test x"$with_locking" = x"flock"; then
-  LOCKTYPE="flock"
-  AC_DEFINE(FLOCK_LOCKING, 1, [Define to use flock() based locking.])dnl
-elif test x"$with_locking" = x"lockf"; then
-  LOCKTYPE="lockf"
-  AC_DEFINE(LOCKF_LOCKING, 1, [Define to use lockf() based locking.])dnl
-elif test x"$with_locking" = x"fcntl"; then
-  LOCKTYPE="fcntl"
-  AC_DEFINE(FCNTL_LOCKING, 1, [Define to use fnctl() based locking.])dnl
-else
-  LOCKTYPE="$default_locktype"
-  AC_DEFINE_UNQUOTED($default_locking, 1)dnl
-fi
+AS_IF([test x"$with_locking" = x"dot"],
+    [LOCKTYPE="dot"
+    AC_DEFINE([DOT_LOCKING], [1], [Define to use dot based file locking.])],
+  [test x"$with_locking" = x"flock"],
+    [LOCKTYPE="flock"
+    AC_DEFINE([FLOCK_LOCKING], [1], [Define to use flock() based locking.])],
+  [test x"$with_locking" = x"lockf"],
+    [LOCKTYPE="lockf"
+    AC_DEFINE([LOCKF_LOCKING], [1], [Define to use lockf() based locking.])],
+  [test x"$with_locking" = x"fcntl"],
+    [LOCKTYPE="fcntl"
+    AC_DEFINE([FCNTL_LOCKING], [1], [Define to use fnctl() based locking.])],
+  [LOCKTYPE="$default_locktype"
+  AC_DEFINE_UNQUOTED([$default_locking], [1])])
 
 dnl Should we use a locking directory?
 AC_ARG_ENABLE([lockdir],
@@ -121,25 +111,10 @@ AS_IF([test x"$with_mts" = x"smtp"], [MTS="smtp"],
       [MTS="smtp"])
 AC_SUBST([MTS])dnl
 
-dnl What should be the default pager?
-AC_ARG_WITH([pager],
-  AS_HELP_STRING([--with-pager=PAGER],[specify the default pager]))
-
-AS_IF([test -n "$with_pager"], [pagerpath="$with_pager"])
-
-dnl If a pager is not explicitly specified, then look for one.
-dnl Fall back to `cat', to avoid catastrophic failure of
-dnl `mhshow', et al., if pagerpath is set to `no'.
-if test -z "$pagerpath"; then
-  pathtmp=/usr/bin:/bin:/usr/ucb:/usr/local/bin
-  AC_PATH_PROGS([pagerpath], [more less most cat], [no], [$pathtmp])
-fi
-AC_SUBST(pagerpath)dnl
-
 dnl What should be the default mail server(s)?
-AC_ARG_WITH(smtpservers,
-  AS_HELP_STRING([--with-smtpservers='SMTPSERVER1@<:@ SMTPSERVER2...@:>@'],
-  [specify the default SMTP server(s) @<:@localhost@:>@]))
+AC_ARG_WITH([smtpservers],
+  [AS_HELP_STRING([--with-smtpservers='SMTPSERVER1@<:@ SMTPSERVER2...@:>@'],
+  [specify the default SMTP server(s) @<:@localhost@:>@])])
 AS_IF([test -n "$with_smtpservers"], [smtpservers="$with_smtpservers"],
       [smtpservers="localhost"])
 AC_SUBST([smtpservers])dnl
@@ -174,7 +149,7 @@ if test "$nmh_cv_has_unusedmacros" = 'yes'; then
                       ||  CPPFLAGS="$CPPFLAGS -Wunused-macros"
   DISABLE_UNUSED_MACROS_WARNING=-Wno-unused-macros
 fi
-AC_SUBST(DISABLE_UNUSED_MACROS_WARNING)dnl
+AC_SUBST([DISABLE_UNUSED_MACROS_WARNING])dnl
 
 AC_CACHE_CHECK([whether compiler supports -Wno-sign-compare],
   [nmh_cv_has_nosigncompare],
@@ -187,7 +162,7 @@ AC_CACHE_CHECK([whether compiler supports -Wno-sign-compare],
 if test "$nmh_cv_has_nosigncompare" = 'yes'; then
   DISABLE_SIGN_COMPARE_WARNING=-Wno-sign-compare
 fi
-AC_SUBST(DISABLE_SIGN_COMPARE_WARNING)dnl
+AC_SUBST([DISABLE_SIGN_COMPARE_WARNING])dnl
 
 AC_CACHE_CHECK([whether compiler supports -Wextra], [nmh_cv_has_wextra],
 [nmh_saved_cflags="$CFLAGS"
@@ -274,8 +249,6 @@ if test -n "$auto_cflags"; then
   fi
 fi
 
-AC_C_CONST              dnl Does compiler support `const'.
-
 dnl ------------------
 dnl CHECK FOR PROGRAMS
 dnl ------------------
@@ -284,7 +257,7 @@ AC_PROG_INSTALL             dnl Check for BSD compatible `install'
 AC_PROG_RANLIB         dnl Check for `ranlib'
 AC_PROG_AWK             dnl Check for mawk,gawk,nawk, then awk
 AC_PROG_SED            dnl Check for Posix-compliant sed
-AC_PROG_LEX             dnl Check for lex/flex
+AM_PROG_LEX             dnl Check for lex/flex
 
 AM_PROG_AR
 
@@ -305,20 +278,16 @@ AC_SUBST([MD5FMT])
 dnl ----------------------------------------------
 dnl check for lclint, and lint if it doesn't exist
 dnl ----------------------------------------------
-AC_CHECK_PROG(linttmp1, lclint, lclint, no)dnl
-if test x$ac_cv_prog_linttmp1 != xno ; then
-  LINT=$ac_cv_prog_linttmp1
-  LINTFLAGS="-weak +posixlib -macrovarprefixexclude"
-else
-  AC_CHECK_PROG(linttmp2, lint, lint, no)dnl
-  if test x$ac_cv_prog_linttmp2 != xno ; then
-    LINT=$ac_cv_prog_linttmp2
-    LINTFLAGS=""
-  else
-    LINT="echo 'No lint program found'"
-    LINTFLAGS=""
-  fi
-fi
+AC_CHECK_PROG([linttmp1], [lclint], [lclint], [no])dnl
+AS_IF([test x$ac_cv_prog_linttmp1 != xno],
+  [LINT=$ac_cv_prog_linttmp1
+  LINTFLAGS="-weak +posixlib -macrovarprefixexclude"],
+  [AC_CHECK_PROG([linttmp2], [lint], [lint], [no])dnl
+  AS_IF([test x$ac_cv_prog_linttmp2 != xno],
+    [LINT=$ac_cv_prog_linttmp2
+    LINTFLAGS=""],
+    [LINT="echo 'No lint program found'"
+    LINTFLAGS=""])])
 AC_SUBST([LINT])dnl
 AC_SUBST([LINTFLAGS])dnl
 
@@ -327,33 +296,21 @@ pathtmp=/usr/bin:/bin:/usr/local/bin:/usr/xpg4/bin:/usr/ucb
 AC_PATH_PROG([lspath], [ls], [no], [$pathtmp])
 
 dnl See how we get ls to display the owner and the group
-if test "$lspath" != "no"; then
-  AC_CACHE_CHECK([how to get ls to show us the group ownership of a file],
+AS_IF([test "$lspath" != "no"],
+  [AC_CACHE_CHECK([how to get ls to show us the group ownership of a file],
                 [nmh_cv_ls_grpopt],
-  [if test x"`$lspath -dl / | $AWK '{print $9}'`" = x"/"; then
+  [AS_IF([test x"`$lspath -dl / | $AWK '{print $9}'`" = x"/"],[
     dnl There were 9 parameters, so unless this is a really bizarre, nonstandard
     dnl ls, it would seem -l gave us both the user and group.  On this type of
     dnl ls, -g makes _only_ the group be displayed (and not the user).
-    nmh_cv_ls_grpopt="-l"
-  else
+    nmh_cv_ls_grpopt="-l"],[
     dnl Looks like -l only gave us the user, so we need -g to get the group too.
-    nmh_cv_ls_grpopt="-lg"
-  fi])
-fi
+    nmh_cv_ls_grpopt="-lg"])])])
 
 dnl Look for `sendmail'
 pathtmp=/usr/lib:/usr/sbin:/usr/etc:/usr/ucblib:/usr/bin:/bin
 AC_PATH_PROG([sendmailpath], [sendmail], [/usr/sbin/sendmail], [$pathtmp])
 
-dnl Look for `vi'
-pathtmp=/usr/bin:/bin:/usr/ucb:/usr/local/bin
-AC_PATH_PROG([vipath], [vi], [/bin/vi], [$pathtmp])
-
-dnl If editor is not specified yet,
-dnl then use `vi' as the default.
-AS_IF([test -z "$editorpath"], [editorpath="$vipath"])
-AC_SUBST([editorpath])dnl
-
 dnl Cygwin FAT filesystems do not support hard links.  So default to
 dnl cp instead, even if running on an NTFS or other filesystem.
 AS_CASE(["$host_os"],
@@ -406,9 +363,8 @@ fi
 
 dnl Provide a way for distcheck to disable setgid_mail via
 dnl DISTCHECK_CONFIGURE_FLAGS.
-if test x"$DISABLE_SETGID_MAIL" != x -a x"$DISABLE_SETGID_MAIL" != x0; then
-  nmh_cv_dotlockfile_setgid=yes
-fi
+AS_IF([test x"$DISABLE_SETGID_MAIL" != x -a x"$DISABLE_SETGID_MAIL" != x0],
+  [nmh_cv_dotlockfile_setgid=yes])
 
 dnl If mailspool is not world-writable and dotlockfile is not setgid,
 dnl we need to #define MAILGROUP to 1 and make inc setgid.
@@ -418,7 +374,7 @@ if test x"$LOCKTYPE" = x"dot" -a x"$nmh_cv_mailspool_world_writable" = x"no" -a
     [Define to 1 if you need to make `inc' set-group-id because your mail spool is not world writable. There are no guarantees as to the safety of doing this, but this #define will add some extra security checks.])dnl
   SETGID_MAIL=1
 fi
-AC_SUBST(SETGID_MAIL)dnl
+AC_SUBST([SETGID_MAIL])dnl
 
 dnl Use ls to see which group owns the mail spool directory.
 AC_CACHE_CHECK(what group owns the mail spool, nmh_cv_ls_mail_grp,
@@ -447,20 +403,9 @@ AS_CASE(["$host_os"],
          AS_IF([test -z "$CPPFLAGS"],[CPPFLAGS="-D_GNU_SOURCE"],
                 [CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"])])
 
-AC_HEADER_STDC
 AC_HEADER_TIOCGWINSZ
-AC_CHECK_HEADERS([errno.h fcntl.h crypt.h ncurses/termcap.h termcap.h \
-                  langinfo.h wchar.h wctype.h iconv.h netdb.h \
-                  sys/param.h sys/time.h sys/stream.h])
-
-dnl
-dnl Checks for _IO_write_ptr. A Linuxism used by nmh on linux. We
-dnl really use a whole set of them, but this check should be
-dnl sufficient.
-dnl
-AC_CHECK_HEADER(libio.h, [
-  AC_EGREP_HEADER(_IO_write_ptr, libio.h, [
-    AC_DEFINE(LINUX_STDIO,1,[Use the Linux _IO_*_ptr defines from <libio.h>.]) ]) ])
+AC_CHECK_HEADERS([fcntl.h ncurses/termcap.h termcap.h langinfo.h \
+                  wchar.h wctype.h sys/param.h sys/time.h sys/stream.h])
 
 AC_CHECK_HEADER([sys/ptem.h], AC_DEFINE(WINSIZE_IN_PTEM,1,
   [Define to 1 if `struct winsize' requires <sys/ptem.h>.]),,
@@ -494,8 +439,12 @@ AC_CHECK_FUNC([modf], , AC_CHECK_LIB([m], [modf]))
 dnl Checks for network libraries (nsl, socket)
 NMH_CHECK_NETLIBS
 
+dnl Check for readline support
 NMH_READLINE
 
+dnl Check for iconv
+NMH_CHECK_ICONV
+
 termcap_curses_order="termcap curses ncurses"
 for lib in $termcap_curses_order; do
   AC_CHECK_LIB(${lib}, tgetent, [TERMLIB="-l$lib"; break])
@@ -505,53 +454,6 @@ AS_IF([test "x$TERMLIB" = "x"],
       [AC_MSG_FAILURE([Could not find tgetent in any library.  Is there a curses
 or ncurses library or package that you can install?])])
 
-
-dnl ---------------
-dnl CHECK FOR ICONV
-dnl ---------------
-
-dnl Find iconv. It may be in libiconv and may be iconv() or libiconv()
-if test "x$ac_cv_header_iconv_h" = "xyes"; then
-  AC_CHECK_FUNC(iconv, ac_found_iconv=yes, ac_found_iconv=no)
-  if test "x$ac_found_iconv" = "xno"; then
-    AC_CHECK_LIB(iconv, iconv, ac_found_iconv=yes)
-    if test "x$ac_found_iconv" = "xno"; then
-      AC_CHECK_LIB(iconv, libiconv, ac_found_iconv=yes)
-    fi
-    if test "x$ac_found_iconv" != "xno"; then
-      ICONVLIB="-liconv"
-    fi
-  else
-    dnl Handle case where there is a native iconv but iconv.h is from libiconv
-    AC_CHECK_DECL(_libiconv_version,
-      [ AC_CHECK_LIB(iconv, libiconv, LIBS="-liconv $LIBS") ],,
-      [ #include <iconv.h> ])
-  fi
-fi
-if test "x$ac_found_iconv" = xyes; then
-  AC_DEFINE([HAVE_ICONV], [1], [Define if you have the iconv() function.])
-fi
-AC_SUBST([ICONVLIB])
-
-dnl Check if iconv uses const in prototype declaration
-if test "x$ac_found_iconv" = "xyes"; then
-  AC_CACHE_CHECK(for iconv declaration, ac_cv_iconv_const,
-    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>
-        #include <iconv.h>]],
-        [[#ifdef __cplusplus
-          "C"
-          #endif
-          #if defined(__STDC__) || defined(__cplusplus)
-          size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-          #else
-          size_t iconv();
-          #endif]])],
-      [ac_cv_iconv_const=],
-      [ac_cv_iconv_const=const])])
-  AC_DEFINE_UNQUOTED([ICONV_CONST], $ac_cv_iconv_const,
-    [Define as const if the declaration of iconv() needs const.])
-fi
-
 dnl --------------
 dnl CHECK FOR NDBM
 dnl --------------
@@ -621,8 +523,8 @@ dnl ------------------
 dnl nmhrpm is used in the final summary, see below.  The default value is
 dnl reported there as ./RPM, consistent with the reporting of the default
 dnl source code location as ., but its absolute path is used in the Makefile.
-AC_ARG_WITH(rpmdir,
-  AS_HELP_STRING([--with-rpmdir=RPMDIR], [RPM build directory @<:@RPM@:>@]))
+AC_ARG_WITH([rpmdir],
+  [AS_HELP_STRING([--with-rpmdir=RPMDIR], [RPM build directory @<:@RPM@:>@])])
   AS_IF([test x"$with_rpmdir" = x], [rpmdir='$(abs_srcdir)/RPM'; nmhrpm=./RPM],
           [rpmdir="$with_rpmdir"; eval "nmhrpm=${rpmdir}"])
 AC_SUBST([rpmdir])
@@ -644,10 +546,12 @@ dnl -----------------
 
 AS_IF([test x"$tls_support" = x"yes"],[
   AC_CHECK_HEADER([openssl/ssl.h], , [AC_MSG_ERROR([openssl/ssl.h not found])])
-  AC_CHECK_LIB([crypto], [BIO_write], ,
+  AC_CHECK_LIB([crypto], [BIO_write], [TLSLIB="-lcrypto"],
     [AC_MSG_ERROR([OpenSSL crypto library not found])])
-  AC_CHECK_LIB([ssl], [SSL_library_init], ,
-    [AC_MSG_ERROR([OpenSSL library not found])])])
+  AC_CHECK_LIB([ssl], [SSL_library_init], [TLSLIB="-lssl $TLSLIB"],
+    [AC_MSG_ERROR([OpenSSL library not found])])],
+  [TLSLIB=])
+AC_SUBST([TLSLIB])
 
 dnl ---------------------
 dnl CHECK TERMCAP LIBRARY
@@ -774,8 +678,8 @@ dnl exist.
 dnl
 
 AC_CONFIG_COMMANDS([build-directories],
-[test -d etc || ${MKDIR_P} etc
-test -d man || ${MKDIR_P} man])
+[test -d etc || AS_MKDIR_P([etc])
+test -d man || AS_MKDIR_P([man])])
 
 AC_CONFIG_COMMANDS_POST([
 
@@ -812,7 +716,6 @@ transport system           : ${MTS}
 file locking type          : ${LOCKTYPE}
 default smtp servers       : ${smtpservers}
 default editor             : ${editorpath}
-default pager              : ${pagerpath}
 SASL support               : ${sasl_support}
 TLS support                : ${tls_support}
 ])])dnl
index 5c10cc895b9ccfd882f3af97858683269b35d258..3514080ddad1893e19ee8eec62425e1f8b8d2916 100644 (file)
@@ -179,7 +179,7 @@ compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
 compctl -K mhfseq -x 's[+][@]' -K mhcomp -S / -q - 's[-]' \
   -k "(file part type list headers noheaders realsize norealsize nolist \
   show serialonly noserialonly form pause nopause noshow store auto noauto \
-  nostore cache nocache rcache wcache check nocheck ebcdicsafe noebcdicsafe \
+  nostore cache nocache rcache wcache check nocheck \
   rfc934mode norfc934mode verbose noverbose help)" - \
   'c[-1,-file]' -f - 'c[-1,-form]' -K mhfile - \
   'C[-1,-[rw]cache]' -k '(public private never ask)' -- mhn
index e84701896bdc3d6a02d1b13d33b2f184dcdcbfd8..f99d10801a4e9f6411414174c41d13fe93b5f72d 100644 (file)
@@ -31,7 +31,7 @@ or other related files, you'll need to first install GNU m4, available
 from <ftp://ftp.gnu.org/pub/gnu/m4/>, then GNU autoconf
 (<ftp://ftp.gnu.org/pub/gnu/autoconf/>) and GNU automake
 (<ftp://ftp.gnu.org/pub/gnu/automake/>).  Nmh is currently using a
-minimum of autoconf 2.61 and automake 1.12.
+minimum of autoconf 2.68 and automake 1.12.
 
 Most of the configure-related files are automatically generated.
 The only files you should need to manually edit are configure.ac
index d8d2315c86a7ae27040a13daf84604f0ff94b867..f17b240fb1d2ffbc163190e1f4b8d7b4261fcb46 100755 (executable)
@@ -3,8 +3,7 @@
 # Configures and builds nmh.
 # * This script must be invoked from an nmh source directory.
 # * This script retrieves configuration from the first existing nmh
-#   installation on your $PATH, if any, as well as any $EDITOR/$VISUAL
-#   and $PAGER environment variable settings.
+#   installation on your $PATH, if any.
 # * Unless the -y option is provided, this script then interactively
 #   walks you through confirmation of common configuration settings.
 #
@@ -45,7 +44,6 @@
 ####
 #### OS-specific setup.
 ####
-which=which
 ldd=ldd
 
 ####
@@ -111,19 +109,25 @@ config_mts=smtp
 config_smtpservers=localhost
 config_sasl=n
 config_tls=n
-config_editor=vi
-for i in more less most cat; do
-  if which $i >/dev/null 2>&1; then
-    config_pager=$i
-    break
-  fi
-done
 config_debug=n
 
+
+#### Find location of a program.  Bourne shell just puts the name in
+#### $0 if it's found from the PATH, so search that if necessary.
+finddir() {
+  case $1 in
+    */*) dirname "$1" ;;
+    *  ) IFS=:
+         for d in $PATH; do
+           [ -f "${d:=.}/$1"  -a  -x "$d/$1" ]  &&  printf %s "$d"  &&  break
+         done ;;
+  esac
+}
+
+
 if install-mh -check >/dev/null 2>&1; then
   # Determine config options from installed nmh.
-  mhparam=`which mhparam`
-  mhbin=`dirname "$mhparam"`
+  mhbin=`finddir install-mh`
 
   config_prefix=`cd $mhbin/.. && pwd`
 
@@ -154,14 +158,6 @@ if install-mh -check >/dev/null 2>&1; then
   fi
 fi
 
-if [ "$EDITOR" ]; then
-  config_editor="$EDITOR"
-elif [ "$VISUAL" ]; then
-  config_editor="$VISUAL"
-fi
-
-[ "$PAGER" ]  &&  config_pager="$PAGER"
-
 [ $debug -ge 1 ]  &&  config_debug=y
 
 if [ $yes -eq 0 ]; then
@@ -201,14 +197,6 @@ if [ $yes -eq 0 ]; then
     config_tls=n
   fi
 
-  printf 'Default editor [%s]: ' $config_editor
-  read editor
-  [ "$editor" ]  &&  config_editor="$editor"
-
-  printf 'Pager [%s]: ' $config_pager
-  read pager
-  [ "$pager" ]  &&  config_pager="$pager"
-
   #### Don't confirm debug here:  obey the -d option to this script.
 fi
 
@@ -225,10 +213,6 @@ config_opts="--prefix=$config_prefix"
   config_opts="$config_opts --with-cyrus-sasl"
 [ "$config_tls" = y ]  &&  \
   config_opts="$config_opts --with-tls"
-[ "$config_editor" ]  &&  \
-  config_opts="$config_opts --with-editor=$config_editor"
-[ "$config_pager" ]  &&  \
-  config_opts="$config_opts --with-pager=$config_pager"
 [ $config_debug = y ]  &&  \
   config_opts="$config_opts --enable-debug"
 
@@ -289,17 +273,19 @@ if [ $status -eq 0 ]; then
    fi
 
     [ $verbose -ge 1 ]  &&  echo testing . . .
-    checkoutput=`make $check 2>>"$logfile"`
+    checkoutput=`make $check AM_COLOR_TESTS=always 2>>"$logfile"`
     status=$?
 
     tests_summary=`echo "$checkoutput" | grep tests`
     #### If multiple tests not run, that line will be caught by the
     #### "grep tests" above.
     test_not_run=`echo "$checkoutput" | grep 'test was not run'`
+    fails=`echo "$checkoutput" | grep FAIL`
     if [ "$tests_summary" ]; then
       echo '===================' >>"$logfile"
-      echo "$tests_summary" >>"$logfile"
       [ "$test_not_run" ]  &&  echo "$test_not_run" >>"$logfile"
+      [ "$fails" ]  &&  echo "$fails" >>"$logfile"
+      echo "$tests_summary" >>"$logfile"
       echo '===================' >>"$logfile"
       [ "$check" = distcheck ]  &&  \
         echo "$checkoutput" | tail -n 4 >>"$logfile"
diff --git a/docs/historical/mh-6.8.5/doc/.null b/docs/historical/mh-6.8.5/doc/.null
deleted file mode 100644 (file)
index e69de29..0000000
index af42878681fca6b3fa928c26bf2cbf97209a9c47..a6ae19c593f52672c8840ea25e4b122ef13ed48f 100644 (file)
@@ -32,6 +32,10 @@ NEW FEATURES
 - inc(1) now supports a -port switch to specify the port used by the
   POP server.
 - pick(1) now decodes MIME-encoded header fields before searching.
+- The VISUAL and EDITOR environment variables are now supported as fallbacks
+  if the user does not configure an editor entry in their profile.
+- The format engine (mh_format(5)) now properly accounts for multibyte
+  characters when accounting for column widths.
 
 
 ----------------------------
@@ -56,6 +60,7 @@ OBSOLETE/DEPRECATED FEATURES
   http://smtpfilter.sourceforge.net/esmtp.html
 - conflict(8) is deprecated and will be removed from the next release.
 - mhtest(8) is deprecated and will be removed from the next release.
+- msh(1) is deprecated and will be removed from the next release.
 - spost(8) has been merged into post(8).  Its functionality is enabled
   by selecting the sendmail/pipe mail transport method, described in
   the mh-tailor(5) man page.  The spost -noalias, -backup/-nobackup,
@@ -66,6 +71,16 @@ OBSOLETE/DEPRECATED FEATURES
   refuses to do that.  For backward compatibility, spost has been
   replaced by a simple shell script that exec's post -mts
   sendmail/pipe.
+- Support for the undocumented and deprecated --enable-nmh-debug configure
+  flag has been removed.
+- Support for encoding some characters designated as EBCDIC-unsafe
+  via the -ebcdicsafe and -noebcdicsafe switches to mhbuild has
+  been removed.
+- The configure flag --with-pager has been removed; the default pager
+  is now hardcoded as "more".  Users are still free to override the
+  default using the PAGER environment variable or entries in .mh_profile.
+- The configure flag --with-editor has been removed; the fallback editor
+  if none is configured is "vi".
 
 ---------
 BUG FIXES
@@ -86,3 +101,5 @@ BUG FIXES
 - Fixed pick(1) to properly unfold multiple-line header fields by
   removing newlines instead of replacing them with spaces [Bug #15215].
 - Removed the artificial limit of 1000 messages at a time for rmmproc.
+- Fixed decoding of header fields when they contain a character that
+  can't be converted.
index 559f9937f24428f388fac467386ab4c45513c2e8..84f7fa40bcb419857eca405d879a967ccf335ac3 100644 (file)
 #define FT_CONCATADDR  70      /* formataddr w/out duplicate removal  */
 #define FT_MYMBOX      71      /* do "mymbox" test on comp            */
 
-/* misc. */            /* ADDTOSEQ only works if you include "options LBL" */
-#define FT_ADDTOSEQ    72      /* add current msg to a sequence       */
-
 /* conditionals & control flow (must be last) */
-#define FT_SAVESTR     73      /* save current str reg               */
-#define FT_DONE                74      /* stop formatting                    */
-#define FT_PAUSE       75      /* pause                              */
-#define FT_NOP         76      /* nop                                */
-#define FT_GOTO                77      /* (relative) goto                    */
-#define FT_IF_S_NULL   78      /* test if "str" null                 */
-#define FT_IF_S                79      /* test if "str" non-null             */
-#define FT_IF_V_EQ     80      /* test if "value" = literal          */
-#define FT_IF_V_NE     81      /* test if "value" != literal         */
-#define FT_IF_V_GT     82      /* test if "value" > literal          */
-#define FT_IF_MATCH    83      /* test if "str" contains literal     */
-#define FT_IF_AMATCH   84      /* test if "str" starts with literal  */
-#define FT_S_NULL      85      /* V = 1 if "str" null                */
-#define FT_S_NONNULL   86      /* V = 1 if "str" non-null            */
-#define FT_V_EQ                87      /* V = 1 if "value" = literal         */
-#define FT_V_NE                88      /* V = 1 if "value" != literal        */
-#define FT_V_GT                89      /* V = 1 if "value" > literal         */
-#define FT_V_MATCH     90      /* V = 1 if "str" contains literal    */
-#define FT_V_AMATCH    91      /* V = 1 if "str" starts with literal */
+#define FT_SAVESTR     72      /* save current str reg               */
+#define FT_DONE                73      /* stop formatting                    */
+#define FT_PAUSE       74      /* pause                              */
+#define FT_NOP         75      /* nop                                */
+#define FT_GOTO                76      /* (relative) goto                    */
+#define FT_IF_S_NULL   77      /* test if "str" null                 */
+#define FT_IF_S                78      /* test if "str" non-null             */
+#define FT_IF_V_EQ     79      /* test if "value" = literal          */
+#define FT_IF_V_NE     80      /* test if "value" != literal         */
+#define FT_IF_V_GT     81      /* test if "value" > literal          */
+#define FT_IF_MATCH    82      /* test if "str" contains literal     */
+#define FT_IF_AMATCH   83      /* test if "str" starts with literal  */
+#define FT_S_NULL      84      /* V = 1 if "str" null                */
+#define FT_S_NONNULL   85      /* V = 1 if "str" non-null            */
+#define FT_V_EQ                86      /* V = 1 if "value" = literal         */
+#define FT_V_NE                87      /* V = 1 if "value" != literal        */
+#define FT_V_GT                88      /* V = 1 if "value" > literal         */
+#define FT_V_MATCH     89      /* V = 1 if "str" contains literal    */
+#define FT_V_AMATCH    90      /* V = 1 if "str" starts with literal */
 
 #define IF_FUNCS FT_S_NULL     /* start of "if" functions */
diff --git a/h/mh.h b/h/mh.h
index 225d0c91ff5b3c7d415f70f1e1e936fa41a472ef..253af9cbaa08372826036ef26f14c7bb1f18fdb4 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
@@ -55,6 +55,11 @@ struct node {
 #define        UNKWNSW  (-1)   /* from smatch() on unknown switch   */
 
 struct swit {
+
+    /*
+     * Switch name
+     */
+
     char *sw;
 
     /* The minchars field is apparently used like this:
@@ -63,8 +68,54 @@ struct swit {
        0  : Switch can't be abbreviated;               switch shown in -help.
        #  : Switch can be abbreviated to # characters; switch shown in -help. */
     int minchars;
+
+    /*
+     * If we pick this switch, return this value from smatch
+     */
+
+    int swret;
 };
 
+/*
+ * Macros to use when declaring struct swit arrays.
+ *
+ * These macros are what known as X-Macros.  In your source code you
+ * use them like this:
+ *
+ * #define FOO_SWITCHES \
+ *    X("switch1", 0, SWITCHSW) \
+ *    X("switch2", 0, SWITCH2SW) \
+ *    X("thirdswitch", 2, SWITCH3SW) \
+ *
+ * The argument to each entry in FOO_SWITCHES are the switch name (sw),
+ * the minchars field (see above) and the return value for this switch.
+ *
+ * After you define FOO_SWITCHES, you instantiate it as follows:
+ *
+ * #define X(sw, minchars, id) id,
+ * DEFINE_SWITCH_ENUM(FOO);
+ * #undef X
+ *
+ * #define X(sw, minchars, id) { sw, minchars, id },
+ * DEFINE_SWITCH_ARRAY(FOO);
+ * #undef X
+ *
+ * DEFINE_SWITCH_ENUM defines an extra enum at the end of the list called
+ * LEN_FOO.
+ */
+
+#define DEFINE_SWITCH_ENUM(name) \
+    enum { \
+       name ## _SWITCHES \
+       LEN_ ## name \
+    }
+
+#define DEFINE_SWITCH_ARRAY(name, array) \
+    static struct swit array[] = { \
+       name ## _SWITCHES \
+       { NULL, 0, 0 } \
+    }
+
 extern struct swit anoyes[];   /* standard yes/no switches */
 
 #define ATTACHFORMATS 3                /* Number of send attach formats. */
@@ -237,11 +288,12 @@ struct msgs {
 #define FMTERR  (-3)           /* Message Format error             */
 #define FLD      0             /* Field returned                   */
 #define FLDPLUS  1             /* Field returned with more to come */
-#define FLDEOF   2             /* Field returned ending at eom     */
 #define BODY     3             /* Body  returned with more to come */
-#define BODYEOF  4             /* Body  returned ending at eom     */
 #define FILEEOF  5             /* Reached end of input file        */
 
+struct m_getfld_state;
+typedef struct m_getfld_state *m_getfld_state_t;
+
 /*
  * Maildrop styles
  */
@@ -251,10 +303,6 @@ struct msgs {
 #define        MS_MMDF         3       /* string mmdlm2              */
 #define        MS_MSH          4       /* whacko msh                 */
 
-extern int msg_count;          /* m_getfld() indicators */
-extern int msg_style;          /*  .. */
-extern char *msg_delim;                /*  .. */
-
 #define        NOUSE   0               /* draft being re-used */
 
 #define TFOLDER 0              /* path() given a +folder */
@@ -316,7 +364,6 @@ extern char *catproc;
 extern char *components;
 extern char *context;
 extern char *current;
-extern char *defaulteditor;
 extern char *defaultfolder;
 extern char *digestcomps;
 extern char *distcomps;
index 9c1db6a4ba0211ba7df1e86e3b15f9a81684a030..8f980a60998912d394d9ea425ac2b3e00e4cbed9 100644 (file)
@@ -6,14 +6,17 @@
 /*
  * various cache policies
  */
-static struct swit caches[] = {
-#define CACHE_NEVER    0
-    { "never", 0 },
-#define CACHE_PRIVATE  1
-    { "private", 0 },
-#define CACHE_PUBLIC   2
-    { "public", 0 },
-#define CACHE_ASK      3
-    { "ask", 0 },
-    { NULL, 0 }
-};
+
+#define CACHE_SWITCHES \
+    X("never", 0, CACHE_NEVER) \
+    X("private", 0, CACHE_PRIVATE) \
+    X("public", 0, CACHE_PUBLIC) \
+    X("ask", 0, CACHE_ASK) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(CACHE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(CACHE, caches);
+#undef X
diff --git a/h/nmh.h b/h/nmh.h
index 0ab5e5d6771cda7402f88f6fc03ad6a75b5201f8..3b91e2c3ad6e5e76acf06863dad240af52896c92 100644 (file)
--- a/h/nmh.h
+++ b/h/nmh.h
 # endif
 #endif
 
+/*
+ * Defaults for programs if they aren't configured in a user's profile
+ */
+
+#define DEFAULT_PAGER "more"
+#define DEFAULT_EDITOR "vi"
+
 #include <signal.h>
index d62fb7a1f585a0dc90bcb68fe5b7a3ce4a15e410..d4fc6eb0ac16e775cdafef095f4dab57d5984198 100644 (file)
@@ -27,6 +27,8 @@ void adios (char *, char *, ...) NORETURN;
 void admonish (char *, char *, ...);
 void advertise (char *, char *, char *, va_list);
 void advise (char *, char *, ...);
+char **argsplit (char *, char **, int *);
+void arglist_free (char *, char **);
 void ambigsw (char *, struct swit *);
 int atooi(char *);
 char **brkstring (char *, char *, char *);
@@ -66,6 +68,7 @@ int getanswer (char *);
 char **getarguments (char *, int, char **, int);
 char *get_charset(void);
 char *getcpy (char *);
+char *get_default_editor(void);
 char *getfolder(int);
 int lkclose(int, char*);
 int lkfclose(FILE *, char *);
@@ -75,8 +78,11 @@ int m_atoi (char *);
 char *m_backup (char *);
 int m_convert (struct msgs *, char *);
 char *m_draft (char *, char *, int, int *);
-void m_eomsbr (int (*)(int));
-int m_getfld (int, unsigned char *, unsigned char *, int, FILE *);
+void m_eomsbr (m_getfld_state_t, int (*)(int));
+void m_getfld_state_reset (m_getfld_state_t *);
+void m_getfld_state_destroy (m_getfld_state_t *);
+void m_getfld_track_filepos (m_getfld_state_t *, FILE *);
+int m_getfld (m_getfld_state_t *, unsigned char[NAMESZ], unsigned char *, int *, FILE *);
 int m_gmprot (void);
 char *m_maildir (char *);
 char *m_mailpath (char *);
@@ -85,7 +91,7 @@ int m_putenv (char *, char *);
 int m_rand (unsigned char *, size_t);
 char *m_mktemp(const char *, int *, FILE **);
 char *m_mktemp2(const char *, const char *, int *, FILE **);
-void m_unknown(FILE *);
+void m_unknown(m_getfld_state_t *, FILE *);
 int makedir (char *);
 char *message_id (time_t, int);
 char *nmh_getpass(const char *);
@@ -106,6 +112,10 @@ void readconfig (struct node **, FILE *, char *, int);
 int refile (char **, char *);
 void ruserpass(char *, char **, char **);
 int remdir (char *);
+void scan_detect_mbox_style (FILE *);
+void scan_finished ();
+void scan_eom_action (int (*)());
+void scan_reset_m_getfld_state ();
 int seq_addmsg (struct msgs *, char *, int, int, int);
 int seq_addsel (struct msgs *, char *, int, int);
 char *seq_bits (struct msgs *);
diff --git a/m4/iconv.m4 b/m4/iconv.m4
new file mode 100644 (file)
index 0000000..949c746
--- /dev/null
@@ -0,0 +1,42 @@
+dnl
+dnl Check for iconv support.  It may be in libiconv and may be iconv()
+dnl or libiconv()
+dnl
+
+AC_DEFUN([NMH_CHECK_ICONV],
+[AC_CHECK_HEADER([iconv.h],
+  [AC_CHECK_FUNC([iconv],
+    [dnl This is where iconv is found in the default libraries (LIBS)
+    nmh_found_iconv=yes
+    dnl Handle the case where there is a native iconv but iconv.h is
+    dnl from libiconv
+    AC_CHECK_DECL([_libiconv_version],
+      [AC_CHECK_LIB([iconv], [libiconv], [LIBS="-liconv $LIBS"])],,
+      [#include <iconv.h>])],
+    [dnl Since we didn't find iconv in LIBS, check libiconv
+    AC_CHECK_LIB([iconv], [iconv], [nmh_found_iconv=yes],
+      [dnl Also check for a function called libiconv()
+      AC_CHECK_LIB([iconv], [libiconv], [nmh_found_iconv=yes])])
+    dnl If either of these tests pass, set ICONVLIB
+    AS_IF([test "x$nmh_found_iconv" = "xyes"], [ICONVLIB="-liconv"])])
+  dnl If we came out of that by finding iconv in some form, define
+  dnl HAVE_ICONV
+  AS_IF([test "x$nmh_found_iconv" = "xyes"],
+    [AC_DEFINE([HAVE_ICONV], [1],
+                  [Define if you have the iconv() function.])
+    AC_CACHE_CHECK([for iconv declaration], [nmh_cv_iconv_const],
+      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>
+          #include <iconv.h>]],
+         [[#ifdef __cplusplus
+           "C"
+           #endif
+           #if defined(__STDC__) || defined(__cplusplus)
+           size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+           #else
+           size_t iconv();
+           #endif]])],
+        [nmh_cv_iconv_const=],
+       [nmh_cv_iconv_const=const])])
+    AC_DEFINE_UNQUOTED([ICONV_CONST], [$nmh_cv_iconv_const],
+      [Define as const if the declaration of iconv() needs const.])])])
+AC_SUBST([ICONVLIB])])
index d1fcf84837a3025cda73aaa91904ff8284bc1c9e..d7b03841874a605ed6646793ec44ed2c54070769 100644 (file)
@@ -145,7 +145,7 @@ man page for details about private sequences.
 .RE
 .PP
 .BR Editor :
-/usr/bin/vi
+vi
 .RS 5
 Defines the editor to be used by the commands
 .BR comp ,
@@ -153,7 +153,9 @@ Defines the editor to be used by the commands
 .BR forw ,
 and
 .BR repl .
-(profile, default: %default_editor%)
+If not set in profile the value will be taken from the VISUAL and
+EDITOR environment variables.
+(profile, default: vi)
 .RE
 .PP
 .BR automimeproc :
@@ -417,7 +419,7 @@ new users of
 .RE
 .PP
 .BR lproc :
-%default_pager%
+more
 .RS 5
 This program is used to list the contents of a message in response
 to the
@@ -482,7 +484,7 @@ that is sent to \*(lqBcc:\*(rq recipients.
 .RE
 .PP
 .BR moreproc :
-%default_pager%
+more
 .RS 5
 This is the program used by
 .B mhl
index 7bd3103c8507dfc8005b9aa2018a4dfbc4ebfce7..57441dad268d84f708497c01886887bbb67a3ab1 100644 (file)
@@ -1,4 +1,4 @@
-.TH MHBUILD %manext1% "May 31, 2012" "%nmhversion%"
+.TH MHBUILD %manext1% "January 4, 2013" "%nmhversion%"
 .\"
 .\" %nmhwarning%
 .\"
@@ -13,7 +13,6 @@ mhbuild \- translate MIME composition draft
 .RB [ \-realsize " | " \-norealsize ]
 .RB [ \-headers " | " \-noheaders ]
 .RB [ \-directives " | " \-nodirectives ]
-.RB [ \-ebcdicsafe " | " \-noebcdicsafe ]
 .RB [ \-rfc934mode " | " \-norfc934mode ]
 .RB [ \-contentid " | " \-nocontentid ]
 .RB [ \-verbose " | " \-noverbose ]
@@ -467,11 +466,11 @@ If
 .B mhbuild
 is given the
 .B \-check
-switch, then it will also associate
-an integrity check with each \*(lqleaf\*(rq content.  This will add a
-Content-MD5 header field to the content, along with the md5 sum of the
-unencoded contents.  This may be used by the receiver of the message to
-verify that the contents of the message were not changed in transport.
+switch, then it will also associate an integrity check with each
+\*(lqleaf\*(rq content.  This will add a Content-MD5 header field to
+the content, along with the md5 sum of the unencoded contents, per RFC
+1864.  This may be used by the receiver of the message to verify that
+the contents of the message were not changed in transport.
 .SS "Transfer Encodings"
 After
 .B mhbuild
@@ -490,17 +489,6 @@ will encode each content with
 a transfer encoding, even it the content contains only 7\-bit data.  This
 is to increase the likelihood that the content is not changed while in
 transport.
-.PP
-The switch
-.B \-ebcdicsafe
-will cause
-.B mhbuild
-to slightly change
-the way in which it performs the \*(lqquoted-printable\*(rq transfer
-encoding.  Along with encoding 8\-bit characters, it will now also encode
-certain common punctuation characters as well.  This slightly reduces the
-readability of the message, but allows the message to pass more reliably
-through mail gateways which involve the EBCDIC character encoding.
 .SS "Invoking mhbuild"
 Typically,
 .B mhbuild
@@ -675,6 +663,9 @@ line         ::=     "##" text EOL
 .I "Proposed Standard for Message Encapsulation"
 (RFC\-934),
 .PP
+.I "The Content-MD5 Header Field"
+(RFC\-1864),
+.PP
 .I "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies"
 (RFC\-2045),
 .PP
@@ -696,6 +687,5 @@ line         ::=     "##" text EOL
 .RB ` \-norfc934mode '
 .RB ` \-contentid '
 .RB ` \-nocheck '
-.RB ` \-noebcdicsafe '
 .RB ` \-noverbose '
 .fi
index cd15735251c8fc512cbd81804936a27db46521ee..5864aa435b6bad95da10a5a4d5a1232d250f3225 100644 (file)
@@ -41,7 +41,6 @@ mhn \- display/list/store/cache MIME messages
 .B mhn
 .B \-build
 .I file
-.RB [ \-ebcdicsafe " | " \-noebcdicsafe ]
 .RB [ \-rfc934mode " | " \-norfc934mode ]
 .ad
 .SH DESCRIPTION
index 57770b52830a5afe652b280d0c8855f64c946555..66e29fbe1d70d8018f1c275fc1c3d24e4f3efb20 100644 (file)
@@ -1,4 +1,4 @@
-.TH MSH %manext1% "November 6, 2012" "%nmhversion%"
+.TH MSH %manext1% "January 26, 2013" "%nmhversion%"
 .\"
 .\" %nmhwarning%
 .\"
@@ -16,12 +16,14 @@ msh \- nmh shell (and BBoard reader)
 .RB [ \-version ]
 .RB [ \-help ]
 .ad
+.SH STATUS
+.B msh is deprecated and will be removed from the next nmh release.
 .SH DESCRIPTION
 .B msh
 is an interactive program that implements a subset of the normal
 .B nmh
 commands operating on a single file in
-.BR packf 'd
+.BR mmdf
 format.
 That is,
 .B msh
index b1d57dd6cdb7775072c4e2bbab7c2089e5d29938..6fd178bcd6d18f1f36ba7a925baab97fd27abcd8 100755 (executable)
@@ -798,9 +798,19 @@ sm_end (int type)
            if (sm_mts == MTS_SMTP)
                smtalk (SM_QUIT, "QUIT");
            else {
+               /* The SIGPIPE block replaces old calls to discard ().
+                  We're not sure what the discard () calls were for,
+                  maybe to prevent deadlock on old systems.  In any
+                  case, blocking SIGPIPE should be harmless.
+                  Because the file handles are closed below, leave it
+                  blocked. */
+               sigset_t set, oset;
+               sigemptyset (&set);
+               sigaddset (&set, SIGPIPE);
+               sigprocmask (SIG_BLOCK, &set, &oset);
+
                kill (sm_child, SIGKILL);
-               discard (sm_rfp);
-               discard (sm_wfp);
+               sm_child = NOTOK;
            }
            if (type == NOTOK) {
                sm_reply.code = sm_note.code;
@@ -840,9 +850,11 @@ sm_end (int type)
        if (sasl_inbuffer)
            free(sasl_inbuffer);
 #endif /* CYRUS_SASL */
-    } else {
+    } else if (sm_child != NOTOK) {
        status = pidwait (sm_child, OK);
        sm_child = NOTOK;
+    } else {
+       status = OK;
     }
 
     sm_rfp = sm_wfp = NULL;
diff --git a/sbr/arglist.c b/sbr/arglist.c
new file mode 100644 (file)
index 0000000..8749a4b
--- /dev/null
@@ -0,0 +1,144 @@
+
+/*
+ * arglist.c -- Routines for handling argument lists for execvp() and friends
+ *
+ * This code is Copyright (c) 2013, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
+ */
+
+#include <h/mh.h>
+#include <h/utils.h>
+
+/*
+ * Split up a command into an appropriate array to pass to execvp()
+ * or similar function.  Returns an allocated argv[] array.
+ *
+ * Function arguments:
+ *
+ * command - String to split up
+ * file    - the first argument to "command", suitable for the first argument
+ *           to execvp().  Returns allocated memory that must be free()d.
+ * argp    - Index to last element (NULL) of returned argv[] array.
+ *
+ * Our basic algorithm is this:
+ *
+ * - If there are no spaces or shell metacharacters in "command", then
+ *   take it as-is.
+ * - If there are spaces in command, space-split command string.
+ * - If we have shell metacharacters, run the command using
+ *   /bin/sh -c 'command "$@"'.  In this case, any additional arguments
+ *   appended to the arglist will be expanded by "$@".
+ *
+ * In all cases additional arguments can be added to the argv[] array.
+ */
+
+/* Shell metacharacters we use to trigger a call to the shell */
+
+#define METACHARS      "$&*(){}[]'\";\\|?<>~`\n"
+
+char **
+argsplit(char *command, char **file, int *argp)
+{
+    char **argvarray, *p;
+    int space = 0, metachar = 0, i;
+
+    for (p = command; *p; p++) {
+       if (*p == ' ' || *p == '\t') {
+               space = 1;
+       } else if (strchr(METACHARS, *p)) {
+               metachar = 1;
+               break;
+       }
+    }
+
+    argvarray = (char **) mh_xmalloc((sizeof(char **) * MAXARGS));
+
+    /*
+     * The simple case - no spaces or shell metacharacters
+     */
+
+    if (!space && !metachar) {
+       argvarray[0] = getcpy(r1bindex(command, '/'));
+       argvarray[1] = NULL;
+       *file = getcpy(command);
+       if (argp)
+           *argp = 1;
+       return argvarray;
+    }
+
+    /*
+     * Spaces, but no shell metacharacters; space-split into seperate
+     * arguments
+     */
+
+    if (space && !metachar) {
+       char **split;
+       p = getcpy(command);
+       split = brkstring(p, " \t", NULL);
+       if (split[0] == NULL) {
+           adios(NULL, "Invalid blank command found");
+       }
+       argvarray[0] = getcpy(r1bindex(split[0], '/'));
+       for (i = 1; split[i] != NULL; i++) {
+           if (i > MAXARGS) {
+               adios(NULL, "Command exceeded argument limit");
+           }
+           argvarray[i] = getcpy(split[i]);
+       }
+       argvarray[i] = NULL;
+       *file = getcpy(split[0]);
+       if (argp)
+           *argp = i;
+       free(p);
+       return argvarray;
+    }
+
+    /*
+     * Remaining option - pass to the shell.
+     *
+     * Some notes here:
+     *
+     * - The command passed to "sh -c" is actually:
+     *      command "$@"
+     *
+     *   If there are additional arguments they will be expanded by the
+     *   shell, otherwise "$@" expands to nothing.
+     *
+     * - Every argument after the -c string gets put into positional
+     *   parameters starting at $0, but $@ starts expanding with $1.
+     *   So we put in a dummy argument (we just use /bin/sh)
+     */
+
+    *file = getcpy("/bin/sh");
+    argvarray[0] = getcpy("sh");
+    argvarray[1] = getcpy("-c");
+    argvarray[2] = getcpy(command);
+    argvarray[2] = add(" \"$@\"", argvarray[2]);
+    argvarray[3] = getcpy("/bin/sh");
+    argvarray[4] = NULL;
+
+    if (argp)
+       *argp = 4;
+
+    return argvarray;
+}
+
+/*
+ * Free our argument array
+ */
+
+void
+arglist_free(char *command, char **argvarray)
+{
+    int i;
+
+    if (command != NULL)
+       free(command);
+
+    if (argvarray != NULL) {
+       for (i = 0; argvarray[i] != NULL; i++)
+           free(argvarray[i]);
+       free(argvarray);
+    }
+}
index a1efa4882aadc9e70297dc167a904c6f898a2f68..83b0bfbc0c5ee9d420f96fbbc9b636130ed7ccfb 100644 (file)
@@ -20,15 +20,7 @@ discard (FILE *io)
 
     tcflush (fileno(io), TCOFLUSH);
 
-#if defined(_FSTDIO) || defined(__DragonFly__)
-    fpurge (io);
-#else
-# ifdef LINUX_STDIO
-    io->_IO_write_ptr = io->_IO_write_base;
-# else
-    if ((io->_ptr = io->_base))
-       io->_cnt = 0;
-# endif
-#endif
+    /* There used to be an fpurge() here on some platforms, stdio
+       hackery on others.  But it didn't seem necessary. */
 }
 
index 014733427dcd6261cded324b744e0cac125cdc7b..437c811cff974ac173981c63b8748a39cfbc1fb3 100644 (file)
@@ -212,7 +212,6 @@ static struct ftable functable[] = {
      { "friendly",   TF_COMP,  FT_LS_FRIENDLY, FT_PARSEADDR,   TFL_PUTS },
 
      { "mymbox",     TF_COMP,  FT_LV_COMPFLAG, FT_MYMBOX,      TFL_PUTN },
-     { "addtoseq",   TF_STR,   FT_ADDTOSEQ,    0,              0 },
 
      { "unquote",   TF_EXPR,   FT_LS_UNQUOTE,  0,              TFL_PUTS},
 
index 4d3fc296d0e90d987d5002035446f30884dd0e5e..25c98c3ded2ae2b392eb652a7ff1d41a49f12318 100644 (file)
@@ -303,8 +303,10 @@ decode_rfc2047 (char *str, char *dst, size_t dstlen)
                            break;
                        /* skip to next input character */
                        if (fromutf8) {
-                           for (start++;(start < q) && ((*start & 192) == 128);start++)
-                               inbytes--;
+                           for (++start, --inbytes;
+                                start < q  &&  (*start & 192) == 128;
+                                ++start, --inbytes)
+                               continue;
                        } else
                            start++, inbytes--;
                        if (start >= q)
index ac4d23afdedd7a9ad496a861ccd04f23c27d9e07..b1370fb745ac145fe0d69015877ecf34e1b269a4 100644 (file)
 #  include <wchar.h>
 #endif
 
-#ifdef LBL
-struct msgs *fmt_current_folder; /* current folder (set by main program) */
-#endif
-
 extern int fmt_norm;           /* defined in sbr/fmt_def.c = AD_NAME */
 struct mailname fmt_mnull = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
                              NULL, NULL };
@@ -118,7 +114,8 @@ cpnumber(char **dest, int num, unsigned int wid, char fill, size_t n) {
  * no more than n bytes are copied
  */
 static void
-cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
+cptrimmed(char **dest, char **ep, char *str, unsigned int wid, char fill,
+         char *epmax) {
     int remaining;     /* remaining output width available */
     int c, ljust;
     int end;           /* number of input bytes remaining in str */
@@ -129,7 +126,6 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
 #endif
     char *sp;          /* current position in source string */
     char *cp = *dest;  /* current position in destination string */
-    char *ep = cp + n; /* end of destination buffer */
     int prevCtrl = 1;
 
     /* get alignment */
@@ -139,12 +135,29 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
        ljust++;
     }
     if ((sp = (str))) {
+#ifdef MULTIBYTE_SUPPORT
        mbtowc(NULL, NULL, 0); /* reset shift state */
+#endif
        end = strlen(str);
        while (*sp && remaining > 0 && end > 0) {
 #ifdef MULTIBYTE_SUPPORT
            char_len = mbtowc(&wide_char, sp, end);
-           if (char_len <= 0 || (cp + char_len > ep))
+
+           if (char_len <= 0)
+               break;
+
+           w = wcwidth(wide_char);
+
+           /*
+            * Multibyte characters can have a variable number of column
+            * widths, so use the column width to bump the end pointer when
+            * appropriate.
+            */
+           if (char_len > 1 && epmax - *ep >= char_len - w) {
+               *ep += char_len - w;
+           }
+
+           if (cp + w > *ep)
                break;
 
            end -= char_len;
@@ -171,7 +184,6 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
            prevCtrl = 0;
 
 #ifdef MULTIBYTE_SUPPORT
-           w = wcwidth(wide_char);
            if (w >= 0 && remaining >= w) {
                strncpy(cp, sp, char_len);
                cp += char_len;
@@ -186,9 +198,10 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
     }
 
     if (ljust) {
-       if (cp + remaining > ep)
-           remaining = ep - cp;
-       ep = cp + remaining;
+        char *endfield;
+       if (cp + remaining > *ep)
+           remaining = *ep - cp;
+       endfield = cp + remaining;
        if (remaining > 0) {
            /* copy string to the right */
            while (--cp >= *dest)
@@ -198,22 +211,22 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
            for (c=remaining; c>0; c--)
                *cp-- = fill;
        }
-       *dest = ep;
+       *dest = endfield;
     } else {
        /* pad remaining space */
-       while (remaining-- > 0 && cp < ep)
+       while (remaining-- > 0 && cp < *ep)
                *cp++ = fill;
        *dest = cp;
     }
 }
 
 static void
-cpstripped (char **dest, char *end, char *str)
+cpstripped (char **dest, char **end, char *max, char *str)
 {
     int prevCtrl = 1;  /* This is 1 so we strip out leading spaces */
     int len;
 #ifdef MULTIBYTE_SUPPORT
-    int char_len;
+    int char_len, w;
     wchar_t wide_char;
 #endif /* MULTIBYTE_SUPPORT */
 
@@ -231,11 +244,21 @@ cpstripped (char **dest, char *end, char *str)
      * then deal with that here.
      */
 
-    while (*str != '\0' && len > 0 && *dest < end) {
+    while (*str != '\0' && len > 0 && *dest < *end) {
 #ifdef MULTIBYTE_SUPPORT
        char_len = mbtowc(&wide_char, str, len);
+       w = wcwidth(wide_char);
+
+       /*
+        * Account for multibyte characters, and increment the end pointer
+        * by the number of "extra" bytes in this character.  That's the
+        * character length (char_len) minus the column width (w).
+        */
+       if (char_len > 1  &&  max - *end >= char_len - w) {
+           *end += char_len - w;
+       }
 
-       if (char_len <= 0 || *dest + char_len > end)
+       if (char_len <= 0 || *dest + char_len > *end)
            break;
 
        len -= char_len;
@@ -356,11 +379,11 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
 
            comp = fmt->f_comp;
 
-           if (! (comp->c_flags & CF_TRIMMED) && comp->c_text) {
-               i = strlen(comp->c_text);
+           if (! (comp->c_flags & CF_TRIMMED) && comp->c_text &&
+               (i = strlen(comp->c_text)) > 0) {
                if (comp->c_text[i - 1] == '\n' &&
-                       strcmp(comp->c_name, "body") != 0 &&
-                       strcmp(comp->c_name, "text") != 0)
+                   strcmp(comp->c_name, "body") != 0 &&
+                   strcmp(comp->c_name, "text") != 0)
                    comp->c_text[i - 1] = '\0';
                comp->c_flags |= CF_TRIMMED;
            }
@@ -373,10 +396,11 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
        switch (fmt->f_type) {
 
        case FT_COMP:
-           cpstripped (&cp, ep, fmt->f_comp->c_text);
+           cpstripped (&cp, &ep, scanl + max - 1, fmt->f_comp->c_text);
            break;
        case FT_COMPF:
-           cptrimmed (&cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill, ep - cp);
+           cptrimmed (&cp, &ep, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill,
+                      scanl + max - 1);
            break;
 
        case FT_LIT:
@@ -399,10 +423,11 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
            break;
 
        case FT_STR:
-           cpstripped (&cp, ep, str);
+           cpstripped (&cp, &ep, scanl + max - 1, str);
            break;
        case FT_STRF:
-           cptrimmed (&cp, str, fmt->f_width, fmt->f_fill, ep - cp);
+           cptrimmed (&cp, &ep, str, fmt->f_width, fmt->f_fill, 
+                      scanl + max - 1);
            break;
        case FT_STRLIT:
            sp = str;
@@ -926,7 +951,7 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
                        *cp++ = ' ';
                }
            }
-           cpstripped (&cp, ep, lp);
+           cpstripped (&cp, &ep, scanl + max - 1, lp);
            }
            break;
 
@@ -980,17 +1005,6 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
                comp->c_mn = &fmt_mnull;
            }
            break;
-
-       case FT_ADDTOSEQ:
-#ifdef LBL
-           /* If we're working on a folder (as opposed to a file), add the
-            * current msg to sequence given in literal field.  Don't
-            * disturb string or value registers.
-            */
-           if (fmt_current_folder)
-                   seq_addmsg(fmt_current_folder, fmt->f_text, dat[0], -1);
-#endif
-           break;
        }
        fmt++;
     }
index c1416a6fb8557ea1ea5b094be18af962703b56ad..671ecc7cc5bc1a473cd40489b7335fad702071bb 100644 (file)
@@ -24,7 +24,7 @@ folder_delmsgs (struct msgs *mp, int unlink_msgs, int nohook)
 {
     pid_t pid;
     int msgnum, vecp, retval = 0;
-    char buf[100], *dp, **vec;
+    char buf[100], *dp, **vec, *prog;
     char       msgpath[BUFSIZ];
 
     /*
@@ -40,10 +40,18 @@ folder_delmsgs (struct msgs *mp, int unlink_msgs, int nohook)
        /* Mark that the sequence information has changed */
        mp->msgflags |= SEQMOD;
 
-       vec = (char **) calloc ((size_t) (mp->numsel + 2), sizeof(*vec));
+       vec = argsplit(rmmproc, &prog, &vecp);
+
+       /*
+        * argsplit allocates a MAXARGS vector by default,  If we need
+        * something bigger, allocate it ourselves
+        */
+
+       if (mp->numsel + vecp + 1 > MAXARGS)
+           vec = (char **) realloc (vec, (size_t) ((mp->numsel + vecp + 1) *
+                                                    sizeof(*vec)));
        if (vec == NULL)
            adios (NULL, "unable to allocate exec vector");
-       vecp = 1;
        for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
            if (is_selected (mp, msgnum) &&
                !(vec[vecp++] = strdup (m_name (msgnum))))
@@ -52,7 +60,6 @@ folder_delmsgs (struct msgs *mp, int unlink_msgs, int nohook)
        vec[vecp] = NULL;
 
        fflush (stdout);
-       vec[0] = r1bindex (rmmproc, '/');
 
        switch (pid = vfork()) {
        case -1:
@@ -60,12 +67,13 @@ folder_delmsgs (struct msgs *mp, int unlink_msgs, int nohook)
            return -1;
 
        case 0:
-           execvp (rmmproc, vec);
+           execvp (prog, vec);
            fprintf (stderr, "unable to exec ");
            perror (rmmproc);
            _exit (-1);
 
        default:
+           arglist_free(prog, vec);
            return (pidwait (pid, -1));
        }
     }
diff --git a/sbr/geteditor.c b/sbr/geteditor.c
new file mode 100644 (file)
index 0000000..6c285da
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * geteditor.c -- Determine the default editor to use
+ *
+ * This code is Copyright (c) 2013, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
+ */
+
+#include <h/mh.h>
+#include <h/utils.h>
+
+static char *default_editor = NULL;
+
+char *
+get_default_editor(void)
+{
+    char *str;
+
+    if (default_editor)
+       return default_editor;
+
+    if (!(str = context_find("editor")) && !(str = getenv("VISUAL")) &&
+       !(str = getenv("EDITOR"))) {
+       str = DEFAULT_EDITOR;
+    }
+
+    return (default_editor = str);
+}
index c88747f09e0de9008adf99e2316b1351a605f726..496978ee9fbfdc4b9a7220a4f0e4baad0f7067bc 100644 (file)
@@ -181,6 +181,18 @@ single:
         * check if message is in-range and exists.
         */
        if (mp->msgflags & ALLOW_NEW) {
+           /*
+            * We can get into a case where the "cur" sequence is way out
+            * of range, and because it's allowed to not exist (think
+            * of "rmm; next") it doesn't get checked to make sure it's
+            * within the range of messages in seq_init().  So if our
+            * desired sequence is out of range of the allocated folder
+            * limits simply reallocate the folder so it's within range.
+            */
+           if (first < mp->lowoff || first > mp->hghoff)
+               mp = folder_realloc(mp, first < mp->lowoff ? first : mp->lowoff,
+                                   first > mp->hghoff ? first : mp->hghoff);
+
            set_select_empty (mp, first);
        } else {
            if (first > mp->hghmsg
index e139505aa941f6d416bf458d26679853dffca43c..af44f09a2161ff44d6704ec453901bc79a1008ed 100644 (file)
 #include <h/mts.h>
 #include <h/utils.h>
 
+/*
+   Purpose
+   =======
+   Reads an Internet message (RFC 5322), or one or more messages
+   stored in a maildrop in mbox (RFC 4155) or MMDF format, from a file
+   stream.  Each call to m_getfld() reads one header field, or a
+   portion of the body, in sequence.
+
+   Inputs
+   ======
+   gstate:  opaque parse state
+   bufsz:  maximum number of characters to load into buf
+   iob:  input file stream
+
+   Outputs
+   =======
+   name:  header field name (array of size NAMESZ=999)
+   buf:  either a header field body or message body
+   bufsz:  number of characters loaded into buf
+   (return value):  message parse state on return from function
+
+   Functions
+   =========
+   void m_getfld_state_destroy (m_getfld_state_t *gstate): destroys
+   the parse state pointed to by the gstate argument.
+
+   m_getfld_state_reset (m_getfld_state_t *gstate): resets the parse
+   state to FLD.
+
+   void m_unknown(FILE *iob):  Determines the message delimiter string
+   for the maildrop.  Called by inc, scan, and msh when reading from a
+   maildrop file.
+
+   void m_eomsbr (int (*action)(int)):  Sets the hook to check for end
+   of message in a maildrop.  Called only by msh.
+
+   State variables
+   ===============
+   m_getfld() retains state internally between calls in the
+   m_getfld_state_t variable.  These are used for detecting the end of
+   each message when reading maildrops:
+
+     unsigned char **pat_map
+     unsigned char *fdelim
+     unsigned char *delimend
+     int fdelimlen
+     unsigned char *edelim
+     int edelimlen
+     char *msg_delim
+     int msg_style
+     int (*eom_action)(int)
+
+   Usage
+   =====
+   m_getfld_state_t gstate = 0;
+      ...
+   int state = m_getfld (&gstate, ...);
+      ...
+   m_getfld_state_destroy (&gstate);
+
+   The state is retained internally by gstate.  To reset its state to FLD:
+   m_getfld_state_reset (&gstate);
+*/
+
+/* The following described the old implementation.  The high-level
+   structure hasn't changed, but some of the details have.  I'm
+   leaving this as-is, though, for posterity.
+ */
+
 /* This module has a long and checkered history.  First, it didn't burst
    maildrops correctly because it considered two CTRL-A:s in a row to be
    an inter-message delimiter.  It really is four CTRL-A:s followed by a
    it knows that _filbuf ignores the _ptr & _cnt and simply fills
    the buffer.  If stdio on your system doesn't work this way, you
    may have to make small changes in this routine.
-   
+
    This routine also "knows" that an EOF indication on a stream is
    "sticky" (i.e., you will keep getting EOF until you reposition the
    stream).  If your system doesn't work this way it is broken and you
    there is data in "name" or "buf").
   */
 
-
 /*
  * static prototypes
  */
-static int m_Eom (int, FILE *);
+struct m_getfld_state;
+static int m_Eom (m_getfld_state_t, int);
 static unsigned char *matchc(int, char *, int, char *);
-static unsigned char *locc(int, unsigned char *, unsigned char);
-
-#define Getc(iob)      getc(iob)
-#define eom(c,iob)     (msg_style != MS_DEFAULT && \
-                        (((c) == *msg_delim && m_Eom(c,iob)) ||\
-                         (eom_action && (*eom_action)(c))))
 
-static unsigned char **pat_map;
+#define eom(c,s)       (s->msg_style != MS_DEFAULT && \
+                        (((c) == *s->msg_delim && m_Eom(s,c)) || \
+                         (s->eom_action && (*s->eom_action)(c))))
 
-/*
- * defined in sbr/m_msgdef.c = 0
- * This is a disgusting hack for "inc" so it can know how many
- * characters were stuffed in the buffer on the last call
- * (see comments in uip/scansbr.c).
+/* This replaces the old approach, with its direct access to stdio
+ * internals.  It uses one fread() to load a buffer that we manage.
+ *
+ * MSG_INPUT_SIZE is the size of the buffer.
+ * MAX_DELIMITER_SIZE is the maximum size of the delimiter used to
+ * separate messages in a maildrop, such as mbox "From ".
+ *
+ * Some of the tests in the test suite assume a MSG_INPUT_SIZE
+ * of 4096.
  */
-extern int msg_count;
+#define MSG_INPUT_SIZE 4096
+#define MAX_DELIMITER_SIZE 5
+
+struct m_getfld_state {
+    unsigned char msg_buf[2 * MSG_INPUT_SIZE + MAX_DELIMITER_SIZE];
+    unsigned char *readpos;
+    unsigned char *end;  /* One past the last character read in. */
+    /* The following support tracking of the read position in the
+       input file stream so that callers can interleave m_getfld()
+       calls with ftell() and fseek().  ytes_read replaces the old
+       m_getfld() msg_count global.  last_caller_pos is stored when
+       leaving m_getfld()/m_unknown(), then checked on the next entry.
+       last_internal_pos is used to remember the position used
+       internally by m_getfld() (read_more(), actually). */
+    off_t bytes_read;
+    off_t total_bytes_read; /* by caller, not necessarily from input file */
+    off_t last_caller_pos;
+    off_t last_internal_pos;
+    FILE *iob;
+
+    unsigned char **pat_map;
+    int msg_style;
+    /*
+     * The "full" delimiter string for a packed maildrop consists
+     * of a newline followed by the actual delimiter.  E.g., the
+     * full string for a Unix maildrop would be: "\n\nFrom ".
+     * "Fdelim" points to the start of the full string and is used
+     * in the BODY case of the main routine to search the buffer for
+     * a possible eom.  Msg_delim points to the first character of
+     * the actual delim. string (i.e., fdelim+1).  Edelim
+     * points to the 2nd character of actual delimiter string.  It
+     * is used in m_Eom because the first character of the string
+     * has been read and matched before m_Eom is called.
+     */
+    char *msg_delim;
+    unsigned char *fdelim;
+    unsigned char *delimend;
+    int fdelimlen;
+    unsigned char *edelim;
+    int edelimlen;
+    int (*eom_action)(int);
+    int state;
+    int track_filepos;
+};
+
+static
+void
+m_getfld_state_init (m_getfld_state_t *gstate, FILE *iob) {
+    m_getfld_state_t s;
+
+    s = *gstate = (m_getfld_state_t) mh_xmalloc(sizeof (struct m_getfld_state));
+    s->readpos = s->end = s->msg_buf;
+    s->bytes_read = s->total_bytes_read = 0;
+    s->last_caller_pos = s->last_internal_pos = 0;
+    s->iob = iob;
+    s->pat_map = NULL;
+    s->msg_style = MS_DEFAULT;
+    s->msg_delim = "";
+    s->fdelim = s->delimend = s->edelim = NULL;
+    s->fdelimlen = s->edelimlen = 0;
+    s->eom_action = NULL;
+    s->state = FLD;
+    s->track_filepos = 0;
+}
 
-/*
- * defined in sbr/m_msgdef.c = MS_DEFAULT
- */
-extern int msg_style;
+/* scan() needs to force a state an initial state of FLD for each message. */
+void
+m_getfld_state_reset (m_getfld_state_t *gstate) {
+    if (*gstate) {
+       (*gstate)->state = FLD;
+    }
+}
+
+/* If the caller interleaves ftell*()/fseek*() calls with m_getfld()
+   calls, m_getfld() must keep track of the file position.  The caller
+   must use this function to inform m_getfld(). */
+void
+m_getfld_track_filepos (m_getfld_state_t *gstate, FILE *iob) {
+    if (! *gstate) {
+       m_getfld_state_init (gstate, iob);
+    }
+
+    (*gstate)->track_filepos = 1;
+}
+
+void m_getfld_state_destroy (m_getfld_state_t *gstate) {
+    m_getfld_state_t s = *gstate;
+
+    if (s) {
+       if (s->fdelim) free (s->fdelim-1);
+       free (s);
+       *gstate = 0;
+    }
+}
 
 /*
- * The "full" delimiter string for a packed maildrop consists
- * of a newline followed by the actual delimiter.  E.g., the
- * full string for a Unix maildrop would be: "\n\nFrom ".
- * "Fdelim" points to the start of the full string and is used
- * in the BODY case of the main routine to search the buffer for
- * a possible eom.  Msg_delim points to the first character of
- * the actual delim. string (i.e., fdelim+1).  Edelim
- * points to the 2nd character of actual delimiter string.  It
- * is used in m_Eom because the first character of the string
- * has been read and matched before m_Eom is called.
- */
-extern char *msg_delim;         /* defined in sbr/m_msgdef.c = "" */
-static unsigned char *fdelim;
-static unsigned char *delimend;
-static int fdelimlen;
-static unsigned char *edelim;
-static int edelimlen;
+  Summary of file and message input buffer positions:
+
+  input file      -------------------------------------------EOF
+                                 |              |
+                          last_caller_pos  last_internal_pos
+
+
+  msg_buf                   --------------------EOF
+                            |         |         |
+                         msg_buf   readpos     end
+
+                            |<>|=retained characters, difference
+                                 between last_internal_pos and
+                                 first readpos value after reading
+                                 in new chunk in read_more()
 
-static int (*eom_action)(int) = NULL;
+  When returning from m_getfld()/m_unknown():
+  1) Save the internal file position in last_internal_pos.  That's the
+     m_getfld() position reference in the input file.
+  2) Set file stream position so that callers can use ftell().
 
-#ifdef _FSTDIO
-# define _ptr    _p            /* Gag   */
-# define _cnt    _r            /* Retch */
-# define _filbuf __srget       /* Puke  */
-# define DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
+  When entering m_getfld()/m_unknown():
+  Check to see if the call had changed the file position.  If so,
+  adjust the internal position reference accordingly.  If not, restore
+  the internal file position from last_internal_pos.
+*/
 
-# if defined __CYGWIN__
-  /* Cygwin's stdio.h does not declare __srget(). */
-  int __srget(FILE *);
-# endif /* __CYGWIN__ */
-#endif
 
-#ifndef DEFINED__FILBUF_TO_SOMETHING_SPECIFIC
-extern int  _filbuf(FILE*);
-#endif
+static void
+enter_getfld (m_getfld_state_t *gstate, FILE *iob) {
+    m_getfld_state_t s;
+    off_t pos = ftello (iob);
+
+    if (! *gstate) {
+       m_getfld_state_init (gstate, iob);
+    }
+    s = *gstate;
+    s->bytes_read = 0;
+
+    /* This is ugly and no longer necessary, but is retained just in
+       case it's needed again.  The parser used to open the input file
+       multiple times, so we had to always use the FILE * that's
+       passed to m_getfld().  Now the parser inits a new
+       m_getfld_state for each file.  See comment below about the
+       readpos shift code being currently unused. */
+    s->iob = iob;
+
+    if (s->track_filepos  &&  (pos != 0  ||  s->last_internal_pos != 0)) {
+       if (s->last_internal_pos == 0) {
+           s->total_bytes_read = pos;
+       } else {
+           off_t pos_movement = pos - s->last_caller_pos; /* Can be < 0. */
+
+           if (pos_movement == 0) {
+               pos = s->last_internal_pos;
+           } else {
+               /* The current file stream position differs from the
+                  last one, so caller must have called ftell/o().
+                  Or, this is the first call and the file position
+                  was not at 0. */
+
+               if (s->readpos + pos_movement >= s->msg_buf  &&
+                   s->readpos + pos_movement < s->end) {
+                   /* This is currently unused.  It could be used by
+                      parse_mime() if it was changed to use a global
+                      m_getfld_state. */
+                   /* We can shift readpos and remain within the
+                      bounds of msg_buf. */
+                   s->readpos += pos_movement;
+                   s->total_bytes_read += pos_movement;
+                   pos = s->last_internal_pos;
+               } else {
+                   size_t num_read;
+
+                   /* This seek skips past an integral number of
+                      chunks of size MSG_INPUT_SIZE. */
+                   fseeko (iob, pos/MSG_INPUT_SIZE * MSG_INPUT_SIZE, SEEK_SET);
+                   num_read = fread (s->msg_buf, 1, MSG_INPUT_SIZE, iob);
+                   s->readpos = s->msg_buf  +  pos % MSG_INPUT_SIZE;
+                   s->end = s->msg_buf + num_read;
+                   s->total_bytes_read = pos;
+               }
+           }
+
+           fseeko (iob, pos, SEEK_SET);
+       }
+    }
+}
+
+static void
+leave_getfld (m_getfld_state_t s) {
+    s->total_bytes_read += s->bytes_read;
+
+    if (s->track_filepos) {
+       /* Save the internal file position that we use for the input buffer. */
+       s->last_internal_pos = ftello (s->iob);
+
+       /* Set file stream position so that callers can use ftell(). */
+       fseeko (s->iob, s->total_bytes_read, SEEK_SET);
+       s->last_caller_pos = ftello (s->iob);
+    }
+}
+
+static size_t
+read_more (m_getfld_state_t s) {
+    /* Retain at least edelimlen characters that have already been
+       read so that we can back up to them in m_Eom(). */
+    ssize_t retain = s->edelimlen;
+    size_t num_read;
+
+    if (retain < s->end - s->readpos) retain = s->end - s->readpos;
+    /* assert (retain <= s->readpos - s->msg_buf <= sizeof msg_buf); */
+
+    /* Move what we want to retain at end of the buffer to the beginning. */
+    memmove (s->msg_buf, s->readpos - retain, retain);
+
+    s->readpos = s->msg_buf + retain;
+    num_read = fread (s->readpos, 1, MSG_INPUT_SIZE, s->iob);
+    s->end = s->readpos + num_read;
+
+    return num_read;
+}
+
+static int
+Getc (m_getfld_state_t s) {
+    if (s->end - s->readpos < 1) {
+       if (read_more (s) == 0) {
+           /* Pretend that we read a character.  That's what stdio does. */
+           ++s->readpos;
+           return EOF;
+       }
+    }
+
+    ++s->bytes_read;
+    return s->readpos < s->end  ?  *s->readpos++  :  EOF;
+}
+
+static int
+Peek (m_getfld_state_t s) {
+    if (s->end - s->readpos < 1) {
+       if (read_more (s) == 0) {
+           /* Pretend that we read a character.  That's what stdio does. */
+           ++s->readpos;
+           return EOF;
+       }
+    }
+
+    return s->readpos < s->end  ?  *s->readpos  :  EOF;
+}
+
+static int
+Ungetc (int c, m_getfld_state_t s) {
+    if (s->readpos == s->msg_buf) {
+       return EOF;
+    } else {
+       --s->bytes_read;
+       return *--s->readpos = c;
+    }
+}
 
 
 int
-m_getfld (int state, unsigned char *name, unsigned char *buf,
-          int bufsz, FILE *iob)
+m_getfld (m_getfld_state_t *gstate, unsigned char name[NAMESZ],
+          unsigned char *buf, int *bufsz, FILE *iob)
 {
-    register unsigned char  *bp, *cp, *ep, *sp;
-    register int cnt, c, i, j;
+    m_getfld_state_t s;
+    register unsigned char *cp;
+    register int max, n, c;
 
-    if ((c = Getc(iob)) < 0) {
-       msg_count = 0;
-       *buf = 0;
-       return FILEEOF;
+    enter_getfld (gstate, iob);
+    s = *gstate;
+
+    if ((c = Getc(s)) < 0) {
+       *bufsz = *buf = 0;
+       leave_getfld (s);
+       return s->state = FILEEOF;
     }
-    if (eom (c, iob)) {
-       if (! eom_action) {
+    if (eom (c, s)) {
+       if (! s->eom_action) {
            /* flush null messages */
-           while ((c = Getc(iob)) >= 0 && eom (c, iob))
+           while ((c = Getc(s)) >= 0 && eom (c, s))
                ;
+
            if (c >= 0)
-               ungetc(c, iob);
+               Ungetc(c, s);
        }
-       msg_count = 0;
-       *buf = 0;
-       return FILEEOF;
+       *bufsz = *buf = 0;
+       leave_getfld (s);
+       return s->state = FILEEOF;
     }
 
-    switch (state) {
-       case FLDEOF: 
-       case BODYEOF: 
-       case FLD: 
+    switch (s->state) {
+       case FLD:
            if (c == '\n' || c == '-') {
                /* we hit the header/body separator */
-               while (c != '\n' && (c = Getc(iob)) >= 0)
-                   ;
+               while (c != '\n' && (c = Getc(s)) >= 0) continue;
 
-               if (c < 0 || (c = Getc(iob)) < 0 || eom (c, iob)) {
-                   if (! eom_action) {
+               if (c < 0 || (c = Getc(s)) < 0 || eom (c, s)) {
+                   if (! s->eom_action) {
                        /* flush null messages */
-                       while ((c = Getc(iob)) >= 0 && eom (c, iob))
+                       while ((c = Getc(s)) >= 0 && eom (c, s))
                            ;
                        if (c >= 0)
-                           ungetc(c, iob);
+                           Ungetc(c, s);
                    }
-                   msg_count = 0;
-                   *buf = 0;
-                   return FILEEOF;
+                   *bufsz = *buf = 0;
+                   leave_getfld (s);
+                   return s->state = FILEEOF;
                }
-               state = BODY;
+               s->state = BODY;
                goto body;
            }
            /*
             * get the name of this component.  take characters up
             * to a ':', a newline or NAMESZ-1 characters, whichever
-            * comes first.  
+            * comes first.
             */
            cp = name;
-           i = NAMESZ - 1;
-           for (;;) {
-#ifdef LINUX_STDIO
-               bp = sp = (unsigned char *) iob->_IO_read_ptr - 1;
-               j = (cnt = ((long) iob->_IO_read_end -
-                       (long) iob->_IO_read_ptr)  + 1) < i ? cnt : i;
-#elif defined(__DragonFly__)
-               bp = sp = (unsigned char *) ((struct __FILE_public *)iob)->_p - 1;
-               j = (cnt = ((struct __FILE_public *)iob)->_r+1) < i ? cnt : i;
-#else
-               bp = sp = (unsigned char *) iob->_ptr - 1;
-               j = (cnt = iob->_cnt+1) < i ? cnt : i;
-#endif
-               while (--j >= 0 && (c = *bp++) != ':' && c != '\n')
-                   *cp++ = c;
-
-               j = bp - sp;
-               if ((cnt -= j) <= 0) {
-#ifdef LINUX_STDIO
-                   iob->_IO_read_ptr = iob->_IO_read_end;
-                   if (__underflow(iob) == EOF) {
-#elif defined(__DragonFly__)
-                   if (__srget(iob) == EOF) {
-#else
-                   if (_filbuf(iob) == EOF) {
-#endif
-                       *cp = *buf = 0;
-                       advise (NULL, "eof encountered in field \"%s\"", name);
-                       return FMTERR;
-                   }
-#ifdef LINUX_STDIO
-               iob->_IO_read_ptr++; /* NOT automatic in __underflow()! */
-#endif
-               } else {
-#ifdef LINUX_STDIO
-                   iob->_IO_read_ptr = bp + 1;
-#elif defined(__DragonFly__)
-                   ((struct __FILE_public *)iob)->_p = bp + 1;
-                   ((struct __FILE_public *)iob)->_r = cnt - 1;
-#else
-                   iob->_ptr = bp + 1;
-                   iob->_cnt = cnt - 1;
-#endif
-               }
-               if (c == ':')
-                   break;
+           max = NAMESZ - 1;
+           /* Get the field name.  The first time through the loop,
+              this copies out the first character, which was loaded
+              into c prior to loop entry.  Initialize n to 1 to
+              account for that. */
+           for (n = 1;
+                c != ':'  &&  c != '\n'  &&  c != EOF  &&  n < max;
+                ++n, c = Getc (s)) {
+               *cp++ = c;
+           }
 
-               /*
-                * something went wrong.  possibilities are:
-                *  . hit a newline (error)
-                *  . got more than namesz chars. (error)
-                *  . hit the end of the buffer. (loop)
-                */
-               if (c == '\n') {
-                   /* We hit the end of the line without seeing ':' to
-                    * terminate the field name.  This is usually (always?)
-                    * spam.  But, blowing up is lame, especially when
-                    * scan(1)ing a folder with such messages.  Pretend such
-                    * lines are the first of the body (at least mutt also
-                    * handles it this way). */
-
-                   /* See if buf can hold this line, since we were assuming
-                    * we had a buffer of NAMESZ, not bufsz. */
-                   /* + 1 for the newline */
-                   if (bufsz < j + 1) {
-                       /* No, it can't.  Oh well, guess we'll blow up. */
-                       *cp = *buf = 0;
-                       advise (NULL, "eol encountered in field \"%s\"", name);
-                       state = FMTERR;
-                       goto finish;
-                   }
-                   memcpy (buf, name, j - 1);
-                   buf[j - 1] = '\n';
-                   buf[j] = '\0';
-                   /* mhparse.c:get_content wants to find the position of the
-                    * body start, but it thinks there's a blank line between
-                    * the header and the body (naturally!), so seek back so
-                    * that things line up even though we don't have that
-                    * blank line in this case.  Simpler parsers (e.g. mhl)
-                    * get extra newlines, but that should be harmless enough,
-                    * right?  This is a corrupt message anyway. */
-                   fseek (iob, ftell (iob) - 2, SEEK_SET);
-                   return BODY;
+           /* Check for next character, which is either the space after
+              the ':' or the first folded whitespace. */
+           {
+               int next_char;
+               if (c == EOF  ||  (next_char = Peek (s)) == EOF) {
+                   *bufsz = *cp = *buf = 0;
+                   advise (NULL, "eof encountered in field \"%s\"", name);
+                   leave_getfld (s);
+                   return s->state = FMTERR;
                }
-               if ((i -= j) <= 0) {
-                   *cp = *buf = 0;
-                   advise (NULL, "field name \"%s\" exceeds %d bytes", name, NAMESZ - 2);
-                   state = LENERR;
-                   goto finish;
+           }
+
+           /* If c isn't ':' here, something went wrong.  Possibilities are:
+            *  . hit a newline (error)
+            *  . got more than namesz chars. (error)
+            */
+           if (c == ':') {
+               /* Finished header name, fall through to FLDPLUS below. */
+           } else if (c == '\n') {
+               /* We hit the end of the line without seeing ':' to
+                * terminate the field name.  This is usually (always?)
+                * spam.  But, blowing up is lame, especially when
+                * scan(1)ing a folder with such messages.  Pretend such
+                * lines are the first of the body (at least mutt also
+                * handles it this way). */
+
+               /* See if buf can hold this line, since we were assuming
+                * we had a buffer of NAMESZ, not bufsz. */
+               /* + 1 for the newline */
+               if (*bufsz < n + 1) {
+                   /* No, it can't.  Oh well, guess we'll blow up. */
+                   *bufsz = *cp = *buf = 0;
+                   advise (NULL, "eol encountered in field \"%s\"", name);
+                   s->state = FMTERR;
+                   break;
                }
+               memcpy (buf, name, n - 1);
+               buf[n - 1] = '\n';
+               buf[n] = '\0';
+               /* The last character read was '\n'.  s->bytes_read
+                  (and n) include that, but it was not put into the
+                  name array in the for loop above.  So subtract 1. */
+               *bufsz = --s->bytes_read;  /* == n - 1 */
+               leave_getfld (s);
+               return s->state = BODY;
+           } else if (max <= n) {
+               /* By design, the loop above discards the last character
+                   it had read.  It's in c, use it. */
+               *cp++ = c;
+               *bufsz = *cp = *buf = 0;
+               advise (NULL, "field name \"%s\" exceeds %d bytes", name,
+                       NAMESZ - 2);
+               s->state = LENERR;
+               break;
            }
 
-           while (isspace (*--cp) && cp >= name)
-               ;
+           /* Trim any trailing spaces from the end of name. */
+           while (isspace (*--cp) && cp >= name) continue;
            *++cp = 0;
+           /* readpos points to the first character of the field body. */
            /* fall through */
 
-       case FLDPLUS: 
+       case FLDPLUS: {
            /*
-            * get (more of) the text of a field.  take
+            * get (more of) the text of a field.  Take
             * characters up to the end of this field (newline
             * followed by non-blank) or bufsz-1 characters.
             */
-           cp = buf; i = bufsz-1;
-           for (;;) {
-#ifdef LINUX_STDIO
-               cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr;
-               bp = (unsigned char *) --iob->_IO_read_ptr;
-#elif defined(__DragonFly__)
-               cnt = ((struct __FILE_public *)iob)->_r++;
-               bp = (unsigned char *) --((struct __FILE_public *)iob)->_p;
-#else
-               cnt = iob->_cnt++;
-               bp = (unsigned char *) --iob->_ptr;
-#endif
-               c = cnt < i ? cnt : i;
-               while ((ep = locc( c, bp, '\n' ))) {
-                   /*
-                    * if we hit the end of this field, return.
-                    */
-                   if ((j = *++ep) != ' ' && j != '\t') {
-#ifdef LINUX_STDIO
-                       j = ep - (unsigned char *) iob->_IO_read_ptr;
-                       memcpy (cp, iob->_IO_read_ptr, j);
-                       iob->_IO_read_ptr = ep;
-#elif defined(__DragonFly__)
-                       j = ep - (unsigned char *) ((struct __FILE_public *)iob)->_p;
-                       memcpy (cp, ((struct __FILE_public *)iob)->_p, j);
-                       ((struct __FILE_public *)iob)->_p = ep;
-                       ((struct __FILE_public *)iob)->_r -= j;
-#else
-                       j = ep - (unsigned char *) iob->_ptr;
-                       memcpy (cp, iob->_ptr, j);
-                       iob->_ptr = ep;
-                       iob->_cnt -= j;
-#endif
-                       cp += j;
-                       state = FLD;
-                       goto finish;
-                   }
-                   c -= ep - bp;
-                   bp = ep;
+           int finished;
+
+           cp = buf;
+           max = *bufsz-1;
+           n = 0;
+           for (finished = 0; ! finished; ) {
+               while (c != '\n'  &&  c != EOF  &&  n++ < max) {
+                   *cp++ = c = Getc (s);
                }
-               /*
-                * end of input or dest buffer - copy what we've found.
-                */
-#ifdef LINUX_STDIO
-               c += bp - (unsigned char *) iob->_IO_read_ptr;
-               memcpy( cp, iob->_IO_read_ptr, c);
-#elif defined(__DragonFly__)
-               c += bp - (unsigned char *) ((struct __FILE_public *)iob)->_p;
-               memcpy( cp, ((struct __FILE_public *)iob)->_p, c);
-#else
-               c += bp - (unsigned char *) iob->_ptr;
-               memcpy( cp, iob->_ptr, c);
-#endif
-               i -= c;
-               cp += c;
-               if (i <= 0) {
+
+               if (c != EOF) c = Peek (s);
+               if (max < n) {
                    /* the dest buffer is full */
-#ifdef LINUX_STDIO
-                   iob->_IO_read_ptr += c;
-#elif defined(__DragonFly__)
-                   ((struct __FILE_public *)iob)->_r -= c;
-                   ((struct __FILE_public *)iob)->_p += c;
-#else
-                   iob->_cnt -= c;
-                   iob->_ptr += c;
-#endif
-                   state = FLDPLUS;
-                   break;
-               }
-               /* 
-                * There's one character left in the input buffer.
-                * Copy it & fill the buffer.  If the last char
-                * was a newline and the next char is not whitespace,
-                * this is the end of the field.  Otherwise loop.
-                */
-               --i;
-#ifdef LINUX_STDIO
-               *cp++ = j = *(iob->_IO_read_ptr + c);
-               iob->_IO_read_ptr = iob->_IO_read_end;
-               c = __underflow(iob);
-               iob->_IO_read_ptr++;    /* NOT automatic! */
-#elif defined(__DragonFly__)
-               *cp++ =j = *(((struct __FILE_public *)iob)->_p + c);
-               c = __srget(iob);
-#else
-               *cp++ = j = *(iob->_ptr + c);
-               c = _filbuf(iob);
-#endif
-                if (c == EOF || 
-                 ((j == '\0' || j == '\n') && c != ' ' && c != '\t')) {
-                   if (c != EOF) {
-#ifdef LINUX_STDIO
-                       --iob->_IO_read_ptr;
-#elif defined(__DragonFly__)
-                       --((struct __FILE_public *)iob)->_p;
-                       ++((struct __FILE_public *)iob)->_r;
-#else
-                       --iob->_ptr;
-                       ++iob->_cnt;
-#endif
-                   }
-                   state = FLD;
-                   break;
+                   s->state = FLDPLUS;
+                   finished = 1;
+               } else if (c != ' '  &&  c != '\t') {
+                   /* The next character is not folded whitespace, so
+                      prepare to move on to the next field.  It's OK
+                      if c is EOF, it will be handled on the next
+                      call to m_getfld (). */
+                   s->state = FLD;
+                   finished = 1;
+               } else {
+                   /* Folded header field, continues on the next line. */
                }
            }
+           *bufsz = s->bytes_read;
            break;
+        }
 
-       case BODY: 
        body:
+       case BODY: {
            /*
             * get the message body up to bufsz characters or the
-            * end of the message.  Sleazy hack: if bufsz is negative
-            * we assume that we were called to copy directly into
-            * the output buffer and we don't add an eos.
+            * end of the message.
             */
-           i = (bufsz < 0) ? -bufsz : bufsz-1;
-#ifdef LINUX_STDIO
-           bp = (unsigned char *) --iob->_IO_read_ptr;
-           cnt = (long) iob->_IO_read_end - (long) iob->_IO_read_ptr;
-#elif defined(__DragonFly__)
-           bp = (unsigned char *) --((struct __FILE_public *)iob)->_p;
-           cnt = ++((struct __FILE_public *)iob)->_r;
-#else
-           bp = (unsigned char *) --iob->_ptr;
-           cnt = ++iob->_cnt;
-#endif
-           c = (cnt < i ? cnt : i);
-           if (msg_style != MS_DEFAULT && c > 1) {
+           unsigned char *bp;
+
+           max = *bufsz-1;
+           /* Back up and store the current position. */
+           bp = --s->readpos;
+           c = s->end - s->readpos < max  ?  s->end - s->readpos  :  max;
+           if (s->msg_style != MS_DEFAULT && c > 1) {
                /*
                 * packed maildrop - only take up to the (possible)
                 * start of the next message.  This "matchc" should
@@ -498,7 +672,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf,
                 * algorithms vs. brute force.)  Since I (currently)
                 * run MH on a vax, we use the matchc instruction. --vj
                 */
-               if ((ep = matchc( fdelimlen, fdelim, c, bp )))
+               unsigned char *ep;
+
+               if ((ep = matchc( s->fdelimlen, s->fdelim, c, bp )))
                    c = ep - bp + 1;
                else {
                    /*
@@ -514,8 +690,10 @@ m_getfld (int state, unsigned char *name, unsigned char *buf,
                     * ends with one of the characters in the pattern
                     * (excluding the first and last), we do only one test.
                     */
+                   unsigned char *sp;
+
                    ep = bp + c - 1;
-                   if ((sp = pat_map[*ep])) {
+                   if ((sp = s->pat_map[*ep])) {
                        do {
                            /* This if() is true unless (a) the buffer is too
                             * small to contain this delimiter prefix, or
@@ -527,7 +705,7 @@ m_getfld (int state, unsigned char *name, unsigned char *buf,
                             * should have found it.  Thus it's not a delim
                             * and we know we won't get a match.
                             */
-                           if (((sp - fdelim) + 2) <= c) {
+                           if (((sp - s->fdelim) + 2) <= c) {
                                cp = sp;
                                /* Unfortunately although fdelim has a preceding NUL
                                 * we can't use this as a sentinel in case the buffer
@@ -535,9 +713,9 @@ m_getfld (int state, unsigned char *name, unsigned char *buf,
                                 * would cause us to run off the front of fdelim).
                                 */
                                while (*--ep == *--cp)
-                                   if (cp < fdelim)
+                                   if (cp < s->fdelim)
                                        break;
-                               if (cp < fdelim) {
+                               if (cp < s->fdelim) {
                                    /* we matched the entire delim prefix,
                                     * so only take the buffer up to there.
                                     * we know ep >= bp -- check above prevents underrun
@@ -548,45 +726,47 @@ m_getfld (int state, unsigned char *name, unsigned char *buf,
                            }
                            /* try matching one less char of delim string */
                            ep = bp + c - 1;
-                       } while (--sp > fdelim);
+                       } while (--sp > s->fdelim);
                    }
                }
            }
            memcpy( buf, bp, c );
-#ifdef LINUX_STDIO
-           iob->_IO_read_ptr += c;
-#elif defined(__DragonFly__)
-           ((struct __FILE_public *)iob)->_r -= c;
-           ((struct __FILE_public *)iob)->_p += c;
-#else
-           iob->_cnt -= c;
-           iob->_ptr += c;
-#endif
-           if (bufsz < 0) {
-               msg_count = c;
-               return (state);
-           }
+           /* Advance the current position to reflect the copy out.
+              c is less than or equal to the number of bytes remaining
+              in the read buffer, so will not overrun it. */
+           s->readpos += c;
            cp = buf + c;
+           /* Subtract 1 from c because the first character was read by
+              Getc(), and therefore already accounted for in s->bytes_read. */
+           s->bytes_read += c - 1;
+           *bufsz = s->bytes_read;
            break;
+        }
 
-       default: 
-           adios (NULL, "m_getfld() called with bogus state of %d", state);
+       default:
+           adios (NULL, "m_getfld() called with bogus state of %d", s->state);
     }
-finish:
+
     *cp = 0;
-    msg_count = cp - buf;
-    return (state);
+    leave_getfld (s);
+
+    return s->state;
 }
 
 
 void
-m_unknown(FILE *iob)
+m_unknown(m_getfld_state_t *gstate, FILE *iob)
 {
+    m_getfld_state_t s;
     register int c;
-    register long pos;
-    char text[10];
+    char text[MAX_DELIMITER_SIZE];
+    char from[] = "From ";
     register char *cp;
     register char *delimstr;
+    unsigned int i;
+
+    enter_getfld (gstate, iob);
+    s = *gstate;
 
 /*
  * Figure out what the message delimitter string is for this
@@ -601,34 +781,35 @@ m_unknown(FILE *iob)
  * specified when nmh was built (or from the mts.conf file).
  */
 
-    msg_style = MS_UNKNOWN;
+    s->msg_style = MS_UNKNOWN;
+
+    for (i = 0, cp = text; i < sizeof text; ++i, ++cp) {
+       if ((*cp = Getc (s)) == EOF) {
+           break;
+       }
+    }
 
-    pos = ftell (iob);
-    if (fread (text, sizeof(*text), 5, iob) == 5
-           && strncmp (text, "From ", 5) == 0) {
-       msg_style = MS_MBOX;
+    if (i == sizeof from-1  &&  strncmp (text, "From ", sizeof from-1) == 0) {
+       s->msg_style = MS_MBOX;
        delimstr = "\nFrom ";
-       while ((c = getc (iob)) != '\n' && c >= 0)
-           ;
+       while ((c = Getc (s)) != '\n' && c >= 0) continue;
     } else {
        /* not a Unix style maildrop */
-       fseek (iob, pos, SEEK_SET);
-       if (mmdlm2 == NULL || *mmdlm2 == 0)
-           mmdlm2 = "\001\001\001\001\n";
+       s->readpos -= s->bytes_read;
        delimstr = mmdlm2;
-       msg_style = MS_MMDF;
+       s->msg_style = MS_MMDF;
     }
     c = strlen (delimstr);
-    fdelim = (unsigned char *) mh_xmalloc((size_t) (c + 3));
-    *fdelim++ = '\0';
-    *fdelim = '\n';
-    msg_delim = (char *)fdelim+1;
-    edelim = (unsigned char *)msg_delim+1;
-    fdelimlen = c + 1;
-    edelimlen = c - 1;
-    strcpy (msg_delim, delimstr);
-    delimend = (unsigned char *)msg_delim + edelimlen;
-    if (edelimlen <= 1)
+    s->fdelim = (unsigned char *) mh_xmalloc((size_t) (c + 3));
+    *s->fdelim++ = '\0';
+    *s->fdelim = '\n';
+    s->msg_delim = (char *)s->fdelim+1;
+    s->edelim = (unsigned char *)s->msg_delim+1;
+    s->fdelimlen = c + 1;
+    s->edelimlen = c - 1; /* == strlen (delimstr) */
+    strcpy (s->msg_delim, delimstr);
+    s->delimend = (unsigned char *)s->msg_delim + s->edelimlen;
+    if (s->edelimlen <= 1)
        adios (NULL, "maildrop delimiter must be at least 2 bytes");
     /*
      * build a Boyer-Moore end-position map for the matcher in m_getfld.
@@ -636,34 +817,36 @@ m_unknown(FILE *iob)
      * separator) or the last char (since the matchc would have found it
      * if it was a real delim).
      */
-    pat_map = (unsigned char **) calloc (256, sizeof(unsigned char *));
+    s->pat_map = (unsigned char **) calloc (256, sizeof(unsigned char *));
 
-    for (cp = (char *) fdelim + 1; cp < (char *) delimend; cp++ )
-       pat_map[(unsigned char)*cp] = (unsigned char *) cp;
+    for (cp = (char *) s->fdelim + 1; cp < (char *) s->delimend; cp++ )
+       s->pat_map[(unsigned char)*cp] = (unsigned char *) cp;
 
-    if (msg_style == MS_MMDF) {
+    if (s->msg_style == MS_MMDF) {
        /* flush extra msg hdrs */
-       while ((c = Getc(iob)) >= 0 && eom (c, iob))
+       while ((c = Getc(s)) >= 0 && eom (c, s))
            ;
        if (c >= 0)
-           ungetc(c, iob);
+           Ungetc(c, s);
     }
+
+    leave_getfld (s);
 }
 
 
 void
-m_eomsbr (int (*action)(int))
+m_eomsbr (m_getfld_state_t s, int (*action)(int))
 {
-    if ((eom_action = action)) {
-       msg_style = MS_MSH;
-       *msg_delim = 0;
-       fdelimlen = 1;
-       delimend = fdelim;
+    if ((s->eom_action = action)) {
+       s->msg_style = MS_MSH;
+       *s->msg_delim = 0;
+       s->fdelimlen = 1;
+       s->delimend = s->fdelim;
     } else {
-       msg_style = MS_MMDF;
-       msg_delim = (char *)fdelim + 1;
-       fdelimlen = strlen((char *)fdelim);
-       delimend = (unsigned char *)(msg_delim + edelimlen);
+       s->msg_style = MS_MMDF;
+       s->msg_delim = (char *)s->fdelim + 1;
+       s->fdelimlen = strlen((char *)s->fdelim);
+       s->delimend = (unsigned char *)(s->msg_delim + s->edelimlen);
     }
 }
 
@@ -673,32 +856,35 @@ m_eomsbr (int (*action)(int))
  */
 
 static int
-m_Eom (int c, FILE *iob)
+m_Eom (m_getfld_state_t s, int c)
 {
-    register long pos = 0L;
     register int i;
-    char text[10];
+    char text[MAX_DELIMITER_SIZE];
+    char *cp;
 
-    pos = ftell (iob);
-    if ((i = fread (text, sizeof *text, edelimlen, iob)) != edelimlen
-           || strncmp (text, (char *)edelim, edelimlen)) {
-       if (i == 0 && msg_style == MS_MBOX)
+    for (i = 0, cp = text; i < s->edelimlen; ++i, ++cp) {
+       if ((*cp = Getc (s)) == EOF) {
+           break;
+       }
+    }
+
+    if (i != s->edelimlen  ||
+        strncmp (text, (char *)s->edelim, s->edelimlen)) {
+       if (i == 0 && s->msg_style == MS_MBOX)
            /* the final newline in the (brain damaged) unix-format
             * maildrop is part of the delimitter - delete it.
             */
            return 1;
 
-#if 0
-       fseek (iob, pos, SEEK_SET);
-#endif
-
-       fseek (iob, (long)(pos-1), SEEK_SET);
-       getc (iob);             /* should be OK */
+       /* Did not find delimiter, so restore the read position.
+          Note that on input, a character had already been read
+          with Getc().  It will be unget by m_getfld () on return. */
+       s->readpos -= s->bytes_read - 1;
        return 0;
     }
 
-    if (msg_style == MS_MBOX) {
-       while ((c = getc (iob)) != '\n')
+    if (s->msg_style == MS_MBOX) {
+       while ((c = Getc (s)) != '\n')
            if (c < 0)
                break;
     }
@@ -725,22 +911,7 @@ matchc(int patln, char *pat, int strln, char *str)
                sp = str; pp = pat;
                while (pp < ep && *sp++ == *pp)
                        pp++;
-               if (pp >= ep) 
+               if (pp >= ep)
                        return ((unsigned char *)--str);
        }
 }
-
-
-/*
- * Locate character "term" in the next "cnt" characters of "src".
- * If found, return its address, otherwise return 0.
- */
-
-static unsigned char *
-locc(int cnt, unsigned char *src, unsigned char term)
-{
-    while (*src++ != term && --cnt > 0);
-
-    return (cnt > 0 ? --src : (unsigned char *)0);
-}
-
diff --git a/sbr/m_msgdef.c b/sbr/m_msgdef.c
deleted file mode 100644 (file)
index d602973..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/*
- * m_msgdef.c -- some defines for sbr/m_getfld.c
- *
- * This code is Copyright (c) 2002, by the authors of nmh.  See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-#include <h/mh.h>
-
-/*
- * disgusting hack for "inc" so it can know how many characters
- * were stuffed in the buffer on the last call (see comments
- * in uip/scansbr.c)
- */
-int msg_count = 0;
-
-int msg_style = MS_DEFAULT;
-
-/*
- * The "full" delimiter string for a packed maildrop consists
- * of a newline followed by the actual delimiter.  E.g., the
- * full string for a Unix maildrop would be: "\n\nFrom ".
- * "Fdelim" points to the start of the full string and is used
- * in the BODY case of the main routine to search the buffer for
- * a possible eom.  Msg_delim points to the first character of
- * the actual delim. string (i.e., fdelim+1).  Edelim
- * points to the 2nd character of actual delimiter string.  It
- * is used in m_Eom because the first character of the string
- * has been read and matched before m_Eom is called.
- */
-char *msg_delim = "";
index 1ddd648f9feeef1563452102578e9e9fd89774e6..b25ea99aa2f6f4c93e40c9c1ffbac1b5a22376ba 100644 (file)
@@ -52,17 +52,18 @@ readconfig (struct node **npp, FILE *ib, char *file, int ctx)
     char name[NAMESZ], field[BUFSIZ];
     register struct node *np;
     register struct procstr *ps;
+    m_getfld_state_t gstate = 0;
 
     if (npp == NULL && (npp = opp) == NULL) {
        admonish (NULL, "bug: readconfig called but pump not primed");
        return;
     }
 
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, field, sizeof(field), ib)) {
+    for (;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, ib)) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                np = (struct node *) mh_xmalloc (sizeof(*np));
                *npp = np;
                *(npp = &np->n_next) = NULL;
@@ -70,7 +71,8 @@ readconfig (struct node **npp, FILE *ib, char *file, int ctx)
                if (state == FLDPLUS) {
                    cp = getcpy (field);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, field, sizeof(field), ib);
+                       fieldsz = sizeof field;
+                       state = m_getfld (&gstate, name, field, &fieldsz, ib);
                        cp = add (field, cp);
                    }
                    np->n_field = trimcpy (cp);
@@ -89,12 +91,9 @@ readconfig (struct node **npp, FILE *ib, char *file, int ctx)
                        *ps->procnaddr = np->n_field;
                        break;
                    }
-               if (state == FLDEOF)
-                   break;
                continue;
 
            case BODY:
-           case BODYEOF:
                adios (NULL, "no blank lines are permitted in %s", file);
 
            case FILEEOF:
@@ -105,6 +104,7 @@ readconfig (struct node **npp, FILE *ib, char *file, int ctx)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * Special handling for the pager processes: lproc and moreproc.
index 985c61e843a9813890e7bad71a6bcf8e0fe5c572..a807ef7d6169b0b000c57535c163590f8e190fd5 100644 (file)
@@ -59,6 +59,7 @@ seq_public (struct msgs *mp)
     char *cp, seqfile[PATH_MAX];
     char name[NAMESZ], field[BUFSIZ];
     FILE *fp;
+    m_getfld_state_t gstate = 0;
 
     /*
      * If mh_seq == NULL (such as if nmh been compiled with
@@ -76,15 +77,16 @@ seq_public (struct msgs *mp)
        return;
 
     /* Use m_getfld to scan sequence file */
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, field, sizeof(field), fp)) {
+    for (;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, fp)) {
            case FLD: 
            case FLDPLUS:
-           case FLDEOF: 
                if (state == FLDPLUS) {
                    cp = getcpy (field);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, field, sizeof(field), fp);
+                       fieldsz = sizeof field;
+                       state = m_getfld (&gstate, name, field, &fieldsz, fp);
                        cp = add (field, cp);
                    }
                    seq_init (mp, getcpy (name), trimcpy (cp));
@@ -92,12 +94,9 @@ seq_public (struct msgs *mp)
                } else {
                    seq_init (mp, getcpy (name), trimcpy (field));
                }
-               if (state == FLDEOF)
-                   break;
                continue;
 
            case BODY: 
-           case BODYEOF: 
                adios (NULL, "no blank lines are permitted in %s", seqfile);
                /* fall */
 
@@ -109,6 +108,7 @@ seq_public (struct msgs *mp)
        }
        break;  /* break from for loop */
     }
+    m_getfld_state_destroy (&gstate);
 
     lkfclose (fp, seqfile);
 }
index 88a098b3a0e629678b3c386eb1f51e728aacf33f..4d1d3d6814b7f977897a2dbd22819de3ee220788 100644 (file)
@@ -29,16 +29,16 @@ smatch(char *string, struct swit *swp)
            continue;                   /* no match */
        for (sp = string; *sp == *tcp++;) {
            if (*sp++ == '\0')
-               return (tp - swp);      /* exact match */
+               return tp->swret;       /* exact match */
        }
        if (*sp) {
            if (*sp != ' ')
                continue;               /* no match */
            if (*--tcp == '\0')
-               return (tp - swp);      /* exact match */
+               return tp->swret;       /* exact match */
        }
        if (firstone == UNKWNSW)
-           firstone = tp - swp;
+           firstone = tp->swret;
        else
            firstone = AMBIGSW;
     }
index 9e66296ded055704a9156cb2c09b2093c96650ed..e993cce812f6e7bcd5d5f7216c1f48a232d378f6 100755 (executable)
@@ -1,10 +1,12 @@
 #!/bin/sh
 ######################################################
 #
-# Test bogus headers (no blank line before body).
+# Test bogus headers (no blank line before body, etc.)
 #
 ######################################################
 
+set -e
+
 if test -z "${MH_OBJ_DIR}"; then
     srcdir=`dirname "$0"`/../..
     MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
@@ -14,13 +16,14 @@ fi
 
 setup_test
 
-expected=$MH_TEST_DIR/$$.expected
-actual=$MH_TEST_DIR/$$.actual
+expected="$MH_TEST_DIR/$$.expected"
+expected_err="$MH_TEST_DIR/$$.expected_err"
+actual="$MH_TEST_DIR/$$.actual"
+actual_err="$MH_TEST_DIR/$$.actual_err"
 
 # Write message with bogus header field (missing blank line, really).
-msgfile=`mhpath new`
-msgnum=`basename $msgfile`
-cat > $msgfile <<EOF
+msgfile="$MH_TEST_DIR/Mail/inbox/11"
+cat >"$msgfile" <<EOF
 Date: Sun, 18 Dec 2005 00:52:39 +0100
 From: foo@example.edu
 To: bar@example.edu
@@ -31,14 +34,14 @@ I am a stupid spammer.
 EOF
 
 # check scan
-cat > $expected <<EOF
+cat >"$expected" <<EOF
   11  12/18 foo@example.edu    test<<This is a multi-part message in MIME forma
 EOF
-scan -width 80 $msgnum > $actual 2>&1
-check $expected $actual
+scan -width 80 last > "$actual" 2>&1
+check "$expected" "$actual"
 
 # check show (mhl)
-cat > $expected <<EOF
+cat >"$expected" <<EOF
 (Message inbox:11)
 
 Date:    Sun, 18 Dec 2005 00:52:39 +0100
@@ -49,14 +52,13 @@ Subject: test
 
 This is a multi-part message in MIME format.
 
-
 I am a stupid spammer.
 EOF
-show $msgnum > $actual 2>&1
-check $expected $actual
+show last > "$actual" 2>&1
+check "$expected" "$actual"
 
 # check mhshow
-cat > $expected <<EOF
+cat >"$expected" <<EOF
 Date:    Sun, 18 Dec 2005 00:52:39 +0100
 To:      bar@example.edu
 From:    foo@example.edu
@@ -69,7 +71,72 @@ This is a multi-part message in MIME format.
 
 I am a stupid spammer.
 EOF
-mhshow -nopause $msgnum > $actual 2>&1
-check $expected $actual
+mhshow -nopause last > "$actual" 2>&1
+check "$expected" "$actual"
+
+# check m_getfld() handling of empty header field
+msgfile="$MH_TEST_DIR/Mail/inbox/12"
+printf 'Date: Sat, 12 Jan 2013 09:07:01 -0600\nReceived:' >"$msgfile"
+cat >"$expected" <<EOF
+  12  01/12 
+EOF
+cat >"$expected_err" <<EOF
+scan: eof encountered in field "Received"
+??Format error (message 12) in component 2
+EOF
+
+scan -width 13 last >"$actual" 2>"$actual_err"
+check "$expected" "$actual"
+check "$expected_err" "$actual_err"
+
+# check m_getfld() handling of excessively long header field name
+msgfile="$MH_TEST_DIR/Mail/inbox/13"
+cat >"$msgfile" <<EOF
+Date: Tue, 15 Jan 2013 21:13:12 -0600
+ThisHeaderFieldNameIsWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayTooLong: OK
+EOF
+cat >"$expected" <<EOF
+  13  01/15 
+EOF
+
+scan -width 13 last >"$actual" 2>"$actual_err"
+check "$expected" "$actual"
+# Cygwin has a BUFSIZ of 1024 so the error message gets truncated.
+# Deal with that by grepping to verify that scan showed the proper error.
+verify_string_in_file() {
+  if grep "$1" "$2" >/dev/null; then
+    :
+  else
+    echo "$0: did not receive expected error message \"$1\""
+    failed=`expr ${failed:-0} + 1`
+  fi
+}
+verify_string_in_file 'scan: field name "ThisHeaderFieldNameIsWa' "$actual_err"
+verify_string_in_file 'exceeds 997' "$actual_err"
+verify_string_in_file '??Format error (message 13) in component 2' "$actual_err"
+rm -f "$actual_err"
+
+# check m_getfld() handling of long header field name without a colon
+msgfile="$MH_TEST_DIR/Mail/inbox/14"
+cat >"$msgfile" <<EOF
+Date: Thu, 17 Jan 2013 19:33:46 -0600
+If a header field name has at least 512 characters without a newline or colon, it will raise a format error in m_getfld().  Here is a test of that.  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901
+
+Test
+
+
+EOF
+cat >"$expected" <<EOF
+  14  01/17 
+EOF
+cat >"$expected_err" <<EOF
+scan: eol encountered in field "If a header field name has at least 512 characters without a newline or colon, it will raise a format error in m_getfld().  Here is a test of that.  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901"
+??Format error (message 14) in component 2
+EOF
+
+scan -width 13 last >"$actual" 2>"$actual_err"
+check "$expected" "$actual"
+check "$expected_err" "$actual_err"
+
 
 exit $failed
index f7624ca85a70a6663812ea4f8ecf00ed7c569606..390f94f98f8d4753a2c3d7cfe2fcfb28d05b576b 100644 (file)
@@ -13,9 +13,8 @@ test -z "$auxexecdir"  &&  auxexecdir="@libdir@"
 test -z "$bindir"  &&  bindir="@bindir@"
 test -z "$mandir"  &&  mandir="@mandir@"
 test -z "$sysconfdir"  &&  sysconfdir="@sysconfdir@"
-test -z "$pagerpath"  &&  pagerpath="@pagerpath@"
 test -z "$MULTIBYTE_ENABLED"  &&  MULTIBYTE_ENABLED="@MULTIBYTE_ENABLED@"
-export MH_TEST_DIR auxexecdir bindir mandir sysconfdir pagerpath
+export MH_TEST_DIR auxexecdir bindir mandir sysconfdir
 export MULTIBYTE_ENABLED
 
 test -z "$MH_INST_DIR"  &&  MH_INST_DIR="${MH_TEST_DIR}/inst"
index 7ef656cdd1cc64398f8cdce62c5aeee24f30aef9..0753ecb0f4d90f404c29c20b1bc5a93881758149 100755 (executable)
@@ -388,7 +388,7 @@ check "$expected" "$actual"
 
 # check -check
 cat >"$expected" <<EOF
-sortm: can't parse date field in message 14, continuing...
+sortm: can't parse date field in message 14, will use file modification time
 sortm: errors found, no messages sorted
 EOF
 
@@ -437,7 +437,8 @@ EOF
 
 sed -e 's/Sep//' $MH_TEST_DIR/Mail/inbox/7 > $MH_TEST_DIR/Mail/inbox/14
 run_test 'sortm -check -nocheck' \
-         "sortm: can't parse date field in message 14, continuing..."
+         "sortm: can't parse date field in message 14, will use file \
+modification time"
 scan >"$actual"
 check "$expected" "$actual"
 
diff --git a/test/format/test-rightjustify b/test/format/test-rightjustify
new file mode 100755 (executable)
index 0000000..2685efd
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Test that the right justification feature works correctly.
+#
+
+if test -z "${MH_OBJ_DIR}"; then
+    srcdir=`dirname "$0"`/../..
+    MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
+fi
+
+. "$MH_OBJ_DIR/test/common.sh"
+
+setup_test
+
+actual=`${MH_LIB_DIR}/ap -format "%-30(friendly{text})<<End of test" "No Such User <nosuch@user.com>"`
+expected="                  No Such User<<End of test"
+##########123456789012345678901234567890
+
+if test x"$actual" != x"$expected"; then
+    echo "$0: right justification test expected:" 1>&2
+    echo "    $expected" 1>&2
+    echo "but instead got:" 1>&2
+    echo "    $actual" 1>&2
+    failed=`expr ${failed:-0} + 1`
+fi
+
+exit $failed
diff --git a/test/getcwidth.c b/test/getcwidth.c
new file mode 100644 (file)
index 0000000..2df307c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * getcwidth - Get the OS's idea of the width of a combining character
+ *
+ * This code is Copyright (c) 2012, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef MULTIBYTE_SUPPORT
+#include <locale.h>
+#include <wchar.h>
+#endif
+
+int
+main(int argc, char *argv[])
+{
+       wchar_t c;
+       int charlen;
+       char *p;
+
+       /*
+        * This is the UTF-8 for "n" + U+0308 (Combining Diaeresis)
+        */
+
+       unsigned char string[] = "n\xcc\x88";
+
+       setlocale(LC_ALL, "");
+
+       if (argc != 1) {
+               fprintf(stderr, "Usage: %s\n", argv[0]);
+               fprintf(stderr, "Returns the column width of a UTF-8 "
+                       "multibyte character\n");
+               exit(1);
+       }
+
+#ifndef MULTIBYTE_SUPPORT
+       fprintf(stderr, "Nmh was not configured with multibyte support\n");
+       exit(1);
+#else
+       /*
+        * It's not clear to me that we can just call mbtowc() with a
+        * combining character; just to be safe, feed it in a base
+        * character first.
+        */
+
+       mbtowc(NULL, NULL, 0);
+
+       charlen = mbtowc(&c, string, strlen(string));
+
+       if (charlen != 1) {
+               fprintf(stderr, "We expected a beginning character length "
+                       "of 1, got %d instead\n", charlen);
+               exit(1);
+       }
+
+       p = string + charlen;
+
+       charlen = mbtowc(&c, p, strlen(p));
+
+       if (charlen != 2) {
+               fprintf(stderr, "We expected a multibyte character length "
+                       "of 2, got %d instead\n", charlen);
+               fprintf(stderr, "Are you using a UTF-8 locale?\n");
+               exit(1);
+       }
+
+       printf("%d\n", wcwidth(c));
+
+       exit(0);
+#endif /* MULTIBYTE_SUPPORT */
+}
index b66965a0fe3cc6fb36f6e82ae5a09e21ba4daaf5..ffe2c46da8f26e81e29980d12140a4b523ba5727 100755 (executable)
@@ -15,6 +15,10 @@ fi
 
 setup_test
 
+thisdir="$srcdir/test/inc"
+expected="$MH_TEST_DIR/$$.expected"
+actual="$MH_TEST_DIR/$$.actual"
+
 cat > "${MH_TEST_DIR}/test.mbox" <<EOF
 From nobody@nowhereville Jan 1 1970
 Received: I am the very model of a modern Major-General,
@@ -195,4 +199,135 @@ rm -f "${MH_TEST_DIR}/test.mbox" "${MH_TEST_DIR}/test.mbox.2"
 run_test "scan -width 120 +inbox 11" \
        "  11+ 03/01 Mr Nobody          Who is on first?<<Abbott: Every dollar of it. And why not, the man's entitled to it. Cos"
 
+# check header field name with ':' character than lands on m_getfld() buffer
+cat >"$MH_TEST_DIR/mess" <<EOF
+Comments: The important characteristic of this message is that the 4097'th
+Comments: byte is the ':' at the end of header field name.  That tests some
+Comments: logic in m_getfld (), assuming its MSG_INPUT_SIZE is 4096.
+Comments: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+Comments: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+Comments: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+Comments: DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+Comments: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+Comments: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+Comments: GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
+Comments: HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
+Comments: IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+Comments: JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
+Comments: KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
+Comments: LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
+Comments: MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+Comments: NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
+Comments: OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
+Comments: PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
+Comments: QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
+Comments: RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
+Comments: SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
+Comments: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
+Comments: UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
+Comments: VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+Comments: WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
+Comments: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+Comments: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
+Comments: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
+Comments: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Comments: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+Comments: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+Comments: dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
+Comments: eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+Comments: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+Comments: gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
+Comments: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+Comments: iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+Comments: jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+Comments: kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+Comments: llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
+Comments: mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+Comments: nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
+Comments: oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
+Comments: pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp
+Comments: qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
+Comments: rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
+Comments: ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
+Comments: tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
+Comments: uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
+Comments: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+Comments: wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
+Comments: This is it, the line with the 4097'th character of ':'.
+Comments: From somewhere
+From: No Such User <nosuch@example.com>
+To: Some Other User <someother@example.com>
+Subject: all that and nothing to say?
+Date: Thu, 10 Jan 2013 19:54:01 -0500
+
+EOF
+
+run_test 'scan -width 60 -file '"$MH_TEST_DIR/mess" \
+         '   1  01/10 No Such User       all that and nothing to say?'
+rm -f "$MH_TEST_DIR/mess"
+
+# check m_getfld() handling of fields with trailing whitespace
+# Even though header field names aren't supposed to have spaces (RFC
+# 28220, m_getfld () trims trailing whitespace from them.
+cat >`mhpath new` <<EOF
+Date : Sun, 18 Dec 2005 00:52:39 +0100
+From   : foo@example.edu
+To: bar@example.edu
+Subject: test
+EOF
+run_test 'scan last' '  12  12/18 foo@example.edu    test'
+
+# check header field body with more than 511 characters
+cat >"$MH_TEST_DIR/mess" <<EOF
+Comments: The important characteristic of this message is that this header
+          field body is more than 511 bytes long.  That tests the logic in
+          m_getfld () for transitioning to the FLDPLUS state.  This is the
+          only use for the FLDPLUS state, handling header field bodies that
+          are longer than the buffer used to retrieve them.  The trailing
+          newline after the last character is the 512th character.  The 511th
+          character, counting all spaces, even the leading one, is*
+From: No Such User <nosuch@example.com>
+To: Some Other User <someother@example.com>
+Subject: FLDPLUS test
+Date: Wed, 16 Jan 2013 20:33:58 -0600
+
+EOF
+
+run_test 'scan -width 80 -file '"$MH_TEST_DIR"'/mess' \
+         '   1  01/16 No Such User       FLDPLUS test'
+rm -f "$MH_TEST_DIR/mess"
+
+# check scan and inc of mbox with multiple messages
+echo y | packf -file "$MH_TEST_DIR/msgbox"
+run_test "scan -width 80 -file $MH_TEST_DIR/msgbox" \
+'   1  09/29 Test1              Testing message 1<<This is message number 1 >>
+   2  09/29 Test2              Testing message 2<<This is message number 2 >>
+   3  09/29 Test3              Testing message 3<<This is message number 3 >>
+   4  09/29 Test4              Testing message 4<<This is message number 4 >>
+   5  09/29 Test5              Testing message 5<<This is message number 5 >>
+   6  09/29 Test6              Testing message 6<<This is message number 6 >>
+   7  09/29 Test7              Testing message 7<<This is message number 7 >>
+   8  09/29 Test8              Testing message 8<<This is message number 8 >>
+   9  09/29 Test9              Testing message 9<<This is message number 9 >>
+  10  09/29 Test10             Testing message 10<<This is message number 10 >>
+  11  03/01 Mr Nobody          Who is on first?<<Abbott: Every dollar of it. An
+  12  12/18 foo@example.edu    test'
+run_test "inc -width 80 -file $MH_TEST_DIR/msgbox -truncate" \
+'Incorporating new mail into inbox...
+
+  13+ 09/29 Test1              Testing message 1<<This is message number 1 >>
+  14  09/29 Test2              Testing message 2<<This is message number 2 >>
+  15  09/29 Test3              Testing message 3<<This is message number 3 >>
+  16  09/29 Test4              Testing message 4<<This is message number 4 >>
+  17  09/29 Test5              Testing message 5<<This is message number 5 >>
+  18  09/29 Test6              Testing message 6<<This is message number 6 >>
+  19  09/29 Test7              Testing message 7<<This is message number 7 >>
+  20  09/29 Test8              Testing message 8<<This is message number 8 >>
+  21  09/29 Test9              Testing message 9<<This is message number 9 >>
+  22  09/29 Test10             Testing message 10<<This is message number 10 >>
+  23  03/01 Mr Nobody          Who is on first?<<Abbott: Every dollar of it. An
+  24  12/18 foo@example.edu    test'
+rm -f  "$MH_TEST_DIR/msgbox"
+
+
 exit ${failed:-0}
index a8bb87fa1cbc76a3648db91b4dba81a31bae0b26..7724ae3c5cab06f030e491decde028564e0c73ca 100755 (executable)
@@ -27,8 +27,9 @@ TESTPASS=testuserpass
 testport=65413
 
 HOME="${MH_TEST_DIR}"; export HOME
-echo "default login ${TESTUSER} password ${TESTPASS}" > ${HOME}/.netrc
-chmod 600 ${HOME}/.netrc
+netrc="${HOME}/.netrc"
+echo "default login ${TESTUSER} password ${TESTPASS}" > "$netrc"
+chmod 600 "$netrc"
 
 expected=$MH_TEST_DIR/$$.expected
 expected_err=$MH_TEST_DIR/$$.expected_err
@@ -55,8 +56,24 @@ run_test "inc -user ${TESTUSER} -host 127.0.0.1 -port $testport -width 80" \
        "Incorporating new mail into inbox...
 
   11+ 12/17 No Such User       Hello<<Hey man, how's it going? . Hope you're do"
+check $testmessage `mhpath +inbox 11` 'keep first'
 
-check `mhpath +inbox 11` $testmessage
-rm -f $testmessage
+# check -pack
+pid=`"${MH_OBJ_DIR}/test/fakepop" "$testmessage" "$testport" \
+                       "$TESTUSER" "$TESTPASS"`
+
+touch "$MH_TEST_DIR/inc.mbox"
+run_test "inc -user ${TESTUSER} -host 127.0.0.1 -port $testport -width 80 \
+          -pack $MH_TEST_DIR/inc.mbox" \
+       "Incorporating new mail into (null)...
+
+   1  12/17 No Such User       Hello<<Hey man, how's it going? . Hope you're do"
+run_test "inc -file $MH_TEST_DIR/inc.mbox -truncate" \
+       "Incorporating new mail into inbox...
+
+  11+ 12/17 No Such User       Hello<<Hey man, how's it going? . Hope you're do"
+
+check $testmessage `mhpath +inbox 11`
+rm -f "$MH_TEST_DIR/inc.mbox" "$MH_TEST_DIR/.inc.map" "$netrc"
 
 exit ${failed:-0}
index 47229de6ab387addf07f336bb3a5ad7ab0b34ef3..3446153f9a9d8aad490d1c49ab989aa5f2017617 100755 (executable)
@@ -93,7 +93,7 @@ To: Somebody <somebody@example.com>
 Subject: Test
 Nmh-Attachment: $MH_TEST_DIR/attachment.txt
 
-¡Ay, caramba!
+¡Ay, caramba!
 EOF
 
 cat > "${testname}.expected" <<EOF
@@ -108,7 +108,7 @@ Date:
 Content-Type: text/plain
 Content-Transfer-Encoding: quoted-printable
 
-=A1Ay, caramba!
+=C2=A1Ay, caramba!
 
 ------- =_aaaaaaaaaa0
 Content-Type: text/plain; name="attachment.txt"
@@ -125,3 +125,9 @@ test_attachment "${testname}.expected"
 rm -f ${MHMTSCONF} "${MH_TEST_DIR}/attachment.txt"
 
 exit ${failed:-0}
+
+# emacs hackage to ensure that it writes the inverted exclamation
+# point as UTF-8 multibyte character \xC2\xA1 instead of just \xA1.
+# Local Variables:
+# coding: utf-8
+# End:
index a56945ca9ac0bb1af064fa0190a2012a5d247735..7af2ef6f36f0dac9ed98de2ec489884e9fe25541 100755 (executable)
@@ -84,7 +84,7 @@ $MH_INST_DIR$bindir/refile
 700
 $bindir/inc
 $auxexecdir/install-mh
-$pagerpath
+more
 $bindir/mhmail
 $MH_INST_DIR$auxexecdir/mhl
 cat
diff --git a/test/mhshow/test-msg-buffer-boundaries b/test/mhshow/test-msg-buffer-boundaries
new file mode 100755 (executable)
index 0000000..4b28fa6
--- /dev/null
@@ -0,0 +1,392 @@
+#!/bin/sh
+######################################################
+#
+# Test m_getfld() with various parts of messages
+# falling on buffer boundaries
+#
+######################################################
+
+set -e
+
+if test -z "${MH_OBJ_DIR}"; then
+    srcdir=`dirname "$0"`/../..
+    MH_OBJ_DIR=`cd "$srcdir" && pwd`; export MH_OBJ_DIR
+fi
+
+. "$MH_OBJ_DIR/test/common.sh"
+
+setup_test
+
+expected="$MH_TEST_DIR/$$.expected"
+actual="$MH_TEST_DIR/$$.actual"
+
+# check a boundary condition in m_getfld():  its internal message
+# buffer holds exactly up to the end of a header field body in a
+# message part
+msgfile=`mhpath new`
+msgnum=`basename $msgfile`
+cat >"$msgfile" <<EOF
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="NextPart_001"
+Content-class: urn:content-classes:message
+Date: Thu, 19 May 2011 00:00:00 -0000
+From: sender@example.com
+To: recipient@example.com
+
+This is a multi-part message in MIME format.
+
+--NextPart_001
+Content-Type: multipart/related;
+    type="multipart/alternative";
+    boundary="NextPart_002"
+
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXX
+
+--NextPart_002
+Content-Type: text/plain;
+    charset="utf-8"
+
+This is the text/plain part.
+
+--NextPart_002--
+
+--NextPart_001--
+EOF
+
+# Write the expected output.
+cat >"$expected" <<EOF
+part 1.1   text/plain                  29
+This is the text/plain part.
+EOF
+
+mhshow -part 1.1 -form mhl.null -nopause $msgnum >"$actual" 2>&1
+check "$expected" "$actual"
+
+# check a boundary condition in m_getfld():  its internal message
+# buffer holds exactly up to the end of a header field name in a
+# message part
+msgfile=`mhpath new`
+msgnum=`basename $msgfile`
+cat >"$msgfile" <<EOF
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="NextPart_001"
+Content-class: urn:content-classes:message
+Date: Thu, 19 May 2011 00:00:00 -0000
+From: sender@example.com
+To: recipient@example.com
+
+This is a multi-part message in MIME format.
+
+--NextPart_001
+Content-Type: multipart/related;
+    type="multipart/alternative";
+    boundary="NextPart_002"
+
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+--NextPart_002
+Content-Type: text/plain;
+    charset="utf-8"
+
+This is the text/plain part.
+
+--NextPart_002--
+
+--NextPart_001--
+EOF
+
+# Write the expected output.
+cat >"$expected" <<EOF
+part 1.1   text/plain                  29
+This is the text/plain part.
+EOF
+
+mhshow -part 1.1 -form mhl.null -nopause $msgnum >"$actual" 2>&1
+check "$expected" "$actual"
+
+# check a boundary condition in m_getfld():  its internal message
+# buffer holds exactly up to the end of a message part boundary
+msgfile=`mhpath new`
+msgnum=`basename $msgfile`
+cat >"$msgfile" <<EOF
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="NextPart_001"
+Content-class: urn:content-classes:message
+Date: Thu, 19 May 2011 00:00:00 -0000
+From: sender@example.com
+To: recipient@example.com
+
+This is a multi-part message in MIME format.
+
+--NextPart_001
+Content-Type: multipart/related;
+    type="multipart/alternative";
+    boundary="NextPart_002"
+
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXX
+The 4096'th character is the '2' at the end of the following NextPart_002.
+
+--NextPart_002
+Content-Type: text/plain;
+    charset="utf-8"
+
+This is the text/plain part.
+
+--NextPart_002--
+
+--NextPart_001--
+EOF
+
+# Write the expected output.
+cat >"$expected" <<EOF
+part 1.1   text/plain                  29
+This is the text/plain part.
+EOF
+
+mhshow -part 1.1 -form mhl.null -nopause $msgnum >"$actual" 2>&1
+check "$expected" "$actual"
+
+
+exit $failed
index 79ac85d5d81a6c93249c904aaade6dcb422c2a9d..632c54bae83e7590e6195bca9ece876707d9008d 100755 (executable)
@@ -14,10 +14,10 @@ fi
 
 setup_test
 
-expected=$MH_TEST_DIR/$$.expected
-actual=$MH_TEST_DIR/$$.actual
+expected="$MH_TEST_DIR/$$.expected"
+actual="$MH_TEST_DIR/$$.actual"
 
-cat > $expected <<EOF
+cat >"$expected" <<EOF
    1  09/29 Test1              Testing message 1<<This is message number 1 >>
    2  09/29 Test2              Testing message 2<<This is message number 2 >>
    3  09/29 Test3              Testing message 3<<This is message number 3 >>
@@ -30,12 +30,11 @@ cat > $expected <<EOF
   10  09/29 Test10             Testing message 10<<This is message number 10 >>
 EOF
 
-scan +inbox -width 80 > $actual || exit 1
-
+scan +inbox -width 80 >"$actual" || exit 1
 check "$expected" "$actual"
 
 # check highlighting
-cat > $expected <<EOF
+cat >"$expected" <<EOF
    1  09/29 Test1              Testing message 1<<This is message number 1 >>\e[m
    2  09/29 Test2              Testing message 2<<This is message number 2 >>\e[m
    3  09/29 Test3              Testing message 3<<This is message number 3 >>\e[m
@@ -51,8 +50,7 @@ EOF
 printf 'Unseen-Sequence: unseen\n' >> $MH
 mark -sequence cur 5
 mark -sequence unseen 10
-scan -form scan.highlighted -width 80 > $actual || exit 1
-
+scan -form scan.highlighted -width 80 >"$actual" || exit 1
 check "$expected" "$actual"
 
 
index ce4ec695e27cb71d47a2c10fcc06fd3f69afcafe..1e9349a09163476e360554be40aae00b856a5bbc 100755 (executable)
@@ -31,25 +31,74 @@ LC_ALL=en_US.UTF-8; export LC_ALL
 #
 # Create a test message with RFC 2047 headers we can scan
 #
+# In this Subject header in this message is a "n" with a Combining Diaeresis
+# (U+0308).  There is different interpretation of this character with respect
+# to wcwidth() (which is supposed to return the column width of a character).
+# We use a test program to determine what the output width of U+0308 is
+# and adjust our test output appropriately.
+#
 
 cat > "${MH_TEST_DIR}/Mail/inbox/11" <<EOF
 From: David =?utf-8?q?=EF=AC=86?= Hubbins <hubbins@example.com>
 To: Sir Denis =?utf-8?q?Eton=E2=80=93Hogg? <sirdenis@example.com>
 Date: Friday, 2 Mar 1984 00:00:00
-Subject: =?utf-8?q?Spin=CC=88al_Tap_=E2=86=92_Tap_into_America!?=
+Subject: =?utf-8?q?Sp=C4=B1n=CC=88al_Tap_=E2=86=92_Tap_into_America!?=
 
 Things are looking great!
 EOF
 
-expected=$MH_TEST_DIR/$$.expected
-actual=$MH_TEST_DIR/$$.actual
+width=`${MH_OBJ_DIR}/test/getcwidth`
+if test $? -ne 0; then
+    echo "getcwidth failed to run"
+    exit 1
+fi
+
+expected="$MH_TEST_DIR/$$.expected"
+actual="$MH_TEST_DIR/$$.actual"
 
-cat > $expected <<EOF
-  11  03/02 David ï¬† Hubbins    Spin̈al Tap â†’ Tap into America!<<Things are
+if test "$width" -eq 1; then
+cat > "$expected" <<EOF
+  11  03/02 David ï¬† Hubbins    Spın̈al Tap â†’ Tap into America!<<Things are look
+EOF
+elif test "$width" -eq 0; then
+cat > "$expected" <<EOF
+  11  03/02 David ï¬† Hubbins    Spın̈al Tap â†’ Tap into America!<<Things are looki
 EOF
+else
+    echo "Unsupported width for combining diaeresis: $width"
+    exit 1
+fi
 
 scan -width 80 +inbox 11 > $actual || exit 1
+check "$expected" "$actual"
+
+# check decoding with an invalid multibyte sequence
+cat >`mhpath new` <<EOF
+From: Test12 <test12@example.com>
+To: Some User <user@example.com>
+Date: Mon, 31 Dec 2012 00:00:00
+Message-Id: 12@test.nmh
+Subject: =?UTF-8?B?MjAxMyBOZXcgWWVhcuKAmXMgRGVhbHMhIFN0YXJ0IHRoZSB5ZWFy?=
+       =?UTF-8?B?IHJpZ2h0IHdpdGggYmlnIHNhdmluZ3M=?=
+
+This message has an encoded Subject with an invalid character for the
+ISO-8859-1 character set, but it (U+2019) is valid UTF-8.
+EOF
+
+cat >"$expected" <<EOF
+  12  12/31 Test12             2013 New Year?s Deals! Start the year right
+EOF
+
+LC_CTYPE=ISO-8859-1 MM_CHARSET=ISO-8859-1 scan -width 75 last >"$actual"
+check "$expected" "$actual"
+
+# check scan width with a valid multibyte sequence
+cat >"$expected" <<EOF
+  12  12/31 Test12             2013 New Year’s Deals! Start the year right
+EOF
 
+LC_CTYPE=en_US.UTF-8 MM_CHARSET=UTF-8 scan -width 75 last >"$actual"
 check "$expected" "$actual"
 
+
 exit $failed
diff --git a/test/sequences/test-out-of-range b/test/sequences/test-out-of-range
new file mode 100755 (executable)
index 0000000..0ee7fb7
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+############################################################
+#
+# Test to see if a out-of-range sequence is handled properly
+#
+############################################################
+
+set -e
+
+if test -z "${MH_OBJ_DIR}"; then
+    srcdir=`dirname $0`/../..
+    MH_OBJ_DIR=`cd $srcdir && pwd`; export MH_OBJ_DIR
+fi
+
+. "$MH_OBJ_DIR/test/common.sh"
+
+setup_test
+
+cat > $MH_TEST_DIR/Mail/inbox/.mh_sequences <<EOS
+cur: 120
+test: 121
+EOS
+
+run_test 'mhpath +inbox test' 'mhpath: sequence test empty'
+
+cat > $MH_TEST_DIR/Mail/inbox/.mh_sequences <<EOS
+cur: 120
+test: 121
+EOS
+
+#
+# Yes, this is right.  "cur" is special in that it can refer to messages
+# that don't exist.
+#
+run_test 'mhpath +inbox cur' "$MH_TEST_DIR/Mail/inbox/120"
+
+exit $failed
index 880fe2123e4ddbe79216bb06d6d461bf5ad99605..3893a1d8ad16c1455cb6abee3bd1dab18d4d3ac4 100644 (file)
--- a/uip/ali.c
+++ b/uip/ali.c
 #include <h/mts.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        ALIASW                0
-    { "alias aliasfile", 0 },
-#define        NALIASW               1
-    { "noalias", -7 },
-#define        LISTSW                2
-    { "list", 0 },
-#define        NLISTSW               3
-    { "nolist", 0 },
-#define        NORMSW                4
-    { "normalize", 0 },
-#define        NNORMSW               5
-    { "nonormalize", 0 },
-#define        USERSW                6
-    { "user", 0 },
-#define        NUSERSW               7
-    { "nouser", 0 },
-#define VERSIONSW             8
-    { "version", 0 },
-#define        HELPSW                9
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define ALI_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("noalias", -7, NALIASW) \
+    X("list", 0, LISTSW) \
+    X("nolist", 0, NLISTSW) \
+    X("normalize", 0, NORMSW) \
+    X("nonormalize", 0, NNORMSW) \
+    X("user", 0, USERSW) \
+    X("nouser", 0, NUSERSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(ALI);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(ALI, switches);
+#undef X
 
 static int pos = 1;
 
index 24726d7f458795b7c11c7c5bc666bcce1d6ae153..0ed6e77f98d9da60e055947be14b828004015e3b 100644 (file)
 #include <h/mh.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        COMPSW  0
-    { "component field", 0 },
-#define        INPLSW  1
-    { "inplace", 0 },
-#define        NINPLSW 2
-    { "noinplace", 0 },
-#define        DATESW  3
-    { "date", 0 },
-#define        NDATESW 4
-    { "nodate", 0 },
-#define        TEXTSW  5
-    { "text body", 0 },
-#define VERSIONSW 6
-    { "version", 0 },
-#define        HELPSW  7
-    { "help", 0 },
-#define        DRFTSW                   8
-    { "draft", 2 },
-#define        LISTSW                   9
-    { "list", 1 },
-#define        DELETESW                10
-    { "delete", 2 },
-#define        NUMBERSW                11
-    { "number", 2 },
-#define        APPENDSW                12
-    { "append", 1 },
-#define        PRESERVESW              13
-    { "preserve", 1 },
-#define        NOPRESERVESW            14
-    { "nopreserve", 3 },
-    { NULL, 0 }
-};
+#define ANNO_SWITCHES \
+    X("component field", 0, COMPSW) \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("date", 0, DATESW) \
+    X("nodate", 0, NDATESW) \
+    X("text body", 0, TEXTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("draft", 2, DRFTSW) \
+    X("list", 1, LISTSW) \
+    X("delete", 2, DELETESW) \
+    X("number", 2, NUMBERSW) \
+    X("append", 1, APPENDSW) \
+    X("preserve", 1, PRESERVESW) \
+    X("nopreserve", 3, NOPRESERVESW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(ANNO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(ANNO, switches);
+#undef X
 
 /*
  * static prototypes
index 80ce8a3fa43ac7087c2d18971979e48fc8fa13bb..105c3fe4d080dd5bca79f77e5f45fdb003ffae93 100644 (file)
--- a/uip/ap.c
+++ b/uip/ap.c
 
 #define        FORMAT  "%<{error}%{error}: %{text}%|%(putstr(proper{text}))%>"
 
-static struct swit switches[] = {
-#define        FORMSW  0
-    { "form formatfile", 0 },
-#define        FMTSW   1
-    { "format string", 5 },
-#define        NORMSW  2
-    { "normalize", 0 },
-#define        NNORMSW 3
-    { "nonormalize", 0 },
-#define        WIDTHSW 4
-    { "width columns", 0 },
-#define VERSIONSW 5
-    { "version", 0 },
-#define        HELPSW  6
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define AP_SWITCHES \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("normalize", 0, NORMSW) \
+    X("nonormalize", 0, NNORMSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(AP);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(AP, switches);
+#undef X
 
 static struct format *fmt;
 
index 93fd5e03b8b4b41ca0fb0186f1c7264c228741fa..0b4a240921eac666a11c7ac2fd96628898fe56ee 100644 (file)
 #include <h/mh.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        INPLSW  0
-    { "inplace", 0 },
-#define        NINPLSW 1
-    { "noinplace", 0 },
-#define        QIETSW  2
-    { "quiet", 0 },
-#define        NQIETSW 3
-    { "noquiet", 0 },
-#define        VERBSW  4
-    { "verbose", 0 },
-#define        NVERBSW 5
-    { "noverbose", 0 },
-#define VERSIONSW 6
-    { "version", 0 },
-#define        HELPSW  7
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define BURST_SWITCHES \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("quiet", 0, QIETSW) \
+    X("noquiet", 0, NQIETSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(BURST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(BURST, switches);
+#undef X
 
 struct smsg {
     off_t s_start;
index 65b213aef9b84f7b36bba619d313bbb435f5b2ca..0b0ac369f804a66f169f4398be211432ec6b8793 100644 (file)
 #include <h/fmt_scan.h>
 #include <fcntl.h>
 
-static struct swit switches[] = {
-#define        DFOLDSW                0
-    { "draftfolder +folder", 0 },
-#define        DMSGSW                 1
-    { "draftmessage msg", 0 },
-#define        NDFLDSW                2
-    { "nodraftfolder", 0 },
-#define        EDITRSW                3
-    { "editor editor", 0 },
-#define        NEDITSW                4
-    { "noedit", 0 },
-#define        FILESW                 5
-    { "file file", 0 },
-#define        FORMSW                 6
-    { "form formfile", 0 },
-#define        USESW                  7
-    { "use", 0 },
-#define        NUSESW                 8
-    { "nouse", 0 },
-#define        WHATSW                 9
-    { "whatnowproc program", 0 },
-#define        NWHATSW               10
-    { "nowhatnowproc", 0 },
-#define VERSIONSW             11
-    { "version", 0 },
-#define        HELPSW                12
-    { "help", 0 },
-#define TOSW                  13
-    { "to address", 0 },
-#define CCSW                  14
-    { "cc address", 0 },
-#define FROMSW                15
-    { "from address", 0 },
-#define FCCSW                 16
-    { "fcc mailbox", 0 },
-#define WIDTHSW                      17
-    { "width colums", 0 },
-#define SUBJECTSW             18
-    { "subject text", 0 },
-    { NULL, 0 }
-};
-
-static struct swit aqrunl[] = {
-#define        NOSW          0
-    { "quit", 0 },
-#define        YESW          1
-    { "replace", 0 },
-#define        USELSW        2
-    { "use", 0 },
-#define        LISTDSW       3
-    { "list", 0 },
-#define        REFILSW       4
-    { "refile +folder", 0 },
-#define NEWSW         5
-    { "new", 0 },
-    { NULL, 0 }
-};
+#define COMP_SWITCHES \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("file file", 0, FILESW) \
+    X("form formfile", 0, FORMSW) \
+    X("use", 0, USESW) \
+    X("nouse", 0, NUSESW) \
+    X("whatnowproc program", 0, WHATSW) \
+    X("nowhatnowproc", 0, NWHATSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("to address", 0, TOSW) \
+    X("cc address", 0, CCSW) \
+    X("from address", 0, FROMSW) \
+    X("fcc mailbox", 0, FCCSW) \
+    X("width colums", 0, WIDTHSW) \
+    X("subject text", 0, SUBJECTSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(COMP);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(COMP, switches);
+#undef X
+
+#define DISPO_SWITCHES \
+    X("quit", 0, NOSW) \
+    X("replace", 0, YESW) \
+    X("use", 0, USELSW) \
+    X("list", 0, LISTDSW) \
+    X("refile +folder", 0, REFILSW) \
+    X("new", 0, NEWSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DISPO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DISPO, aqrunl);
+#undef X
 
 static struct swit aqrul[] = {
-    { "quit", 0 },
-    { "replace", 0 },
-    { "use", 0 },
-    { "list", 0 },
-    { "refile", 0 },
-    { NULL, 0 }
+    { "quit", 0, NOSW },
+    { "replace", 0, YESW },
+    { "use", 0, USELSW },
+    { "list", 0, LISTDSW },
+    { "refile", 0, REFILSW },
+    { NULL, 0, 0 }
 };
 
 int
index 2324c650a4eabab9672695835eb29b491a1dfc4c..d8c45669720075eb9f96e825b6d783725db84cf9 100644 (file)
  */
 #define        NGRPS   100
 
-static struct swit switches[] = {
-#define        MAILSW         0
-    { "mail name", 0 },
-#define        SERCHSW        1
-    { "search directory", 0 },
-#define VERSIONSW      2
-    { "version", 0 },
-#define        HELPSW         3
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define CONFLICT_SWITCHES \
+    X("mail name", 0, MAILSW) \
+    X("search directory", 0, SERCHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(CONFLICT);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(CONFLICT, switches);
+#undef X
 
 static char *mail = NULL;
 static char *dirs[NDIRS];
index b7799beb7067e50cb65c5c3e371a62dbc258d4f2..3d247181b5c9c50f03faefc9ef7f6a768407f461 100644 (file)
 #include <h/utils.h>
 #include <fcntl.h>
 
-static struct swit switches[] = {
-#define        ANNOSW  0
-    { "annotate", 0 },
-#define        NANNOSW 1
-    { "noannotate", 0 },
-#define        DFOLDSW 2
-    { "draftfolder +folder", 0 },
-#define        DMSGSW  3
-    { "draftmessage msg", 0 },
-#define        NDFLDSW 4
-    { "nodraftfolder", 0 },
-#define        EDITRSW 5
-    { "editor editor", 0 },
-#define        NEDITSW 6
-    { "noedit", 0 },
-#define        FORMSW  7
-    { "form formfile", 0 },
-#define        INPLSW  8
-    { "inplace", 0 },
-#define        NINPLSW 9
-    { "noinplace", 0 },
-#define        WHATSW  10
-    { "whatnowproc program", 0 },
-#define        NWHATSW 11
-    { "nowhatnowproc", 0 },
-#define VERSIONSW 12
-    { "version", 0 },
-#define        HELPSW  13
-    { "help", 0 },
-#define        FILESW  14
-    { "file file", -4 },       /* interface from msh */
-#define FROMSW  15
-    { "from address", 0 },
-#define TOSW    16
-    { "to address", 0 },
-#define CCSW    17
-    { "cc address", 0 },
-#define FCCSW   18
-    { "fcc mailbox", 0 },
-#define WIDTHSW 19
-    { "width columns", 0 },
-#define ATFILESW 20
-    { "atfile", 0 },
-#define NOATFILESW 21
-    { "noatfile", 0 },
-    { NULL, 0 }
-};
-
-static struct swit aqrnl[] = {
-#define        NOSW    0
-    { "quit", 0 },
-#define        YESW    1
-    { "replace", 0 },
-#define        LISTDSW 2
-    { "list", 0 },
-#define        REFILSW 3
-    { "refile +folder", 0 },
-#define NEWSW  4
-    { "new", 0 },
-    { NULL, 0 }
-};
+#define DIST_SWITCHES \
+    X("annotate", 0, ANNOSW) \
+    X("noannotate", 0, NANNOSW) \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("form formfile", 0, FORMSW) \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("whatnowproc program", 0, WHATSW) \
+    X("nowhatnowproc", 0, NWHATSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("file file", -4, FILESW) \
+    X("from address", 0, FROMSW) \
+    X("to address", 0, TOSW) \
+    X("cc address", 0, CCSW) \
+    X("fcc mailbox", 0, FCCSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("atfile", 0, ATFILESW) \
+    X("noatfile", 0, NOATFILESW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DIST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DIST, switches);
+#undef X
+
+#define DISPO_SWITCHES \
+    X("quit", 0, NOSW) \
+    X("replace", 0, YESW) \
+    X("list", 0, LISTDSW) \
+    X("refile +folder", 0, REFILSW) \
+    X("new", 0, NEWSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DISPO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DISPO, aqrnl);
+#undef X
 
 
 static struct swit aqrl[] = {
-    { "quit", 0 },
-    { "replace", 0 },
-    { "list", 0 },
-    { "refile +folder", 0 },
-    { NULL, 0 }
+    { "quit", 0, NOSW },
+    { "replace", 0, YESW },
+    { "list", 0, LISTDSW },
+    { "refile +folder", 0, REFILSW },
+    { NULL, 0, 0 }
 };
 
 
index afd4e419122a09255a9d469913b8eec2a3c9f170..b5119fbe88a39d9692b3b1dd78d1938e391881ef 100644 (file)
@@ -32,6 +32,7 @@ distout (char *drft, char *msgnam, char *backup)
     register char *resent;
     char name[NAMESZ], buffer[BUFSIZ];
     register FILE *ifp, *ofp;
+    m_getfld_state_t gstate = 0;
 
     if (rename (drft, strcpy (backup, m_backup (drft))) == NOTOK)
        adios (backup, "unable to rename %s to",drft);
@@ -46,12 +47,11 @@ distout (char *drft, char *msgnam, char *backup)
     lseek (hdrfd, (off_t) 0, SEEK_SET); /* msgnam not accurate */
     cpydata (hdrfd, fileno (ofp), msgnam, drft);
 
-    for (state = FLD, resent = NULL;;)
-       switch (state =
-               m_getfld (state, name, buffer, sizeof buffer, ifp)) {
+    for (resent = NULL;;) {
+       int buffersz = sizeof buffer;
+       switch (state = m_getfld (&gstate, name, buffer, &buffersz, ifp)) {
            case FLD: 
            case FLDPLUS: 
-           case FLDEOF: 
                if (uprf (name, "distribute-"))
                    snprintf (name, sizeof(name), "%s%s", "Resent", &name[10]);
                if (uprf (name, "distribution-"))
@@ -65,17 +65,14 @@ distout (char *drft, char *msgnam, char *backup)
                resent = add (buffer, resent);
                fprintf (ofp, "%s: %s", name, buffer);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name,
-                           buffer, sizeof buffer, ifp);
+                   buffersz = sizeof buffer;
+                   state = m_getfld (&gstate, name, buffer, &buffersz, ifp);
                    resent = add (buffer, resent);
                    fputs (buffer, ofp);
                }
-               if (state == FLDEOF)
-                   goto process;
                break;
 
            case BODY: 
-           case BODYEOF: 
                for (dp = buffer; *dp; dp++)
                    if (!isspace (*dp)) {
                        advise (NULL, BADTXT, "draft");
@@ -99,7 +96,9 @@ distout (char *drft, char *msgnam, char *backup)
            default: 
                adios (NULL, "getfld() returned %d", state);
        }
+    }
 process: ;
+    m_getfld_state_destroy (&gstate);
     fclose (ifp);
     fflush (ofp);
 
@@ -131,6 +130,7 @@ ready_msg (char *msgnam)
     char name[NAMESZ], buffer[BUFSIZ], tmpfil[BUFSIZ];
     register FILE *ifp, *ofp;
     char *cp = NULL;
+    m_getfld_state_t gstate = 0;
 
     if (hdrfd != NOTOK)
        close (hdrfd), hdrfd = NOTOK;
@@ -151,26 +151,22 @@ ready_msg (char *msgnam)
        adios (NULL, "no file descriptors -- you lose big");
     unlink (tmpfil);
 
-    for (state = FLD;;)
-       switch (state =
-               m_getfld (state, name, buffer, sizeof buffer, ifp)) {
+    for (;;) {
+       int buffersz = sizeof buffer;
+       switch (state = m_getfld (&gstate, name, buffer, &buffersz, ifp)) {
            case FLD: 
            case FLDPLUS: 
-           case FLDEOF: 
                if (uprf (name, "resent"))
                    fprintf (ofp, "Prev-");
                fprintf (ofp, "%s: %s", name, buffer);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name,
-                           buffer, sizeof buffer, ifp);
+                   buffersz = sizeof buffer;
+                   state = m_getfld (&gstate, name, buffer, &buffersz, ifp);
                    fputs (buffer, ofp);
                }
-               if (state == FLDEOF)
-                   goto process;
                break;
 
            case BODY: 
-           case BODYEOF: 
                fclose (ofp);
 
                 cp = m_mktemp2(NULL, "dist", &txtfd, NULL);
@@ -185,8 +181,8 @@ ready_msg (char *msgnam)
                unlink (tmpfil);
                fprintf (ofp, "\n%s", buffer);
                while (state == BODY) {
-                   state = m_getfld (state, name,
-                           buffer, sizeof buffer, ifp);
+                   buffersz = sizeof buffer;
+                   state = m_getfld (&gstate, name, buffer, &buffersz, ifp);
                    fputs (buffer, ofp);
                }
            case FILEEOF: 
@@ -199,7 +195,9 @@ ready_msg (char *msgnam)
            default: 
                adios (NULL, "getfld() returned %d", state);
        }
+    }
 process: ;
+    m_getfld_state_destroy (&gstate);
     fclose (ifp);
     fclose (ofp);
 }
index b9158459be7ab6236bca8bd63fb457b63c569d58..eef77908115421b0cbd1671e9f394801025dda9a 100644 (file)
--- a/uip/dp.c
+++ b/uip/dp.c
 
 #define        FORMAT "%<(nodate{text})error: %{text}%|%(putstr(pretty{text}))%>"
 
-static struct swit switches[] = {
-#define        FORMSW                0
-    { "form formatfile", 0 },
-#define        FMTSW                 1
-    { "format string", 5 },
-#define        WIDTHSW               2
-    { "width columns", 0 },
-#define VERSIONSW             3
-    { "version", 0 },
-#define        HELPSW                4
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define DP_SWITCHES \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DP);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DP, switches);
+#undef X
 
 static struct format *fmt;
 
index b4aff9cd3882a980003487950ae1562513d8ccb8..4c0469edff755d822ca315ebb3d610fdd1120036 100644 (file)
 #define MAXFOLDERS  100
 
 
-static struct swit switches[] = {
-#define SEQSW           0
-    { "sequence name", 0 },
-#define ALLSW           1
-    { "all", 0 },
-#define NOALLSW         2
-    { "noall", 0 },
-#define RECURSE         3
-    { "recurse", 0 },
-#define NORECURSE       4
-    { "norecurse", 0 },
-#define SHOWZERO        5
-    { "showzero", 0 },
-#define NOSHOWZERO      6
-    { "noshowzero", 0 },
-#define ALPHASW         7
-    { "alpha", 0 },
-#define NOALPHASW       8
-    { "noalpha", 0 },
-#define FASTSW          9
-    { "fast", 0 },
-#define NOFASTSW        10
-    { "nofast", 0 },
-#define TOTALSW         11
-    { "total", -5 },
-#define NOTOTALSW       12
-    { "nototal", -7 },
-#define VERSIONSW      13
-    { "version", 0 },
-#define HELPSW          14
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FLIST_SWITCHES \
+    X("sequence name", 0, SEQSW) \
+    X("all", 0, ALLSW) \
+    X("noall", 0, NOALLSW) \
+    X("recurse", 0, RECURSE) \
+    X("norecurse", 0, NORECURSE) \
+    X("showzero", 0, SHOWZERO) \
+    X("noshowzero", 0, NOSHOWZERO) \
+    X("alpha", 0, ALPHASW) \
+    X("noalpha", 0, NOALPHASW) \
+    X("fast", 0, FASTSW) \
+    X("nofast", 0, NOFASTSW) \
+    X("total", -5, TOTALSW) \
+    X("nototal", -7, NOTOTALSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FLIST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FLIST, switches);
+#undef X
 
 struct Folder {
     char *name;                        /* name of folder */
index 2ec0a8069bf8f0adca791229fe13e42e6ae0f339..653581684c1c87f82aeafa0a7fbe8f2114e87cad 100644 (file)
 #include <h/fmt_compile.h>
 #include <h/scansbr.h>
 
-static struct swit switches[] = {
-#define        FORMSW              0
-    { "form formatfile", 0 },
-#define        FMTSW               1
-    { "format string", 5 },
-#define VERSIONSW           2
-    { "version", 0 },
-#define        HELPSW              3
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FMTDUMP_SWITCHES \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FMTDUMP);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FMTDUMP, switches);
+#undef X
 
 /* for assignlabel */
 static struct format *lvec[128];
@@ -415,9 +417,6 @@ f_typestr(int t)
        case FT_FORMATADDR: return("FORMATADDR");
        case FT_CONCATADDR: return("CONCATADDR");
        case FT_MYMBOX: return("MYMBOX");
-#ifdef FT_ADDTOSEQ
-       case FT_ADDTOSEQ: return("ADDTOSEQ");
-#endif
        case FT_SAVESTR: return("SAVESTR");
 #ifdef FT_PAUSE
        case FT_PAUSE: return ("PAUSE");
index 4f43b9fc56b639a0225cb36f68307b3186249a6b..e4defc70552a79d3318b5a73442019b2701e1e27 100644 (file)
 #include <h/utils.h>
 #include <errno.h>
 
-static struct swit switches[] = {
-#define        ALLSW           0
-    { "all", 0 },
-#define NALLSW         1
-    { "noall", 0 },
-#define        CREATSW         2
-    { "create", 0 },
-#define        NCREATSW        3
-    { "nocreate", 0 },
-#define        FASTSW          4
-    { "fast", 0 },
-#define        NFASTSW         5
-    { "nofast", 0 },
-#define        HDRSW           6
-    { "header", 0 },
-#define        NHDRSW          7
-    { "noheader", 0 },
-#define        PACKSW          8
-    { "pack", 0 },
-#define        NPACKSW         9
-    { "nopack", 0 },
-#define        VERBSW         10
-    { "verbose", 0 },
-#define        NVERBSW        11
-    { "noverbose", 0 },
-#define        RECURSW        12
-    { "recurse", 0 },
-#define        NRECRSW        13
-    { "norecurse", 0 },
-#define        TOTALSW        14
-    { "total", 0 },
-#define        NTOTLSW        15
-    { "nototal", 0 },
-#define        LISTSW         16
-    { "list", 0 },
-#define        NLISTSW        17
-    { "nolist", 0 },
-#define        PRNTSW         18
-    { "print", 0 },
-#define        NPRNTSW        19
-    { "noprint", -4 },
-#define        PUSHSW         20
-    { "push", 0 },
-#define        POPSW          21
-    { "pop", 0 },
-#define VERSIONSW      22
-    { "version", 0 },
-#define        HELPSW         23
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FOLDER_SWITCHES \
+    X("all", 0, ALLSW) \
+    X("noall", 0, NALLSW) \
+    X("create", 0, CREATSW) \
+    X("nocreate", 0, NCREATSW) \
+    X("fast", 0, FASTSW) \
+    X("nofast", 0, NFASTSW) \
+    X("header", 0, HDRSW) \
+    X("noheader", 0, NHDRSW) \
+    X("pack", 0, PACKSW) \
+    X("nopack", 0, NPACKSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("recurse", 0, RECURSW) \
+    X("norecurse", 0, NRECRSW) \
+    X("total", 0, TOTALSW) \
+    X("nototal", 0, NTOTLSW) \
+    X("list", 0, LISTSW) \
+    X("nolist", 0, NLISTSW) \
+    X("print", 0, PRNTSW) \
+    X("noprint", -4, NPRNTSW) \
+    X("push", 0, PUSHSW) \
+    X("pop", 0, POPSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FOLDER);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FOLDER, switches);
+#undef X
 
 static int fshort   = 0;       /* output only folder names                 */
 static int fcreat   = 0;       /* should we ask to create new folders?     */
index 2d6709e8fd5c6c9e4064e55e256367ac7549ee1f..97714dc412f2d3caa7afc7a5d12f9b0f9d00eac2 100644 (file)
 #define        IFORMAT "digest-issue-%s"
 #define        VFORMAT "digest-volume-%s"
 
-static struct swit switches[] = {
-#define        ANNOSW                 0
-    { "annotate", 0 },
-#define        NANNOSW                1
-    { "noannotate", 0 },
-#define        DFOLDSW                2
-    { "draftfolder +folder", 0 },
-#define        DMSGSW                 3
-    { "draftmessage msg", 0 },
-#define        NDFLDSW                4
-    { "nodraftfolder", 0 },
-#define        EDITRSW                5
-    { "editor editor", 0 },
-#define        NEDITSW                6
-    { "noedit", 0 },
-#define        FILTSW                 7
-    { "filter filterfile", 0 },
-#define        FORMSW                 8
-    { "form formfile", 0 },
-#define        FRMTSW                 9
-    { "format", 5 },
-#define        NFRMTSW               10
-    { "noformat", 7 },
-#define        INPLSW                11
-    { "inplace", 0 },
-#define        NINPLSW               12
-    { "noinplace", 0 },
-#define MIMESW                13
-    { "mime", 0 },
-#define NMIMESW               14
-    { "nomime", 0 },
-#define        DGSTSW                15
-    { "digest list", 0 },
-#define        ISSUESW               16
-    { "issue number", 0 },
-#define        VOLUMSW               17
-    { "volume number", 0 },
-#define        WHATSW                18
-    { "whatnowproc program", 0 },
-#define        NWHATSW               19
-    { "nowhatnowproc", 0 },
-#define        BITSTUFFSW            20
-    { "dashstuffing", 0 },             /* interface to mhl */
-#define        NBITSTUFFSW           21
-    { "nodashstuffing", 0 },
-#define VERSIONSW             22
-    { "version", 0 },
-#define        HELPSW                23
-    { "help", 0 },
-#define        FILESW                24
-    { "file file", 4 },                        /* interface from msh */
-#define        BILDSW                25
-    { "build", 5 },                    /* interface from mhe */
-#define FROMSW                26
-    { "from address", 0 },
-#define TOSW                  27
-    { "to address", 0 },
-#define CCSW                  28
-    { "cc address", 0 },
-#define SUBJECTSW             29
-    { "subject text", 0 },
-#define FCCSW                 30
-    { "fcc mailbox", 0 },
-#define WIDTHSW               31
-    { "width columns", 0 },
-    { NULL, 0 }
-};
-
-static struct swit aqrnl[] = {
-#define        NOSW         0
-    { "quit", 0 },
-#define        YESW         1
-    { "replace", 0 },
-#define        LISTDSW      2
-    { "list", 0 },
-#define        REFILSW      3
-    { "refile +folder", 0 },
-#define NEWSW        4
-    { "new", 0 },
-    { NULL, 0 }
-};
+#define FORW_SWITCHES \
+    X("annotate", 0, ANNOSW) \
+    X("noannotate", 0, NANNOSW) \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("filter filterfile", 0, FILTSW) \
+    X("form formfile", 0, FORMSW) \
+    X("format", 5, FRMTSW) \
+    X("noformat", 7, NFRMTSW) \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("digest list", 0, DGSTSW) \
+    X("issue number", 0, ISSUESW) \
+    X("volume number", 0, VOLUMSW) \
+    X("whatnowproc program", 0, WHATSW) \
+    X("nowhatnowproc", 0, NWHATSW) \
+    X("dashstuffing", 0, BITSTUFFSW)          /* interface to mhl */ \
+    X("nodashstuffing", 0, NBITSTUFFSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("file file", 4, FILESW)                 /* interface from msh */ \
+    X("build", 5, BILDSW)                     /* interface from mhe */ \
+    X("from address", 0, FROMSW) \
+    X("to address", 0, TOSW) \
+    X("cc address", 0, CCSW) \
+    X("subject text", 0, SUBJECTSW) \
+    X("fcc mailbox", 0, FCCSW) \
+    X("width columns", 0, WIDTHSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FORW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FORW, switches);
+#undef X
+
+#define DISPO_SWITCHES \
+    X("quit", 0, NOSW) \
+    X("replace", 0, YESW) \
+    X("list", 0, LISTDSW) \
+    X("refile +folder", 0, REFILSW) \
+    X("new", 0, NEWSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DISPO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DISPO, aqrnl);
+#undef X
 
 static struct swit aqrl[] = {
-    { "quit", 0 },
-    { "replace", 0 },
-    { "list", 0 },
-    { "refile +folder", 0 },
-    { NULL, 0 }
+    { "quit", 0, NOSW },
+    { "replace", 0, YESW },
+    { "list", 0, LISTDSW },
+    { "refile +folder", 0, REFILSW },
+    { NULL, 0, 0 }
 };
 
 static char drft[BUFSIZ];
index 86255857cecac7d9b85050485118fab8e7700d61..cf043c40b2bbba6d74b7ae7d165913d98debddcd 100644 (file)
@@ -46,7 +46,7 @@ build_form (char *form, char *digest, int *dat, char *from, char *to,
            char *cc, char *fcc, char *subject, char *inputfile)
 {
     int        in;
-    int fmtsize, state, char_read = 0;
+    int fmtsize, state;
     int i;
     register char *nfs;
     char *line, tmpfil[BUFSIZ], name[NAMESZ], **ap;
@@ -54,6 +54,7 @@ build_form (char *form, char *digest, int *dat, char *from, char *to,
     register struct comp *cptr;
     struct format *fmt;
     char *cp = NULL;
+    m_getfld_state_t gstate = 0;
 
     /*
      * Open the message we'll be scanning for components
@@ -86,8 +87,9 @@ build_form (char *form, char *digest, int *dat, char *from, char *to,
      * these routines?
      */
 
-    for (state = FLD;;) {
-       state = m_getfld(state, name, msgbuf, sizeof(msgbuf), tmp);
+    for (;;) {
+       int msg_count = sizeof msgbuf;
+       state = m_getfld (&gstate, name, msgbuf, &msg_count, tmp);
        switch (state) {
            case FLD:
            case FLDPLUS:
@@ -99,16 +101,16 @@ build_form (char *form, char *digest, int *dat, char *from, char *to,
 
                i = fmt_addcomptext(name, msgbuf);
                if (i != -1) {
-                   char_read += msg_count;
                    while (state == FLDPLUS) {
-                       state = m_getfld(state, name, msgbuf,
-                                        sizeof(msgbuf), tmp);
+                       msg_count = sizeof msgbuf;
+                       state = m_getfld (&gstate, name, msgbuf, &msg_count, tmp);
                        fmt_appendcomp(i, name, msgbuf);
-                       char_read += msg_count;
                    }
                }
-               while (state == FLDPLUS)
-                   state = m_getfld(state, name, msgbuf, sizeof(msgbuf), tmp);
+               while (state == FLDPLUS) {
+                   msg_count = sizeof msgbuf;
+                   state = m_getfld (&gstate, name, msgbuf, &msg_count, tmp);
+               }
                break;
 
            case LENERR:
@@ -121,6 +123,7 @@ build_form (char *form, char *digest, int *dat, char *from, char *to,
                adios(NULL, "m_getfld() returned %d", state);
        }
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * Override any components just in case they were included in the
index 07440b123f3cd5e56f668dc28abcbbd45ba5c0dd..2d791f68383949d657f65a1fc91abbbcc75962e2 100644 (file)
--- a/uip/inc.c
+++ b/uip/inc.c
 # define SASLminc(a)  0
 #endif
 
-static struct swit switches[] = {
-#define        AUDSW                      0
-    { "audit audit-file", 0 },
-#define        NAUDSW                     1
-    { "noaudit", 0 },
-#define        CHGSW                      2
-    { "changecur", 0 },
-#define        NCHGSW                     3
-    { "nochangecur", 0 },
-#define        FILESW                     4
-    { "file name", 0 },
-#define        FORMSW                     5
-    { "form formatfile", 0 },
-#define        FMTSW                      6
-    { "format string", 5 },
-#define        HOSTSW                     7
-    { "host hostname", 0 },
-#define        USERSW                     8
-    { "user username", 0 },
-#define        PACKSW                     9
-    { "pack file", 0},
-#define        NPACKSW                   10
-    { "nopack", 0 },
-#define PORTSW                   11
-    { "port name/number", 0 },
-#define        SILSW                     12
-    { "silent", 0 },
-#define        NSILSW                    13
-    { "nosilent", 0 },
-#define        TRNCSW                    14
-    { "truncate", 0 },
-#define        NTRNCSW                   15
-    { "notruncate", 0 },
-#define        WIDTHSW                   16
-    { "width columns", 0 },
-#define VERSIONSW                 17
-    { "version", 0 },
-#define        HELPSW                    18
-    { "help", 0 },
-#define SNOOPSW                   19
-    { "snoop", -5 },
-#define SASLSW                    20
-    { "sasl", SASLminc(-4) },
-#define NOSASLSW                  21
-    { "nosasl", SASLminc(-6) },
-#define SASLMECHSW                22
-    { "saslmech", SASLminc(-8) },
-#define PROXYSW                   23
-    { "proxy command", 0 },
-    { NULL, 0 }
-};
+#define INC_SWITCHES \
+    X("audit audit-file", 0, AUDSW) \
+    X("noaudit", 0, NAUDSW) \
+    X("changecur", 0, CHGSW) \
+    X("nochangecur", 0, NCHGSW) \
+    X("file name", 0, FILESW) \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("host hostname", 0, HOSTSW) \
+    X("user username", 0, USERSW) \
+    X("pack file", 0, PACKSW) \
+    X("nopack", 0, NPACKSW) \
+    X("port name/number", 0, PORTSW) \
+    X("silent", 0, SILSW) \
+    X("nosilent", 0, NSILSW) \
+    X("truncate", 0, TRNCSW) \
+    X("notruncate", 0, NTRNCSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("snoop", -5, SNOOPSW) \
+    X("sasl", SASLminc(-4), SASLSW) \
+    X("nosasl", SASLminc(-6), NOSASLSW) \
+    X("saslmech", SASLminc(-8), SASLMECHSW) \
+    X("proxy command", 0, PROXYSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(INC);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(INC, switches);
+#undef X
 
 /*
  * flags for the mail source
@@ -587,6 +569,7 @@ go_to_it:
        fflush (stdout);
     }
 
+
     /*
      * Get the mail from a POP server
      */
@@ -720,7 +703,7 @@ go_to_it:
      * Get the mail from file (usually mail spool)
      */
     if (inc_type == INC_FILE && Maildir == NULL) {
-       m_unknown (in);         /* the MAGIC invocation... */
+       scan_detect_mbox_style (in);            /* the MAGIC invocation... */
        hghnum = msgnum = mp->hghmsg;
        for (;;) {
            /*
@@ -887,6 +870,8 @@ go_to_it:
        free (Maildir); /* From now on Maildir is just a flag - don't dref! */
     }
 
+    scan_finished ();
+
     if (incerr < 0) {          /* error */
        if (locked) {
             GETGROUPPRIVS();      /* Be sure we can unlock mail file */
index 2cf9081c7a78b03675df212a2219abecb21dc538..2921d2619ccc0bd74f2f9e285ae4e08da05c8ce9 100644 (file)
 #include <h/utils.h>
 #include <pwd.h>                               /* structure for getpwuid() results */
 
-static struct swit switches[] = {
-#define AUTOSW     0
-    { "auto", 0 },
-#define VERSIONSW  1
-    { "version", 0 },
-#define HELPSW     2
-    { "help", 0 },
-#define CHECKSW     3
-    { "check", 1 },
-    { NULL, 0 }
-};
+#define INSTALLMH_SWITCHES \
+    X("auto", 0, AUTOSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("check", 1, CHECKSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(INSTALLMH);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(INSTALLMH, switches);
+#undef X
 
 /*
  * static prototypes
index 22a12ee3588aa7282ff4482af37a7d97dc82dff9..f99832a2c76847fa64ad7b38aea5909b5d191dd2 100644 (file)
 #include <h/mh.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        ADDSW               0
-    { "add", 0 },
-#define        DELSW               1
-    { "delete", 0 },
-#define        LSTSW               2
-    { "list", 0 },
-#define        SEQSW               3
-    { "sequence name", 0 },
-#define        PUBLSW              4
-    { "public", 0 },
-#define        NPUBLSW             5
-    { "nopublic", 0 },
-#define        ZEROSW              6
-    { "zero", 0 },
-#define        NZEROSW             7
-    { "nozero", 0 },
-#define VERSIONSW           8
-    { "version", 0 },
-#define        HELPSW              9
-    { "help", 0 },
-#define        DEBUGSW            10
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MARK_SWITCHES \
+    X("add", 0, ADDSW) \
+    X("delete", 0, DELSW) \
+    X("list", 0, LSTSW) \
+    X("sequence name", 0, SEQSW) \
+    X("public", 0, PUBLSW) \
+    X("nopublic", 0, NPUBLSW) \
+    X("zero", 0, ZEROSW) \
+    X("nozero", 0, NZEROSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MARK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MARK, switches);
+#undef X
 
 /*
  * static prototypes
index e8e74231b53edd2bcdc2beb949ea31ff247c4375..893ef8d644e09e640591fd664ff2e33856d593a0 100644 (file)
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        CHECKSW                 0
-    { "check", 0 },
-#define        NCHECKSW                1
-    { "nocheck", 0 },
-#define        DIRECTIVES              2
-    { "directives", 0 },
-#define        NDIRECTIVES             3
-    { "nodirectives", 0 },
-#define        EBCDICSW                4
-    { "ebcdicsafe", 0 },
-#define        NEBCDICSW               5
-    { "noebcdicsafe", 0 },
-#define        HEADSW                  6
-    { "headers", 0 },
-#define        NHEADSW                 7
-    { "noheaders", 0 },
-#define        LISTSW                  8
-    { "list", 0 },
-#define        NLISTSW                 9
-    { "nolist", 0 },
-#define        SIZESW                 10
-    { "realsize", 0 },
-#define        NSIZESW                11
-    { "norealsize", 0 },
-#define        RFC934SW               12
-    { "rfc934mode", 0 },
-#define        NRFC934SW              13
-    { "norfc934mode", 0 },
-#define        VERBSW                 14
-    { "verbose", 0 },
-#define        NVERBSW                15
-    { "noverbose", 0 },
-#define        RCACHESW               16
-    { "rcache policy", 0 },
-#define        WCACHESW               17
-    { "wcache policy", 0 },
-#define        CONTENTIDSW            18
-    { "contentid", 0 },
-#define        NCONTENTIDSW           19
-    { "nocontentid", 0 },
-#define VERSIONSW              20
-    { "version", 0 },
-#define        HELPSW                 21
-    { "help", 0 },
-#define        DEBUGSW                22
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MHBUILD_SWITCHES \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("directives", 0, DIRECTIVES) \
+    X("nodirectives", 0, NDIRECTIVES) \
+    X("headers", 0, HEADSW) \
+    X("noheaders", 0, NHEADSW) \
+    X("list", 0, LISTSW) \
+    X("nolist", 0, NLISTSW) \
+    X("realsize", 0, SIZESW) \
+    X("norealsize", 0, NSIZESW) \
+    X("rfc934mode", 0, RFC934SW) \
+    X("norfc934mode", 0, NRFC934SW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("contentid", 0, CONTENTIDSW) \
+    X("nocontentid", 0, NCONTENTIDSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHBUILD);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHBUILD, switches);
+#undef X
 
 
 /* mhbuildsbr.c */
@@ -83,7 +64,6 @@ extern char *cache_private;
 int debugsw = 0;
 int verbosw = 0;
 
-int ebcdicsw = 0;
 int listsw   = 0;
 int rfc934sw = 0;
 int contentidsw = 1;
@@ -188,13 +168,6 @@ main (int argc, char **argv)
                checksw = 0;
                continue;
 
-           case EBCDICSW:
-               ebcdicsw++;
-               continue;
-           case NEBCDICSW:
-               ebcdicsw = 0;
-               continue;
-
            case HEADSW:
                headsw++;
                continue;
index ec2c195a2c6a7ed85b05beb96e5718e24ac95531..a344a7c7536d5fbbf896998411c96854fb5531c1 100644 (file)
@@ -36,7 +36,6 @@
 extern int debugsw;
 extern int verbosw;
 
-extern int ebcdicsw;
 extern int listsw;
 extern int rfc934sw;
 extern int contentidsw;
@@ -135,6 +134,7 @@ build_mime (char *infile, int directives)
     struct part **pp;
     CT ct;
     FILE *in;
+    m_getfld_state_t gstate = 0;
 
     directive_init(directives);
 
@@ -162,11 +162,12 @@ build_mime (char *infile, int directives)
      * draft into the linked list of header fields for
      * the new MIME message.
      */
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), in)) {
+    m_getfld_track_filepos (&gstate, in);
+    for (compnum = 1;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
        case FLD:
        case FLDPLUS:
-       case FLDEOF:
            compnum++;
 
            /* abort if draft has Mime-Version header field */
@@ -179,8 +180,10 @@ build_mime (char *infile, int directives)
 
            /* ignore any Content-Type fields in the header */
            if (!mh_strcasecmp (name, TYPE_FIELD)) {
-               while (state == FLDPLUS)
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
+               while (state == FLDPLUS) {
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
+               }
                goto finish_field;
            }
 
@@ -190,7 +193,8 @@ build_mime (char *infile, int directives)
 
            /* if necessary, get rest of field */
            while (state == FLDPLUS) {
-               state = m_getfld (state, name, buf, sizeof(buf), in);
+               bufsz = sizeof buf;
+               state = m_getfld (&gstate, name, buf, &bufsz, in);
                vp = add (buf, vp);     /* add to previous value */
            }
 
@@ -199,16 +203,13 @@ build_mime (char *infile, int directives)
 
 finish_field:
            /* if this wasn't the last header field, then continue */
-           if (state != FLDEOF)
-               continue;
-           /* else fall... */
+           continue;
 
        case FILEEOF:
            adios (NULL, "draft has empty body -- no directives!");
            /* NOTREACHED */
 
        case BODY:
-       case BODYEOF:
            fseek (in, (long) (-strlen (buf)), SEEK_CUR);
            break;
 
@@ -221,6 +222,7 @@ finish_field:
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * Now add the MIME-Version header field
@@ -911,42 +913,6 @@ set_id (CT ct, int top)
 }
 
 
-static char ebcdicsafe[0x100] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
 /*
  * Fill out, or expand the various contents in the composition
  * draft.  Read-in any necessary files.  Parse and execute any
@@ -1190,7 +1156,6 @@ scan_content (CT ct)
     int checklinelen = 0, linelen = 0;   /* check for long lines                       */
     int checkboundary = 0, boundaryclash = 0; /* check if clashes with multipart boundary   */
     int checklinespace = 0, linespace = 0;  /* check if any line ends with space          */
-    int checkebcdic = 0, ebcdicunsafe = 0;  /* check if contains ebcdic unsafe characters */
     unsigned char *cp = NULL, buffer[BUFSIZ];
     struct text *t = NULL;
     FILE *in = NULL;
@@ -1231,11 +1196,9 @@ scan_content (CT ct)
        check8bit = 1;
        checkboundary = 1;
        if (ct->c_subtype == TEXT_PLAIN) {
-           checkebcdic = 0;
            checklinelen = 0;
            checklinespace = 0;
        } else {
-           checkebcdic = ebcdicsw;
            checklinelen = 1;
            checklinespace = 1;
        }
@@ -1243,7 +1206,6 @@ scan_content (CT ct)
 
     case CT_APPLICATION:
        check8bit = 1;
-       checkebcdic = ebcdicsw;
        checklinelen = 1;
        checklinespace = 1;
        checkboundary = 1;
@@ -1251,7 +1213,6 @@ scan_content (CT ct)
 
     case CT_MESSAGE:
        check8bit = 0;
-       checkebcdic = 0;
        checklinelen = 0;
        checklinespace = 0;
 
@@ -1270,7 +1231,6 @@ scan_content (CT ct)
         * since we are forcing use of base64.
         */
        check8bit = 0;
-       checkebcdic = 0;
        checklinelen = 0;
        checklinespace = 0;
        checkboundary = 0;
@@ -1295,14 +1255,6 @@ scan_content (CT ct)
                        contains8bit = 1;
                        check8bit = 0;  /* no need to keep checking */
                    }
-                   /*
-                    * Check if character is ebcdic-safe.  We only check
-                    * this if also checking for 8bit data.
-                    */
-                   if (checkebcdic && !ebcdicsafe[*cp & 0xff]) {
-                       ebcdicunsafe = 1;
-                       checkebcdic = 0; /* no need to keep checking */
-                   }
                }
            }
 
@@ -1370,7 +1322,7 @@ scan_content (CT ct)
            *ep = cp;
        }
 
-       if (contains8bit || ebcdicunsafe || linelen || linespace || checksw)
+       if (contains8bit || linelen || linespace || checksw)
            ct->c_encoding = CE_QUOTED;
        else
            ct->c_encoding = CE_7BIT;
@@ -1378,7 +1330,7 @@ scan_content (CT ct)
 
     case CT_APPLICATION:
        /* For application type, use base64, except when postscript */
-       if (contains8bit || ebcdicunsafe || linelen || linespace || checksw)
+       if (contains8bit || linelen || linespace || checksw)
            ct->c_encoding = (ct->c_subtype == APPLICATION_POSTSCRIPT)
                ? CE_QUOTED : CE_BASE64;
        else
index 5f7777d0035e17a035d60685758c2a8789807272..25ac9ab0b7a430654b9747e870dcf8752b9c08f7 100644 (file)
@@ -376,25 +376,27 @@ find_cache_aux2 (char *mapfile, char *id, char *mapname, int namelen)
     int        state;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *fp;
+    m_getfld_state_t gstate = 0;
 
     if (!(fp = lkfopen (mapfile, "r")))
        return NOTOK;
 
-    for (state = FLD;;) {
+    for (;;) {
        int result;
        char *cp, *dp;
+       int bufsz = sizeof buf;
 
-       switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                strncpy (mapname, name, namelen);
                if (state != FLDPLUS)
                    cp = buf;
                else {
                    cp = add (buf, NULL);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buf, sizeof(buf), fp);
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, fp);
                        cp = add (buf, cp);
                    }
                }
@@ -410,18 +412,16 @@ find_cache_aux2 (char *mapfile, char *id, char *mapname, int namelen)
                    lkfclose (fp, mapfile);
                    return OK;
                }
-               if (state != FLDEOF)
-                   continue;
-               /* else fall... */
+               continue;
 
            case BODY:
-           case BODYEOF:
            case FILEEOF:
            default:
                break;
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     lkfclose (fp, mapfile);
     return NOTOK;
index 021a4b202ff9194728abe1add4fa2b7792f8cbb9..1363081c39b0edc6cdd0df389953467906ab1cd4 100644 (file)
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        CHECKSW                 0
-    { "check", 0 },
-#define        NCHECKSW                1
-    { "nocheck", 0 },
-#define        HEADSW                  2
-    { "headers", 0 },
-#define        NHEADSW                 3
-    { "noheaders", 0 },
-#define        SIZESW                  4
-    { "realsize", 0 },
-#define        NSIZESW                 5
-    { "norealsize", 0 },
-#define        VERBSW                  6
-    { "verbose", 0 },
-#define        NVERBSW                 7
-    { "noverbose", 0 },
-#define        FILESW                  8       /* interface from show */
-    { "file file", 0 },
-#define        PARTSW                  9
-    { "part number", 0 },
-#define        TYPESW                 10
-    { "type content", 0 },
-#define        RCACHESW               11
-    { "rcache policy", 0 },
-#define        WCACHESW               12
-    { "wcache policy", 0 },
-#define VERSIONSW              13
-    { "version", 0 },
-#define        HELPSW                 14
-    { "help", 0 },
-
-/*
- * switches for debugging
- */
-#define        DEBUGSW                15
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MHLIST_SWITCHES \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("headers", 0, HEADSW) \
+    X("noheaders", 0, NHEADSW) \
+    X("realsize", 0, SIZESW) \
+    X("norealsize", 0, NSIZESW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("file file", 0, FILESW) \
+    X("part number", 0, PARTSW) \
+    X("type content", 0, TYPESW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHLIST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHLIST, switches);
+#undef X
 
 
 /* mhparse.c */
index 45d99b037d1f1e585d34187dfd881ce2c7ac6661..f87c47d35c0f19ab1ea04647ad258e7732fd8203 100644 (file)
 
 #define        QUOTE   '\\'
 
-static struct swit mhlswitches[] = {
-#define        BELLSW         0
-    { "bell", 0 },
-#define        NBELLSW        1
-    { "nobell", 0 },
-#define        CLRSW          2
-    { "clear", 0 },
-#define        NCLRSW         3
-    { "noclear", 0 },
-#define        FOLDSW         4
-    { "folder +folder", 0 },
-#define        FORMSW         5
-    { "form formfile", 0 },
-#define        PROGSW         6
-    { "moreproc program", 0 },
-#define        NPROGSW        7
-    { "nomoreproc", 0 },
-#define        LENSW          8
-    { "length lines", 0 },
-#define        WIDTHSW        9
-    { "width columns", 0 },
-#define        SLEEPSW       10
-    { "sleep seconds",  0 },
-#define        BITSTUFFSW    11
-    { "dashstuffing", -12 },   /* interface from forw */
-#define        NBITSTUFFSW   12
-    { "nodashstuffing", -14 }, /* interface from forw */
-#define VERSIONSW     13
-    { "version", 0 },
-#define        HELPSW        14
-    { "help", 0 },
-#define        FORW1SW       15
-    { "forward", -7 },         /* interface from forw */
-#define        FORW2SW       16
-    { "forwall", -7 },         /* interface from forw */
-#define        DGSTSW        17
-    { "digest list", -6 },
-#define VOLUMSW       18
-    { "volume number", -6 },
-#define ISSUESW       19
-    { "issue number", -5 },
-#define NBODYSW       20
-    { "nobody", -6 },
-#define FMTPROCSW     21
-    { "fmtproc program", 0 },
-#define NFMTPROCSW    22
-    { "nofmtproc", 0 },
-    { NULL, 0 }
-};
+#define MHL_SWITCHES \
+    X("bell", 0, BELLSW) \
+    X("nobell", 0, NBELLSW) \
+    X("clear", 0, CLRSW) \
+    X("noclear", 0, NCLRSW) \
+    X("folder +folder", 0, FOLDSW) \
+    X("form formfile", 0, FORMSW) \
+    X("moreproc program", 0, PROGSW) \
+    X("nomoreproc", 0, NPROGSW) \
+    X("length lines", 0, LENSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("sleep seconds", 0, SLEEPSW) \
+    X("dashstuffing", -12, BITSTUFFSW)    /* interface from forw */ \
+    X("nodashstuffing", -14, NBITSTUFFSW) /* interface from forw */ \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("forward", -7, FORW1SW)             /* interface from forw */ \
+    X("forwall", -7, FORW2SW)             /* interface from forw */ \
+    X("digest list", -6, DGSTSW) \
+    X("volume number", -6, VOLUMSW) \
+    X("issue number", -5, ISSUESW) \
+    X("nobody", -6, NBODYSW) \
+    X("fmtproc program", 0, FMTPROCSW) \
+    X("nofmtproc", 0, NFMTPROCSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHL, mhlswitches);
+#undef X
 
 #define NOCOMPONENT 0x000001   /* don't show component name         */
 #define UPPERCASE   0x000002   /* display in all upper case         */
@@ -353,7 +336,8 @@ static void quitser (int);
 static void mhladios (char *, char *, ...);
 static void mhldone (int);
 static void m_popen (char *);
-static void filterbody (struct mcomp *, char *, int, int, FILE *);
+static void filterbody (struct mcomp *, char *, int, int, FILE *,
+                        m_getfld_state_t);
 static void compile_formatfield(struct mcomp *);
 static void compile_filterargs (void);
 
@@ -953,6 +937,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
     int state, bucket;
     struct mcomp *c1, *c2, *c3;
     char **ip, name[NAMESZ], buf[BUFSIZ];
+    m_getfld_state_t gstate = 0;
 
     compile_filterargs();
 
@@ -1014,15 +999,17 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
        }
     }
 
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
            case FLD: 
            case FLDPLUS: 
                bucket = fmt_addcomptext(name, buf);
                for (ip = ignores; *ip; ip++)
                    if (!mh_strcasecmp (name, *ip)) {
                        while (state == FLDPLUS) {
-                           state = m_getfld (state, name, buf, sizeof(buf), fp);
+                           bufsz = sizeof buf;
+                           state = m_getfld (&gstate, name, buf, &bufsz, fp);
                            fmt_appendcomp(bucket, name, buf);
                        }
                        break;
@@ -1044,7 +1031,8 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                if (c1 == NULL)
                    c1 = add_queue (&msghd, &msgtl, name, buf, 0);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    c1->c_text = add (buf, c1->c_text);
                    fmt_appendcomp(bucket, name, buf);
                }
@@ -1077,14 +1065,15 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                    if (dobody && !mh_strcasecmp (c1->c_name, "body")) {
                        if (c1->c_flags & FMTFILTER && state == BODY &&
                                                        formatproc != NULL) {
-                           filterbody(c1, buf, sizeof(buf), state, fp);
+                           filterbody(c1, buf, sizeof(buf), state, fp, gstate);
                        } else {
                            holder.c_text = mh_xmalloc (sizeof(buf));
                            strncpy (holder.c_text, buf, sizeof(buf));
                            while (state == BODY) {
                                putcomp (c1, &holder, BODYCOMP);
-                               state = m_getfld (state, name, holder.c_text,
-                                           sizeof(buf), fp);
+                               bufsz = sizeof buf;
+                               state = m_getfld (&gstate, name, holder.c_text,
+                                           &bufsz, fp);
                            }
                            free (holder.c_text);
                            holder.c_text = NULL;
@@ -1110,6 +1099,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                adios (NULL, "getfld() returned %d", state);
        }
     }
+    m_getfld_state_destroy (&gstate);
 }
 
 
@@ -1658,6 +1648,8 @@ static void
 m_popen (char *name)
 {
     int pd[2];
+    char *file;
+    char **arglist;
 
     if (mhl_action && (sd = dup (fileno (stdout))) == NOTOK)
        adios ("standard output", "unable to dup()");
@@ -1678,7 +1670,8 @@ m_popen (char *name)
                dup2 (pd[0], fileno (stdin));
                close (pd[0]);
            }
-           execlp (name, r1bindex (name, '/'), NULL);
+           arglist = argsplit(name, &file, NULL);
+           execvp (file, arglist);
            fprintf (stderr, "unable to exec ");
            perror (name);
            _exit (-1);
@@ -1784,7 +1777,8 @@ compile_filterargs (void)
  */
 
 static void
-filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp)
+filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp,
+            m_getfld_state_t gstate)
 {
     struct mcomp holder;
     char name[NAMESZ];
@@ -1838,8 +1832,9 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state, FILE *fp)
         */
 
        while (state == BODY) {
+           int bufsz2 = bufsz;
            write(fdinput[1], buf, strlen(buf));
-           state = m_getfld(state, name, buf, bufsz, fp);
+           state = m_getfld (&gstate, name, buf, &bufsz2, fp);
        }
 
        /*
index 65e78d31d98b3a1d0820ae8c534c7ebdcdd27bf9..5ce762227bc738801950b6395779f945a348dd7d 100644 (file)
--- a/uip/mhn.c
+++ b/uip/mhn.c
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        AUTOSW                  0
-    { "auto", 0 },
-#define        NAUTOSW                 1
-    { "noauto", 0 },
-#define        CACHESW                 2
-    { "cache", 0 },
-#define        NCACHESW                3
-    { "nocache", 0 },
-#define        CHECKSW                 4
-    { "check", 0 },
-#define        NCHECKSW                5
-    { "nocheck", 0 },
-#define        HEADSW                  6
-    { "headers", 0 },
-#define        NHEADSW                 7
-    { "noheaders", 0 },
-#define        LISTSW                  8
-    { "list", 0 },
-#define        NLISTSW                 9
-    { "nolist", 0 },
-#define        PAUSESW                10
-    { "pause", 0 },
-#define        NPAUSESW               11
-    { "nopause", 0 },
-#define        SIZESW                 12
-    { "realsize", 0 },
-#define        NSIZESW                13
-    { "norealsize", 0 },
-#define        SERIALSW               14
-    { "serialonly", 0 },
-#define        NSERIALSW              15
-    { "noserialonly", 0 },
-#define        SHOWSW                 16
-    { "show", 0 },
-#define        NSHOWSW                17
-    { "noshow", 0 },
-#define        STORESW                18
-    { "store", 0 },
-#define        NSTORESW               19
-    { "nostore", 0 },
-#define        VERBSW                 20
-    { "verbose", 0 },
-#define        NVERBSW                21
-    { "noverbose", 0 },
-#define        FILESW                 22       /* interface from show */
-    { "file file", 0 },
-#define        FORMSW                 23
-    { "form formfile", 0 },
-#define        PARTSW                 24
-    { "part number", 0 },
-#define        TYPESW                 25
-    { "type content", 0 },
-#define        RCACHESW               26
-    { "rcache policy", 0 },
-#define        WCACHESW               27
-    { "wcache policy", 0 },
-#define VERSIONSW              28
-    { "version", 0 },
-#define        HELPSW                 29
-    { "help", 0 },
-
-/*
- * switches for debugging
- */
-#define        DEBUGSW                30
-    { "debug", -5 },
-
-/*
- * switches for moreproc/mhlproc
- */
-#define        PROGSW                 31
-    { "moreproc program", -4 },
-#define        NPROGSW                32
-    { "nomoreproc", -3 },
-#define        LENSW                  33
-    { "length lines", -4 },
-#define        WIDTHSW                34
-    { "width columns", -4 },
-
-/*
- * switches for mhbuild
- */
-#define BUILDSW                35
-    { "build", -5 },
-#define NBUILDSW               36
-    { "nobuild", -7 },
-#define        EBCDICSW               37
-    { "ebcdicsafe", -10 },
-#define        NEBCDICSW              38
-    { "noebcdicsafe", -12 },
-#define        RFC934SW               39
-    { "rfc934mode", -10 },
-#define        NRFC934SW              40
-    { "norfc934mode", -12 },
-    { NULL, 0 }
-};
+#define MHN_SWITCHES \
+    X("auto", 0, AUTOSW) \
+    X("noauto", 0, NAUTOSW) \
+    X("cache", 0, CACHESW) \
+    X("nocache", 0, NCACHESW) \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("headers", 0, HEADSW) \
+    X("noheaders", 0, NHEADSW) \
+    X("list", 0, LISTSW) \
+    X("nolist", 0, NLISTSW) \
+    X("pause", 0, PAUSESW) \
+    X("nopause", 0, NPAUSESW) \
+    X("realsize", 0, SIZESW) \
+    X("norealsize", 0, NSIZESW) \
+    X("serialonly", 0, SERIALSW) \
+    X("noserialonly", 0, NSERIALSW) \
+    X("show", 0, SHOWSW) \
+    X("noshow", 0, NSHOWSW) \
+    X("store", 0, STORESW) \
+    X("nostore", 0, NSTORESW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("file file", 0, FILESW) \
+    X("form formfile", 0, FORMSW) \
+    X("part number", 0, PARTSW) \
+    X("type content", 0, TYPESW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    /*                                 \
+     * for debugging                   \
+     */                                        \
+    X("debug", -5, DEBUGSW) \
+    /*                                 \
+     * switches for moreproc/mhlproc   \
+     */                                        \
+    X("moreproc program", -4, PROGSW) \
+    X("nomoreproc", -3, NPROGSW) \
+    X("length lines", -4, LENSW) \
+    X("width columns", -4, WIDTHSW) \
+    /*                                 \
+     * switches for mhbuild            \
+     */                                        \
+    X("build", -5, BUILDSW) \
+    X("nobuild", -7, NBUILDSW) \
+    X("rfc934mode", -10, RFC934SW) \
+    X("norfc934mode", -12, NRFC934SW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHN);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHN, switches);
+#undef X
 
 
 /* mhparse.c */
@@ -154,7 +114,6 @@ int verbosw = 0;
  * variables for mhbuild (mhn -build)
  */
 static int buildsw  = 0;
-static int ebcdicsw = 0;
 static int rfc934sw = 0;
 
 /*
@@ -398,12 +357,6 @@ do_cache:
            case NRFC934SW:
                rfc934sw = -1;
                continue;
-           case EBCDICSW:
-               ebcdicsw = 1;
-               continue;
-           case NEBCDICSW:
-               ebcdicsw = -1;
-               continue;
 
            case VERBSW: 
                verbosw = 1;
@@ -493,11 +446,6 @@ do_cache:
        vecp = 0;
        vec[vecp++] = "mhbuild";
 
-       if (ebcdicsw == 1)
-           vec[vecp++] = "-ebcdicsafe";
-       else if (ebcdicsw == -1)
-           vec[vecp++] = "-noebcdicsafe";
-
        if (rfc934sw == 1)
            vec[vecp++] = "-rfc934mode";
        else if (rfc934sw == -1)
@@ -525,11 +473,6 @@ do_cache:
        vecp = 0;
        vec[vecp++] = "mhbuild";
 
-       if (ebcdicsw == 1)
-           vec[vecp++] = "-ebcdicsafe";
-       else if (ebcdicsw == -1)
-           vec[vecp++] = "-noebcdicsafe";
-
        if (rfc934sw == 1)
            vec[vecp++] = "-rfc934mode";
        else if (rfc934sw == -1)
index 97f97f08ffdf3eae1e9444ae2b01327aeb6674c1..57a5df93db59fa6a9320789d7fa5f28bddc46885 100644 (file)
 #include <h/mhparse.h>
 
 
-extern int ebcdicsw;
-
-static char ebcdicsafe[0x100] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-    0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
 /*
  * prototypes
  */
@@ -372,8 +335,7 @@ writeQuoted (CT ct, FILE *out)
                    break;
 
                default:
-                   if (*cp < '!' || *cp > '~'
-                           || (ebcdicsw && !ebcdicsafe[*cp & 0xff]))
+                   if (*cp < '!' || *cp > '~')
                        goto three_print;
                    putc (*cp, out);
                    n++;
index d2603522f858a5f9bb497280773c178a5ffb8657..1fb50a724d41d9e57592fa68db7dccc0c7e67e35 100644 (file)
@@ -17,21 +17,21 @@ extern char *mhetcdir;
 
 char *sbackup = BACKUP_PREFIX;
 
-static struct swit switches[] = {
-#define        COMPSW    0
-    { "components", 0 },
-#define        NCOMPSW   1
-    { "nocomponents", 0 },
-#define        ALLSW     2
-    { "all", 0 },
-#define VERSIONSW 3
-    { "version", 0 },
-#define        HELPSW    4
-    { "help", 0 },
-#define DEBUGSW   5
-    { "debug", 5 },
-    { NULL, 0 }
-};
+#define MHPARAM_SWITCHES \
+    X("components", 0, COMPSW) \
+    X("nocomponents", 0, NCOMPSW) \
+    X("all", 0, ALLSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", 5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHPARAM);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHPARAM, switches);
+#undef X
 
 struct proc {
     char *p_name;
index 8cfa89980ee9e37d8fee9a61104ab107124f5aaa..0dcd1333d499e027070a754034b9b41ac21aef53 100644 (file)
@@ -262,6 +262,7 @@ get_content (FILE *in, char *file, int toplevel)
     char *np, *vp;
     CT ct;
     HF hp;
+    m_getfld_state_t gstate = 0;
 
     /* allocate the content structure */
     if (!(ct = (CT) calloc (1, sizeof(*ct))))
@@ -275,11 +276,12 @@ get_content (FILE *in, char *file, int toplevel)
      * Parse the header fields for this
      * content into a linked list.
      */
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), in)) {
+    m_getfld_track_filepos (&gstate, in);
+    for (compnum = 1;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
        case FLD:
        case FLDPLUS:
-       case FLDEOF:
            compnum++;
 
            /* get copies of the buffers */
@@ -288,22 +290,19 @@ get_content (FILE *in, char *file, int toplevel)
 
            /* if necessary, get rest of field */
            while (state == FLDPLUS) {
-               state = m_getfld (state, name, buf, sizeof(buf), in);
+               bufsz = sizeof buf;
+               state = m_getfld (&gstate, name, buf, &bufsz, in);
                vp = add (buf, vp);     /* add to previous value */
            }
 
            /* Now add the header data to the list */
            add_header (ct, np, vp);
 
-           /* continue, if this isn't the last header field */
-           if (state != FLDEOF) {
-               ct->c_begin = ftell (in) + 1;
-               continue;
-           }
-           /* else fall... */
+           /* continue, to see if this isn't the last header field */
+           ct->c_begin = ftell (in) + 1;
+           continue;
 
        case BODY:
-       case BODYEOF:
            ct->c_begin = ftell (in) - strlen (buf);
            break;
 
@@ -322,6 +321,7 @@ get_content (FILE *in, char *file, int toplevel)
        /* break out of the loop */
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * Read the content headers.  We will parse the
@@ -1121,9 +1121,22 @@ InitMultiPart (CT ct)
      */
     if (ct->c_encoding != CE_7BIT && ct->c_encoding != CE_8BIT
        && ct->c_encoding != CE_BINARY) {
+       /* Copy the Content-Transfer-Encoding header field body so we can
+          remove any trailing whitespace and leading blanks from it. */
+       char *cte = add (ct->c_celine ? ct->c_celine : "(null)", NULL);
+
+       bp = cte + strlen (cte) - 1;
+       while (bp >= cte && isspace (*bp)) *bp-- = '\0';
+       for (bp = cte; *bp && isblank (*bp); ++bp) continue;
+
        admonish (NULL,
-                 "\"%s/%s\" type in message %s must be encoded in 7bit, 8bit, or binary",
-                 ci->ci_type, ci->ci_subtype, ct->c_file);
+                 "\"%s/%s\" type in message %s must be encoded in\n"
+                 "7bit, 8bit, or binary, per RFC 2045 (6.4).  One workaround "
+                 "is to\nmanually edit the file and change the \"%s\"\n"
+                 "Content-Transfer-Encoding to one of those.  For now",
+                 ci->ci_type, ci->ci_subtype, ct->c_file, bp);
+       free (cte);
+
        return NOTOK;
     }
 
index bb77996cfa4456bc612bf10b75743c2caff4ddd4..ef16bce2025c1b72358e024e81b5ba2884d88799 100644 (file)
 #include <h/mh.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define VERSIONSW 0
-    { "version", 0 },
-#define        HELPSW  1
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define MHPATH_SWITCHES \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHPATH);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHPATH, switches);
+#undef X
 
 int
 main(int argc, char **argv)
index 993477bb6c8e23b9cc97de7925c70440e933d760..8e1a9003f7fd22da26d32c5ac4d33945c51a5106 100644 (file)
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        CHECKSW                 0
-    { "check", 0 },
-#define        NCHECKSW                1
-    { "nocheck", 0 },
-#define        PAUSESW                 2
-    { "pause", 0 },
-#define        NPAUSESW                3
-    { "nopause", 0 },
-#define        SERIALSW                4
-    { "serialonly", 0 },
-#define        NSERIALSW               5
-    { "noserialonly", 0 },
-#define        VERBSW                  6
-    { "verbose", 0 },
-#define        NVERBSW                 7
-    { "noverbose", 0 },
-#define        FILESW                  8       /* interface from show */
-    { "file file", 0 },
-#define        FORMSW                  9
-    { "form formfile", 0 },
-#define        PARTSW                 10
-    { "part number", 0 },
-#define        TYPESW                 11
-    { "type content", 0 },
-#define        RCACHESW               12
-    { "rcache policy", 0 },
-#define        WCACHESW               13
-    { "wcache policy", 0 },
-#define VERSIONSW              14
-    { "version", 0 },
-#define        HELPSW                 15
-    { "help", 0 },
-
-/*
- * switches for moreproc/mhlproc
- */
-#define        PROGSW                 16
-    { "moreproc program", -4 },
-#define        NPROGSW                17
-    { "nomoreproc", -3 },
-#define        LENSW                  18
-    { "length lines", -4 },
-#define        WIDTHSW                19
-    { "width columns", -4 },
-
-/*
- * switches for debugging
- */
-#define        DEBUGSW                20
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MHSHOW_SWITCHES \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("pause", 0, PAUSESW) \
+    X("nopause", 0, NPAUSESW) \
+    X("serialonly", 0, SERIALSW) \
+    X("noserialonly", 0, NSERIALSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("file file", 0, FILESW) \
+    X("form formfile", 0, FORMSW) \
+    X("part number", 0, PARTSW) \
+    X("type content", 0, TYPESW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    /*                                 \
+     * switches for moreproc/mhlproc   \
+     */                                        \
+    X("moreproc program", -4, PROGSW) \
+    X("nomoreproc", -3, NPROGSW) \
+    X("length lines", -4, LENSW) \
+    X("width columns", -4, WIDTHSW) \
+    /*                         \
+     * switches for debugging  \
+     */                                \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHSHOW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHSHOW, switches);
+#undef X
 
 
 /* mhparse.c */
index 3b91eebf78ccb74ff46e044cea46e94c96189d51..866a41bfbcbca9f684c754c62877101c0757f29b 100644 (file)
@@ -168,24 +168,24 @@ DisplayMsgHeader (CT ct, char *form)
 {
     pid_t child_id;
     int i, vecp;
-    char *vec[8];
+    char **vec;
+    char *file;
 
-    vecp = 0;
-    vec[vecp++] = r1bindex (mhlproc, '/');
-    vec[vecp++] = "-form";
-    vec[vecp++] = form;
-    vec[vecp++] = "-nobody";
-    vec[vecp++] = ct->c_file;
+    vec = argsplit(mhlproc, &file, &vecp);
+    vec[vecp++] = getcpy("-form");
+    vec[vecp++] = getcpy(form);
+    vec[vecp++] = getcpy("-nobody");
+    vec[vecp++] = getcpy(ct->c_file);
 
     /*
      * If we've specified -(no)moreproc,
      * then just pass that along.
      */
     if (nomore) {
-       vec[vecp++] = "-nomoreproc";
+       vec[vecp++] = getcpy("-nomoreproc");
     } else if (progsw) {
-       vec[vecp++] = "-moreproc";
-       vec[vecp++] = progsw;
+       vec[vecp++] = getcpy("-moreproc");
+       vec[vecp++] = getcpy(progsw);
     }
     vec[vecp] = NULL;
 
@@ -200,7 +200,7 @@ DisplayMsgHeader (CT ct, char *form)
        /* NOTREACHED */
 
     case OK:
-       execvp (mhlproc, vec);
+       execvp (file, vec);
        fprintf (stderr, "unable to exec ");
        perror (mhlproc);
        _exit (-1);
@@ -210,6 +210,8 @@ DisplayMsgHeader (CT ct, char *form)
        xpid = -child_id;
        break;
     }
+
+    arglist_free(file, vec);
 }
 
 
index fa30e035fa24c24ce84d4cf2b58dba1f16df2c40..61a54e631a04daefea38ca460af7f16dcda35d52 100644 (file)
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        AUTOSW                  0
-    { "auto", 0 },
-#define        NAUTOSW                 1
-    { "noauto", 0 },
-#define        CHECKSW                 2
-    { "check", 0 },
-#define        NCHECKSW                3
-    { "nocheck", 0 },
-#define        VERBSW                  4
-    { "verbose", 0 },
-#define        NVERBSW                 5
-    { "noverbose", 0 },
-#define        FILESW                  6       /* interface from show */
-    { "file file", 0 },
-#define        PARTSW                  7
-    { "part number", 0 },
-#define        TYPESW                  8
-    { "type content", 0 },
-#define        RCACHESW                9
-    { "rcache policy", 0 },
-#define        WCACHESW               10
-    { "wcache policy", 0 },
-#define VERSIONSW              11
-    { "version", 0 },
-#define        HELPSW                 12
-    { "help", 0 },
-#define        CLOBBERSW              13
-    { "clobber always|auto|suffix|ask|never", 0 },
-
-/*
- * switches for debugging
- */
-#define        DEBUGSW                14
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MHSTORE_SWITCHES \
+    X("auto", 0, AUTOSW) \
+    X("noauto", 0, NAUTOSW) \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("file file", 0, FILESW)          /* interface from show */ \
+    X("part number", 0, PARTSW) \
+    X("type content", 0, TYPESW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("clobber always|auto|suffix|ask|never", 0, CLOBBERSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHSTORE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHSTORE, switches);
+#undef X
 
 
 int save_clobber_policy (const char *);
index ca03bda8677dd4e62da40e4399d8de2fc4420efb..b978dbfb3c304f7c262dc4f50aa9f6c9b9c7a4f4 100644 (file)
@@ -1228,7 +1228,7 @@ clobber_check (char *original_file) {
         if (stat (file, &st) == OK) {
           enum answers { NMH_YES, NMH_NO, NMH_RENAME };
           static struct swit answer[4] = {
-            { "yes", 0 }, { "no", 0 }, { "rename", 0 }, { NULL, 0 } };
+            { "yes", 0, NMH_YES }, { "no", 0, NMH_NO }, { "rename", 0, NMH_RENAME }, { NULL, 0, 0 } };
           char **ans;
 
           if (isatty (fileno (stdin))) {
index cbaefd33f9eedb5b43feefcb432fadd77a7ef3d0..44cc3b23b7930aa4f370000723da8213bf88435d 100644 (file)
 #include <h/mhcachesbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        CHECKSW                 0
-    { "check", 0 },
-#define        NCHECKSW                1
-    { "nocheck", 0 },
-#define        VERBSW                  2
-    { "verbose", 0 },
-#define        NVERBSW                 3
-    { "noverbose", 0 },
-#define        FILESW                  4
-    { "file file", 0 },
-#define OUTFILESW               5
-    { "outfile file", 0 },
-#define        PARTSW                  6
-    { "part number", 0 },
-#define        TYPESW                  7
-    { "type content", 0 },
-#define        RCACHESW                8
-    { "rcache policy", 0 },
-#define        WCACHESW                9
-    { "wcache policy", 0 },
-#define VERSIONSW              10
-    { "version", 0 },
-#define        HELPSW                 11
-    { "help", 0 },
+#define MHTEST_SWITCHES \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("file file", 0, FILESW) \
+    X("outfile file", 0, OUTFILESW) \
+    X("part number", 0, PARTSW) \
+    X("type content", 0, TYPESW) \
+    X("rcache policy", 0, RCACHESW) \
+    X("wcache policy", 0, WCACHESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHTEST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHTEST, switches);
+#undef X
 
-/*
- * switches for debugging
- */
-#define        DEBUGSW                12
-    { "debug", -5 },
-    { NULL, 0 }
-};
-
-
-int ebcdicsw = 0;      /* hack for linking purposes */
 
 /* mhparse.c */
 extern char *tmp;      /* directory to place temp files */
index 3654995b381516df80e5b3e535d2480fe6a563d4..6a0a12e7940f7b094ff790bcc7e42ff0306093b8 100644 (file)
 # define SASLminc(a)  0
 #endif
 
-static struct swit switches[] = {
-#define        DATESW                   0
-    { "date", 0 },
-#define        NDATESW                  1
-    { "nodate", 0 },
-#define        NOTESW                   2
-    { "notify type", 0 },
-#define        NNOTESW                  3
-    { "nonotify type", 0 },
-#define        HOSTSW                   4
-    { "host hostname", 0 },
-#define        USERSW                   5
-    { "user username", 0 },
-#define PORTSW                  6
-    { "port name/number", 0 },
-#define VERSIONSW                7
-    { "version", 0 },
-#define        HELPSW                   8
-    { "help", 0 },
-#define SNOOPSW                  9
-    { "snoop", -5 },
-#define SASLSW                  10
-    { "sasl", SASLminc(-4) },
-#define SASLMECHSW             11
-    { "saslmech", SASLminc(-5) },
-#define PROXYSW                12
-    { "proxy command", 0 },
-    { NULL, 0 }
-};
+#define MSGCHK_SWITCHES \
+    X("date", 0, DATESW) \
+    X("nodate", 0, NDATESW) \
+    X("notify type", 0, NOTESW) \
+    X("nonotify type", 0, NNOTESW) \
+    X("host hostname", 0, HOSTSW) \
+    X("user username", 0, USERSW) \
+    X("port name/number", 0, PORTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("snoop", -5, SNOOPSW) \
+    X("sasl", SASLminc(-4), SASLSW) \
+    X("saslmech", SASLminc(-5), SASLMECHSW) \
+    X("proxy command", 0, PROXYSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MSGCHK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MSGCHK, switches);
+#undef X
 
 /*
  * Maximum numbers of users we can check (plus
@@ -240,15 +233,18 @@ main (int argc, char **argv)
 }
 
 
-static struct swit ntswitches[] = {
-#define        NALLSW     0
-    { "all", 0 },
-#define        NMAISW     1
-    { "mail", 0 },
-#define        NNMAISW    2
-    { "nomail", 0 },
-    { NULL, 0 }
-};
+#define NOTE_SWITCHES \
+    X("all", 0, NALLSW) \
+    X("mail", 0, NMAISW) \
+    X("nomail", 0, NNMAISW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(NOTE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(NOTE, ntswitches);
+#undef X
 
 
 static int
index b3aa3a107aec077ce57472d8c129851b197ccdca..e5f82bfadb44f21df62d694fdddbd22ad921f33e 100644 (file)
--- a/uip/msh.c
+++ b/uip/msh.c
 
 #define        QUOTE   '\\'            /* sigh */
 
-static struct swit switches[] = {
-#define        IDSW                  0
-    { "idstart number", -7 },          /* interface from bbc */
-#define        FDSW                  1
-    { "idstop number", -6 },           /*  .. */
-#define        QDSW                  2
-    { "idquit number", -6 },           /*  .. */
-#define        NMSW                  3
-    { "idname BBoard", -6 },           /*  .. */
-#define        PRMPTSW               4
-    { "prompt string", 0 },
-#define        SCANSW                5
-    { "scan", 0 },
-#define        NSCANSW               6
-    { "noscan", 0 },
-#define        READSW                7
-    { "vmhread fd", -7 },
-#define        WRITESW               8
-    { "vmhwrite fd", -8 },     
-#define        PREADSW               9
-    { "popread fd", -7 },
-#define        PWRITSW              10
-    { "popwrite fd", -8 },
-#define        TCURSW               11
-    { "topcur", 0 },
-#define        NTCURSW              12
-    { "notopcur", 0 },
-#define VERSIONSW            13
-    { "version", 0 },
-#define        HELPSW               14
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define MSH_SWITCHES \
+    X("idstart number", -7, IDSW) /* interface from bbc */ \
+    X("idstop number", -6, FDSW) /*  .. */ \
+    X("idquit number", -6, QDSW) /*  .. */ \
+    X("idname BBoard", -6, NMSW) /*  .. */ \
+    X("prompt string", 0, PRMPTSW) \
+    X("scan", 0, SCANSW) \
+    X("noscan", 0, NSCANSW) \
+    X("vmhread fd", -7, READSW) \
+    X("vmhwrite fd", -8, WRITESW) \
+    X("popread fd", -7, PREADSW) \
+    X("popwrite fd", -8, PWRITSW) \
+    X("topcur", 0, TCURSW) \
+    X("notopcur", 0, NTCURSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MSH);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MSH, switches);
+#undef X
 
 static int mbx_style = MMDF_FORMAT;
 
@@ -164,6 +155,8 @@ void seq_setcur (struct msgs *, int);
 void padios (char *, char *, ...);
 void padvise (char *, char *, ...);
 
+extern m_getfld_state_t gstate;        /* use the gstate in scansbr.c */
+
 
 /*
  * static prototypes
@@ -350,6 +343,7 @@ main (int argc, char **argv)
     display_info (id > 0 ? scansw : 0);
 
     msh (id > 0 ? scansw : 0);
+    scan_finished ();
 
     m_reset ();
     
@@ -358,65 +352,43 @@ main (int argc, char **argv)
 }
 
 
-static struct swit mshcmds[] = {
-#define        ADVCMD  0
-    { "advance", -7 },
-#define        ALICMD  1
-    { "ali", 0 },
-#define        EXPLCMD 2
-    { "burst", 0 },
-#define        COMPCMD 3
-    { "comp", 0 },
-#define        DISTCMD 4
-    { "dist", 0 },
-#define        EXITCMD 5
-    { "exit", 0 },
-#define        FOLDCMD 6
-    { "folder", 0 },
-#define        FORWCMD 7
-    { "forw", 0 },
-#define        HELPCMD 8
-    { "help", 0 },
-#define        INCMD   9
-    { "inc", 0 },
-#define        MARKCMD 10
-    { "mark", 0 },
-#define        MAILCMD 11
-    { "mhmail", 0 },
-#define        MHNCMD  12
-    { "mhn", 0 },
-#define        MSGKCMD 13
-    { "msgchk", 0 },
-#define        NEXTCMD 14
-    { "next", 0 },
-#define        PACKCMD 15
-    { "packf", 0 },
-#define        PICKCMD 16
-    { "pick", 0 },
-#define        PREVCMD 17
-    { "prev", 0 },
-#define        QUITCMD 18
-    { "quit", 0 },
-#define        FILECMD 19
-    { "refile", 0 },
-#define        REPLCMD 20
-    { "repl", 0 },
-#define        RMMCMD  21
-    { "rmm", 0 },
-#define        SCANCMD 22
-    { "scan", 0 },
-#define        SENDCMD 23
-    { "send", 0 },
-#define        SHOWCMD 24
-    { "show", 0 },
-#define        SORTCMD 25
-    { "sortm", 0 },
-#define        WHATCMD 26
-    { "whatnow", 0 },
-#define        WHOMCMD 27
-    { "whom", 0 },
-    { NULL, 0 }
-};
+#define MSHCMDS_SWITCHES \
+    X("advance", -7, ADVCMD) \
+    X("ali", 0, ALICMD) \
+    X("burst", 0, EXPLCMD) \
+    X("comp", 0, COMPCMD) \
+    X("dist", 0, DISTCMD) \
+    X("exit", 0, EXITCMD) \
+    X("folder", 0, FOLDCMD) \
+    X("forw", 0, FORWCMD) \
+    X("help", 0, HELPCMD) \
+    X("inc", 0, INCMD) \
+    X("mark", 0, MARKCMD) \
+    X("mhmail", 0, MAILCMD) \
+    X("mhn", 0, MHNCMD) \
+    X("msgchk", 0, MSGKCMD) \
+    X("next", 0, NEXTCMD) \
+    X("packf", 0, PACKCMD) \
+    X("pick", 0, PICKCMD) \
+    X("prev", 0, PREVCMD) \
+    X("quit", 0, QUITCMD) \
+    X("refile", 0, FILECMD) \
+    X("repl", 0, REPLCMD) \
+    X("rmm", 0, RMMCMD) \
+    X("scan", 0, SCANCMD) \
+    X("send", 0, SENDCMD) \
+    X("show", 0, SHOWCMD) \
+    X("sortm", 0, SORTCMD) \
+    X("whatnow", 0, WHATCMD) \
+    X("whom", 0, WHOMCMD) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MSHCMDS);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MSHCMDS, mshcmds);
+#undef X
 
 
 static void
@@ -713,7 +685,7 @@ setup (char *file)
     mp->msgattrs[0] = getcpy ("unseen");
     mp->msgattrs[1] = NULL;
 
-    m_unknown (fp);            /* the MAGIC invocation */    
+    scan_detect_mbox_style (fp);               /* the MAGIC invocation */
     if (fmsh) {
        free (fmsh);
        fmsh = NULL;
@@ -836,7 +808,8 @@ msh_ready (int msgnum, int full)
        return yp;
     }
 
-    m_eomsbr ((int (*)()) 0);  /* XXX */
+    scan_reset_m_getfld_state ();
+    scan_eom_action ((int (*)()) 0);   /* XXX */
     fseek (fp, Msgs[msgnum].m_start, SEEK_SET);
     return fp;
 }
@@ -1005,15 +978,16 @@ readid (int msgnum)
        return Msgs[msgnum].m_bboard_id;
 
     zp = msh_ready (msgnum, 0);
-    for (state = FLD;;)
-       switch (state = m_getfld (state, name, buf, sizeof(buf), zp)) {
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, zp)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                if (!mh_strcasecmp (name, BBoard_ID)) {
                    bp = getcpy (buf);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buf, sizeof(buf), zp);
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, zp);
                        bp = add (buf, bp);
                    }
                    i = atoi (bp);
@@ -1023,14 +997,16 @@ readid (int msgnum)
                    else
                        continue;
                }
-               while (state == FLDPLUS)
-                   state = m_getfld (state, name, buf, sizeof(buf), zp);
-               if (state != FLDEOF)
-                   continue;
+               while (state == FLDPLUS) {
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, zp);
+               }
+               continue;
 
            default: 
                return 0;
        }
+    }
 }
 
 
index 5f571b49796ff49b5a58467ce7ef44fe70e7d70b..6ea1126c5039bb0b88edbcf0df6aa2d1df031d63 100644 (file)
@@ -51,6 +51,8 @@ static int process (int, char *, int, char **);
 static void copy_message (int, FILE *);
 static void copy_digest (int, FILE *);
 
+extern m_getfld_state_t gstate;        /* use the gstate in scansbr.c */
+
 void
 forkcmd (char **args, char *pgm)
 {
@@ -93,35 +95,28 @@ forkcmd (char **args, char *pgm)
 }
 
 
-static struct swit distswit[] = {
-#define        DIANSW                    0
-    { "annotate", 0 },
-#define        DINANSW                   1
-    { "noannotate", 0 },
-#define        DIDFSW                    2
-    { "draftfolder +folder", 0 },
-#define        DIDMSW                    3
-    { "draftmessage msg", 0 },
-#define        DINDFSW                   4
-    { "nodraftfolder", 0 },
-#define        DIEDTSW                   5
-    { "editor editor", 0 },
-#define        DINEDSW                   6
-    { "noedit", 0 },
-#define        DIFRMSW                   7
-    { "form formfile", 0 },
-#define        DIINSW                    8
-    { "inplace", 0 },
-#define        DININSW                   9
-    { "noinplace", 0 },
-#define        DIWHTSW                  10
-    { "whatnowproc program", 0 },
-#define        DINWTSW                  11
-    { "nowhatnowproc", 0 },
-#define        DIHELP                   12
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define DIST_SWITCHES \
+    X("annotate", 0, DIANSW) \
+    X("noannotate", 0, DINANSW) \
+    X("draftfolder +folder", 0, DIDFSW) \
+    X("draftmessage msg", 0, DIDMSW) \
+    X("nodraftfolder", 0, DINDFSW) \
+    X("editor editor", 0, DIEDTSW) \
+    X("noedit", 0, DINEDSW) \
+    X("form formfile", 0, DIFRMSW) \
+    X("inplace", 0, DIINSW) \
+    X("noinplace", 0, DININSW) \
+    X("whatnowproc program", 0, DIWHTSW) \
+    X("nowhatnowproc", 0, DINWTSW) \
+    X("help", 0, DIHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DIST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DIST, distswit);
+#undef X
 
 
 void
@@ -206,23 +201,22 @@ distcmd (char **args)
 }
 
 
-static struct swit explswit[] = {
-#define        EXINSW         0
-    { "inplace", 0 },
-#define        EXNINSW        1
-    { "noinplace", 0 },
-#define        EXQISW         2
-    { "quiet", 0 },
-#define        EXNQISW        3
-    { "noquiet", 0 },
-#define        EXVBSW         4
-    { "verbose", 0 },
-#define        EXNVBSW        5
-    { "noverbose", 0 },
-#define        EXHELP         6
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define EXPLODE_SWITCHES \
+    X("inplace", 0, EXINSW) \
+    X("noinplace", 0, EXNINSW) \
+    X("quiet", 0, EXQISW) \
+    X("noquiet", 0, EXNQISW) \
+    X("verbose", 0, EXVBSW) \
+    X("noverbose", 0, EXNVBSW) \
+    X("help", 0, EXHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(EXPLODE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(EXPLODE, explswit);
+#undef X
 
 
 void
@@ -429,29 +423,25 @@ burst (struct Msg *smsgs, int msgnum, int inplace, int quietsw, int verbosw)
 }
 
 
-static struct swit fileswit[] = {
-#define        FIDRFT               0
-    { "draft", 0 },
-#define        FILINK               1
-    { "link", 0 },
-#define        FINLINK              2
-    { "nolink", 0 },
-#define        FIPRES               3
-    { "preserve", 0 },
-#define FINPRES              4
-    { "nopreserve", 0 },
-#define        FISRC                5
-    { "src +folder", 0 },
-#define        FIFILE               6
-    { "file file", 0 },
-#define        FIPROC               7
-    { "rmmproc program", 0 },
-#define        FINPRC               8
-    { "normmproc", 0 },
-#define        FIHELP               9
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FILE_SWITCHES \
+    X("draft", 0, FIDRFT) \
+    X("link", 0, FILINK) \
+    X("nolink", 0, FINLINK) \
+    X("preserve", 0, FIPRES) \
+    X("nopreserve", 0, FINPRES) \
+    X("src +folder", 0, FISRC) \
+    X("file file", 0, FIFILE) \
+    X("rmmproc program", 0, FIPROC) \
+    X("normmproc", 0, FINPRC) \
+    X("help", 0, FIHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FILE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FILE, fileswit);
+#undef X
 
 
 void
@@ -581,41 +571,31 @@ filehak (char **args)
 }
 
 
-static struct swit foldswit[] = {
-#define        FLALSW         0
-    { "all", 0 },
-#define        FLFASW         1
-    { "fast", 0 },
-#define        FLNFASW        2
-    { "nofast", 0 },
-#define        FLHDSW         3
-    { "header", 0 },
-#define        FLNHDSW        4
-    { "noheader", 0 },
-#define        FLPKSW         5
-    { "pack", 0 },
-#define        FLNPKSW        6
-    { "nopack", 0 },
-#define        FLRCSW         7
-    { "recurse", 0 },
-#define        FLNRCSW        8
-    { "norecurse", 0 },
-#define        FLTLSW         9
-    { "total", 0 },
-#define        FLNTLSW       10
-    { "nototal", 0 },
-#define        FLPRSW        11
-    { "print", 0 },
-#define        FLPUSW        12
-    { "push", 0 },
-#define        FLPOSW        13
-    { "pop", 0 },
-#define        FLLISW        14
-    { "list", 0 },
-#define        FLHELP        15
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FOLDER_SWITCHES \
+    X("all", 0, FLALSW) \
+    X("fast", 0, FLFASW) \
+    X("nofast", 0, FLNFASW) \
+    X("header", 0, FLHDSW) \
+    X("noheader", 0, FLNHDSW) \
+    X("pack", 0, FLPKSW) \
+    X("nopack", 0, FLNPKSW) \
+    X("recurse", 0, FLRCSW) \
+    X("norecurse", 0, FLNRCSW) \
+    X("total", 0, FLTLSW) \
+    X("nototal", 0, FLNTLSW) \
+    X("print", 0, FLPRSW) \
+    X("push", 0, FLPUSW) \
+    X("pop", 0, FLPOSW) \
+    X("list", 0, FLLISW) \
+    X("help", 0, FLHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FOLDER);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FOLDER, foldswit);
+#undef X
 
 
 void
@@ -796,45 +776,33 @@ fast: ;
 }
 
 
-static struct swit forwswit[] = {
-#define        FOANSW                   0
-    { "annotate", 0 },
-#define        FONANSW                  1
-    { "noannotate", 0 },
-#define        FODFSW                   2
-    { "draftfolder +folder", 0 },
-#define        FODMSW                   3
-    { "draftmessage msg", 0 },
-#define        FONDFSW                  4
-    { "nodraftfolder", 0 },
-#define        FOEDTSW                  5
-    { "editor editor", 0 },
-#define        FONEDSW                  6
-    { "noedit", 0 },
-#define        FOFTRSW                  7
-    { "filter filterfile", 0 },
-#define        FOFRMSW                  8
-    { "form formfile", 0 },
-#define        FOFTSW                   9
-    { "format", 5 },
-#define        FONFTSW                 10
-    { "noformat", 7 },
-#define        FOINSW                  11
-    { "inplace", 0 },
-#define        FONINSW                 12
-    { "noinplace", 0 },
-#define        FOMISW                  13
-    { "mime", 0 },
-#define        FONMISW                 14
-    { "nomime", 0 },
-#define        FOWHTSW                 15
-    { "whatnowproc program", 0 },
-#define        FONWTSW                 16
-    { "nowhatnow", 0 },
-#define        FOHELP                  17
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define FORW_SWITCHES \
+    X("annotate", 0, FOANSW) \
+    X("noannotate", 0, FONANSW) \
+    X("draftfolder +folder", 0, FODFSW) \
+    X("draftmessage msg", 0, FODMSW) \
+    X("nodraftfolder", 0, FONDFSW) \
+    X("editor editor", 0, FOEDTSW) \
+    X("noedit", 0, FONEDSW) \
+    X("filter filterfile", 0, FOFTRSW) \
+    X("form formfile", 0, FOFRMSW) \
+    X("format", 5, FOFTSW) \
+    X("noformat", 7, FONFTSW) \
+    X("inplace", 0, FOINSW) \
+    X("noinplace", 0, FONINSW) \
+    X("mime", 0, FOMISW) \
+    X("nomime", 0, FONMISW) \
+    X("whatnowproc program", 0, FOWHTSW) \
+    X("nowhatnow", 0, FONWTSW) \
+    X("help", 0, FOHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(FORW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(FORW, forwswit);
+#undef X
 
 
 void
@@ -984,7 +952,7 @@ forw (char *proc, char *filter, int vecp, char **vec)
                        args[i++] = getcpy (m_name (msgnum));
                args[i] = NULL;
                mhlsbr (i, args, mhl_action);
-               m_eomsbr ((int (*) ()) 0);
+               scan_eom_action ((int (*) ()) 0);
                fclose (stdout);
                _exit (0);
 
@@ -1085,29 +1053,25 @@ helpcmd (char **args)
 }
 
 
-static struct swit markswit[] = {
-#define        MADDSW             0
-    { "add", 0 },
-#define        MDELSW             1
-    { "delete", 0 },
-#define        MLSTSW             2
-    { "list", 0 },
-#define        MSEQSW             3
-    { "sequence name", 0 },
-#define        MPUBSW             4
-    { "public", 0 },
-#define        MNPUBSW            5
-    { "nopublic", 0 },
-#define        MZERSW             6
-    { "zero", 0 },
-#define        MNZERSW            7
-    { "nozero", 0 },
-#define        MHELP              8
-    { "help", 0 },
-#define        MDBUGSW            9
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define MARK_SWITCHES \
+    X("add", 0, MADDSW) \
+    X("delete", 0, MDELSW) \
+    X("list", 0, MLSTSW) \
+    X("sequence name", 0, MSEQSW) \
+    X("public", 0, MPUBSW) \
+    X("nopublic", 0, MNPUBSW) \
+    X("zero", 0, MZERSW) \
+    X("nozero", 0, MNZERSW) \
+    X("help", 0, MHELP) \
+    X("debug", -5, MDBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MARK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MARK, markswit);
+#undef X
 
 
 void
@@ -1273,67 +1237,42 @@ markcmd (char **args)
 }
 
 
-static struct swit mhnswit[] = {
-#define        MHNAUTOSW           0
-    { "auto", 0 },
-#define        MHNNAUTOSW          1
-    { "noauto", 0 },
-#define        MHNDEBUGSW          2
-    { "debug", -5 },
-#define        MHNEBCDICSW         3
-    { "ebcdicsafe", 0 },
-#define        MHNNEBCDICSW        4
-    { "noebcdicsafe", 0 },
-#define        MHNFORMSW           5
-    { "form formfile", 4 },
-#define        MHNHEADSW           6
-    { "headers", 0 },
-#define        MHNNHEADSW          7
-    { "noheaders", 0 },
-#define        MHNLISTSW           8
-    { "list", 0 },
-#define        MHNNLISTSW          9
-    { "nolist", 0 },
-#define        MHNPARTSW          10
-    { "part number", 0 },
-#define        MHNSIZESW          11
-    { "realsize", 0 },
-#define        MHNNSIZESW         12
-    { "norealsize", 0 },
-#define        MHNRFC934SW        13
-    { "rfc934mode", 0 },
-#define        MHNNRFC934SW       14
-    { "norfc934mode", 0 },
-#define        MHNSERIALSW        15
-    { "serialonly", 0 },
-#define        MHNNSERIALSW       16
-    { "noserialonly", 0 },
-#define        MHNSHOWSW          17
-    { "show", 0 },
-#define        MHNNSHOWSW         18
-    { "noshow", 0 },
-#define        MHNSTORESW         19
-    { "store", 0 },
-#define        MHNNSTORESW        20
-    { "nostore", 0 },
-#define        MHNTYPESW          21
-    { "type content", 0 },
-#define        MHNVERBSW          22
-    { "verbose", 0 },
-#define        MHNNVERBSW         23
-    { "noverbose", 0 },
-#define        MHNHELPSW          24
-    { "help", 0 },
-#define        MHNPROGSW          25
-    { "moreproc program", -4 },
-#define        MHNNPROGSW         26
-    { "nomoreproc", -3 },
-#define        MHNLENSW           27
-    { "length lines", -4 },
-#define        MHNWIDSW           28
-    { "width columns", -4 },
-    { NULL, 0 }
-};
+#define MHN_SWITCHES \
+    X("auto", 0, MHNAUTOSW) \
+    X("noauto", 0, MHNNAUTOSW) \
+    X("debug", -5, MHNDEBUGSW) \
+    X("form formfile", 4, MHNFORMSW) \
+    X("headers", 0, MHNHEADSW) \
+    X("noheaders", 0, MHNNHEADSW) \
+    X("list", 0, MHNLISTSW) \
+    X("nolist", 0, MHNNLISTSW) \
+    X("part number", 0, MHNPARTSW) \
+    X("realsize", 0, MHNSIZESW) \
+    X("norealsize", 0, MHNNSIZESW) \
+    X("rfc934mode", 0, MHNRFC934SW) \
+    X("norfc934mode", 0, MHNNRFC934SW) \
+    X("serialonly", 0, MHNSERIALSW) \
+    X("noserialonly", 0, MHNNSERIALSW) \
+    X("show", 0, MHNSHOWSW) \
+    X("noshow", 0, MHNNSHOWSW) \
+    X("store", 0, MHNSTORESW) \
+    X("nostore", 0, MHNNSTORESW) \
+    X("type content", 0, MHNTYPESW) \
+    X("verbose", 0, MHNVERBSW) \
+    X("noverbose", 0, MHNNVERBSW) \
+    X("help", 0, MHNHELPSW) \
+    X("moreproc program", -4, MHNPROGSW) \
+    X("nomoreproc", -3, MHNNPROGSW) \
+    X("length lines", -4, MHNLENSW) \
+    X("width columns", -4, MHNWIDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(MHN);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(MHN, mhnswit);
+#undef X
 
 
 void
@@ -1365,8 +1304,6 @@ mhncmd (char **args)
                case MHNAUTOSW:
                case MHNNAUTOSW:
                case MHNDEBUGSW:
-               case MHNEBCDICSW:
-               case MHNNEBCDICSW:
                case MHNHEADSW:
                case MHNNHEADSW:
                case MHNLISTSW:
@@ -1434,13 +1371,17 @@ mhncmd (char **args)
 }
 
 
-static struct swit packswit[] = {
-#define        PAFISW         0
-    { "file name", 0 },
-#define        PAHELP         1
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define PACK_SWITCHES \
+    X("file name", 0, PAFISW) \
+    X("help", 0, PAHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PACK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PACK, packswit);
+#undef X
 
 static int mbx_style = MMDF_FORMAT;
 
@@ -1570,55 +1511,38 @@ packhak (char **args)
 }
 
 
-static struct swit pickswit[] = {
-#define        PIANSW                0
-    { "and", 0 },
-#define        PIORSW                1
-    { "or", 0 },
-#define        PINTSW                2
-    { "not", 0 },
-#define        PILBSW                3
-    { "lbrace", 0 },
-#define        PIRBSW                4
-    { "rbrace", 0 },
-#define        PICCSW                5
-    { "cc  pattern", 0 },
-#define        PIDASW                6
-    { "date  pattern", 0 },
-#define        PIFRSW                7
-    { "from  pattern", 0 },
-#define        PISESW                8
-    { "search  pattern", 0 },
-#define        PISUSW                9
-    { "subject  pattern", 0 },
-#define        PITOSW               10
-    { "to  pattern", 0 },
-#define        PIOTSW               11
-    { "-othercomponent  pattern", 15 },
-#define        PIAFSW               12
-    { "after date", 0 },
-#define        PIBFSW               13
-    { "before date", 0 },
-#define        PIDFSW               14
-    { "datefield field", 5 },
-#define        PISQSW               15
-    { "sequence name", 0 },
-#define        PIPUSW               16
-    { "public", 0 },
-#define        PINPUSW              17
-    { "nopublic", 0 },
-#define        PIZRSW               18
-    { "zero", 0 },
-#define        PINZRSW              19
-    { "nozero", 0 },
-#define        PILISW               20
-    { "list", 0 },
-#define        PINLISW              21
-    { "nolist", 0 },
-#define        PIHELP               22
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define PICK_SWITCHES \
+    X("and", 0, PIANSW) \
+    X("or", 0, PIORSW) \
+    X("not", 0, PINTSW) \
+    X("lbrace", 0, PILBSW) \
+    X("rbrace", 0, PIRBSW) \
+    X("cc  pattern", 0, PICCSW) \
+    X("date  pattern", 0, PIDASW) \
+    X("from  pattern", 0, PIFRSW) \
+    X("search  pattern", 0, PISESW) \
+    X("subject  pattern", 0, PISUSW) \
+    X("to  pattern", 0, PITOSW) \
+    X("-othercomponent  pattern", 15, PIOTSW) \
+    X("after date", 0, PIAFSW) \
+    X("before date", 0, PIBFSW) \
+    X("datefield field", 5, PIDFSW) \
+    X("sequence name", 0, PISQSW) \
+    X("public", 0, PIPUSW) \
+    X("nopublic", 0, PINPUSW) \
+    X("zero", 0, PIZRSW) \
+    X("nozero", 0, PINZRSW) \
+    X("list", 0, PILISW) \
+    X("nolist", 0, PINLISW) \
+    X("help", 0, PIHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PICK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PICK, pickswit);
+#undef X
 
 
 void
@@ -1764,49 +1688,35 @@ pattern: ;
 }
 
 
-static struct swit replswit[] = {
-#define        REANSW                  0
-    { "annotate", 0 },
-#define        RENANSW                 1
-    { "noannotate", 0 },
-#define        RECCSW                  2
-    { "cc type", 0 },
-#define        RENCCSW                 3
-    { "nocc type", 0 },
-#define        REDFSW                  4
-    { "draftfolder +folder", 0 },
-#define        REDMSW                  5
-    { "draftmessage msg", 0 },
-#define        RENDFSW                 6
-    { "nodraftfolder", 0 },
-#define        REEDTSW                 7
-    { "editor editor", 0 },
-#define        RENEDSW                 8
-    { "noedit", 0 },
-#define        REFCCSW                 9
-    { "fcc +folder", 0 },
-#define        REFLTSW                10
-    { "filter filterfile", 0 },
-#define        REFRMSW                11
-    { "form formfile", 0 },
-#define        REINSW                 12
-    { "inplace", 0 },
-#define        RENINSW                13
-    { "noinplace", 0 },
-#define        REQUSW                 14
-    { "query", 0 },
-#define        RENQUSW                15
-    { "noquery", 0 },
-#define        REWHTSW                16
-    { "whatnowproc program", 0 },
-#define        RENWTSW                17
-    { "nowhatnow", 0 },
-#define        REWIDSW                19
-    { "width columns", 0 },
-#define        REHELP                 20
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define REPL_SWITCHES \
+    X("annotate", 0, REANSW) \
+    X("noannotate", 0, RENANSW) \
+    X("cc type", 0, RECCSW) \
+    X("nocc type", 0, RENCCSW) \
+    X("draftfolder +folder", 0, REDFSW) \
+    X("draftmessage msg", 0, REDMSW) \
+    X("nodraftfolder", 0, RENDFSW) \
+    X("editor editor", 0, REEDTSW) \
+    X("noedit", 0, RENEDSW) \
+    X("fcc +folder", 0, REFCCSW) \
+    X("filter filterfile", 0, REFLTSW) \
+    X("form formfile", 0, REFRMSW) \
+    X("inplace", 0, REINSW) \
+    X("noinplace", 0, RENINSW) \
+    X("query", 0, REQUSW) \
+    X("noquery", 0, RENQUSW) \
+    X("whatnowproc program", 0, REWHTSW) \
+    X("nowhatnow", 0, RENWTSW) \
+    X("width columns", 0, REWIDSW) \
+    X("help", 0, REHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(REPL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(REPL, replswit);
+#undef X
 
 
 void
@@ -1898,11 +1808,16 @@ replcmd (char **args)
 }
 
 
-static struct swit rmmswit[] = {
-#define        RMHELP    0
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RMM_SWITCHES \
+    X("help", 0, RMHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RMM);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RMM, rmmswit);
+#undef X
 
 
 void
@@ -2007,25 +1922,23 @@ rmm (void)
 }
 
 
-static struct swit scanswit[] = {
-#define        SCCLR              0
-    { "clear", 0 },
-#define        SCNCLR             1
-    { "noclear", 0 },
-#define        SCFORM             2
-    { "form formatfile", 0 },
-#define        SCFMT              3
-    { "format string", 5 },
-#define        SCHEAD             4
-    { "header", 0 },
-#define SCNHEAD            5
-    { "noheader", 0 },
-#define        SCWID              6
-    { "width columns", 0 },
-#define        SCHELP             7
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SCAN_SWITCHES \
+    X("clear", 0, SCCLR) \
+    X("noclear", 0, SCNCLR) \
+    X("form formatfile", 0, SCFORM) \
+    X("format string", 5, SCFMT) \
+    X("header", 0, SCHEAD) \
+    X("noheader", 0, SCNHEAD) \
+    X("width columns", 0, SCWID) \
+    X("help", 0, SCHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SCAN);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SCAN, scanswit);
+#undef X
 
 
 void
@@ -2162,31 +2075,26 @@ scancmd (char **args)
 }
 
 
-static struct swit showswit[] = {
-#define        SHDRAFT               0
-    { "draft", 5 },
-#define        SHFORM                1
-    { "form formfile", 4 },
-#define        SHPROG                2
-    { "moreproc program", 4 },
-#define        SHNPROG               3
-    { "nomoreproc", 3 },
-#define        SHLEN                 4
-    { "length lines", 4 },
-#define        SHWID                 5
-    { "width columns", 4 },
-#define        SHSHOW                6
-    { "showproc program", 4 },
-#define        SHNSHOW               7
-    { "noshowproc", 3 },
-#define        SHHEAD                8
-    { "header", 4 },
-#define SHNHEAD               9
-    { "noheader", 3 },
-#define        SHHELP               10
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SHOW_SWITCHES \
+    X("draft", 5, SHDRAFT) \
+    X("form formfile", 4, SHFORM) \
+    X("moreproc program", 4, SHPROG) \
+    X("nomoreproc", 3, SHNPROG) \
+    X("length lines", 4, SHLEN) \
+    X("width columns", 4, SHWID) \
+    X("showproc program", 4, SHSHOW) \
+    X("noshowproc", 3, SHNSHOW) \
+    X("header", 4, SHHEAD) \
+    X("noheader", 3, SHNHEAD) \
+    X("help", 0, SHHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SHOW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SHOW, showswit);
+#undef X
 
 
 void
@@ -2305,7 +2213,7 @@ finish: ;
        if (mp->numsel == 1 && headersw)
            show (mp->lowsel);
        mhlsbr (vecp, vec, mhl_action);
-       m_eomsbr ((int (*)()) 0);
+       scan_eom_action ((int (*)()) 0);
        while (msgp < vecp)
            free (vec[msgp++]);
     } else {
@@ -2377,7 +2285,7 @@ mhl_action (char *name)
 
     mhlfp = msh_ready (msgnum, 1);
     if (!fmsh)
-       m_eomsbr (eom_action);
+       scan_eom_action (eom_action);
 
     return mhlfp;
 }
@@ -2435,11 +2343,11 @@ is_nontext (int msgnum)
 
     fp = msh_ready (msgnum, 1);
 
-    for (state = FLD;;)
-       switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
        case FLD:
        case FLDPLUS:
-       case FLDEOF:
            /*
             * Check Content-Type field
             */
@@ -2449,7 +2357,8 @@ is_nontext (int msgnum)
 
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof buf, fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
                bp = cp;
@@ -2552,7 +2461,8 @@ out:
            if (!mh_strcasecmp (name, ENCODING_FIELD)) {
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof buf, fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
                for (bp = cp; isspace (*bp); bp++)
@@ -2576,8 +2486,10 @@ out:
             * Just skip the rest of this header
             * field and go to next one.
             */
-           while (state == FLDPLUS)
-               state = m_getfld (state, name, buf, sizeof(buf), fp);
+           while (state == FLDPLUS) {
+               bufsz = sizeof buf;
+               state = m_getfld (&gstate, name, buf, &bufsz, fp);
+           }
            break;
 
            /*
@@ -2587,28 +2499,27 @@ out:
        default:
            return 0;
        }
+    }
 }
 
 
-static struct swit sortswit[] = {
-#define        SODATE               0
-    { "datefield field", 0 },
-#define        SOSUBJ               1
-    { "textfield field", 0 },
-#define        SONSUBJ              2
-    { "notextfield", 0 },
-#define        SOLIMT               3
-    { "limit days", 0 },
-#define        SONLIMT              4
-    { "nolimit", 0 },
-#define        SOVERB               5
-    { "verbose", 0 },
-#define        SONVERB              6
-    { "noverbose", 0 },
-#define        SOHELP               7
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SORT_SWITCHES \
+    X("datefield field", 0, SODATE) \
+    X("textfield field", 0, SOSUBJ) \
+    X("notextfield", 0, SONSUBJ) \
+    X("limit days", 0, SOLIMT) \
+    X("nolimit", 0, SONLIMT) \
+    X("verbose", 0, SOVERB) \
+    X("noverbose", 0, SONVERB) \
+    X("help", 0, SOHELP) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SORT);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SORT, sortswit);
+#undef X
 
 
 void
@@ -2741,15 +2652,17 @@ get_fields (char *datesw, char *subjsw, int msgnum, struct Msg *msgp)
     register FILE *zp;
 
     zp = msh_ready (msgnum, 0);
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof buf, zp)) {
+
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, zp)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                if (!mh_strcasecmp (name, datesw)) {
                    bp = getcpy (buf);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buf, sizeof buf, zp);
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, zp);
                        bp = add (buf, bp);
                    }
                    if ((tw = dparsetime (bp)) == NULL)
@@ -2766,7 +2679,8 @@ get_fields (char *datesw, char *subjsw, int msgnum, struct Msg *msgp)
                else if (subjsw && !mh_strcasecmp(name, subjsw)) {
                    bp = getcpy (buf);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buf, sizeof buf, zp);
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, zp);
                        bp = add (buf, bp);
                    }
                    msgp->m_scanl = sosmash(subjsw, bp);
@@ -2775,13 +2689,14 @@ get_fields (char *datesw, char *subjsw, int msgnum, struct Msg *msgp)
                    else
                        subjsw = (char *)0;/* subject done, need date */
                } else {
-                   while (state == FLDPLUS)    /* flush this one */
-                       state = m_getfld (state, name, buf, sizeof buf, zp);
+                   while (state == FLDPLUS) {  /* flush this one */
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, zp);
+                   }
                }
                continue;
 
            case BODY: 
-           case BODYEOF: 
            case FILEEOF: 
                break;
 
index 10854dc98ea5a4ec800248152cd41d6163520479..e391ba200d5b57caaaf6aa92e1d6f92113047151 100644 (file)
--- a/uip/new.c
+++ b/uip/new.c
 #include <h/crawl_folders.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define MODESW 0
-    { "mode", 1 },
-#define FOLDERSSW 1
-    { "folders", 1 },
-#define VERSIONSW 2
-    { "version", 1 },
-#define HELPSW 3
-    { "help", 1 },
-    { NULL, 0 }
-};
+#define NEW_SWITCHES \
+    X("mode", 1, MODESW) \
+    X("folders", 1, FOLDERSSW) \
+    X("version", 1, VERSIONSW) \
+    X("help", 1, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(NEW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(NEW, switches);
+#undef X
 
 static enum { NEW, FNEXT, FPREV, UNSEEN } run_mode = NEW;
 
@@ -97,6 +99,7 @@ get_msgnums(char *folder, char *sequences[])
     char name[NAMESZ], field[BUFSIZ];
     char *cp;
     char *msgnums = NULL, *this_msgnums, *old_msgnums;
+    m_getfld_state_t gstate = 0;
 
     /* no sequences file -> no messages */
     if (fp == NULL) {
@@ -104,16 +107,16 @@ get_msgnums(char *folder, char *sequences[])
     }
 
     /* copied from seq_read.c:seq_public */
-    for (state = FLD;;) {
-        switch (state = m_getfld (state, name, field, sizeof(field), fp)) {
+    for (;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, fp)) {
             case FLD:
             case FLDPLUS:
-            case FLDEOF:
                 if (state == FLDPLUS) {
                     cp = getcpy (field);
                     while (state == FLDPLUS) {
-                        state = m_getfld (state, name, field,
-                                          sizeof(field), fp);
+                       fieldsz = sizeof field;
+                       state = m_getfld (&gstate, name, field, &fieldsz, fp);
                         cp = add (field, cp);
                     }
 
@@ -148,12 +151,9 @@ get_msgnums(char *folder, char *sequences[])
                     }
                 }
 
-                if (state == FLDEOF)
-                    break;
                 continue;
 
             case BODY:
-            case BODYEOF:
                 adios (NULL, "no blank lines are permitted in %s", seqfile);
                 /* fall */
 
@@ -165,6 +165,7 @@ get_msgnums(char *folder, char *sequences[])
         }
         break;  /* break from for loop */
     }
+    m_getfld_state_destroy (&gstate);
 
     fclose(fp);
 
index cd003dd78824bfa7ec1dc496625eeec84ed3bf1c..53e696afb78f69233a72311b9e1cf8f6c5ee84b8 100644 (file)
 #include <h/utils.h>
 #include <errno.h>
 
-static struct swit switches[] = {
-#define FILESW         0
-    { "file name", 0 },
-#define MBOXSW         1
-    { "mbox", 0 },
-#define MMDFSW         2
-    { "mmdf", 0 },
-#define VERSIONSW      3
-    { "version", 0 },
-#define        HELPSW         4
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define PACKF_SWITCHES \
+    X("file name", 0, FILESW) \
+    X("mbox", 0, MBOXSW) \
+    X("mmdf", 0, MMDFSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PACKF);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PACKF, switches);
+#undef X
 
 static int md = NOTOK;
 static int mbx_style = MBOX_FORMAT;
index 6f450af20274a2dca1ef4e5bb7c522edf3fe35ec..5549ea64ac24eb88dffc4bf50d515fdc84c9bda1 100644 (file)
 #include <h/picksbr.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        ANDSW                   0
-    { "and", 0 },
-#define        ORSW                    1
-    { "or", 0 },
-#define        NOTSW                   2
-    { "not", 0 },
-#define        LBRSW                   3
-    { "lbrace", 0 },
-#define        RBRSW                   4
-    { "rbrace", 0 },
-#define        CCSW                    5
-    { "cc  pattern", 0 },
-#define        DATESW                  6
-    { "date  pattern", 0 },
-#define        FROMSW                  7
-    { "from  pattern", 0 },
-#define        SRCHSW                  8
-    { "search  pattern", 0 },
-#define        SUBJSW                  9
-    { "subject  pattern", 0 },
-#define        TOSW                   10
-    { "to  pattern", 0 },
-#define        OTHRSW                 11
-    { "-othercomponent  pattern", 0 },
-#define        AFTRSW                 12
-    { "after date", 0 },
-#define        BEFRSW                 13
-    { "before date", 0 },
-#define        DATFDSW                14
-    { "datefield field", 5 },
-#define        SEQSW                  15
-    { "sequence name", 0 },
-#define        NSEQSW                 16
-    { "nosequence", 0 },
-#define        PUBLSW                 17
-    { "public", 0 },
-#define        NPUBLSW                18
-    { "nopublic", 0 },
-#define        ZEROSW                 19
-    { "zero", 0 },
-#define        NZEROSW                20
-    { "nozero", 0 },
-#define        LISTSW                 21
-    { "list", 0 },
-#define        NLISTSW                22
-    { "nolist", 0 },
-#define VERSIONSW              23
-    { "version", 0 },
-#define        HELPSW                 24
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define PICK_SWITCHES \
+    X("and", 0, ANDSW) \
+    X("or", 0, ORSW) \
+    X("not", 0, NOTSW) \
+    X("lbrace", 0, LBRSW) \
+    X("rbrace", 0, RBRSW) \
+    X("cc  pattern", 0, CCSW) \
+    X("date  pattern", 0, DATESW) \
+    X("from  pattern", 0, FROMSW) \
+    X("search  pattern", 0, SRCHSW) \
+    X("subject  pattern", 0, SUBJSW) \
+    X("to  pattern", 0, TOSW) \
+    X("-othercomponent  pattern", 0, OTHRSW) \
+    X("after date", 0, AFTRSW) \
+    X("before date", 0, BEFRSW) \
+    X("datefield field", 5, DATFDSW) \
+    X("sequence name", 0, SEQSW) \
+    X("nosequence", 0, NSEQSW) \
+    X("public", 0, PUBLSW) \
+    X("nopublic", 0, NPUBLSW) \
+    X("zero", 0, ZEROSW) \
+    X("nozero", 0, NZEROSW) \
+    X("list", 0, LISTSW) \
+    X("nolist", 0, NLISTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PICK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PICK, switches);
+#undef X
 
 static int listsw = -1;
 
index 91893e3cbf89f71138e39b0405d785bddf51a94b..c572cde01ff82a6b53bf8c6b7ad80ef165f36d37 100644 (file)
 #endif
 #include <time.h>
 
-static struct swit parswit[] = {
-#define        PRAND                   0
-    { "and", 0 },
-#define        PROR                    1
-    { "or", 0 },
-#define        PRNOT                   2
-    { "not", 0 },
-#define        PRLBR                   3
-    { "lbrace", 0 },
-#define        PRRBR                   4
-    { "rbrace", 0 },
-#define        PRCC                    5
-    { "cc  pattern", 0 },
-#define        PRDATE                  6
-    { "date  pattern", 0 },
-#define        PRFROM                  7
-    { "from  pattern", 0 },
-#define        PRSRCH                  8
-    { "search  pattern", 0 },
-#define        PRSUBJ                  9
-    { "subject  pattern", 0 },
-#define        PRTO                   10
-    { "to  pattern", 0 },
-#define        PROTHR                 11
-    { "-othercomponent  pattern", 15 },
-#define        PRAFTR                 12
-    { "after date", 0 },
-#define        PRBEFR                 13
-    { "before date", 0 },
-#define        PRDATF                 14
-    { "datefield field", 5 },
-    { NULL, 0 }
-};
+#define PARSE_SWITCHES \
+    X("and", 0, PRAND) \
+    X("or", 0, PROR) \
+    X("not", 0, PRNOT) \
+    X("lbrace", 0, PRLBR) \
+    X("rbrace", 0, PRRBR) \
+    X("cc  pattern", 0, PRCC) \
+    X("date  pattern", 0, PRDATE) \
+    X("from  pattern", 0, PRFROM) \
+    X("search  pattern", 0, PRSRCH) \
+    X("subject  pattern", 0, PRSUBJ) \
+    X("to  pattern", 0, PRTO) \
+    X("-othercomponent  pattern", 15, PROTHR) \
+    X("after date", 0, PRAFTR) \
+    X("before date", 0, PRBEFR) \
+    X("datefield field", 5, PRDATF) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PARSE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PARSE, parswit);
+#undef X
 
 /* DEFINITIONS FOR PATTERN MATCHING */
 
@@ -943,28 +934,28 @@ plist
     register char *bp;
     char buf[BUFSIZ], name[NAMESZ];
     register struct tws *tw;
+    m_getfld_state_t gstate = 0;
     NMH_UNUSED (stop);
 
     fseek (fp, start, SEEK_SET);
-    for (state = FLD, bp = NULL;;) {
-       switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
+    for (bp = NULL;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                if (bp != NULL)
                    free (bp), bp = NULL;
                bp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof buf, fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    bp = add (buf, bp);
                }
                if (!mh_strcasecmp (name, n->n_datef))
                    break;
-               if (state != FLDEOF)
-                   continue;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
            case FILEEOF: 
            case LENERR: 
            case FMTERR: 
@@ -979,6 +970,7 @@ plist
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     if ((tw = dparsetime (bp)) == NULL)
        advise (NULL, "unable to parse %s field in message %d, matching...",
index 6b0786192c4be04df52d3dcc1346b03a4097d3af..7bed6f8a70e0a47512dec02a7472bde15816248a 100644 (file)
    0  : Switch can't be abbreviated;               switch shown in -help.
    #  : Switch can be abbreviated to # characters; switch shown in -help. */
 
-static struct swit switches[] = {
-#define        ALIASW                    0
-    { "alias aliasfile", 0 },
-#define        CHKSW                     1
-    { "check", -5 },                   /* interface from whom */
-#define        NCHKSW                    2
-    { "nocheck", -7 },                 /* interface from whom */
-#define        DEBUGSW                   3
-    { "debug", -5 },
-#define        DISTSW                    4
-    { "dist", -4 },                    /* interface from dist */
-#define        FILTSW                    5
-    { "filter filterfile", 0 },
-#define        NFILTSW                   6
-    { "nofilter", 0 },
-#define        FRMTSW                    7
-    { "format", 0 },
-#define        NFRMTSW                   8
-    { "noformat", 0 },
-#define        LIBSW                     9
-    { "library directory", -7 },       /* interface from send, whom */
-#define        MIMESW                   10
-    { "mime", 0 },
-#define        NMIMESW                  11
-    { "nomime", 0 },
-#define        MSGDSW                   12
-    { "msgid", 0 },
-#define        NMSGDSW                  13
-    { "nomsgid", 0 },
-#define        VERBSW                   14
-    { "verbose", 0 },
-#define        NVERBSW                  15
-    { "noverbose", 0 },
-#define        WATCSW                   16
-    { "watch", 0 },
-#define        NWATCSW                  17
-    { "nowatch", 0 },
-#define        WHOMSW                   18
-    { "whom", -4 },                    /* interface from whom */
-#define        WIDTHSW                  19
-    { "width columns", 0 },
-#define VERSIONSW                20
-    { "version", 0 },
-#define        HELPSW                   21
-    { "help", 0 },
-#define BITSTUFFSW               22
-    { "dashstuffing", -12 },           /* should we dashstuff BCC messages? */
-#define NBITSTUFFSW              23
-    { "nodashstuffing", -14 },
-#define        ANNOSW                   24
-    { "idanno number", -6 },           /* interface from send    */
-#define        CLIESW                   25
-    { "client host", -6 },
-#define        SERVSW                   26
-    { "server host", 6 },              /* specify alternate SMTP server */
-#define        SNOOPSW                  27
-    { "snoop", -5 },                   /* snoop the SMTP transaction */
-#define        PARTSW                   28
-    { "partno", -6 },
-#define        QUEUESW                  29
-    { "queued", -6 },
-#define SASLSW                   30
-    { "sasl", SASLminc(-4) },
-#define NOSASLSW                 31
-    { "nosasl", SASLminc(-6) },
-#define SASLMXSSFSW              32
-    { "saslmaxssf", SASLminc(-10) },
-#define SASLMECHSW               33
-    { "saslmech", SASLminc(-5) },
-#define USERSW                   34
-    { "user", SASLminc(-4) },
-#define PORTSW                  35
-    { "port server port name/number", 4 },
-#define TLSSW                   36
-    { "tls", TLSminc(-3) },
-#define NTLSSW                   37
-    { "notls", TLSminc(-5) },
-#define FILEPROCSW              38
-    { "fileproc", -4 },
-#define MHLPROCSW               39
-    { "mhlproc", -3 },
-#define MTSSW                   40
-    { "mts smtp|sendmail/smtp|sendmail/pipe", 2 },
-#define MESSAGEIDSW             41
-    { "messageid localname|random", 2 },
-    { NULL, 0 }
-};
+#define POST_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("check", -5, CHKSW) /* interface from whom */ \
+    X("nocheck", -7, NCHKSW) /* interface from whom */ \
+    X("debug", -5, DEBUGSW) \
+    X("dist", -4, DISTSW) /* interface from dist */ \
+    X("filter filterfile", 0, FILTSW) \
+    X("nofilter", 0, NFILTSW) \
+    X("format", 0, FRMTSW) \
+    X("noformat", 0, NFRMTSW) \
+    X("library directory", -7, LIBSW) /* interface from send, whom */ \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("msgid", 0, MSGDSW) \
+    X("nomsgid", 0, NMSGDSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("watch", 0, WATCSW) \
+    X("nowatch", 0, NWATCSW) \
+    X("whom", -4, WHOMSW) /* interface from whom */ \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("dashstuffing", -12, BITSTUFFSW) /* should we dashstuff BCC messages? */ \
+    X("nodashstuffing", -14, NBITSTUFFSW) \
+    X("idanno number", -6, ANNOSW) /* interface from send    */ \
+    X("client host", -6, CLIESW) \
+    X("server host", 6, SERVSW) /* specify alternate SMTP server */ \
+    X("snoop", -5, SNOOPSW) /* snoop the SMTP transaction */ \
+    X("partno", -6, PARTSW) \
+    X("queued", -6, QUEUESW) \
+    X("sasl", SASLminc(-4), SASLSW) \
+    X("nosasl", SASLminc(-6), NOSASLSW) \
+    X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \
+    X("saslmech", SASLminc(-5), SASLMECHSW) \
+    X("user", SASLminc(-4), USERSW) \
+    X("port server port name/number", 4, PORTSW) \
+    X("tls", TLSminc(-3), TLSSW) \
+    X("notls", TLSminc(-5), NTLSSW) \
+    X("fileproc", -4, FILEPROCSW) \
+    X("mhlproc", -3, MHLPROCSW) \
+    X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \
+    X("messageid localname|random", 2, MESSAGEIDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(POST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(POST, switches);
+#undef X
 
 
 struct headers {
@@ -322,6 +286,7 @@ main (int argc, char **argv)
     char *cp, *msg = NULL, **argp, **arguments, *envelope;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *in, *out;
+    m_getfld_state_t gstate = 0;
 
 #ifdef LOCALE
     setlocale(LC_ALL, "");
@@ -558,7 +523,7 @@ main (int argc, char **argv)
     start_headers ();
     if (debug) {
        verbose++;
-       discard (out = stdout); /* XXX: reference discard() to help loader */
+       out = stdout;
     } else {
        if (whomsw) {
            if ((out = fopen ("/dev/null", "w")) == NULL)
@@ -578,32 +543,30 @@ main (int argc, char **argv)
 
     hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
 
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), in)) {
+    for (compnum = 1;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                compnum++;
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    cp = add (buf, cp);
                }
                putfmt (name, cp, out);
                free (cp);
-               if (state != FLDEOF)
-                   continue;
-               finish_headers (out);
-               break;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
                finish_headers (out);
                if (whomsw)
                    break;
                fprintf (out, "\n%s", buf);
                while (state == BODY) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    fputs (buf, out);
                }
                break;
@@ -621,6 +584,7 @@ main (int argc, char **argv)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     if (pfd != NOTOK)
        anno ();
@@ -1823,8 +1787,9 @@ static void
 fcc (char *file, char *folder)
 {
     pid_t child_id;
-    int i, status;
+    int i, status, argp;
     char fold[BUFSIZ];
+    char **arglist, *program;
 
     if (verbose)
        printf ("  %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
@@ -1847,8 +1812,14 @@ fcc (char *file, char *folder)
                    *folder == '+' || *folder == '@' ? "" : "+", folder);
 
            /* now exec the fileproc */
-           execlp (fileproc, r1bindex (fileproc, '/'),
-                   "-link", "-file", file, fold, NULL);
+
+           arglist = argsplit(fileproc, &program, &argp);
+           arglist[argp++] = "-link";
+           arglist[argp++] = "-file";
+           arglist[argp++] = file;
+           arglist[argp++] = fold;
+           arglist[argp] = NULL;
+           execvp (program, arglist);
            _exit (-1);
 
        default: 
index 795e4724d4966061c274ef7423606896a15ad555..563da058e3aab67c13e9dedcb0320a187c1fba28 100644 (file)
 # define CERASE '#'
 #endif
 
-static struct swit switches[] = {
-#define        ERASESW 0
-    { "erase chr", 0 },
-#define        KILLSW  1
-    { "kill chr", 0 },
-#define        PREPSW  2
-    { "prepend", 0 },
-#define        NPREPSW 3
-    { "noprepend", 0 },        
-#define        RAPDSW  4
-    { "rapid", 0 },
-#define        NRAPDSW 5
-    { "norapid", 0 },
-#define        BODYSW  6
-    { "body", -4 },
-#define        NBODYSW 7
-    { "nobody", -6 },
-#define        DOTSW   8
-    { "doteof", 0 },
-#define        NDOTSW  9
-    { "nodoteof", 0 },
-#define VERSIONSW 10
-    { "version", 0 },
-#define        HELPSW  11
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define PROMPTER_SWITCHES \
+    X("erase chr", 0, ERASESW) \
+    X("kill chr", 0, KILLSW) \
+    X("prepend", 0, PREPSW) \
+    X("noprepend", 0, NPREPSW) \
+    X("rapid", 0, RAPDSW) \
+    X("norapid", 0, NRAPDSW) \
+    X("body", -4, BODYSW) \
+    X("nobody", -6, NBODYSW) \
+    X("doteof", 0, DOTSW) \
+    X("nodoteof", 0, NDOTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PROMPTER);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PROMPTER, switches);
+#undef X
 
 
 static struct termios tio;
@@ -84,6 +78,7 @@ main (int argc, char **argv)
     char **arguments, **argp;
     FILE *in, *out;
     char *tfile = NULL;
+    m_getfld_state_t gstate = 0;
 
 #ifdef LOCALE
     setlocale(LC_ALL, "");
@@ -208,10 +203,10 @@ main (int argc, char **argv)
     /*
      * Loop through the lines of the draft skeleton.
      */
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, field, sizeof(field), in)) {
+    for (;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, in)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                /*
                 * Check if the value of field contains anything
@@ -226,8 +221,8 @@ main (int argc, char **argv)
                    printf ("%s:%s", name, field);
                    fprintf (out, "%s:%s", name, field);
                    while (state == FLDPLUS) {
-                       state =
-                           m_getfld (state, name, field, sizeof(field), in);
+                       fieldsz = sizeof field;
+                       state = m_getfld (&gstate, name, field, &fieldsz, in);
                        printf ("%s", field);
                        fprintf (out, "%s", field);
                    }
@@ -257,17 +252,9 @@ abort:
                    }
                }
 
-               if (state == FLDEOF) {  /* moby hack */
-                   fprintf (out, "--------\n");
-                   printf ("--------\n");
-                   if (!body)
-                       break;
-                   goto no_body;
-               }
                continue;
 
            case BODY: 
-           case BODYEOF:
            case FILEEOF: 
                if (!body)
                    break;
@@ -293,13 +280,14 @@ abort:
                        if (!rapid && !sigint)
                            printf ("%s", field);
                    } while (state == BODY &&
-                           (state = m_getfld (state, name, field, sizeof(field), in)));
+                           (fieldsz = sizeof field,
+                            state = m_getfld (&gstate, name, field, &fieldsz, in)));
                    if (prepend || !body)
                        break;
                    else
                        printf ("\n--------Enter additional text\n\n");
                }
-no_body:
+
                fflush (stdout);
                for (;;) {
                    getln (field, sizeof(field));
@@ -316,6 +304,7 @@ no_body:
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     if (body)
        printf ("--------\n");
index d3f36caa594f7734c105c8a376e3b243c74013cf..33890d5f786343bc869dc75de4d3ab2fde5ea130 100644 (file)
 #include <h/mts.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define        FORMSW       0
-    { "form formfile",  4 },
-#define VERSIONSW    1
-    { "version", 0 },
-#define        HELPSW       2
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RCVDIST_SWITCHES \
+    X("form formfile", 4, FORMSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RCVDIST);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RCVDIST, switches);
+#undef X
 
 static char backup[BUFSIZ] = "";
 static char drft[BUFSIZ] = "";
@@ -173,6 +176,7 @@ rcvdistout (FILE *inb, char *form, char *addrs)
     char *cp, *scanl, name[NAMESZ], tmpbuf[SBUFSIZ];
     register struct comp *cptr;
     FILE *out;
+    m_getfld_state_t gstate = 0;
 
     if (!(out = fopen (drft, "w")))
        adios (drft, "unable to create");
@@ -192,22 +196,26 @@ rcvdistout (FILE *inb, char *form, char *addrs)
     if (cptr)
        cptr->c_text = addrs;
 
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb)) {
+    for (;;) {
+       int msg_count = SBUFSIZ;
+       switch (state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb)) {
            case FLD: 
            case FLDPLUS: 
                i = fmt_addcomptext(name, tmpbuf);
                if (i != -1) {
                    char_read += msg_count;
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
+                       msg_count = SBUFSIZ;
+                       state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb);
                        fmt_appendcomp(i, name, tmpbuf);
                        char_read += msg_count;
                    }
                }
 
-               while (state == FLDPLUS)
-                   state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
+               while (state == FLDPLUS) {
+                   msg_count = SBUFSIZ;
+                   state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb);
+               }
                break;
 
            case LENERR: 
@@ -221,6 +229,7 @@ rcvdistout (FILE *inb, char *form, char *addrs)
        }
     }
 finished: ;
+    m_getfld_state_destroy (&gstate);
 
     i = format_len + char_read + 256;
     scanl = mh_xmalloc ((size_t) i + 2);
index f9e5bbb62c1e54e022e9ea0c69b8f7673a084784..4725f26cc94a876066bfaf828a863badbc4f461f 100644 (file)
 #include <h/tws.h>
 #include <h/mts.h>
 
-static struct swit switches[] = {
-#define MBOXSW       0
-    { "mbox", 0 },
-#define MMDFSW       1
-    { "mmdf", 0 },
-#define VERSIONSW    2
-    { "version", 0 },
-#define        HELPSW       3
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RCVPACK_SWITCHES \
+    X("mbox", 0, MBOXSW) \
+    X("mmdf", 0, MMDFSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RCVPACK);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RCVPACK, switches);
+#undef X
 
 /*
  * default format in which to save messages
index acf54beb237bc8e779e00f258bbf711516942463..3afe12e3dcd789f82e0f248d1f8a1a50d78fa90d 100644 (file)
 #include <signal.h>
 #include <h/mts.h>
 
-static struct swit switches[] = {
-#define CRETSW         0
-    { "create",        0 },
-#define NCRETSW        1
-    { "nocreate", 0 },
-#define UNSEENSW       2
-    { "unseen", 0 },
-#define NUNSEENSW      3
-    { "nounseen", 0 },
-#define PUBSW          4
-    { "public",        0 },
-#define NPUBSW         5
-    { "nopublic",  0 },
-#define ZEROSW         6
-    { "zero",  0 },
-#define NZEROSW        7
-    { "nozero",        0 },
-#define SEQSW          8
-    { "sequence name", 0 },
-#define VERSIONSW      9
-    { "version", 0 },
-#define HELPSW        10
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RCVSTORE_SWITCHES \
+    X("create", 0, CRETSW) \
+    X("nocreate", 0, NCRETSW) \
+    X("unseen", 0, UNSEENSW) \
+    X("nounseen", 0, NUNSEENSW) \
+    X("public", 0, PUBSW) \
+    X("nopublic", 0, NPUBSW) \
+    X("zero", 0, ZEROSW) \
+    X("nozero", 0, NZEROSW) \
+    X("sequence name", 0, SEQSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RCVSTORE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RCVSTORE, switches);
+#undef X
 
 
 /*
index 29f2dd9d639845cbdfaef1d1ece030ede7e43299..92334c18f0b203679f9930528f893e8c3ec9feb2 100644 (file)
 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>%<(zero)%17(friendly{from})%>  \
 %{subject}%<{body}<<%{body}>>%>"
 
-static struct swit switches[] = {
-#define        BIFFSW  0
-    { "biff", 0 },
-#define        FORMSW  1
-    { "form formatfile", 0 },
-#define        FMTSW   2
-    { "format string", 5 },
-#define WIDTHSW 3
-    { "width columns", 0 },
-#define NLSW    4
-    { "newline", 0 },
-#define NNLSW   5
-    { "nonewline", 0 },
-#define BELSW  6
-    { "bell", 0 },
-#define        NBELSW  7
-    { "nobell", 0 },
-#define VERSIONSW 8
-    { "version", 0 },
-#define        HELPSW  9
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RCVTTY_SWITCHES \
+    X("biff", 0, BIFFSW) \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("newline", 0, NLSW) \
+    X("nonewline", 0, NNLSW) \
+    X("bell", 0, BELSW) \
+    X("nobell", 0, NBELSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RCVTTY);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RCVTTY, switches);
+#undef X
 
 static jmp_buf myctx;
 static int bell = 1;
@@ -261,6 +257,7 @@ header_fd (void)
     /* get new format string */
     nfs = new_fs (form, format, SCANFMT);
     scan (stdin, 0, 0, nfs, width, 0, 0, NULL, 0L, 0);
+    scan_finished ();
     if (newline)
         write (fd, "\n\r", 2);
     write (fd, scanl, strlen (scanl));
index 2bd12ed837f80cad03850eacf948d7fc30f2b679..ae71de23e12eb1ffc48527289ffe239b4c76c190 100644 (file)
 #include <fcntl.h>
 #include <errno.h>
 
-static struct swit switches[] = {
-#define        DRAFTSW          0
-    { "draft", 0 },
-#define        LINKSW           1
-    { "link", 0 },
-#define        NLINKSW          2
-    { "nolink", 0 },
-#define        PRESSW           3
-    { "preserve", 0 },
-#define        NPRESSW          4
-    { "nopreserve", 0 },
-#define UNLINKSW         5
-    { "unlink", 0 },
-#define NUNLINKSW        6
-    { "nounlink", 0 },
-#define        SRCSW            7
-    { "src +folder", 0 },
-#define        FILESW           8
-    { "file file", 0 },
-#define        RPROCSW          9
-    { "rmmproc program", 0 },
-#define        NRPRCSW         10
-    { "normmproc", 0 },
-#define VERSIONSW       11
-    { "version", 0 },
-#define        HELPSW          12
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define REFILE_SWITCHES \
+    X("draft", 0, DRAFTSW) \
+    X("link", 0, LINKSW) \
+    X("nolink", 0, NLINKSW) \
+    X("preserve", 0, PRESSW) \
+    X("nopreserve", 0, NPRESSW) \
+    X("unlink", 0, UNLINKSW) \
+    X("nounlink", 0, NUNLINKSW) \
+    X("src +folder", 0, SRCSW) \
+    X("file file", 0, FILESW) \
+    X("rmmproc program", 0, RPROCSW) \
+    X("normmproc", 0, NRPRCSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(REFILE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(REFILE, switches);
+#undef X
 
 static char maildir[BUFSIZ];
 
index cc8a86b9bda2e7e1ba9d27e413c12e47102bab2c..e8d64907cdb63bea01eb583524cc69545bdff2ee 100644 (file)
 #include <h/utils.h>
 
 
-static struct swit switches[] = {
-#define GROUPSW                0
-    { "group", 0 },
-#define NGROUPSW               1
-    { "nogroup", 0 },
-#define        ANNOSW                 2
-    { "annotate", 0 },
-#define        NANNOSW                3
-    { "noannotate", 0 },
-#define        CCSW                   4
-    { "cc all|to|cc|me", 0 },
-#define        NCCSW                  5
-    { "nocc type", 0 },
-#define        DFOLDSW                6
-    { "draftfolder +folder", 0 },
-#define        DMSGSW                 7
-    { "draftmessage msg", 0 },
-#define        NDFLDSW                8
-    { "nodraftfolder", 0 },
-#define        EDITRSW                9
-    { "editor editor", 0 },
-#define        NEDITSW               10
-    { "noedit", 0 },
-#define        FCCSW                 11
-    { "fcc folder", 0 },
-#define        FILTSW                12
-    { "filter filterfile", 0 },
-#define        FORMSW                13
-    { "form formfile", 0 },
-#define        FRMTSW                14
-    { "format", 5 },
-#define        NFRMTSW               15
-    { "noformat", 7 },
-#define        INPLSW                16
-    { "inplace", 0 },
-#define        NINPLSW               17
-    { "noinplace", 0 },
-#define MIMESW                18
-    { "mime", 0 },
-#define NMIMESW               19
-    { "nomime", 0 },
-#define        QURYSW                20
-    { "query", 0 },
-#define        NQURYSW               21
-    { "noquery", 0 },
-#define        WHATSW                22
-    { "whatnowproc program", 0 },
-#define        NWHATSW               23
-    { "nowhatnowproc", 0 },
-#define        WIDTHSW               24
-    { "width columns", 0 },
-#define VERSIONSW             25
-    { "version", 0 },
-#define        HELPSW                26
-    { "help", 0 },
-#define        FILESW                27
-    { "file file", 4 },                        /* interface from msh */
-#define        BILDSW                28
-    { "build", 5 },                    /* interface from mhe */
-#define ATFILESW              29
-    { "atfile", 0 },
-#define NOATFILESW            30
-    { "noatfile", 0 },
-#define FMTPROCSW             31
-    { "fmtproc program", 0 },
-#define NFMTPROCSW            32
-    { "nofmtproc", 0 },
-
-    { NULL, 0 }
-};
-
-static struct swit ccswitches[] = {
-#define        CTOSW   0
-    { "to", 0 },
-#define        CCCSW   1
-    { "cc", 0 },
-#define        CMESW   2
-    { "me", 0 },
-#define        CALSW   3
-    { "all", 0 },
-    { NULL, 0 }
-};
-
-static struct swit aqrnl[] = {
-#define        NOSW         0
-    { "quit", 0 },
-#define        YESW         1
-    { "replace", 0 },
-#define        LISTDSW      2
-    { "list", 0 },
-#define        REFILSW      3
-    { "refile +folder", 0 },
-#define NEWSW        4
-    { "new", 0 },
-    { NULL, 0 }
-};
+#define REPL_SWITCHES \
+    X("group", 0, GROUPSW) \
+    X("nogroup", 0, NGROUPSW) \
+    X("annotate", 0, ANNOSW) \
+    X("noannotate", 0, NANNOSW) \
+    X("cc all|to|cc|me", 0, CCSW) \
+    X("nocc type", 0, NCCSW) \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("fcc folder", 0, FCCSW) \
+    X("filter filterfile", 0, FILTSW) \
+    X("form formfile", 0, FORMSW) \
+    X("format", 5, FRMTSW) \
+    X("noformat", 7, NFRMTSW) \
+    X("inplace", 0, INPLSW) \
+    X("noinplace", 0, NINPLSW) \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("query", 0, QURYSW) \
+    X("noquery", 0, NQURYSW) \
+    X("whatnowproc program", 0, WHATSW) \
+    X("nowhatnowproc", 0, NWHATSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("file file", 4, FILESW) /* interface from msh */ \
+    X("build", 5, BILDSW) /* interface from mhe */ \
+    X("atfile", 0, ATFILESW) \
+    X("noatfile", 0, NOATFILESW) \
+    X("fmtproc program", 0, FMTPROCSW) \
+    X("nofmtproc", 0, NFMTPROCSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(REPL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(REPL, switches);
+#undef X
+
+#define CC_SWITCHES \
+    X("to", 0, CTOSW) \
+    X("cc", 0, CCCSW) \
+    X("me", 0, CMESW) \
+    X("all", 0, CALSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(CC);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(CC, ccswitches);
+#undef X
+
+#define DISPO_SWITCHES \
+    X("quit", 0, NOSW) \
+    X("replace", 0, YESW) \
+    X("list", 0, LISTDSW) \
+    X("refile +folder", 0, REFILSW) \
+    X("new", 0, NEWSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(DISPO);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(DISPO, aqrnl);
+#undef X
 
 static struct swit aqrl[] = {
-    { "quit", 0 },
-    { "replace", 0 },
-    { "list", 0 },
-    { "refile +folder", 0 },
-    { NULL, 0 }
+    { "quit", 0, NOSW },
+    { "replace", 0, YESW },
+    { "list", 0, LISTDSW },
+    { "refile +folder", 0, REFILSW },
+    { NULL, 0, 0 }
 };
 
 short ccto = -1;               /* global for replsbr */
index 3dbc3031ee614874f3a941ea45dd048321b4590c..b696ae71eaaf1ac26fea246e827eb8ce6597f43a 100644 (file)
@@ -72,6 +72,7 @@ replout (FILE *inb, char *msg, char *drft, struct msgs *mp, int outputlinelen,
     char name[NAMESZ], *scanl;
     unsigned char *cp;
     static int dat[5];                 /* aux. data for format routine */
+    m_getfld_state_t gstate = 0;
 
     FILE *out;
     NMH_UNUSED (msg);
@@ -131,8 +132,9 @@ replout (FILE *inb, char *msg, char *drft, struct msgs *mp, int outputlinelen,
     /*
      * pick any interesting stuff out of msg "inb"
      */
-    for (state = FLD;;) {
-       state = m_getfld (state, name, tmpbuf, sizeof(tmpbuf), inb);
+    for (;;) {
+       int msg_count = sizeof tmpbuf;
+       state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb);
        switch (state) {
            case FLD: 
            case FLDPLUS: 
@@ -147,15 +149,17 @@ replout (FILE *inb, char *msg, char *drft, struct msgs *mp, int outputlinelen,
                if (i != -1) {
                    char_read += msg_count;
                    while (state == FLDPLUS) {
-                       state = m_getfld(state, name, tmpbuf,
-                                        sizeof(tmpbuf), inb);
+                       msg_count= sizeof tmpbuf;
+                       state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb);
                        fmt_appendcomp(i, name, tmpbuf);
                        char_read += msg_count;
                    }
                }
 
-               while (state == FLDPLUS)
-                   state = m_getfld (state, name, tmpbuf, SBUFSIZ, inb);
+               while (state == FLDPLUS) {
+                   msg_count= sizeof tmpbuf;
+                   state = m_getfld (&gstate, name, tmpbuf, &msg_count, inb);
+               }
                break;
 
            case LENERR: 
@@ -168,6 +172,7 @@ replout (FILE *inb, char *msg, char *drft, struct msgs *mp, int outputlinelen,
                adios (NULL, "m_getfld() returned %d", state);
        }
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * format and output the header lines.
@@ -407,7 +412,8 @@ replfilter (FILE *in, FILE *out, char *filter, int fmtproc)
     int        pid;
     char *mhl;
     char *errstr;
-    char *arglist[7];
+    char **arglist;
+    int argnum;
 
     if (filter == NULL)
        return;
@@ -415,8 +421,6 @@ replfilter (FILE *in, FILE *out, char *filter, int fmtproc)
     if (access (filter, R_OK) == NOTOK)
        adios (filter, "unable to read");
 
-    mhl = r1bindex (mhlproc, '/');
-
     rewind (in);
     lseek (fileno(in), (off_t) 0, SEEK_SET);
 
@@ -429,26 +433,29 @@ replfilter (FILE *in, FILE *out, char *filter, int fmtproc)
            dup2 (fileno (out), fileno (stdout));
            closefds (3);
 
-           arglist[0] = mhl;
-           arglist[1] = "-form";
-           arglist[2] = filter;
-           arglist[3] = "-noclear";
+           /*
+            * We're not allocating the memory for the extra arguments,
+            * because we never call arglist_free().  But if we ever change
+            * that be sure to use getcpy() for the extra arguments.
+            */
+           arglist = argsplit(mhlproc, &mhl, &argnum);
+           arglist[argnum++] = "-form";
+           arglist[argnum++] = filter;
+           arglist[argnum++] = "-noclear";
 
            switch (fmtproc) {
            case 1:
-               arglist[4] = "-fmtproc";
-               arglist[5] = formatproc;
-               arglist[6] = NULL;
+               arglist[argnum++] = "-fmtproc";
+               arglist[argnum++] = formatproc;
                break;
            case 0:
-               arglist[4] = "-nofmtproc";
-               arglist[5] = NULL;
+               arglist[argnum++] = "-nofmtproc";
                break;
-           default:
-               arglist[4] = NULL;
            }
 
-           execvp (mhlproc, arglist);
+           arglist[argnum++] = NULL;
+
+           execvp (mhl, arglist);
            errstr = strerror(errno);
            write(2, "unable to exec ", 15);
            write(2, mhlproc, strlen(mhlproc));
index c9a04f55eb636121047d872de3e019079acc0608..9e922475c6df63ed8cec4fdb3a1ebb3f661bdc78 100644 (file)
--- a/uip/rmf.c
+++ b/uip/rmf.c
@@ -9,17 +9,19 @@
 
 #include <h/mh.h>
 
-static struct swit switches[] = {
-#define        INTRSW            0
-    { "interactive", 0 },
-#define        NINTRSW           1
-    { "nointeractive", 0 },
-#define VERSIONSW         2
-    { "version", 0 },
-#define        HELPSW            3
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RMF_SWITCHES \
+    X("interactive", 0, INTRSW) \
+    X("nointeractive", 0, NINTRSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RMF);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RMF, switches);
+#undef X
 
 /*
  * static prototypes
index 28c26fb4703a047e78f1e89506bdf28028bf5f29..d96622ed835c3492546098874d38a303c462bd26 100644 (file)
--- a/uip/rmm.c
+++ b/uip/rmm.c
 #include <h/mh.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define UNLINKSW      0
-    { "unlink", 0 },
-#define NUNLINKSW    1
-    { "nounlink", 0 },
-#define VERSIONSW     2
-    { "version", 0 },
-#define        HELPSW        3
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define RMM_SWITCHES \
+    X("unlink", 0, UNLINKSW) \
+    X("nounlink", 0, NUNLINKSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(RMM);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(RMM, switches);
+#undef X
 
 
 int
index 08c893b33211b00b8660c1b2b1f336613017e465..459fcb0730b38ee602d8b967e6e0498f4d2b0659 100644 (file)
 #include <h/utils.h>
 #include <errno.h>
 
-static struct swit switches[] = {
-#define        CLRSW   0
-    { "clear", 0 },
-#define        NCLRSW  1
-    { "noclear", 0 },
-#define        FORMSW  2
-    { "form formatfile", 0 },
-#define        FMTSW   3
-    { "format string", 5 },
-#define        HEADSW  4
-    { "header", 0 },
-#define        NHEADSW 5
-    { "noheader", 0 },
-#define        WIDTHSW 6
-    { "width columns", 0 },
-#define        REVSW   7
-    { "reverse", 0 },
-#define        NREVSW  8
-    { "noreverse", 0 },
-#define        FILESW  9
-    { "file file", 4 },
-#define VERSIONSW 10
-    { "version", 0 },
-#define        HELPSW  11
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SCAN_SWITCHES \
+    X("clear", 0, CLRSW) \
+    X("noclear", 0, NCLRSW) \
+    X("form formatfile", 0, FORMSW) \
+    X("format string", 5, FMTSW) \
+    X("header", 0, HEADSW) \
+    X("noheader", 0, NHEADSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("reverse", 0, REVSW) \
+    X("noreverse", 0, NREVSW) \
+    X("file file", 4, FILESW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SCAN);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SCAN, switches);
+#undef X
 
 
-/*
- * global for sbr/formatsbr.c - yech!
- */
-#ifdef LBL
-extern struct msgs *fmt_current_folder;        
-#endif
-
 /*
  * prototypes
  */
@@ -188,13 +175,14 @@ main (int argc, char **argv)
            printf ("FOLDER %s\t%s\n", file, dtimenow (1));
        }
 
-       m_unknown (in);
+       scan_detect_mbox_style (in);
        for (msgnum = 1; ; ++msgnum) {
            state = scan (in, msgnum, -1, nfs, width, 0, 0,
                    hdrflag ? file : NULL, 0L, 1);
            if (state != SCNMSG && state != SCNENC)
                break;
        }
+       scan_finished ();
        fclose (in);
        done (0);
     }
@@ -249,11 +237,6 @@ main (int argc, char **argv)
 
     ontty = isatty (fileno (stdout));
 
-#ifdef LBL
-    else
-       fmt_current_folder = mp;
-#endif
-
     for (msgnum = revflag ? mp->hghsel : mp->lowsel;
         (revflag ? msgnum >= mp->lowsel : msgnum <= mp->hghsel);
         msgnum += (revflag ? -1 : 1)) {
@@ -294,6 +277,7 @@ main (int argc, char **argv)
                    advise (NULL, "message %d: empty", msgnum);
                    break;
            }
+           scan_finished ();
            hdrflag = 0;
            fclose (in);
            if (ontty)
@@ -301,10 +285,6 @@ main (int argc, char **argv)
        }
     }
 
-#ifdef LBL
-    seq_save (mp);     /* because formatsbr might have made changes */
-#endif
-
     folder_free (mp);  /* free folder/message structure */
     if (clearflag)
        clear_screen ();
index 232a41906e99d4524e68440a240ff0d50a44914c..930cfbc25f65864ca4d1dd0681f83a8f5f889fed 100644 (file)
@@ -36,6 +36,7 @@ static struct comp **used_buf = 0;    /* stack for comp that use buffers */
 static int dat[5];                     /* aux. data for format routine    */
 
 char *scanl = 0;                       /* text of most recent scanline    */
+m_getfld_state_t gstate;               /* for access by msh */
 
 #define DIEWRERR() adios (scnmsg, "write error on")
 
@@ -68,6 +69,7 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
     char *scnmsg = NULL;
     FILE *scnout = NULL;
     char name[NAMESZ];
+    int bufsz;
     static int rlwidth, slwidth;
     static size_t scanl_size;
 
@@ -162,7 +164,9 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
      * Get the first field.  If the message is non-empty
      * and we're doing an "inc", open the output file.
      */
-    if ((state = m_getfld (FLD, name, tmpbuf, rlwidth, inb)) == FILEEOF) {
+    bufsz = rlwidth;
+    m_getfld_state_reset (&gstate);
+    if ((state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb)) == FILEEOF) {
        if (ferror(inb)) {
            advise("read", "unable to"); /* "read error" */
            return SCNFAT;
@@ -184,7 +188,8 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
     }
 
     /* scan - main loop */
-    for (compnum = 1; ; state = m_getfld (state, name, tmpbuf, rlwidth, inb)) {
+    for (compnum = 1; ;
+       bufsz = rlwidth, state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb)) {
        switch (state) {
            case FLD: 
            case FLDPLUS: 
@@ -215,7 +220,8 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
                }
 
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, tmpbuf, rlwidth, inb);
+                   bufsz = rlwidth;
+                   state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb);
                    if (outnum)
                        FPUTS (tmpbuf);
                }
@@ -229,8 +235,8 @@ scan (FILE *inb, int innum, int outnum, char *nfs, int width, int curflg,
                 */
 
                if ((i = strlen(tmpbuf)) < rlwidth) {
-                   state = m_getfld (state, name, tmpbuf + i,
-                                     rlwidth - i, inb);
+                   bufsz = rlwidth - i;
+                   state = m_getfld (&gstate, name, tmpbuf + i, &bufsz, inb);
                }
 
                if (! outnum) {
@@ -264,7 +270,8 @@ body:;
                }
 
                while (state == BODY) {
-                   state = m_getfld(state, name, tmpbuf, rlwidth, inb);
+                   bufsz = rlwidth;
+                   state = m_getfld (&gstate, name, tmpbuf, &bufsz, inb);
                    FPUTS(tmpbuf);
                }
                goto finished;
@@ -351,10 +358,8 @@ finished:
 
     /* return dynamically allocated buffers to pool */
     while ((cptr = *savecomp++)) {
-       *--nxtbuf = cptr->c_text;
        cptr->c_text = NULL;
     }
-    *--nxtbuf = tmpbuf;
 
     if (outnum && (ferror(scnout) || fclose (scnout) == EOF))
        DIEWRERR();
@@ -374,3 +379,23 @@ mh_fputs(char *s, FILE *stream)
     return (0);
 }
 
+/* The following three functions allow access to the global gstate above. */
+void
+scan_finished () {
+    m_getfld_state_destroy (&gstate);
+}
+
+void
+scan_detect_mbox_style (FILE *f) {
+    m_unknown (&gstate, f);
+}
+
+void
+scan_eom_action (int (*action)()) {
+    m_eomsbr (gstate, action);
+}
+
+void
+scan_reset_m_getfld_state () {
+    m_getfld_state_reset (&gstate);
+}
index 7f0529e7ea95411fb7894f676553ebf11bbf87f4..1bfd0608cf0ea920d4260789f6f4f25697b64502 100644 (file)
 # define TLSminc(a)   0
 #endif /* TLS_SUPPORT */
 
-static struct swit switches[] = {
-#define        ALIASW                 0
-    { "alias aliasfile", 0 },
-#define        DEBUGSW                1
-    { "debug", -5 },
-#define        DRAFTSW                2
-    { "draft", 0 },
-#define        DFOLDSW                3
-    { "draftfolder +folder", 6 },
-#define        DMSGSW                 4
-    { "draftmessage msg", 6 },
-#define        NDFLDSW                5
-    { "nodraftfolder", 0 },
-#define        FILTSW                 6
-    { "filter filterfile", 0 },
-#define        NFILTSW                7
-    { "nofilter", 0 },
-#define        FRMTSW                 8
-    { "format", 0 },
-#define        NFRMTSW                9
-    { "noformat", 0 },
-#define        FORWSW                10
-    { "forward", 0 },
-#define        NFORWSW               11
-    { "noforward", 0 },
-#define MIMESW                12
-    { "mime", 0 },
-#define NMIMESW               13
-    { "nomime", 0 },
-#define        MSGDSW                14
-    { "msgid", 0 },
-#define        NMSGDSW               15
-    { "nomsgid", 0 },
-#define        PUSHSW                16
-    { "push", 0 },
-#define        NPUSHSW               17
-    { "nopush", 0 },
-#define        SPLITSW               18
-    { "split seconds", 0 },
-#define        UNIQSW                19
-    { "unique", -6 },
-#define        NUNIQSW               20
-    { "nounique", -8 },
-#define        VERBSW                21
-    { "verbose", 0 },
-#define        NVERBSW               22
-    { "noverbose", 0 },
-#define        WATCSW                23
-    { "watch", 0 },
-#define        NWATCSW               24
-    { "nowatch", 0 },
-#define        WIDTHSW               25
-    { "width columns", 0 },
-#define VERSIONSW             26
-    { "version", 0 },
-#define        HELPSW                27
-    { "help", 0 },
-#define BITSTUFFSW            28
-    { "dashstuffing", -12 },
-#define NBITSTUFFSW           29
-    { "nodashstuffing", -14 },
-#define        MAILSW                30
-    { "mail", -4 },
-#define        SAMLSW                31
-    { "saml", -4 },
-#define        SENDSW                32
-    { "send", -4 },
-#define        SOMLSW                33
-    { "soml", -4 },
-#define        CLIESW                34
-    { "client host", -6 },
-#define        SERVSW                35
-    { "server host", 6 },
-#define        SNOOPSW               36
-    { "snoop", 5 },
-#define SASLSW                37
-    { "sasl", SASLminc(4) },
-#define NOSASLSW              38
-    { "nosasl", SASLminc(-6) },
-#define SASLMXSSFSW           39
-    { "saslmaxssf", SASLminc(-10) },
-#define SASLMECHSW            40
-    { "saslmech mechanism", SASLminc(-5) },
-#define USERSW                41
-    { "user username", SASLminc(-4) },
-#define ATTACHSW              42
-    { "attach", 6 },
-#define NOATTACHSW            43
-    { "noattach", 0 },
-#define ATTACHFORMATSW        44
-    { "attachformat", 7 },
-#define PORTSW               45
-    { "port server-port-name/number" , 4 },
-#define TLSSW                46
-    { "tls", TLSminc(-3) },
-#define NTLSSW                47
-    { "notls", TLSminc(-5) },
-#define MTSSW                48
-    { "mts smtp|sendmail/smtp|sendmail/pipe", 2 },
-#define MESSAGEIDSW          49
-    { "messageid localname|random", 2 },
-    { NULL, 0 }
-};
-
-static struct swit anyl[] = {
-#define        NOSW     0
-    { "no", 0 },
-#define        YESW     1
-    { "yes", 0 },
-#define        LISTDSW  2
-    { "list", 0 },
-    { NULL, 0 }
-};
+#define SEND_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("debug", -5, DEBUGSW) \
+    X("draft", 0, DRAFTSW) \
+    X("draftfolder +folder", 6, DFOLDSW) \
+    X("draftmessage msg", 6, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("filter filterfile", 0, FILTSW) \
+    X("nofilter", 0, NFILTSW) \
+    X("format", 0, FRMTSW) \
+    X("noformat", 0, NFRMTSW) \
+    X("forward", 0, FORWSW) \
+    X("noforward", 0, NFORWSW) \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("msgid", 0, MSGDSW) \
+    X("nomsgid", 0, NMSGDSW) \
+    X("push", 0, PUSHSW) \
+    X("nopush", 0, NPUSHSW) \
+    X("split seconds", 0, SPLITSW) \
+    X("unique", -6, UNIQSW) \
+    X("nounique", -8, NUNIQSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("watch", 0, WATCSW) \
+    X("nowatch", 0, NWATCSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("dashstuffing", -12, BITSTUFFSW) \
+    X("nodashstuffing", -14, NBITSTUFFSW) \
+    X("mail", -4, MAILSW) \
+    X("saml", -4, SAMLSW) \
+    X("send", -4, SENDSW) \
+    X("soml", -4, SOMLSW) \
+    X("client host", -6, CLIESW) \
+    X("server host", 6, SERVSW) \
+    X("snoop", 5, SNOOPSW) \
+    X("sasl", SASLminc(4), SASLSW) \
+    X("nosasl", SASLminc(-6), NOSASLSW) \
+    X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \
+    X("saslmech mechanism", SASLminc(-5), SASLMECHSW) \
+    X("user username", SASLminc(-4), USERSW) \
+    X("attach", 6, ATTACHSW) \
+    X("noattach", 0, NOATTACHSW) \
+    X("attachformat", 7, ATTACHFORMATSW) \
+    X("port server-port-name/number", 4, PORTSW) \
+    X("tls", TLSminc(-3), TLSSW) \
+    X("notls", TLSminc(-5), NTLSSW) \
+    X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \
+    X("messageid localname|random", 2, MESSAGEIDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SEND);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SEND, switches);
+#undef X
+
+#define USE_SWITCHES \
+    X("no", 0, NOSW) \
+    X("yes", 0, YESW) \
+    X("list", 0, LISTDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(USE);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(USE, anyl);
+#undef X
 
 extern int debugsw;            /* from sendsbr.c */
 extern int forwsw;
index dfd974f481694c9b9d6763cd450038ab2caa884f..2350ccf4bddefd9210272946f9ac0dd74b930cfa 100644 (file)
@@ -591,6 +591,7 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
     char subject[BUFSIZ];
     char name[NAMESZ], partnum[BUFSIZ];
     FILE *in;
+    m_getfld_state_t gstate = 0;
 
     if ((in = fopen (drft, "r")) == NULL)
        adios (drft, "unable to open for reading");
@@ -602,19 +603,22 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
      * Scan through the message and examine the various header fields,
      * as well as locate the beginning of the message body.
      */
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, name, buffer, sizeof(buffer), in)) {
+    m_getfld_track_filepos (&gstate, in);
+    for (compnum = 1;;) {
+       int bufsz = sizeof buffer;
+       switch (state = m_getfld (&gstate, name, buffer, &bufsz, in)) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                compnum++;
 
                /*
                 * This header field is discarded.
                 */
                if (!mh_strcasecmp (name, "Message-ID")) {
-                   while (state == FLDPLUS)
-                       state = m_getfld (state, name, buffer, sizeof(buffer), in);
+                   while (state == FLDPLUS) {
+                       bufsz = sizeof buffer;
+                       state = m_getfld (&gstate, name, buffer, &bufsz, in);
+                   }
                } else if (uprf (name, XXX_FIELD_PRF)
                        || !mh_strcasecmp (name, VRSN_FIELD)
                        || !mh_strcasecmp (name, "Subject")
@@ -638,7 +642,8 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
 
                    dp = add (concat (name, ":", buffer, NULL), dp);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buffer, sizeof(buffer), in);
+                       bufsz = sizeof buffer;
+                       state = m_getfld (&gstate, name, buffer, &bufsz, in);
                        dp = add (buffer, dp);
                    }
                } else {
@@ -648,19 +653,16 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
                     */
                    cp = add (concat (name, ":", buffer, NULL), cp);
                    while (state == FLDPLUS) {
-                       state = m_getfld (state, name, buffer, sizeof(buffer), in);
+                       bufsz = sizeof buffer;
+                       state = m_getfld (&gstate, name, buffer, &bufsz, in);
                        cp = add (buffer, cp);
                    }
                }
 
-               if (state != FLDEOF) {
-                   start = ftell (in) + 1;
-                   continue;
-               }
-               /* else fall... */
+               start = ftell (in) + 1;
+               continue;
 
           case BODY:
-          case BODYEOF:
           case FILEEOF:
                break;
 
@@ -674,6 +676,7 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
 
        break;
     }
+    m_getfld_state_destroy (&gstate);
     if (cp == NULL)
        adios (NULL, "headers missing from draft");
 
@@ -905,8 +908,10 @@ static void
 alert (char *file, int out)
 {
     pid_t child_id;
-    int i, in;
+    int i, in, argp;
     char buf[BUFSIZ];
+    char *program;
+    char **arglist;
 
     for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
        sleep (5);
@@ -946,8 +951,14 @@ alert (char *file, int out)
            snprintf (buf, sizeof(buf), "send failed on %s",
                        forwsw ? "enclosed draft" : file);
 
-           execlp (mailproc, r1bindex (mailproc, '/'), getusername (),
-                   "-subject", buf, NULL);
+           arglist = argsplit(mailproc, &program, &argp);
+
+           arglist[argp++] = getusername();
+           arglist[argp++] = "-subject";
+           arglist[argp++] = buf;
+           arglist[argp] = NULL;
+
+           execvp (program, arglist);
            fprintf (stderr, "unable to exec ");
            perror (mailproc);
            _exit (-1);
index 849421647bcb4d8420a2663be9ca6142effa6cbe..766aec947906f1a1dea3adeb7b5ba4add31dfe83 100644 (file)
 #include <h/mime.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define CHECKMIMESW          0
-    { "checkmime", 0 },
-#define NOCHECKMIMESW        1
-    { "nocheckmime", 0 },
-#define        HEADSW               2
-    { "header", 0 },
-#define        NHEADSW              3
-    { "noheader", 0 },
-#define        FORMSW               4
-    { "form formfile", 0 },
-#define        PROGSW               5
-    { "moreproc program", 0 },
-#define        NPROGSW              6
-    { "nomoreproc", 0 },
-#define        LENSW                7
-    { "length lines", 0 },
-#define        WIDTHSW              8
-    { "width columns", 0 },
-#define        SHOWSW               9
-    { "showproc program", 0 },
-#define SHOWMIMESW          10
-    { "showmimeproc program", 0 },
-#define        NSHOWSW             11
-    { "noshowproc", 0 },
-#define        DRFTSW              12
-    { "draft", 0 },
-#define        FILESW              13
-    { "file file", -4 },               /* interface from showfile */
-#define FMTPROCSW           14
-    { "fmtproc program", 0 },
-#define NFMTPROCSW          15
-    { "nofmtproc", 0 },
-#define VERSIONSW           16
-    { "version", 0 },
-#define        HELPSW              17
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SHOW_SWITCHES \
+    X("checkmime", 0, CHECKMIMESW) \
+    X("nocheckmime", 0, NOCHECKMIMESW) \
+    X("header", 0, HEADSW) \
+    X("noheader", 0, NHEADSW) \
+    X("form formfile", 0, FORMSW) \
+    X("moreproc program", 0, PROGSW) \
+    X("nomoreproc", 0, NPROGSW) \
+    X("length lines", 0, LENSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("showproc program", 0, SHOWSW) \
+    X("showmimeproc program", 0, SHOWMIMESW) \
+    X("noshowproc", 0, NSHOWSW) \
+    X("draft", 0, DRFTSW) \
+    X("file file", -4, FILESW) /* interface from showfile */ \
+    X("fmtproc program", 0, FMTPROCSW) \
+    X("nofmtproc", 0, NFMTPROCSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SHOW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SHOW, switches);
+#undef X
 
 /*
  * static prototypes
@@ -348,15 +336,16 @@ is_nontext (char *msgnam)
     char *cp;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *fp;
+    m_getfld_state_t gstate = 0;
 
     if ((fp = fopen (msgnam, "r")) == NULL)
        return 0;
 
-    for (state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
        case FLD:
        case FLDPLUS:
-       case FLDEOF:
            /*
             * Check Content-Type field
             */
@@ -366,7 +355,8 @@ is_nontext (char *msgnam)
 
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
                bp = cp;
@@ -469,7 +459,8 @@ out:
            if (!mh_strcasecmp (name, ENCODING_FIELD)) {
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                    cp = add (buf, cp);
                }
                for (bp = cp; isspace (*bp); bp++)
@@ -493,8 +484,10 @@ out:
             * Just skip the rest of this header
             * field and go to next one.
             */
-           while (state == FLDPLUS)
-               state = m_getfld (state, name, buf, sizeof(buf), fp);
+           while (state == FLDPLUS) {
+               bufsz = sizeof buf;
+               state = m_getfld (&gstate, name, buf, &bufsz, fp);
+           }
            break;
 
            /*
@@ -506,4 +499,5 @@ out:
            return 0;
        }
     }
+    m_getfld_state_destroy (&gstate);
 }
index 869fa17f81a3a4ca51816059451d6e597e44af33..3c5e512d1838be6076619634d4b4728c0d98651a 100644 (file)
 #include <utmpx.h>
 #endif /* HAVE_GETUTXENT */
 
-static struct swit switches[] = {
-#define        ADDRSW         0
-    { "addr address", 0 },
-#define        USERSW         1
-    { "user name", 0 },
-#define        FILESW         2
-    { "file file", 0 },
-#define        SENDERSW       3
-    { "sender address", 0 },
-#define        MAILBOXSW      4
-    { "mailbox file", 0 },
-#define        HOMESW         5
-    { "home directory", -4 },
-#define        INFOSW         6
-    { "info data", 0 },
-#define        MAILSW         7
-    { "maildelivery file", 0 },
-#define        VERBSW         8
-    { "verbose", 0 },
-#define        NVERBSW        9
-    { "noverbose", 0 },
-#define SUPPRESSDUP   10
-    { "suppressdup", 0 },
-#define NSUPPRESSDUP 11
-    { "nosuppressdup", 0 },
-#define        DEBUGSW       12
-    { "debug", 0 },
-#define VERSIONSW     13
-    { "version", 0 },
-#define        HELPSW        14
-    { "help", 0 },
-    { NULL, 0 }
-};
+#define SLOCAL_SWITCHES \
+    X("addr address", 0, ADDRSW) \
+    X("user name", 0, USERSW) \
+    X("file file", 0, FILESW) \
+    X("sender address", 0, SENDERSW) \
+    X("mailbox file", 0, MAILBOXSW) \
+    X("home directory", -4, HOMESW) \
+    X("info data", 0, INFOSW) \
+    X("maildelivery file", 0, MAILSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("suppressdup", 0, SUPPRESSDUP) \
+    X("nosuppressdup", 0, NSUPPRESSDUP) \
+    X("debug", 0, DEBUGSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SLOCAL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SLOCAL, switches);
+#undef X
 
 static int globbed = 0;                /* have we built "vars" table yet?        */
 static int parsed = 0;         /* have we built header field table yet   */
@@ -716,6 +707,7 @@ parse (int fd)
     char name[NAMESZ], field[BUFSIZ];
     struct pair *p, *q;
     FILE  *in;
+    m_getfld_state_t gstate = 0;
 
     if (parsed++)
        return 0;
@@ -739,14 +731,15 @@ parse (int fd)
      * Scan the headers of the message and build
      * a lookup table.
      */
-    for (i = 0, state = FLD;;) {
-       switch (state = m_getfld (state, name, field, sizeof(field), in)) {
+    for (i = 0;;) {
+       int fieldsz = sizeof field;
+       switch (state = m_getfld (&gstate, name, field, &fieldsz, in)) {
            case FLD: 
-           case FLDEOF: 
            case FLDPLUS: 
                lp = add (field, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, field, sizeof(field), in);
+                   fieldsz = sizeof field;
+                   state = m_getfld (&gstate, name, field, &fieldsz, in);
                    lp = add (field, lp);
                }
                for (p = hdrs; p->p_name; p++) {
@@ -775,12 +768,9 @@ parse (int fd)
                    p++, i++;
                    p->p_name = NULL;
                }
-               if (state != FLDEOF)
-                   continue;
-               break;
+               continue;
 
            case BODY: 
-           case BODYEOF: 
            case FILEEOF: 
                break;
 
@@ -796,6 +786,7 @@ parse (int fd)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
     fclose (in);
 
     if ((p = lookup (vars, "reply-to"))) {
@@ -1414,6 +1405,7 @@ suppress_duplicates (int fd, char *file)
     datum key, value;
     DBM *db;
     FILE *in;
+    m_getfld_state_t gstate = 0;
 
     if ((fd1 = dup (fd)) == -1)
        return -1;
@@ -1423,22 +1415,25 @@ suppress_duplicates (int fd, char *file)
     }
     rewind (in);
 
-    for (state = FLD;;) {
-       state = m_getfld (state, name, buf, sizeof(buf), in);
+    for (;;) {
+       int bufsz = sizeof buf;
+       state = m_getfld (&gstate, name, buf, &bufsz, in);
        switch (state) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                /* Search for the message ID */
                if (mh_strcasecmp (name, "Message-ID")) {
-                   while (state == FLDPLUS)
-                       state = m_getfld (state, name, buf, sizeof(buf), in);
+                   while (state == FLDPLUS) {
+                       bufsz = sizeof buf;
+                       state = m_getfld (&gstate, name, buf, &bufsz, in);
+                   }
                    continue;
                }
 
                cp = add (buf, NULL);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, in);
                    cp = add (buf, cp);
                }
                key.dptr = trimcpy (cp);
@@ -1486,7 +1481,6 @@ suppress_duplicates (int fd, char *file)
                break;
 
           case BODY:
-          case BODYEOF:
           case FILEEOF:
                break;
 
@@ -1498,6 +1492,7 @@ suppress_duplicates (int fd, char *file)
 
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     fclose (in);
     return 0;
index 024fcf5c4c20643633a52cd8395b56fd9ffc6d14..68132989061c6c40ba3524d8ed35216eaea1b29d 100644 (file)
 #include <h/tws.h>
 #include <h/utils.h>
 
-static struct swit switches[] = {
-#define DATESW                 0
-     { "datefield field", 0 },
-#define        TEXTSW                 1
-     { "textfield field", 0 },
-#define        NSUBJSW                2
-     { "notextfield", 0 },
-#define SUBJSW                 3
-     { "subject", -3 },                   /* backward-compatibility */
-#define LIMSW                  4
-     { "limit days", 0 },
-#define        NLIMSW                 5
-     { "nolimit", 0 },
-#define VERBSW                 6
-     { "verbose", 0 },
-#define NVERBSW                7
-     { "noverbose", 0 },
-#define ALLMSGS                8
-     { "all", 0 },
-#define NALLMSGS               9
-     { "noall", 0 },
-#define CHECKSW               10
-     { "check", 0 },
-#define NCHECKSW              11
-     { "nocheck", 0 },
-#define VERSIONSW             12
-     { "version", 0 },
-#define HELPSW                13
-     { "help", 0 },
-     { NULL, 0 }
-};
+#define SORTM_SWITCHES \
+    X("datefield field", 0, DATESW) \
+    X("textfield field", 0, TEXTSW) \
+    X("notextfield", 0, NSUBJSW) \
+    X("subject", -3, SUBJSW) /* backward-compatibility */ \
+    X("limit days", 0, LIMSW) \
+    X("nolimit", 0, NLIMSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("all", 0, ALLMSGS) \
+    X("noall", 0, NALLMSGS) \
+    X("check", 0, CHECKSW) \
+    X("nocheck", 0, NCHECKSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SORTM);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SORTM, switches);
+#undef X
 
 struct smsg {
     int s_msg;
@@ -365,21 +357,23 @@ get_fields (char *datesw, int msg, struct smsg *smsg)
     register struct tws *tw;
     register char *datecomp = NULL, *subjcomp = NULL;
     register FILE *in;
+    m_getfld_state_t gstate = 0;
 
     if ((in = fopen (msgnam = m_name (msg), "r")) == NULL) {
        admonish (msgnam, "unable to read message");
        return (0);
     }
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, nam, buf, sizeof(buf), in)) {
+    for (compnum = 1;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, nam, buf, &bufsz, in)) {
        case FLD:
-       case FLDEOF:
        case FLDPLUS:
            compnum++;
            if (!mh_strcasecmp (nam, datesw)) {
                datecomp = add (buf, datecomp);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, nam, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, nam, buf, &bufsz, in);
                    datecomp = add (buf, datecomp);
                }
                if (!subjsort || subjcomp)
@@ -387,20 +381,22 @@ get_fields (char *datesw, int msg, struct smsg *smsg)
            } else if (subjsort && !mh_strcasecmp (nam, subjsort)) {
                subjcomp = add (buf, subjcomp);
                while (state == FLDPLUS) {
-                   state = m_getfld (state, nam, buf, sizeof(buf), in);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, nam, buf, &bufsz, in);
                    subjcomp = add (buf, subjcomp);
                }
                if (datecomp)
                    break;
            } else {
                /* just flush this guy */
-               while (state == FLDPLUS)
-                   state = m_getfld (state, nam, buf, sizeof(buf), in);
+               while (state == FLDPLUS) {
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, nam, buf, &bufsz, in);
+               }
            }
            continue;
 
        case BODY:
-       case BODYEOF:
        case FILEEOF:
            break;
 
@@ -423,6 +419,7 @@ get_fields (char *datesw, int msg, struct smsg *smsg)
        }
        break;
     }
+    m_getfld_state_destroy (&gstate);
 
     /*
      * If no date component, then use the modification
@@ -431,7 +428,10 @@ get_fields (char *datesw, int msg, struct smsg *smsg)
     if (!datecomp || (tw = dparsetime (datecomp)) == NULL) {
        struct stat st;
 
-       admonish (NULL, "can't parse %s field in message %d", datesw, msg);
+       advise (NULL,
+               "can't parse %s field in message %d, "
+               "will use file modification time",
+               datesw, msg);
        fstat (fileno (in), &st);
        smsg->s_clock = st.st_mtime;
        check_failed = 1;
index 2176200200210d45c426788ae9bc6a3534458955..82c7db583386c23fef8ebeba4528bd18ab904556 100644 (file)
 #include <h/mime.h>
 #include <h/mhparse.h>
 
-static struct swit switches[] = {
-#define        TOSW                    0
-    { "to mailpath", 0 },
-#define        FROMSW                  1
-    { "from mailpath", 0 },
-#define        SUBJECTSW               2
-    { "subject subject", 0 },
-#define        PARAMSW                 3
-    { "parameters arguments", 0 },
-#define        DESCRIPTSW              4
-    { "description text", 0 },
-#define        COMMENTSW               5
-    { "comment text", 0 },
-#define        DELAYSW                 6
-    { "delay seconds", 0 },
-#define        VERBSW                  7
-    { "verbose", 0 },
-#define        NVERBSW                 8
-    { "noverbose", 0 },
-#define VERSIONSW               9
-    { "version", 0 },
-#define        HELPSW                 10
-    { "help", 0 },
-#define DEBUGSW                11
-    { "debug", -5 },
-    { NULL, 0 }
-};
+#define VIAMAIL_SWITCHES \
+    X("to mailpath", 0, TOSW) \
+    X("from mailpath", 0, FROMSW) \
+    X("subject subject", 0, SUBJECTSW) \
+    X("parameters arguments", 0, PARAMSW) \
+    X("description text", 0, DESCRIPTSW) \
+    X("comment text", 0, COMMENTSW) \
+    X("delay seconds", 0, DELAYSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("debug", -5, DEBUGSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(VIAMAIL);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(VIAMAIL, switches);
+#undef X
 
 extern int debugsw;
 extern int splitsw;
 extern int verbsw;
 
-int ebcdicsw = 0;      /* hack for linking purposes */
-
 /*
  * static prototypes
  */
index fc8783d0b8df0267a9e3c84cf0c3f15f3c4c5719..05dc8ff3f67bcb896d86201a1fe88f224f038304 100644 (file)
@@ -55,8 +55,7 @@ what_now (char *ed, int nedit, int use, char *file, char *altmsg, int dist,
     if (nedit) {
        unputenv ("mheditor");
     } else {
-       m_putenv ("mheditor", ed ? ed : (ed = context_find ("editor"))
-           ? ed : defaulteditor);
+       m_putenv ("mheditor", ed ? ed : (ed = get_default_editor()));
     }
     snprintf (buffer, sizeof(buffer), "%d", use);
     m_putenv ("mhuse", buffer);
index 389053727c45213dcdfc0c525e39c41a2a5c358f..c9cbf50384096b5e6fe556d18cf893db8f7db2e7 100644 (file)
 #include <h/mime.h>
 #include <h/utils.h>
 
-static struct swit whatnowswitches[] = {
-#define        DFOLDSW                 0
-    { "draftfolder +folder", 0 },
-#define        DMSGSW                  1
-    { "draftmessage msg", 0 },
-#define        NDFLDSW                 2
-    { "nodraftfolder", 0 },
-#define        EDITRSW                 3
-    { "editor editor", 0 },
-#define        NEDITSW                 4
-    { "noedit", 0 },
-#define        PRMPTSW                 5
-    { "prompt string", 4 },
-#define VERSIONSW               6
-    { "version", 0 },
-#define        HELPSW                  7
-    { "help", 0 },
-#define        ATTACHSW                8
-    { "attach header-field-name", 0 },
-#define NOATTACHSW              9
-    { "noattach", 0 },
-    { NULL, 0 }
-};
+#define WHATNOW_SWITCHES \
+    X("draftfolder +folder", 0, DFOLDSW) \
+    X("draftmessage msg", 0, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("editor editor", 0, EDITRSW) \
+    X("noedit", 0, NEDITSW) \
+    X("prompt string", 4, PRMPTSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("attach header-field-name", 0, ATTACHSW) \
+    X("noattach", 0, NOATTACHSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(WHATNOW);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(WHATNOW, whatnowswitches);
+#undef X
 
 /*
  * Options at the "whatnow" prompt
  */
-static struct swit aleqs[] = {
-#define        EDITSW                         0
-    { "edit [<editor> <switches>]", 0 },
-#define        REFILEOPT                      1
-    { "refile [<switches>] +folder", 0 },
-#define BUILDMIMESW                    2
-    { "mime [<switches>]", 0 },
-#define        DISPSW                         3
-    { "display [<switches>]", 0 },
-#define        LISTSW                         4
-    { "list [<switches>]", 0 },
-#define        SENDSW                         5
-    { "send [<switches>]", 0 },
-#define        PUSHSW                         6
-    { "push [<switches>]", 0 },
-#define        WHOMSW                         7
-    { "whom [<switches>]", 0 },
-#define        QUITSW                         8
-    { "quit [-delete]", 0 },
-#define DELETESW                       9
-    { "delete", 0 },
-#define        CDCMDSW                       10
-    { "cd [directory]", 0 },
-#define        PWDCMDSW                      11
-    { "pwd", 0 },
-#define        LSCMDSW                       12
-    { "ls", 2 },
-#define        ATTACHCMDSW                   13
-    { "attach", 0 },
-#define        DETACHCMDSW                   14
-    { "detach [-n]", 2 },
-#define        ALISTCMDSW                    15
-    { "alist [-ln] ", 2 },
-    { NULL, 0 }
-};
+#define PROMPT_SWITCHES \
+    X("edit [<editor> <switches>]", 0, EDITSW) \
+    X("refile [<switches>] +folder", 0, REFILEOPT) \
+    X("mime [<switches>]", 0, BUILDMIMESW) \
+    X("display [<switches>]", 0, DISPSW) \
+    X("list [<switches>]", 0, LISTSW) \
+    X("send [<switches>]", 0, SENDSW) \
+    X("push [<switches>]", 0, PUSHSW) \
+    X("whom [<switches>]", 0, WHOMSW) \
+    X("quit [-delete]", 0, QUITSW) \
+    X("delete", 0, DELETESW) \
+    X("cd [directory]", 0, CDCMDSW) \
+    X("pwd", 0, PWDCMDSW) \
+    X("ls", 2, LSCMDSW) \
+    X("attach", 0, ATTACHCMDSW) \
+    X("detach [-n]", 2, DETACHCMDSW) \
+    X("alist [-ln] ", 2, ALISTCMDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(PROMPT);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(PROMPT, aleqs);
+#undef X
 
 static char *myprompt = "\nWhat now? ";
 
@@ -658,7 +644,7 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp,
 {
     int pid, status, vecp;
     char altpath[BUFSIZ], linkpath[BUFSIZ];
-    char *cp, *vec[MAXARGS];
+    char *cp, *prog, **vec;
     struct stat st;
 
 #ifdef HAVE_LSTAT
@@ -679,8 +665,8 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp,
        }
     } else {
        /* set initial editor */
-       if (*ed == NULL && (*ed = context_find ("editor")) == NULL)
-           *ed = defaulteditor;
+       if (*ed == NULL)
+           *ed = get_default_editor();
     }
 
     if (altmsg) {
@@ -726,15 +712,15 @@ editfile (char **ed, char **arg, char *file, int use, struct msgs *mp,
                m_putenv ("editalt", altpath);
            }
 
-           vecp = 0;
-           vec[vecp++] = r1bindex (*ed, '/');
+           vec = argsplit(*ed, &prog, &vecp);
+
            if (arg)
                while (*arg)
                    vec[vecp++] = *arg++;
            vec[vecp++] = file;
            vec[vecp] = NULL;
 
-           execvp (*ed, vec);
+           execvp (prog, vec);
            fprintf (stderr, "unable to exec ");
            perror (*ed);
            _exit (-1);
@@ -938,14 +924,15 @@ check_draft (char *msgnam)
     int        state;
     char buf[BUFSIZ], name[NAMESZ];
     FILE *fp;
+    m_getfld_state_t gstate = 0;
 
     if ((fp = fopen (msgnam, "r")) == NULL)
        return 0;
-    for (state = FLD;;)
-       switch (state = m_getfld (state, name, buf, sizeof(buf), fp)) {
+    for (;;) {
+       int bufsz = sizeof buf;
+       switch (state = m_getfld (&gstate, name, buf, &bufsz, fp)) {
            case FLD:
            case FLDPLUS:
-           case FLDEOF:
                /*
                 * If draft already contains any of the
                 * Content-XXX fields, then assume it already
@@ -955,8 +942,10 @@ check_draft (char *msgnam)
                    fclose (fp);
                    return 0;
                }
-               while (state == FLDPLUS)
-                   state = m_getfld (state, name, buf, sizeof(buf), fp);
+               while (state == FLDPLUS) {
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
+               }
                break;
 
            case BODY:
@@ -969,7 +958,8 @@ check_draft (char *msgnam)
                            return 1;
                        }
 
-                   state = m_getfld (state, name, buf, sizeof(buf), fp);
+                   bufsz = sizeof buf;
+                   state = m_getfld (&gstate, name, buf, &bufsz, fp);
                } while (state == BODY);
                /* and fall... */
 
@@ -977,6 +967,8 @@ check_draft (char *msgnam)
                fclose (fp);
                return 0;
        }
+    }
+    m_getfld_state_destroy (&gstate);
 }
 
 
@@ -992,107 +984,64 @@ check_draft (char *msgnam)
 # define TLSminc(a)   0
 #endif /* TLS_SUPPORT */
 
-static struct swit  sendswitches[] = {
-#define        ALIASW            0
-    { "alias aliasfile", 0 },
-#define        DEBUGSW           1
-    { "debug", -5 },
-#define        FILTSW            2
-    { "filter filterfile", 0 },
-#define        NFILTSW           3
-    { "nofilter", 0 },
-#define        FRMTSW            4
-    { "format", 0 },
-#define        NFRMTSW           5
-    { "noformat", 0 },
-#define        FORWSW            6
-    { "forward", 0 },
-#define        NFORWSW           7
-    { "noforward", 0 },
-#define MIMESW            8
-    { "mime", 0 },
-#define NMIMESW           9
-    { "nomime", 0 },
-#define MSGDSW           10
-    { "msgid", 0 },
-#define NMSGDSW          11
-    { "nomsgid", 0 },
-#define SPSHSW           12
-    { "push", 0 },
-#define NSPSHSW          13
-    { "nopush", 0 },
-#define SPLITSW          14
-    { "split seconds", 0 },
-#define UNIQSW           15
-    { "unique", -6 },
-#define NUNIQSW          16
-    { "nounique", -8 },
-#define VERBSW           17
-    { "verbose", 0 },
-#define NVERBSW          18
-    { "noverbose", 0 },
-#define        WATCSW           19
-    { "watch", 0 },
-#define        NWATCSW          20
-    { "nowatch", 0 },
-#define        WIDTHSW          21
-    { "width columns", 0 },
-#define SVERSIONSW       22
-    { "version", 0 },
-#define        SHELPSW          23
-    { "help", 0 },
-#define BITSTUFFSW       24
-    { "dashstuffing", -12 },
-#define NBITSTUFFSW      25
-    { "nodashstuffing", -14 },
-#define        MAILSW           26
-    { "mail", -4 },
-#define        SAMLSW           27
-    { "saml", -4 },
-#define        SSNDSW           28
-    { "send", -4 },
-#define        SOMLSW           29
-    { "soml", -4 },
-#define        CLIESW           30
-    { "client host", -6 },
-#define        SERVSW           31
-    { "server host", 6 },
-#define        SNOOPSW          32
-    { "snoop", -5 },
-#define SDRFSW           33
-    { "draftfolder +folder", -6 },
-#define SDRMSW           34
-    { "draftmessage msg", -6 },
-#define SNDRFSW          35
-    { "nodraftfolder", -3 },
-#define SASLSW           36
-    { "sasl", SASLminc(-4) },
-#define NOSASLSW         37
-    { "nosasl", SASLminc(-6) },
-#define SASLMXSSFSW      38
-    { "saslmaxssf", SASLminc(-10) },
-#define SASLMECHSW       39
-    { "saslmech", SASLminc(-5) },
-#define USERSW           40
-    { "user", SASLminc(-4) },
-#define SNDATTACHSW       41
-    { "attach file", 6 },
-#define SNDNOATTACHSW     42
-    { "noattach", 0 },
-#define SNDATTACHFORMAT   43
-    { "attachformat", 7 },
-#define PORTSW           44
-    { "port server-port-name/number", 4 },
-#define TLSSW            45
-    { "tls", TLSminc(-3) },
-#define NTLSSW            46
-    { "notls", TLSminc(-5) },
-#define MTSSW            47
-    { "mts smtp|sendmail/smtp|sendmail/pipe", 2 },
-#define MESSAGEIDSW      48
-    { "messageid localname|random", 2 },
-    { NULL, 0 }
-};
+#define SEND_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("debug", -5, DEBUGSW) \
+    X("filter filterfile", 0, FILTSW) \
+    X("nofilter", 0, NFILTSW) \
+    X("format", 0, FRMTSW) \
+    X("noformat", 0, NFRMTSW) \
+    X("forward", 0, FORWSW) \
+    X("noforward", 0, NFORWSW) \
+    X("mime", 0, MIMESW) \
+    X("nomime", 0, NMIMESW) \
+    X("msgid", 0, MSGDSW) \
+    X("nomsgid", 0, NMSGDSW) \
+    X("push", 0, SPSHSW) \
+    X("nopush", 0, NSPSHSW) \
+    X("split seconds", 0, SPLITSW) \
+    X("unique", -6, UNIQSW) \
+    X("nounique", -8, NUNIQSW) \
+    X("verbose", 0, VERBSW) \
+    X("noverbose", 0, NVERBSW) \
+    X("watch", 0, WATCSW) \
+    X("nowatch", 0, NWATCSW) \
+    X("width columns", 0, WIDTHSW) \
+    X("version", 0, SVERSIONSW) \
+    X("help", 0, SHELPSW) \
+    X("dashstuffing", -12, BITSTUFFSW) \
+    X("nodashstuffing", -14, NBITSTUFFSW) \
+    X("mail", -4, MAILSW) \
+    X("saml", -4, SAMLSW) \
+    X("send", -4, SSNDSW) \
+    X("soml", -4, SOMLSW) \
+    X("client host", -6, CLIESW) \
+    X("server host", 6, SERVSW) \
+    X("snoop", -5, SNOOPSW) \
+    X("draftfolder +folder", -6, SDRFSW) \
+    X("draftmessage msg", -6, SDRMSW) \
+    X("nodraftfolder", -3, SNDRFSW) \
+    X("sasl", SASLminc(-4), SASLSW) \
+    X("nosasl", SASLminc(-6), NOSASLSW) \
+    X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \
+    X("saslmech", SASLminc(-5), SASLMECHSW) \
+    X("user", SASLminc(-4), USERSW) \
+    X("attach file", 6, SNDATTACHSW) \
+    X("noattach", 0, SNDNOATTACHSW) \
+    X("attachformat", 7, SNDATTACHFORMAT) \
+    X("port server-port-name/number", 4, PORTSW) \
+    X("tls", TLSminc(-3), TLSSW) \
+    X("notls", TLSminc(-5), NTLSSW) \
+    X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \
+    X("messageid localname|random", 2, MESSAGEIDSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(SEND);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(SEND, sendswitches);
+#undef X
 
 
 extern int debugsw;            /* from sendsbr.c */
index ad49d86a4ccb8ddb2dbdea95397aeb9426d593c4..3830e5eb07e3a4192090151b79ae98bbd9d2d162 100644 (file)
 # define TLSminc(a)   0
 #endif /* TLS_SUPPORT */
 
-static struct swit switches[] = {
-#define        ALIASW              0
-    { "alias aliasfile", 0 },
-#define        CHKSW               1
-    { "check", 0 },
-#define        NOCHKSW             2
-    { "nocheck", 0 },
-#define        DRAFTSW             3
-    { "draft", 0 },
-#define        DFOLDSW             4
-    { "draftfolder +folder", 6 },
-#define        DMSGSW              5
-    { "draftmessage msg", 6 },
-#define        NDFLDSW             6
-    { "nodraftfolder", 0 },
-#define VERSIONSW           7
-    { "version", 0 },
-#define        HELPSW              8
-    { "help", 0 },
-#define        CLIESW              9
-    { "client host", -6 },
-#define        SERVSW             10
-    { "server host", -6 },
-#define        SNOOPSW            11
-    { "snoop", -5 },
-#define SASLSW             12
-    { "sasl", SASLminc(4) },
-#define SASLMECHSW         13
-    { "saslmech mechanism", SASLminc(-5) },
-#define USERSW             14
-    { "user username", SASLminc(-4) },
-#define PORTSW            15
-    { "port server port name/number", 4 },
-#define TLSSW             16
-    { "tls", TLSminc(-3) },
-#define NTLSSW             17
-    { "notls", TLSminc(-5) },
-#define MTSSW             18
-    { "mts smtp|sendmail/smtp|sendmail/pipe", 0 },
-    { NULL, 0 }
-};
+#define WHOM_SWITCHES \
+    X("alias aliasfile", 0, ALIASW) \
+    X("check", 0, CHKSW) \
+    X("nocheck", 0, NOCHKSW) \
+    X("draft", 0, DRAFTSW) \
+    X("draftfolder +folder", 6, DFOLDSW) \
+    X("draftmessage msg", 6, DMSGSW) \
+    X("nodraftfolder", 0, NDFLDSW) \
+    X("version", 0, VERSIONSW) \
+    X("help", 0, HELPSW) \
+    X("client host", -6, CLIESW) \
+    X("server host", -6, SERVSW) \
+    X("snoop", -5, SNOOPSW) \
+    X("sasl", SASLminc(4), SASLSW) \
+    X("saslmech mechanism", SASLminc(-5), SASLMECHSW) \
+    X("user username", SASLminc(-4), USERSW) \
+    X("port server port name/number", 4, PORTSW) \
+    X("tls", TLSminc(-3), TLSSW) \
+    X("notls", TLSminc(-5), NTLSSW) \
+    X("mts smtp|sendmail/smtp|sendmail/pipe", 0, MTSSW) \
+
+#define X(sw, minchars, id) id,
+DEFINE_SWITCH_ENUM(WHOM);
+#undef X
+
+#define X(sw, minchars, id) { sw, minchars, id },
+DEFINE_SWITCH_ARRAY(WHOM, switches);
+#undef X
 
 
 int