From: David Levine Date: Thu, 8 Jan 2015 02:32:20 +0000 (-0600) Subject: Merge remote-tracking branch 'origin' into convertargs X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/e2eebc77cc570f77d906bc0cc6890092068468cb?hp=ebd52474945910d72e7ba2ae487e9fe1b4cb4220 Merge remote-tracking branch 'origin' into convertargs --- diff --git a/Makefile.am b/Makefile.am index 55525270..90dee631 100644 --- a/Makefile.am +++ b/Makefile.am @@ -39,6 +39,7 @@ TESTS_ENVIRONMENT = MH_OBJ_DIR="@abs_builddir@" \ MH_TEST_DIR="@abs_builddir@/test/testdir" \ nmhlibexecdir="$(nmhlibexecdir)" bindir="$(bindir)" \ mandir="$(mandir)" nmhetcdir="$(nmhetcdir)" \ + nmhetcdirinst="@nmhetcdirinst@$(nmhetcdir)" \ supported_locks="$(supported_locks)" \ default_locking="${default_locking}" \ MULTIBYTE_ENABLED=$(MULTIBYTE_ENABLED) \ @@ -104,7 +105,13 @@ TESTS = test/ali/test-ali test/anno/test-anno \ check_SCRIPTS = test/common.sh check_PROGRAMS = test/getfullname test/getcanon test/fakepop test/fakesmtp \ test/getcwidth -DISTCHECK_CONFIGURE_FLAGS = DISABLE_SETGID_MAIL=1 + +## The location of installed nmhetcdir is, for all purposes except +## distcheck, $nmhetcdir. For distcheck, prepend $MH_INST_DIR (from +## test/common.sh.in), which is based on $MH_TEST_DIR (from +## $TESTS_ENVIRONMENT). +DISTCHECK_CONFIGURE_FLAGS = DISABLE_SETGID_MAIL=1 \ + NMHETCDIRINST='$${abs_builddir}/test/testdir/inst' ## ## Stuff that should be cleaned via "make clean" @@ -608,7 +615,7 @@ sbr_libmh_a_SOURCES = sbr/addrsbr.c sbr/ambigsw.c sbr/atooi.c sbr/arglist.c \ config/sbr_libmh_a-config.$(OBJEXT) sbr/sbr_libmh_a-mts.$(OBJEXT): Makefile -sbr_libmh_a_CPPFLAGS = -I./sbr -DNMHETCDIR='"$(nmhetcdir)"' \ +sbr_libmh_a_CPPFLAGS = -I./sbr -DNMHETCDIR='"@nmhetcdirinst@$(nmhetcdir)"' \ -DMAILSPOOL='"$(mailspool)"' \ -DSENDMAILPATH='"$(sendmailpath)"' -DNMHBINDIR='"$(bindir)"' \ -DNMHLIBEXECDIR='"$(nmhlibexecdir)"' diff --git a/configure.ac b/configure.ac index 4e195b61..754ccb6a 100644 --- a/configure.ac +++ b/configure.ac @@ -516,6 +516,13 @@ AS_IF([test "$LEX" = flex], '; sed "s/\( \)int i;/\1yy_size_t i;/" $@ >$@.tmp && mv -f $@.tmp $@']) AC_SUBST([LFLAGS])]) +dnl ------------------ +dnl FOR INTERNAL USE by the NMH test suite +dnl ------------------ +AC_ARG_VAR([NMHETCDIRINST], [for internal use by nmh test suite]) +AS_IF([test -n "$NMHETCDIRINST"], [nmhetcdirinst=$NMHETCDIRINST] + AC_SUBST([nmhetcdirinst])) + dnl ---------------- dnl CHECK STRUCTURES dnl ---------------- diff --git a/docs/pending-release-notes b/docs/pending-release-notes index 991b1696..4ae67075 100644 --- a/docs/pending-release-notes +++ b/docs/pending-release-notes @@ -25,7 +25,8 @@ NEW FEATURES - When building from source, configure will derive ${prefix} from an existing nmh installation if it finds one in your $PATH. - Added getmymbox and getmyaddr mh-format(5) function escapes. -- The -changecur and -nochangecur switches have been added to mhfixmsg(1). +- New -changecur, -nochangecur, and -fixtype switches have been added + to mhfixmsg(1). - mhfixmsg now removes an extraneous trailing semicolon from header parameter lists. - Added -convertargs switch to repl(1), to pass arguments to programs diff --git a/h/mhparse.h b/h/mhparse.h index 371e671a..c3b0b9f1 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -338,6 +338,8 @@ void close_encoding (CT); void free_content (CT); char *ct_type_str (int); char *ct_subtype_str (int, int); +int ct_str_type (const char *); +int ct_str_subtype (int, const char *); const struct str2init *get_ct_init (int); const char *ce_str (int); const struct str2init *get_ce_method (const char *); diff --git a/h/prototypes.h b/h/prototypes.h index a338fd52..3399384e 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -384,7 +384,7 @@ int unputenv (char *); * */ void unquote_string(const char *input, char *output); -int uprf (char *, char *); +int uprf (const char *, const char *); int vfgets (FILE *, char **); /* diff --git a/man/mh-profile.man b/man/mh-profile.man index 81e2ccbe..cdd78128 100644 --- a/man/mh-profile.man +++ b/man/mh-profile.man @@ -1,4 +1,4 @@ -.TH MH-PROFILE %manext5% "April 18, 2014" "%nmhversion%" +.TH MH-PROFILE %manext5% "December 21, 2014" "%nmhversion%" .\" .\" %nmhwarning% .\" @@ -44,6 +44,15 @@ context, and indicates what the default value is. Note that a profile component can only appear once. Multiple appearances with trigger a warning that all appearances after the first are ignored. .PP +Some MH programs, including +.BR mhbuild , +.BR mhshow , +and +.BR mhstore , +have specific profile components that are described in their respective +man pages. Each component name begins with the name of the program and +is followed by a dash. +.PP .BR Path : Mail .RS 5 @@ -1045,6 +1054,9 @@ if annotations are to occur. .SH "SEE ALSO" .IR environ (5), .IR mh-sequence (5), +.IR mhbuild (1), +.IR mhshow (1), +.IR mhstore (1), .IR nmh (7) .SH HISTORY The diff --git a/man/mhfixmsg.man b/man/mhfixmsg.man index 3bb8e84e..3afb4ba8 100644 --- a/man/mhfixmsg.man +++ b/man/mhfixmsg.man @@ -1,4 +1,4 @@ -.TH MHFIXMSG %manext1% "November 30, 2014" "%nmhversion%" +.TH MHFIXMSG %manext1% "December 25, 2014" "%nmhversion%" .\" .\" %nmhwarning% .\" @@ -23,6 +23,8 @@ mhfixmsg \- rewrite MIME messages with various transformations .RB [ \-replacetextplain " | " \-noreplacetextplain ] .RB [ \-fixboundary " | " \-nofixboundary ] .RB [ \-fixcte " | " \-nofixcte ] +.RB [ \-fixtype +.IR mimetype ] .RB [ \-outfile .IR outfile ] .RB [ \-rmmproc @@ -149,6 +151,14 @@ and other .B nmh programs that parse MIME messages. .PP +The +.B \-fixtype +switch ensures that each part of the message has the correct MIME type +shown in its Content-Type header. It may be repeated. It is +typically used to replace \*(lqapplication/octet-stream\*(rq with a +more descriptive MIME type. It may not be used for multipart and +message types. +.PP .B mhfixmsg applies one transformation unconditionally: it removes an extraneous trailing semicolon from the parameter lists of MIME header fields. @@ -240,6 +250,7 @@ content type and/or encoding as follows: \-reformat text parts that are not text/plain \-fixboundary outermost multipart part \-fixcte multipart part +\-fixtype all except multipart and message parts .fi .RE .PP diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index 5732af91..97a4a05a 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -93,13 +93,18 @@ cpnumber(charstring_t dest, int num, unsigned int wid, char fill, size_t max) { charstring_push_back (rev, '?'); } else if (num < 0 && wid > 0) { /* Shouldn't need the wid > 0 check, that's why the condition - at the top checks wid < max-1 when num < 0. */ - charstring_push_back (rev, '-'); + at the top checks wid < max-1 when num < 0. */ --wid; + if (fill == ' ') { + charstring_push_back (rev, '-'); + } } while (wid-- > 0 && fill != 0) { charstring_push_back (rev, fill); } + if (num < 0 && fill == '0') { + charstring_push_back (rev, '-'); + } { /* Output the string in reverse. */ diff --git a/sbr/getansreadline.c b/sbr/getansreadline.c index 3282e499..e68cba89 100644 --- a/sbr/getansreadline.c +++ b/sbr/getansreadline.c @@ -9,7 +9,6 @@ #include #include -#include #ifdef READLINE_SUPPORT #include diff --git a/sbr/mime_type.c b/sbr/mime_type.c index 06a6156d..23ccf038 100644 --- a/sbr/mime_type.c +++ b/sbr/mime_type.c @@ -37,14 +37,15 @@ mime_type(const char *file_name) { if ((mimeencoding = get_file_info(MIMEENCODINGPROC, file_name))) { content_type = concat(mimetype, "; charset=", mimeencoding, NULL); + free (mimetype); } else { - content_type = strdup(mimetype); + content_type = mimetype; } } else { - content_type = strdup(mimetype); + content_type = mimetype; } #else /* MIMEENCODINGPROC */ - content_type = strdup(mimetype); + content_type = mimetype; #endif /* MIMEENCODINGPROC */ } #endif /* MIMETYPEPROC */ diff --git a/sbr/uprf.c b/sbr/uprf.c index 500b036d..dddacaf8 100644 --- a/sbr/uprf.c +++ b/sbr/uprf.c @@ -11,7 +11,7 @@ int -uprf (char *c1, char *c2) +uprf (const char *c1, const char *c2) { int c, mask; diff --git a/test/common.sh.in b/test/common.sh.in index 99d64a50..e84d8e62 100644 --- a/test/common.sh.in +++ b/test/common.sh.in @@ -1,27 +1,26 @@ -# Common helper routines for test shell scripts -- intended to be sourced by them +# Common helper routines for test shell scripts -- to be sourced by them # @configure_input@ -#### The following exported variables are set by "make check". Ensure +#### The following variables are set by "make check". Ensure #### that they are set here so that individual tests can be run #### outside of make. Requires that MH_OBJ_DIR be set on entry. test -z "$MH_TEST_DIR" && MH_TEST_DIR="$MH_OBJ_DIR/test/testdir" +test -z "$MH_INST_DIR" && MH_INST_DIR="${MH_TEST_DIR}/inst" test -z "$prefix" && prefix=@prefix@ test -z "$datarootdir" && datarootdir=@datarootdir@ test -z "$exec_prefix" && exec_prefix=@exec_prefix@ -test -z "$nmhexecdir" && nmhexecdir="@libexecdir@/nmh" test -z "$bindir" && bindir="@bindir@" test -z "$mandir" && mandir="@mandir@" test -z "$nmhetcdir" && nmhetcdir="@sysconfdir@/nmh" +#### The following doesn't support running the distcheck version of +#### test-mhparam standalone, but only via make distcheck. +test -z "$nmhetcdirinst" && nmhetcdirinst="@nmhetcdirinst@$nmhetcdir" +test -z "$nmhlibexecdir" && nmhlibexecdir="@libexecdir@/nmh" test -z "$supported_locks" && supported_locks="@supported_locks@" test -z "$default_locking" && default_locking="@default_locking@" test -z "$MULTIBYTE_ENABLED" && MULTIBYTE_ENABLED="@MULTIBYTE_ENABLED@" test -z "$ICONV_ENABLED" && ICONV_ENABLED="@ICONV_ENABLED@" -export MH_TEST_DIR nmhexecdir bindir mandir nmhetcdir -export MULTIBYTE_ENABLED ICONV_ENABLED - -test -z "$MH_INST_DIR" && MH_INST_DIR="${MH_TEST_DIR}/inst" -export MH_INST_DIR unset MAILDROP MHBUILD MHCONTEXT MHMTSUSERCONF MHN MHSHOW MHSTORE unset MHLDEBUG MHPDEBUG MHWDEBUG PAGER @@ -247,7 +246,7 @@ setup_test () { MH="${MH_TEST_DIR}/Mail/.mh_profile" MHMTSCONF="${MH_INST_DIR}${nmhetcdir}/mts.conf" - MH_LIBEXEC_DIR="${MH_INST_DIR}${nmhexecdir}" + MH_LIBEXEC_DIR="${MH_INST_DIR}${nmhlibexecdir}" export MH MHMTSCONF MH_LIBEXEC_DIR # @@ -293,16 +292,14 @@ postproc: ${MH_LIBEXEC_DIR}/post showproc: ${MH_LIBEXEC_DIR}/mhl EOF - for f in MailAliases components digestcomps distcomps forwcomps \ - mhical.12hour mhical.24hour mhl.body mhl.digest mhl.format \ - mhl.forward mhl.headers mhl.reply mhl.replywithoutbody \ - mhn.defaults rcvdistcomps replcomps replgroupcomps \ - scan.MMDDYY scan.YYYYMMDD scan.curses scan.default \ - scan.highlighted scan.mailx scan.nomime scan.size scan.time \ - scan.timely scan.unseen - do - cp "${MH_INST_DIR}${nmhetcdir}/${f}" "${MH_TEST_DIR}/Mail" || exit 1 - done + if test -z '@nmhetcdirinst@'; then + #### This isn't used with make distcheck, so that we can use it to + #### be sure that etc files are not used from an existing nmh + #### installation. + #### posh doesn't like "${MH_INST_DIR}${nmhetcdir}"/*, so cd to + #### the directory and provide an argument without quotes to cp. + (cd "${MH_INST_DIR}${nmhetcdir}/" && cp * "${MH_TEST_DIR}/Mail") + fi folder -create +inbox > /dev/null # create 10 basic messages diff --git a/test/format/test-fmtdump b/test/format/test-fmtdump index b10374c1..5680a5b1 100755 --- a/test/format/test-fmtdump +++ b/test/format/test-fmtdump @@ -110,7 +110,7 @@ run_prog $fmtdump >$actual 2>&1 check $expected $actual 'keep first' # check -form -run_prog $fmtdump -form "$MH_TEST_DIR/Mail/scan.default" >$actual 2>&1 +run_prog $fmtdump -form "$MH_INST_DIR${nmhetcdir}/scan.default" >$actual 2>&1 check $expected $actual # check -format diff --git a/test/format/test-functions b/test/format/test-functions index 9cfaeeeb..b757e8e0 100755 --- a/test/format/test-functions +++ b/test/format/test-functions @@ -12,18 +12,29 @@ fi . "$MH_OBJ_DIR/test/common.sh" setup_test -expected="$MH_TEST_DIR/$$.expected" -actual="$MH_TEST_DIR/$$.actual" +expected="$MH_TEST_DIR/test-functions$$.expected" +actual="$MH_TEST_DIR/test-functions$$.actual" # check sday when day of week is specified -echo 1 >"$expected" +printf '1\n' >"$expected" fmttest -raw -format '%(sday{text})' 'Fri Sep 12 20:02 2014' >"$actual" check "$expected" "$actual" # check sday when day of week is not specified -echo 0 >"$expected" +printf '0\n' >"$expected" fmttest -raw -format '%(sday{text})' 'Sep 12 20:02 2014' >"$actual" check "$expected" "$actual" +# check negative number, without padding +printf '%s\n' ' -42' >"$expected" +fmttest -raw -format '%4(minus -42)' 0 >"$actual" +check "$expected" "$actual" + +# check negative number, with padding +# Output was "0-42" with nmh 1.6 and earlier. +printf '%s\n' -042 >"$expected" +fmttest -raw -format '%04(minus -42)' 0 >"$actual" +check "$expected" "$actual" + exit $failed diff --git a/test/mhfixmsg/test-mhfixmsg b/test/mhfixmsg/test-mhfixmsg index cc69aea7..b8e0b426 100755 --- a/test/mhfixmsg/test-mhfixmsg +++ b/test/mhfixmsg/test-mhfixmsg @@ -12,7 +12,9 @@ if test -z "${MH_OBJ_DIR}"; then MH_OBJ_DIR=`cd $srcdir && pwd`; export MH_OBJ_DIR fi -. "${srcdir}/test/post/test-post-common.sh" +. "${MH_OBJ_DIR}/test/common.sh" + +setup_test #### Make sure that html-to-text conversion is what we expect. require_locale en_US.utf-8 en_US.utf8 @@ -23,10 +25,12 @@ expected_err="$MH_TEST_DIR/test-mhfixmsg$$.expected_err" actual="$MH_TEST_DIR/test-mhfixmsg$$.actual" actual_err="$MH_TEST_DIR/test-mhfixmsg$$.actual_err" -if grep mhfixmsg-format-text/html "${MH_TEST_DIR}/Mail/mhn.defaults" \ +mhn_defaults="$MH_INST_DIR${nmhetcdir}/mhn.defaults" + +if grep mhfixmsg-format-text/html "${mhn_defaults}" \ >/dev/null; then can_reformat_texthtml=1 - if grep 'mhfixmsg-format-text/html.*w3m' "${MH_TEST_DIR}/Mail/mhn.defaults" \ + if grep 'mhfixmsg-format-text/html.*w3m' "${mhn_defaults}" \ >/dev/null; then #### w3m uses $HOME/.w3m/, and creates it if it doesn't exist. To #### support testing with non-writeable $HOME, and to not leave @@ -42,7 +46,6 @@ fi # check -help -# Verified behavior consistent with compiled sendmail. cat >"$expected" <&2 @@ -1110,6 +1113,41 @@ if test -f '${MH_TEST_DIR}/Mail/inbox/20.backup'; then fi +# check -fixtype +cat >"$expected" <`mhpath new` <"$actual" diff --git a/test/mhparam/test-mhparam b/test/mhparam/test-mhparam index c3157782..8a48b8de 100755 --- a/test/mhparam/test-mhparam +++ b/test/mhparam/test-mhparam @@ -85,18 +85,18 @@ $MH_INST_DIR$bindir/refile $bindir/inc more $bindir/mhmail -$MH_INST_DIR$nmhexecdir/mhl +$MH_INST_DIR$nmhlibexecdir/mhl cat 600 $bindir/packf -$MH_INST_DIR$nmhexecdir/post +$MH_INST_DIR$nmhlibexecdir/post $bindir/send $bindir/mhshow -$MH_INST_DIR$nmhexecdir/mhl +$MH_INST_DIR$nmhlibexecdir/mhl nmh-`cat ${srcdir}/VERSION` $bindir/whatnow $bindir/whom -$nmhetcdir +$nmhetcdirinst $MH_LIBEXEC_DIR fcntl ${default_locking} diff --git a/test/whatnow/test-cd b/test/whatnow/test-cd index 8b01ab6c..e5111bdd 100755 --- a/test/whatnow/test-cd +++ b/test/whatnow/test-cd @@ -37,13 +37,17 @@ actual=$MH_TEST_DIR/$$.actual set +e whatnowtest=`echo cd | whatnow -prompt ''` set -e - case ${whatnowtest} in cd) cat > "$expected" </dev/null` || COLUMNS=8192 + export COLUMNS ;; "") cat > "$expected" <fixboundary) { status = fix_boundary (ctp, &message_mods); } + if (status == OK && fx->fixtypes != NULL) { + status = fix_types (*ctp, fx->fixtypes, &message_mods); + } if (status == OK && fx->fixcte) { status = fix_multipart_cte (*ctp, &message_mods); } @@ -727,6 +748,144 @@ replace_boundary (CT ct, char *file, char *boundary) { } +static int +fix_types (CT ct, svector_t fixtypes, int *message_mods) { + int status = OK; + + switch (ct->c_type) { + case CT_MULTIPART: { + struct multipart *m = (struct multipart *) ct->c_ctparams; + struct part *part; + + for (part = m->mp_parts; status == OK && part; part = part->mp_next) { + status = fix_types (part->mp_part, fixtypes, message_mods); + } + break; + } + + case CT_MESSAGE: + if (ct->c_subtype == MESSAGE_EXTERNAL) { + struct exbody *e = (struct exbody *) ct->c_ctparams; + + status = fix_types (e->eb_content, fixtypes, message_mods); + } + break; + + default: { + char **typep, *type; + + if (ct->c_ctinfo.ci_type && ct->c_ctinfo.ci_subtype) { + for (typep = svector_strs (fixtypes); + typep && (type = *typep); + ++typep) { + char *type_subtype = + concat (ct->c_ctinfo.ci_type, "/", ct->c_ctinfo.ci_subtype, + NULL); + + if (! strcasecmp (type, type_subtype) && + decode_part (ct) == OK && + ct->c_cefile.ce_file != NULL) { + char *ct_type_subtype = mime_type (ct->c_cefile.ce_file); + char *cp; + + if ((cp = strchr (ct_type_subtype, ';'))) { + /* Truncate to remove any parameter list from + mime_type () result. */ + *cp = '\0'; + } + + if (strcasecmp (type, ct_type_subtype)) { + char *ct_type, *ct_subtype; + HF hf; + + /* The Content-Type header does not match the + content, so update these struct Content + fields to match: + * c_type, c_subtype + * c_ctinfo.ci_type, c_ctinfo.ci_subtype + * c_ctline + */ + /* Extract type and subtype from type/subtype. */ + ct_type = getcpy (ct_type_subtype); + if ((cp = strchr (ct_type, '/'))) { + *cp = '\0'; + ct_subtype = getcpy (++cp); + } else { + advise (NULL, "missing / in MIME type of %s %s", + ct->c_file, ct->c_partno); + free (ct_type); + return NOTOK; + } + + ct->c_type = ct_str_type (ct_type); + ct->c_subtype = ct_str_subtype (ct->c_type, ct_subtype); + + free (ct->c_ctinfo.ci_type); + ct->c_ctinfo.ci_type = ct_type; + free (ct->c_ctinfo.ci_subtype); + ct->c_ctinfo.ci_subtype = ct_subtype; + if (! replace_substring (&ct->c_ctline, type, + ct_type_subtype)) { + advise (NULL, "did not find %s in %s", + type, ct->c_ctline); + } + + /* Update Content-Type header field. */ + for (hf = ct->c_first_hf; hf; hf = hf->next) { + if (! strcasecmp (TYPE_FIELD, hf->name)) { + if (replace_substring (&hf->value, type, + ct_type_subtype)) { + ++*message_mods; + if (verbosw) { + report (NULL, ct->c_partno, ct->c_file, + "change Content-Type in header " + "from %s to %s", + type, ct_type_subtype); + } + break; + } else { + advise (NULL, "did not find %s in %s", + type, hf->value); + } + } + } + } + free (ct_type_subtype); + } + free (type_subtype); + } + } + }} + + return status; +} + +char * +replace_substring (char **str, const char *old, const char *new) { + char *cp; + + if ((cp = strstr (*str, old))) { + char *remainder = cp + strlen (old); + char *prefix, *new_str; + + if (cp - *str) { + prefix = getcpy (*str); + *(prefix + (cp - *str)) = '\0'; + new_str = concat (prefix, new, remainder, NULL); + free (prefix); + } else { + new_str = concat (new, remainder, NULL); + } + + free (*str); + + return *str = new_str; + } else { + return NULL; + } +} + + static int fix_multipart_cte (CT ct, int *message_mods) { int status = OK; @@ -1062,13 +1221,14 @@ build_text_plain_part (CT encoded_part) { if ((tempfile = m_mktemp2 (NULL, invo_name, NULL, NULL)) == NULL) { advise (NULL, "unable to create temporary file in %s", get_temp_dir()); - } - tmp_plain_file = add (tempfile, NULL); - if (reformat_part (tp_part, tmp_plain_file, - tp_part->c_ctinfo.ci_type, - tp_part->c_ctinfo.ci_subtype, - tp_part->c_type) == OK) { - return tp_part; + } else { + tmp_plain_file = add (tempfile, NULL); + if (reformat_part (tp_part, tmp_plain_file, + tp_part->c_ctinfo.ci_type, + tp_part->c_ctinfo.ci_subtype, + tp_part->c_type) == OK) { + return tp_part; + } } } diff --git a/uip/mhlsbr.c b/uip/mhlsbr.c index 28d48947..3bc08085 100644 --- a/uip/mhlsbr.c +++ b/uip/mhlsbr.c @@ -875,14 +875,18 @@ parse (void) static void process (char *folder, char *fname, int ofilen, int ofilec) { - char *cp = NULL; - FILE *fp = NULL; + /* static to prevent "might be clobbered" warning from gcc 4.9.2: */ + static char *cp; + static FILE *fp; struct mcomp *c1; struct stat st; struct arglist *ap; /* volatile to prevent "might be clobbered" warning from gcc: */ char *volatile fname2 = fname ? fname : "(stdin)"; + cp = NULL; + fp = NULL; + switch (setjmp (env)) { case OK: if (fname) { @@ -913,12 +917,12 @@ process (char *folder, char *fname, int ofilen, int ofilec) if (arglist_head) fmt_free(NULL, 1); - default: + default: if (ontty != PITTY) SIGNAL (SIGINT, SIG_IGN); - if (mhl_action == NULL && fp != stdin) + if (mhl_action == NULL && fp != stdin && fp != NULL) fclose (fp); - free (cp); + free (cp); if (holder.c_text) { free (holder.c_text); holder.c_text = NULL; diff --git a/uip/mhparse.c b/uip/mhparse.c index 96af58e9..a3a80f9a 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -1008,7 +1008,6 @@ InitText (CT ct) char *chset = NULL; char *cp; PM pm; - struct k2v *kv; struct text *t; CI ci = &ct->c_ctinfo; @@ -1017,10 +1016,7 @@ InitText (CT ct) ci->ci_subtype = add ("plain", ci->ci_subtype); /* match subtype */ - for (kv = SubText; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) - break; - ct->c_subtype = kv->kv_value; + ct->c_subtype = ct_str_subtype (CT_TEXT, ci->ci_subtype); /* allocate text character set structure */ if ((t = (struct text *) mh_xcalloc (1, sizeof(*t))) == NULL) @@ -1073,7 +1069,6 @@ InitMultiPart (CT ct) size_t buflen; ssize_t gotlen; struct multipart *m; - struct k2v *kv; struct part *part, **next; CI ci = &ct->c_ctinfo; CT p; @@ -1105,10 +1100,7 @@ InitMultiPart (CT ct) } /* match subtype */ - for (kv = SubMultiPart; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) - break; - ct->c_subtype = kv->kv_value; + ct->c_subtype = ct_str_subtype (CT_MULTIPART, ci->ci_subtype); /* * Check for "boundary" parameter, which is @@ -1329,7 +1321,6 @@ reverse_alternative_parts (CT ct) { static int InitMessage (CT ct) { - struct k2v *kv; CI ci = &ct->c_ctinfo; if ((ct->c_encoding != CE_7BIT) && (ct->c_encoding != CE_8BIT)) { @@ -1344,10 +1335,7 @@ InitMessage (CT ct) ci->ci_subtype = add ("rfc822", ci->ci_subtype); /* match subtype */ - for (kv = SubMessage; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) - break; - ct->c_subtype = kv->kv_value; + ct->c_subtype = ct_str_subtype (CT_MESSAGE, ci->ci_subtype); switch (ct->c_subtype) { case MESSAGE_RFC822: @@ -1597,14 +1585,10 @@ params_external (CT ct, int composing) static int InitApplication (CT ct) { - struct k2v *kv; CI ci = &ct->c_ctinfo; /* match subtype */ - for (kv = SubApplication; kv->kv_key; kv++) - if (!strcasecmp (ci->ci_subtype, kv->kv_key)) - break; - ct->c_subtype = kv->kv_value; + ct->c_subtype = ct_str_subtype (CT_APPLICATION, ci->ci_subtype); return OK; } @@ -3176,6 +3160,62 @@ ct_subtype_str (int type, int subtype) { } +int +ct_str_type (const char *type) { + struct str2init *s2i; + + for (s2i = str2cts; s2i->si_key; ++s2i) { + if (! strcasecmp (type, s2i->si_key)) { + break; + } + } + if (! s2i->si_key && ! uprf (type, "X-")) { + ++s2i; + } + + return s2i->si_val; +} + + +int +ct_str_subtype (int type, const char *subtype) { + struct k2v *kv; + + switch (type) { + case CT_APPLICATION: + for (kv = SubApplication; kv->kv_key; ++kv) { + if (! strcasecmp (subtype, kv->kv_key)) { + break; + } + } + return kv->kv_value; + case CT_MESSAGE: + for (kv = SubMessage; kv->kv_key; ++kv) { + if (! strcasecmp (subtype, kv->kv_key)) { + break; + } + } + return kv->kv_value; + case CT_MULTIPART: + for (kv = SubMultiPart; kv->kv_key; ++kv) { + if (! strcasecmp (subtype, kv->kv_key)) { + break; + } + } + return kv->kv_value; + case CT_TEXT: + for (kv = SubText; kv->kv_key; ++kv) { + if (! strcasecmp (subtype, kv->kv_key)) { + break; + } + } + return kv->kv_value; + default: + return 0; + } +} + + /* Find the content type and InitFunc for the CT. */ const struct str2init * get_ct_init (int type) { diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 986ffb91..a9aa9c0b 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/uip/prompter.c b/uip/prompter.c index 304c9a5d..58347d47 100644 --- a/uip/prompter.c +++ b/uip/prompter.c @@ -331,8 +331,7 @@ getln (char *buffer, int n) char *cp; static int quoting = 0; - cp = buffer; - *cp = 0; + *buffer = 0; switch (setjmp (sigenv)) { case OK: @@ -348,6 +347,9 @@ getln (char *buffer, int n) return NOTOK; } + cp = buffer; + *cp = 0; + for (;;) { switch (c = getchar ()) { case EOF: diff --git a/uip/whatnowsbr.c b/uip/whatnowsbr.c index 2c2d2043..21fb1519 100644 --- a/uip/whatnowsbr.c +++ b/uip/whatnowsbr.c @@ -446,9 +446,6 @@ WhatNow (int argc, char **argv) annotate(drft, ATTACH_FIELD, file, 1, 0, -2, 1); if (verbose) { ctype = mime_type(file); - } - - if (verbose) { printf ("Attaching %s as a %s\n", file, ctype); free (ctype); }