This file is indexed.

/usr/bin/mh/mhmail is in nmh 1.6-2.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#! /bin/sh
#
# mhmail -- simple mail program
#
# 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.
#
# Emulation of compiled mhmail(1), with these differences:
# * Adds -send/-nosend, -headerfield, and -attach options.
# * Adds optional -to switch for recipient addresses.
# * Supports all post(8) (by default, without -profile) or send(1)
#   (with -profile) options.
# * Optionally (with -profile) obeys the users profile, including
#   AliasFile and send entries.
# * Instead of silently not sending an empty message, notifies user
#   "mhmail: empty message not sent, use -body '' to force."
# * The compiled mhmail dropped a trailing newline from the -body argument.
# * Drops support for undocumented -queue option.

usage='Usage: mhmail [-t(o)] addrs ... [switches]
  switches are:
  -at(tach) file [-at(tach) file] ...
  -b(ody) text
  -c(c) addrs ...
  -f(rom) addr
  -hea(derfield) name:value [-hea(derfield) name:value] ...
  -su(bject) text
  -r(esent)
  -pr(ofile)
  -se(nd)
  -nose(nd)
  -v(ersion)
  -hel(p)
  and all post(8)/send(1) switches
  mhmail with no arguments is equivalent to inc'


#### 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
}

#### Convenience function to allow concise code below.
die() {
    [ $# -gt 0 ]  &&  printf '%s\n' "$1" >&2
    exit 1
}


bindir=`finddir $0`
nmhbindir=`cd "$bindir" && pwd`
nmhlibdir=`$nmhbindir/mhparam libdir`
case `printf 'OK\n' | tail -n 1 2>&1` in
  OK) tail='tail -n ' ;;
  *)  tail='tail -' ;;
esac


#### Checks for missing mandatory arguments.
checkforargs() {
  if [ $attacharg -eq 1 ]; then
    die 'mhmail: missing argument to -attach'
  elif [ $bodyarg -eq 1 ]; then
    die 'mhmail: missing argument to -body'
  elif [ $ccarg -eq 1  -a  "$cclist"x = x ]; then
    die 'mhmail: missing argument to -cc'
  elif [ $fromarg -eq 1 ]; then
    die 'mhmail: missing argument to -from'
  elif [ $headerfieldarg -eq 1 ]; then
    die 'mhmail: missing argument to -headerfield'
  elif [ $subjectarg -eq 1 ]; then
    die 'mhmail: missing argument to -subject'
  elif [ $toarg -eq 1 ]; then
    die 'mhmail: missing argument to -to'
  fi
}

if [ $# -eq 0 ]; then
  #### Emulate mhmail for reading mail.
  exec "$nmhbindir"/inc
fi

#### Go through all the switches so we can build the draft.
tolist=                     ## To: addresses
toarg=0                     ## whether currently handling -to
attacharg=0                 ## whether currently handling -attach
attachind=Attach            ## attachment indicator
body=                       ## contents of the message body
bodyarg=0                   ## whether currently handling -body
cclist=                     ## Cc: addresses
ccarg=0                     ## whether currently handling -cc
from=                       ## From: contents
fromarg=0                   ## whether currently handling -from
headerfieldlist=            ## header fields to be added to draft
headerfieldarg=0            ## whether currently handling -headerfield
mhmailswitch=0              ## whether currently handling any mhmail switch
subject=                    ## Subject: contents
subjectarg=0                ## whether currently handling -subject
resent=0                    ## whether resending
postsendargs=               ## switches to pass on to post or send
post_send_switch_arg=0      ## whether currently handling a post/send switch
use_send=0                  ## use post (default) or send (-profile)
sendsw=1                    ## to send (default) or not to send
for arg in "$@"; do
  case $arg in
    #### Post and send won't accept -f -or -s because they'd be
    #### ambiguous, so no conflicts with them.  And they don't have
    #### -b, -c, -r, -t.  For the new switches that compiled mhmail
    #### didn't have:  let -p indicate mhmail -profile, not send
    #### -port.  -send masks the send(1) -send switch.  -attach
    #### masks the send(1) -attach switch.
    -at|-att|-atta|-attac|-attach)
       mhmailswitch=1
       attacharg=1
       use_send=1
       ;;
    -b|-bo|-bod|-body) mhmailswitch=1; bodyarg=1 ;;
    -c|-cc) mhmailswitch=1; ccarg=1 ;;
    -f|-fr|-fro|-from) mhmailswitch=1; fromarg=1 ;;
    -hea|-head|-heade|-header|-headerf|-headerfi|-headerfie|-headerfiel|\
-headerfield) mhmailswitch=1; headerfieldarg=1 ;;
    -hel|-help) printf '%s\n' "$usage"; exit ;;
    -nose|-nosen|-nosend) mhmailswitch=1; sendsw=0 ;;
    -p|-pr|-pro|-prof|-profi|-profil|-profile) mhmailswitch=1; use_send=1 ;;
    -resend) die 'mhmail: did you mean -resent instead of -resend?' ;;
    -r|-re|-res|-rese|-resen|-resent) mhmailswitch=1; resent=1 ;;
    -se|-sen|-send) mhmailswitch=1; sendsw=1 ;;
    -su|-sub|-subj|-subje|-subjec|-subject) mhmailswitch=1; subjectarg=1 ;;
    -t|-to) toarg=1; ccarg=0 ;;
    -v|-ve|-ver|-vers|-versi|-versio|-version)
       #### Cheat instead of using autoconf and make to fill in the version.
       "$nmhbindir"/mhpath -v | sed 's/mhpath/mhmail/'; exit ;;
    -*) if [ $mhmailswitch -eq 1 ]; then
          checkforargs
          mhmailswitch=0
        fi
        post_send_switch_arg=1
        postsendargs="${postsendargs:+$postsendargs }$arg" ;;
    *) mhmailswitch=0
       if [ $bodyarg -eq 1 ]; then
         body="$arg
"
         bodyarg=0
         #### Allow -body "" by using just a newline for the body.
         [ "$body"x = x ]  &&  body='
'
       elif [ $fromarg -eq 1 ]; then
         from="$arg"
         fromarg=0
       elif [ $subjectarg -eq 1 ]; then
         subject="$arg"
         subjectarg=0
       elif [ $attacharg -eq 1 ]; then
         headerfieldlist="${headerfieldlist:+$headerfieldlist}$attachind: $arg
"
         attacharg=0
       elif [ $headerfieldarg -eq 1 ]; then
         #### It's not strictly necessary to have one space after
         #### the : that separates the header field name from the
         #### body, but do it to avoid surprising someone.
         #### Solaris sed wants the trailing newline in its input.
         add=`printf '%s\n' "$arg" | sed -e 's/:/: /' -e 's/:  /: /'`
         headerfieldlist="${headerfieldlist:+$headerfieldlist}$add
"
         headerfieldarg=0
       elif [ $post_send_switch_arg -eq 1 ]; then
         postsendargs="${postsendargs:+$postsendargs }$arg"
       elif [ $ccarg -eq 1 ]; then
         #### ccarg can only be reset to 0 by -to.
         cclist="${cclist:+$cclist, }$arg"
       else
         #### An address.
         tolist="${tolist:+$tolist, }$arg"
         toarg=0
       fi ;;
  esac
done

#### Check for at least one address and -from.
if [ "$tolist"x = x ]; then
  die 'Usage: mhmail [-t(o)] addrs ... [switches]'
fi
if [ "$from"x = x ]; then
  from=`${nmhlibdir}/ap -format '%(localmbox)' 0`
fi

#### Check for missing mandatory arguments.
checkforargs

#### Build header.
[ $resent -eq 0 ]  &&  prefix=  ||  prefix='Resent-'
header="${prefix}To: $tolist
"
[ "$cclist"x = x ]  ||  header="$header${prefix}Cc: $cclist
"
[ "$subject"x = x ]  ||  header="$header${prefix}Subject: $subject
"
[ "$from"x = x ]  ||  header="$header${prefix}From: $from
"

if [ "$headerfieldlist" ]; then
  header="$header$headerfieldlist"
fi

#### Set up a file to supply as a draft to post/send.  And set a trap
#### to remove it.  send moves the file to a backup and can create a
#### .orig file, so it will remove them, too.
umask 077
tmpdir="${MHTMPDIR:-${TMPDIR:-`$nmhbindir/mhpath +`}}"
tmpfilename=`cd "$tmpdir"  &&  "${nmhlibdir}/mkstemp" -p mhmail`
[ $? -ne 0 ]  &&  die "mhmail: failed to create temporary file in $tmpdir"
tmpfile="$tmpdir/$tmpfilename"
backup_char=`"$nmhbindir"/mhparam sbackup`
tmpfilebackup="$tmpdir/${backup_char}${tmpfilename}*"
tmpfileresent=

message_file=
if [ $resent -eq 0 ]; then
  #### Add blank line after header if not resending.
  header="$header
"
  message_file="$tmpfile"
else
  if [ $use_send -eq 0 ]; then
    postsendargs="${postsendargs:+$postsendargs }-dist"
    message_file="$tmpfile"
  else
    #### When resending with send, tmpfile will just contain the
    #### Resent- header fields.  "$tmpfileresent" will contain
    #### the message that is being resent.
    tmpfileresent=`"${nmhlibdir}/mkstemp" -d "$tmpdir" -p mhmail-resent`
    [ $? -ne 0 ]  &&  die "mhmail: failed to create temporary file in $tmpdir"
    mhdist=1; export mhdist
    mhaltmsg=$tmpfileresent; export mhaltmsg
    message_file="$tmpfileresent"
    printf '' >"$message_file"  || exit 2
  fi
fi

trap "rm -f '$tmpfile' $tmpfilebackup ${tmpfileresent:+'$tmpfileresent'}" 0

if [ "$body"x = x ]; then
  #### First put message header in the file.
  printf %s "$header" >"$tmpfile" || exit 2

  tmpfile_size_before=`wc -c "$message_file"`
  #### Now grab the body from stdin.  cat >> handles blank lines
  #### better than body=`cat`.
  cat >>"$message_file" || exit 2
  tmpfile_size_after=`wc -c "$message_file"`

  #### Don't allow an empty body (from stdin).  Use string
  #### comparison so we don't have to strip the filename, etc.
  if [ "$tmpfile_size_before" = "$tmpfile_size_after" ]; then
    die 'mhmail: empty message not sent, use -body '"''"' to force.'
  fi

  #### Add trailing newline to body if it doesn't have one.
  if [ `${tail}1 "$message_file" | wc -l` -ne 1 ]; then
    printf '\n' >>"$message_file" || exit 2
  fi
else
  #### Add trailing newline to body if it doesn't have one.
  [ `printf %s "$body" | ${tail}1 | wc -l` -ne 1 ]  &&  body="$body
"

  if [ "$tmpfileresent" ]; then
    #### Put just the new message header in the file.
    printf %s "$header" >"$tmpfile" || exit 2
    #### and the body in the file to resend.
    printf %s "$body" >"$tmpfileresent" || exit 2
  else
    #### Put message header and body in the file.
    printf %s "$header$body" >"$tmpfile" || exit 2
  fi
fi

if [ $sendsw -eq 0 ]; then
  cat "$tmpfile"
else
  if [ $use_send -eq 0 ]; then
    post_or_send=`$nmhbindir/mhparam postproc`
  else
    post_or_send="$nmhbindir/send"
  fi

  if "$post_or_send" "$tmpfile" $postsendargs; then
    exit
  else
    status=$?
    mv -f "$tmpfile" dead.letter
    printf 'Letter saved in dead.letter\n' >&2
    exit $status
  fi
fi