mvmf: mvmtr man page

mvmf: mvmtr man page


MVMTR(1)                    General Commands Manual                    MVMTR(1)

NAME
       mvmtr - mvmf's Mail Transport Agent (MTA) receiver

SYNOPSIS
       mvmtr [-b bodycache] [-C startfile] [-h hostname] [-v] [-V]

DESCRIPTION
       mvmtr  implements a receiver portion of a mail transport agent (MTA) de-
       signed to be used in conjunction with  the  mvmda  mail  delivery  agent
       (MDA).   mvmtr,  at  least in its initial incarnation, is designed to be
       used in place of qmail's qmail-smtpd program.

       It is not a drop-in replacment for qmail-smtpd, as it uses its own  con-
       trol interface.  However it can be configured at compile-time to use the
       same  control files as (and be generally drop-in-compatible with) stock,
       unpatched qmail-smtpd version  1.03  .  (See  qmail-smtpd  compatibility
       notes elsewhere.)

       mvmtr  includes an interpreter for its built-in mfl language, which is a
       sort of mongrelization of C and Sieve.  mfl, which is described  in  an-
       other  document,  allows  programmed control over what happens to email,
       and includes a number of intrinsics related to processing email.

       Options which may be given are as follows:

       -b bodycache
              Says how many bytes of message body to cache in memory.  The num-
              ber given is constrained to lie between  a  minimum  and  maximum
              specified  at  compile time.  The actual limit is somewhat fuzzy:
              regardless of the number specified and regardless  of  the  total
              number  already  cached, there is also a minimum amount that will
              be cached in each MIME part.

       -C startfile
              The name of a startup file.  The startup file is simply mfl code,
              it is run in admin mode (with regards to  the  "admin"  mfl  con-
              trol).   If  this option is omitted, a default is used if config-
              ured at compile time.  The startfile name must  be  found  within
              the  system-wide  mfl include path, and should therefore not be a
              full path to the file.
              This option will override any default startfile or one  specified
              via an environment variable.

       -h hostname
              specifies  a  host  name to use in the SMTP dialog when accepting
              email.  The SMTP server must identify the server's host  name  to
              the  connecting  client.   If  this option is not given, the host
              name determined by a system call (e.g.  gethostname()) is used.

       -v     prints mvtr's version number.  The version number has three deci-
              mal parts separated by periods: first  a  major  version  number,
              next  a  minor version number, and finally a fix number.  The fix
              number is incremented whenever a new version contains only  fixes
              and  enhancements  to existing features.  The minor number is in-
              cremented whenever a new facility or technique is added, and  the
              major  number  is  incremented  when  enough new things have been
              added to consider it a major new edition of the program.  A major
              number of zero (0)  indicates  a  prerelease  version  (one  that
              doesn't  yet include all its initial release features or that may
              not yet be considered fully tested).

       -V     prints mvmtr's version and control settings, in a  form  suitable
              to be re-read via MFL.  This will show the effects of any initial
              startup configuration.

MODES and CONTROLS
       mvmtr  is  controlled  by  its command line options, various environment
       variables, and some control files.  Each of these controls is  described
       in  a  separate  section  (command line options have been addressed ear-
       lier).

       mvmtr may operate in one of several modes, as described here.  Of  these
       modes, only ucspi-tcp mode is implemented at this time; the others, how-
       ever, are planned.

       inetd mode
              In this mode, there is some daemon process such as inetd, outside
              of  mvmtr's scope, that accepts incoming TCP/IP connections.  For
              each SMTP connection, that process invokes a specific program (in
              this case, mvmtr) with the network connection set up on stdin and
              stdout.  No other information is given to mvmtr.

       ucspi-tcp mode
              is somewhat like inetd  mode.   Here,  there  is  also  a  daemon
              process,  again  outside  of mvmtr's scope, that accepts incoming
              TCP/IP connections.  In this case, though, that daemon process is
              known either to be the tcpserver program that's  part  of  D.  J.
              Bernstein's ucspi-tcp package, or a functional equivalent of that
              program.   The  network connection is set up on stdin and stdout,
              but a number of environment variables are set by the parent  pro-
              gram  that give information about the connection, and other vari-
              ables may be set as control parameters.  Additionally, stderr  is
              assumed to be set up to accept log messages.

       daemon mode
              assumes no parent process at all.  In this mode, mvmtr listens on
              specific  network  ports  for incoming SMTP connections.  It will
              then handle each of these connections (specifically by forking  a
              child process of itself).

ENVIRONMENT VARIABLES
       The  following  environment variables are significant to mvmtr.  Not all
       variables are relevant to all operating modes.

       inetd mode

       There are no specific environment variables associated with this mode.

       ucspi-tcp mode

       When operating in this mode, mvmtr is invoked  once  for  each  incoming
       SMTP  connection.  The parent process is expected to set a number of en-
       vironment variables that describe the connection to the client and offer
       some guidance about how to treat the client.  Each of the variable names
       listed below is followed in parentheses by an indication of whether it's
       required or optional, plus an indication of  the  reference  application
       from  which  this variable use is derived.  For example, a note of "(re-
       quired, ucspi-tcp)" means that the environment  variable  is  mandatory,
       and that the use of this variable stems from precedent set by the ucspi-
       tcp utility.

       TCPLOCALHOST (required, ucspi-tcp)
              is the name of the local host.

       TCPLOCALIP (required, ucspi-tcp)
              is  the  IP  address  of the local system; i.e. the IP address on
              which the SMTP connection arrived.

       TCPREMOTEHOST (optional, ucspi-tcp)
              is the DNS name of the client system.

       TCPREMOTEIP (required, ucspi-tcp)
              is the IP address of the client.

       RELAYCLIENT (optional, qmail)
              if this variable is set, the client has (somehow) been  validated
              as  a host for whom it's OK to relay messages to unrelated desti-
              nations.  If this variable is not set, then the client is assumed
              to be a foreign system  unrelated to the  receiving  system,  and
              will  be  required to authenticate (using SMTP AUTH) before being
              allowed to relay such messages.  Use  of  this  variable  may  be
              phased out in the future (other than in qmail-smtpd compatibility
              mode).  Until that time, though, we simply support this value.
              Unlike stock qmail-smtpd, mvmtr does not append the value of this
              environment variable to all incoming addresses.

       SUPPRESS_AUTH (optional, mvmtr and mem's qmail patches)
              if this environment variable is present, mvmtr will not advertise
              the  SMTP  AUTH capability in response to EHLO greetings from the
              client.  This should only be used if RELAYCLIENT is also set, and
              is merely a workaround for some buggy clients  that  will  always
              attempt  to  do  SMTP  AUTH if that capability is advertised.  As
              with RELAYCLIENT, use of this variable is expected to be  removed
              when more explicit authorization controls are added.

       daemon mode

       There are no specific environment variables associated with this mode.

       generic variables

       This  section  lists variables that are may be relevant to any operating
       mode.

       MVMTR_RC (optional)
              specifies a startup file for mvmtr.  As with the -C command  line
              option,  the  startfile  must be found within the system-wide mfl
              include path.  This environment variable  (if  present  and  non-
              empty)  will  override  any  default startfile, but may itself be
              overridden by the -C command line option.

CONTROL FILES
       mvmtr reads some control files for instructions.

       startfile
              The startfile contains mfl code to affect the operation of mvmtr.
              By default this file is  /usr/local/sys/mvmf/mvmtr/mvmtr.mfl  but
              this  may  be  changed  during the installation process.  (It may
              also be overridden via an environment variable or a command  line
              option,  as  described  elsewhere  in  this document.)  This file
              should contain calls to built-in mfl functions to set mvmtr  con-
              trol values, as described in the CONTROL VALUES section later on.
              This file may also define mfl "hook" functions that may be called
              by  mvmtr  at various points in its execution.  The possible hook
              functions are described in a later section called HOOKS

       address map file
              The address map file provides a database of known email addresses
              and address patterns.  It may be consulted via one of the  checks
              that  is  done at (or after) RCPT TO commands in the SMTP dialog.
              This is an indexed file using D. J. Bernstein's constant database
              file format (cdb).  It is  typically  named  addrmap.cdb  in  the
              mvmtr  system  directory  (e.g.   /usr/local/sys/mvmf/mvmtr/) but
              this may be changed during the installation process.  Each  entry
              in this file has an address key and a map value.

              Please  note that this file and the format of its keys and values
              are still subject to change while this utility is  evolving.   It
              may  also  be removed entirely since its functionality can easily
              be provided via an mfl hook (e.g., $hook_rcpt_to).  On the  other
              hand, interesting ideas and suggestions are welcome!

              Keys have the following formats:

              user@domain --
                     matches an email address exactly.

              user*@domain --
                     matches  any  email  address with the specific domain name
                     where the local part begins with the the string "user".

              domain --
                     matches any email address in the specified domain name.

              .domain --
                     matches any email address in any subdomain of  the  speci-
                     fied domain name.

              When  mvmtr  looks up an incoming email address in this database,
              it finds the most exact match that  it  can.   When  it  finds  a
              match, it returns a result depending on the map value that corre-
              sponds to the entry.  The result values are analagous to the mail
              disposition  values described elsewhere in this document, and are
              as follows:

              accept --
                     this address is valid and will be accepted (subject to any
                     further test that mvmtr performs).

              deny --
                     this address is known to be invalid and will be rejected.

              defer --
                     this address is probably valid, but not for this  particu-
                     lar  server.  (This corresponds to the "known" mail dispo-
                     sition value.)  mvmtr will only accept this address if the
                     client is allowed to relay (e.g. the client has AUTHed  or
                     has otherwise has relay permission).  Otherwise it returns
                     a  "known"  result, which is likely to produce a temporary
                     deferral SMTP dialog result, causing the sending system to
                     retry at some later time.  A value of defer may be used on
                     any server that's not the primary MX destination for  that
                     address.   Deferring  acceptance of addresses on backup MX
                     servers is way to politely refuse email, and can help turn
                     away connections from malware that tries to send to backup
                     MX servers only.

              pass --
                     this address will be accepted, and it may also be eligible
                     for a pass from some of the other checks  (connect,  helo,
                     etc),  if that check is configured to test for a pass (see
                     the description of various check controls).

              The source for the address map file is typically maintained in  a
              text  file,  with  each line containing the email address key and
              the map value separated by a colon.  You can then use the  cdbgen
              utility  that's  included  with  the mvmf kit to generate the cdb
              file from that source.  Consider  this  source  file  named  "ad-
              drmap":

                  .example.net:deny
                  example.net:deny
                  mark@example.net:accept
                  mem@example.org:defer
                  example.org:deny
                  .example.org:deny

              An  address of "mark@example.net" will be accepted; an address of
              "mem@example.org" will be accepted only if it's OK to accept sub-
              missions from (i.e. relay for) the client; any other addresses in
              "example.net" and "example.org" and any of their subdomains  will
              be  rejected.  Any other address (i.e., anything not mentioned in
              the address map file) are unknown and will only be accepted on  a
              submission basis.

              This may be compiled into "addrmap.cdb" by issuing shell commands
              such as:

                   cdbgen -o addrmap.tmp addrmap
                   if [ -s addrmap.tmp ] ; then
                       ln -f addrmap.cdb addrmap.cdb-;
                       chmod a+r addrmap.tmp;
                       mv -f addrmap.tmp addrmap.cdb;
                   fi

              It's important to know a couple more things about how mvmtr looks
              up  wildcard  local  names  in  the  address  map file.  Checking
              against wildcards in this file has to be  done  iteratively.   In
              many environments, wildcards are only relevant when they follow a
              particular  separator  character  such  as  a  hyphen (e.g., user
              "mark" might be able to have any address  "mark-*"  but  may  not
              have any address "mark*"), so mvmtr may be compiled and installed
              so  that  it only checks for wildcards at particular points (such
              as after hyphens).  Also, mvmtr will never attempt to look up  an
              address  key where the local part is just "*".  If your intent is
              to have a key such as "*@example.com" you must use just the naked
              "example.com" instead.

CONTROL VALUES
       Various control values may be set by mfl code using the $control_  func-
       tions (see the mfl language documentation for more info on those).  Con-
       trol  values are typically set when the mvmtr program is started, by in-
       voking the $control_ functions directly in the  startfile.   Values  may
       also be adjusted as part of hook processing.

       Control  values  are  described below.  Each description begins with the
       name of the value and the type of the value (for example an integer or a
       string) and then follows with a brief description of the control.

       add_x_peer_info (integer) -- Whether to add an "X-Peer-Info"  header  on
       the message.  Default is 0.
       X-Peer-Info is an MV-centric header, most people probably won't want it.
       It  simply inserts the local and remote host information in a convenient
       format for downstream parsing.  (This will likely be phased out in favor
       of using a hook.)

       admin (integer) -- This is a control that is required by  MFL's  control
       system  itself.  It is set to 1, since it's expected that mvmtr is being
       run by an administrator.  Care must be taken (e.g. to  revoke  this)  if
       you want to invoke user-supplied scripts.

       data_directory  (string)  --  specifies  the data directory for some mfl
       functions.  Currently not really needed by mvmtr, but provided for mfl's
       sake.

       log_private_name (string) -- The name of a "private" logfile.   This  is
       not  relevant  to  mvmtr but the control has to exist for the benefit of
       low-level logging functions.  (Mentioned here only for completeness.)

       log_program_name (string) -- The name of the program  as  reported  when
       logging.  Default is mvmtr.

       mvmcas  (integer)  --  Whether or not to consult mvmcas, the mail client
       assessment server.  0 disables the use of mvmcas, 1 enables it.  Default
       is 0.
       Only available if mvmcas support has been configured into mvmtr at  com-
       pile time.

       mvmcas_host  (string) -- The name of the host where the mvmcas server is
       to be found.  May include an optional colon and port number.  Default is
       "localhost:nnnn" where nnnn is the default port number.
       Only available if mvmcas support has been configured into mvmtr at  com-
       pile time.

       pipe_allow (integer) -- whether mfl code is allowed to open a pipe.  Set
       to 1 by default, since mvmtr is expected to be run by an admin.

       prog_checkpassword  (string)  -- The path to the djb-style checkpassword
       program that is used by AUTH commands.  This may be one or  two  program
       paths  separated by spaces.  The first path is the checkpassword program
       to use.  The underlying checkpassword program may need to run as a priv-
       ileged program, and so the one specified here might actually be a  wrap-
       per  program  that  is only available to whatever uid/gid mvmtr runs as.
       The second path, if given, is to the program that the checkpassword pro-
       gram takes as an argument when  authentication  is  successful  (typical
       mvmtr use is /usr/bin/true or equivalent).

       qmail_smtpd_compatibility  (integer)  -- Whether to enable compatibility
       with qmail-smtpd's control files.  0 disables this compatibility, 1  en-
       ables  it;  default  is  1.  If this is enabled, the qmail-smtpd startup
       files in qmail's "control" directory are consulted and used in ways sim-
       ilar to qmail-smtpd.  Because this program is not  qmail-smtpd,  use  of
       the controls may not exactly mirror qmail-smtpd's use of them.  (See the
       QMAIL-COMPATIBILITY  notes  in  the  mvmtr  source area for discussion.)
       However, this setting will allow mvmtr to function as a drop-in replace-
       ment for a stock qmail-smtpd.
       Only available if qmail-smtpd compatibility  has  been  configured  into
       mvmtr at compile time.

       smtp_server_autoblock_enable  (integer)  --  Whether to honor autoblocks
       (e.g. from mvmcas).  Default is 1 (enabled).

       smtp_server_badcmd_max (integer) -- How many bad (unknown) SMTP commands
       to tolerate before closing the session.  Default is 3.

       smtp_server_badrcpt_delay (integer) -- Number of seconds to defer a  re-
       sponse after a bad RCPT-TO has been received.  This is an attempt to de-
       lay  bad senders, but probably shouldn't be used if an assessment server
       (e.g. mvmcas) is being consulted (as that will have a better,  long-term
       feedback process).  Default is 5 (seconds).

       smtp_server_badrcpt_max  (integer)  --  Maximum  number  of bad/deferred
       RCPT-TO addresses allowed in a session before we declare this a bad ses-
       sion.  If this maximum is reached,  further  RCPT-TO  commands  will  be
       given  a  negative  response, and the mail will be refused at DATA time.
       Or,  if  strict  SMTP  sessions  adherence  is  turned  off   (see   the
       smtp_server_strict_sessions control) the connection may be dropped imme-
       diately.  Default is 2.

       smtp_server_connect_check (string) -- A list of checks to perform when a
       connection  begins.   This  is an annotated checklist (see the ANNOTATED
       CHECKLIST section) that specifies the checks to perform, in  order.   An
       "accept" checklist result will cause the dialog to proceed as normal.  A
       "reject" checklist return will cause mvmtr to respond to the client with
       a  421  "go-away" greeting and then disconnect.  Any other checklist re-
       sult will cause the session to be dropped gracelessly (without notice).

       The default value of this control is NULL (no checks).

       smtp_server_greet_delay (integer) -- How many seconds  the  SMTP  server
       will  delay  after  receiving a connection from an unknown client before
       issuing the initial greeting.  If any commands are received prior to is-
       suing the greeting, the connection will be considered suspicious and the
       conversation will not be accepted.  (Legitimate SMTP clients  will  wait
       for  a  greeting  before  beginning  the SMTP dialog; malware often will
       not).  If the client has otherwise been identified as  a  local  client,
       this delay may be suppressed.  When you use a greeting delay, you should
       be  aware  of  the  negative effect that larger values will have on your
       (and the senders') throughput.  An intelligent assessment  server  (such
       as mvmcas) will be able to adjust this value dynamically on a per-sender
       basis.  Default is 5 (which is only somewhat effective).

       If  the use of an mvmcas server is enabled, information from that server
       will set the pre-greeting delay on a per-client basis.

       smtp_server_greet_delay_max (integer) -- The maximum smtp  server  greet
       delay, regardless of any other setting or input (e.g. from mvmcas).  De-
       fault is 60.

       smtp_server_greeting  (string)  -- Additional SMTP greeting text.  mvmtr
       will always emit a first standard line of greeting;  if  any  additional
       greeting  text  is supplied, it follows that standard first line, and is
       itself followed by another standard closing line.  mvmtr  adds  its  own
       text  around the additional greeting because RFC2821 requires a particu-
       lar format of the first line, and in order to deal with potential client
       problems many clients can not deal with a  multi-line  greeting  without
       particular  formatting in either the first or last line.  The additional
       greeting text may itself be multi-line.

       smtp_server_greylisting (integer) -- Whether to enable greylisting (0  =
       off, 1 or 2 = on).  Greylisting is accomplished by consulting an outside
       agent  (e.g.  mvmcas);  it  is  useful to disable greylisting for a good
       amount of time (days or weeks) in order to train the  greylisting  data-
       base.   The  greylisting  used  by mvmtr and mvmcas is a degenerate form
       that only pays attention to the IP address and not to the specific email
       addresses used.  Because mvmcas makes other assessments,  this  form  of
       greylisting has proven to be quite effective.

       When  greylisting  is  enabled  with  a value of 1, mvmtr will honor the
       smtp_server_strict_sessions control to decide whether to keep  the  ses-
       sion  open.   Enabling  with  a  value  of 2 will cause mvmtr to issue a
       greeting with a 421 code and exit immediately when greylisted.

       smtp_server_helo_check (string) -- A list of checks to  perform  when  a
       HELO/EHLO  command  has  been  received.  This is an annotated checklist
       (see the ANNOTATED CHECKLIST section) that specifies checks  to  perform
       in order.  An "accept" or "dunno" checklist result will cause a positive
       response  to  the command, and the dialog to continue; a "reject" result
       will cause the HELO name to be rejected with an appropriate SMTP  reply,
       and the dialog to continue; other results will function the same as "re-
       ject"  but  may  be  handled specially in future releases.  See also the
       controls smtp_server_strict_sessions and smtp_server_ss_helo.

       The default value of this control is "helo-syntax helo-hook helo-me".

       smtp_server_localip_host (string) -- The hostname  that  is  substituted
       for  any  bracketed IP address in a rcpt-to address, when the IP address
       is one that belongs to the local host (is on an "up"  interface  on  the
       local host).

       smtp_server_log_commands (integer) -- If non-zero, mvmtr will log all of
       the  commands received from the client.  This was originally a debugging
       instrument, but as of this writing most commands are logged  by  default
       anyway.

       smtp_server_mail_check  (string)  --  A list of checks to perform when a
       MAIL FROM command has been received.  This  is  an  annotated  checklist
       (see  the  ANNOTATED CHECKLIST section) that specifies checks to perform
       in order.  An "accept" or "dunno" checklist result will cause a positive
       response to the command, and the dialog to continue; a  "reject"  result
       will  cause  the  MAIL FROM name to be rejected with an appropriate SMTP
       reply, and the dialog to continue; other results will function the  same
       as  "reject"  but may be handled specially in future releases.  Also see
       the smtp_server_strict_sessions control.

       The default value of this control is "mail-hook".  A reasonable alterna-
       tive might be something like: "
       Pc,A:
       r0:mail-dns
       mail-hook
       "

       Note that the a null MAIL FROM address, i.e. <>, will always be accepted
       and is not subject to MAIL FROM checks.

       smtp_server_msgsize_max (integer) -- The maximum message size, in bytes,
       that we will accept, or zero for no limit.  By default this is zero; you
       should probably set it to something sane.

       smtp_server_rcpt_check (string) -- A list of checks to  perform  when  a
       RCPT  TO command has been received.  This is an annotated checklist (see
       the ANNOTATED CHECKLIST section) that specifies checks to perform in or-
       der.  An "accept" or "dunno" checklist result will cause a positive  re-
       sponse  to  the  command,  and the dialog to continue; a "reject" result
       will cause the MAIL FROM name to be rejected with a  reject  SMTP  reply
       (5xx),  and  the dialog to continue; a "known" (aka "defer") result will
       cause the MAIL FROM name to be given a deferral SMTP response (4xx), and
       the dialog to continue; other results will function the same as "reject"
       but may be handled specially in future releases.

       The default value of this control is "rcpt-hook".   It  is  likely  that
       you'll want to have something more elaborate instead.

       smtp_server_reply_[cccc]_[ssss] (string) --

       This  is  a  set  of  controls that provide some guidance about how SMTP
       replies are formatted for certain commands in certain  situations.   The
       actual  control names are formed by replacing [cccc] with the lowercased
       context name and by replacing [ssss] with a string representing the  re-
       ply  severity.  (The context name is usually the name of the command be-
       ing replied to.)

       Valid values for [cccc] are data (for "DATA" command), mail  (for  "MAIL
       FROM"  command),  and  rcpt (for "RCPT TO" command).  A special value of
       grt is used to tailor the initial greeting message when the  session  is
       rejected, in some circumstances.

       Valid  values for [ssss] are hard (for a 5xx return) and soft (for a 4xx
       return).

       The relevant control value is consulted whenever mvmtr  issues  an  SMTP
       reply that is a rejection and that uses the generic customizable format.
       See the CUSTOMIZABLE REJECTION REPLIES section for a bit of a discussion
       about how these are used.

       smtp_server_ss_helo     (integer)     --    An    override    for    the
       smtp_server_strict_sessions control for the HELO command.  If set to -1,
       HELO processing will adhere to the smtp_server_strict_sessions  control.
       Otherwise  this control's value will apply to HELO processing.  Often it
       is practical to drop the connection after identifying a bad HELO, rather
       than continuing until the client quits as per RFCs.  Default is -1.

       smtp_server_strict_sessions (integer) -- Enable or disable  strict  SMTP
       session  adherence.   When  enabled, once a client has been greeted, the
       sessions will not be terminated until the client ends (via QUIT or  dis-
       connect).   This is required by RFCs but is one of the many requirements
       that is often set aside due to today's  pragmatism.   Some  controls  or
       other  parameters  might terminate a session when this is disabled; when
       it is enabled, the effect of those controls will  be  delayed  appropri-
       ately.  Default is 1.

       smtp_server_timeout (integer) -- General smtpd server timeout.  The max-
       imum time, in seconds, to wait for data from the client for general com-
       mand  states  (i.e.,  not  covered  by another timeout).  Default is 300
       (seconds).

       smtp_server_timeout_helo (integer) -- How many seconds the  SMTP  server
       will  wait for a HELO or EHLO command after issuing a greeting.  If this
       number of seconds elapses before the HELO/EHLO is received, the  connec-
       tion will be closed.  Default is 30 (seconds).

CHECKS
       mvmtr supports a number of built-in checks that may be initiated at var-
       ious  times  in the smtp dialog.  The checks may be specified as part of
       an annotated checklist (see that section), or they may be  invoked  from
       an MFL hook (see the section on hooks).  Each check has a name, reflect-
       ing  what  it does, and it makes a decision about what to do with a par-
       ticular SMTP dialog element or parameter.  All  checks  are  defined  to
       take  an  optional  argument, however most checks are self-contained and
       ignore (do nothing with) any argument given to them.

       Each check returns a mail disposition value as described  in  the  HOOKS
       section  (should  probably  be  described elsewhere).  Typically a check
       will return either "accept" or "reject" (with the obvious meanings);  in
       some  contexts some other returns may be valid.  A check may also return
       "dunno" to make no judgment.  In the descriptions below, some checks are
       described as "passing" or "failing" -- "pass" generally means  returning
       "accept" or "dunno" and "fail" generally means returning a "reject".

       Each  check,  when  returning  a  non-pass  result (neither "accept" nor
       "dunno"), will also "suggest" a score.  This is a numerical  value  that
       can  be used in (say) accumulating a total before deciding to give up on
       the client.  The suggested score can be overridden in various ways  (via
       an  annotation  in  an annotated checklist, or by MFL code which invokes
       the check).

       Checks are:

       client-generic -- Tests whether the client is judged to be  coming  from
       generic  IP  space.   (See  the  discussion near the presentation of the
       $hook_generic_ip hook for more.)  Any optional argument is ignored.

       client-hook -- Attempts to invokes the MFL $hook_client function,  which
       can  be  supplied by the administrator.  See the HOOKS section for a de-
       scription of how this function is called.  Any optional argument will be
       taken as an alternative name for this hook.

       helo-dns -- Passes if the HELO name resolves to an A entry in  the  DNS;
       fails otherwise.

       helo-dnsclient  -- Passes if the HELO name resolves to an A entry in the
       DNS which matches the IP address of the connecting client; fails  other-
       wise.

       helo-generic -- Tests whether the HELO name is judged to indicate a name
       associated  with  generic  IP space, taking the client's IP address into
       account as well.  (See the  discussion  near  the  presentation  of  the
       $hook_generic_ip hook for more.)

       helo-hook  --  Invokes  the  MFL hook $hook_helo if it has been defined.
       See the HOOKS section for more info on this and other  hooks.   Any  op-
       tional argument will be taken as an alternative name for this hook.

       helo-me  --  Looks at the HELO name to see if it is an invalid imperson-
       ation of the receiving server (i.e., me).  This  is  not  an  exhaustive
       look,  but  it  will catch HELO names that look like one of the local IP
       addresses (without the required square brackets).

       helo-syntax -- Does a strict syntax check on the HELO name.  This  is  a
       syntax check only, making sure that the HELO name contains valid charac-
       ters put together in valid ways.  This test is highly recommended.

       mail-dns  -- Passes if the domain name in the MAIL FROM address resolves
       to an A or MX record; fails otherwise.  Note that failure only occurs on
       a definitive DNS response indicating lack of DNS record(s);  soft  fail-
       ures will not cause rejection.

       mail-hook  --  Invokes  the  MFL hook $hook_mail_from if it has been de-
       fined.  See the HOOKS section for more info on  this  and  other  hooks.
       Any  optional  argument  will  be  taken as an alternative name for this
       hook.

       mail-qmail -- Checks the MAIL FROM address  in  a  way  compatible  with
       qmail's  check,  e.g.  its badmailfrom check, as described in the QMAIL-
       COMPATIBILITY notes provided with the mvmtr source kit.

       rcpt-addrmap -- Consults the address map file for this RCPT TO  address.
       The address map handling is described elsewhere in this manpage.

       rcpt-hook  -- Invokes the MFL hook $hook_rcpt_to if it has been defined.
       See the HOOKS section for more info on this and other  hooks.   Any  op-
       tional argument will be taken as an alternative name for this hook.

       rcpt-qmail  --  Checks  the  RCPT  TO  address  in a way compatible with
       qmail's check, e.g. its rcpthosts and morercpthosts check, as  described
       in the QMAIL-COMPATIBILITY notes provided with the mvmtr source kit.

       Beware  that  many strict HELO checks are infeasible as of this writing,
       since there are so many poorly  configured  email  clients  out  in  the
       world.

ANNOTATED CHECKLISTS
       An annotated checklist is simply a string that is a list of named checks
       to  be  done,  along with (you guessed it) some annotations that help to
       control the interpretation and flow of the checks.  Annotated checklists
       are specified via certain string controls that are referred to  at  cer-
       tain  points  in the SMTP dialog.  (All of these controls and where they
       are referenced have been described above.)

       This facility provides a middle ground between having every  operational
       decision hard-coded in the mvmtr program and having you (the administra-
       tor)  write  these decisions in terms of MFL hooks.  80% (or so) of what
       most everyone might want in an SMTP server  ought  to  be  provided  via
       built-in facilities, but you might want have some degree of control over
       them.   The  other 20% may vary widely from administrator to administra-
       tor, and these are the things that are better done through external  MFL
       code.

       The  annotated  checklist is simply a list of annotated checks separated
       by whitespace (spaces, tabs, newlines).  Each  annotated  check  is  the
       name  of check (as described in the CHECKS section), optionally preceded
       by a set of annotations and a colon, and optionally followed by a  colon
       and a tail part.  The tail part (if given) is used as an argument to the
       check (but most checks don't take arguments).  The set of annotations is
       a  comma- or slash- separated list of character notes, each of which may
       have an argument.  The check name may be left blank, in order to process
       annotations only.

       Each check is performed in turn, ignoring "accept" results, until one of
       them returns a hard result (neither a  "soft"  return  nor  a  "dunno").
       "Accept" results are ignored so that subsequent checks can be processed,
       as  that's  usually what's wanted; however, the 'y' note (see below) can
       be used to force an "accept" to be taken.  When a hard result is  given,
       the  checklist  processing  stops  and  this return is the result of the
       checklist.  (Some annotations may cause hard returns to be ignored).  If
       the list ends before a hard result is obtained, any soft result will  be
       turned  into a hard result and that will be returned.  Otherwise the en-
       tire list returns "dunno."

       These are the note characters that can be used in a set of annotations:

       # -- skip this check.  This provides a way of commenting out a check.

       A -- skip all remaining checks if client is authenticated.

       a -- skip this check if client is authenticated.

       I -- skip all remaining checks if client is allowed to relay  (i.e.,  is
       considered "internal).

       i -- skip this check if the client is allowed to relay.

       P[t..]  --  skip all remaining checks if there is a pass of type t.  The
       pass types are 'c' for client (client has a pass, e.g. from mvmcas), and
       'r' for recipient (recipient has a pass, e.g. from addrmap).

       p[t..] -- skip this check if there is a pass of type 't'.  Types are the
       same as for the 'P' note character.

       r[nn] -- any "reject" return, instead of being  used  outright,  accumu-
       lates  a score.  The 'r' may be followed by a score value, otherwise the
       check's suggested score will be used.  A value of 0 makes  this  a  soft
       check.   If  there  is  no 'r' annotation, a reject value return will be
       used absolutely.

       s -- set the maximum score value.  If the  cumulative  score  gets  this
       high  or higher, stop processing the namelist and return a reject.  This
       value is sticky across the rest  of  the  namelist  (and  may  later  be
       changed via another

       y  --  any yes ("accept") return is a hard accept: the namelist ends and
       the accept is returned.  Otherwise, the accept return is  advisory  only
       and is treated as a "dunno".

       Consider this setting for the "smtp_server_rcpt_check" control:

       @define RCPT_CHECKS "
       Prc,a:mail-dns
       y:rcpt-addrmap
       rcpt-hook
       "
       $control_string_set( "smtp_server_rcpt_check", RCPT_CHECKS );

       This says that whenever an RCPT TO command is taken, the MAIL FROM argu-
       ment that was collected earlier will be tested for legitimate DNS unless
       either the recipient or the client has a pass or the client has been au-
       thenticated;  the RCPT TO address will be tested via the address map and
       an "accept" from the address map is considered absolute.   The  RCPT  TO
       address is potentially tested via any $hook_rcpt_to MFL hook.

CUSTOMIZABLE REJECTION REPLIES
       For some SMTP commands where deliveries or transactions can be rejected,
       mvmtr  uses a standard reply format for such rejections that can be cus-
       tomized via  certain  control  values,  as  described  earlier  for  the
       smtp_server_reply_[cccc]_[ssss]  controls.   As mentioned there, the af-
       fected SMTP commands are "DATA", "MAIL  FROM",  and  "RCPT  TO".   While
       these  replies aren't completely customizable, this mechanism provides a
       way to tailor them somewhat.  (Later versions of mvmtr may indeed  carry
       this further).

       The  standard  rejection  message format approximately follows this tem-
       plate:

           nnn [brief] [extended] [built-in]

       where

       "nnn"  is the standard SMTP reply code that begins the  line;  this  may
              include a continuation indicator and/or an extended reply code.

       "brief"
              is a brief explanation of the rejection, provided by mvmtr.  This
              brief  string is only output if there is an extended string or if
              there is no built-in string.

       "extended"
              is optional extended reply information dictated by  the  contents
              of  the  relevant  control (i.e., the appropriate smtp_server_re-
              ply_[cccc]_[ssss] control).  This control value may be encoded to
              include certain variable information; see below.

       "built-in"
              is any detailed message provided internally by mvmtr.

       To find the optional extended reply string, an appropriate control value
       is consulted.  As detailed earlier, the name  of  the  control  is  con-
       structed  according to the template smtp_server_reply_[cccc]_[ssss] with
       [cccc] being replaced with a string representing the  SMTP  command  in-
       volved, and [ssss] replaced by a string representing the severity of the
       rejection  (either "hard" or "soft").  The value of this control is then
       used as the optional extended reply component.  (A blank string value is
       treated the same as a missing value.)

       When supplied, the value is subject to interpretation.  The  value  must
       start  with zero or more flag characters, ending with a comma.  There is
       only one defined flag character at present: 'l' (the letter 'l'),  which
       will  cause the extended reply string to be followed by a line-item list
       of the keywords and detail text for each rejection reason that has  been
       given for the rejection.  (These keyword/text pairs are provided via the
       mechanism of "RISET"s, aka result/reply information sets; see the RISETs
       section.)  The text following the comma is then given as part of the re-
       ply, with some interpretation.  Two-character sequences beginning with a
       percent sign are given special treatment:

       %%     results in a single percent-sign;

       %k     will  be  replaced by a list of the keywords associated with each
              reason that has been accumulated for this  rejection.   The  list
              will be comma-separated.  This is intended to be suitable for in-
              terpretation by a web page or by a human who might be receiving a
              report of this message.

       %i     is  replaced  by the IP address of the client.  This is likely to
              be useful when a sender reports an error sending mail.

       Let's say, for example, that a series of checks is done at the time  the
       "RCPT  TO"  command  is processed, and that the command is hard-rejected
       for two reasons:  there is no DNS  record  associated  with  the  domain
       given  in  the "MAIL FROM" command (and thus the mail can not be replied
       to), and the IP address has been listed on a  DNSBL  called  the  "xyz".
       The  relevant  control  for  the  extended  part  of  this  response  is
       smtp_server_reply_rcpt_hard.  If it is defined like this  (i.e.  in  the
       mvmtr.mfl startup file):

           $control_string_set( "smtp_server_reply_rcpt_hard",
               "l,ip=%i reason[s]=%k" );

       then the client, connecting from IP address 10.0.1.2, would likely see a
       reply similar to this:

           550-Recipient rejected -- ip=10.0.1.2 reason[s]=mail-dns,xyz
           550-   mail-dns -- MAIL FROM name has no DNS record
           550    xyz -- Your IP address is on the xyz DNSBL

       The first line is enough for a human at the receiving site to interpret.
       Instead  of  simply  a  "reason[s]" string, this might be a pointer to a
       website that is capable of explaining the rejection  and  perhaps  doing
       something about it.

RISETs
       A  lot  of  the decisions that mvmtr makes are the result of a number of
       inputs.  This is clear from the discussions of annotated checklists  and
       from  descriptions  of  some  of mvmtr's processes.  This gives a lot of
       flexibility to the decision making, but also creates  some  problems  in
       regards to what to say about those decisions.  mvmtr addresses this with
       the  option of associating a set of information with each of the factors
       that contribute to a decision.  Each is known as  reply/result  informa-
       tion,  or  just  RI, and the set of these RI going into a decision is an
       RISET.

       Each RI can be either for logging or for replying  to  the  client,  and
       there  will  usually be both kinds present in an RISET.  Once a decision
       is acted on (e.g., an SMTP command has completed), the log items  in  an
       RISET  may  be  discarded or they may be sent to the log.  Similarly the
       reply items may be used in the SMTP reply to the client (see the section
       on CUSTOMIZABLE REJECTION REPLIES) or ignored.

       Each RI consists of at least the following:

       keyword
              This is a short string that can be used to uniquely identify  the
              contributing  reason.   When  logged,  it  is  enclosed in square
              brackets for easy analysis.  When given as part of  a  reply,  it
              can  be  used  as part of a keyword string (e.g. to give to a web
              URL), and it can also be used as part of a line-item list of rea-
              sons.

       disposition
              Used mainly (exclusively?) for logging, this is a code that indi-
              cates the nature of the input.  Typically it  is  either  a  plus
              sign  (for  acceptance)  or  a minus sign (for rejection) but can
              also be a "?nn" sequence which represents a contribution of nn to
              a score.  This disposition can be adjusted while the RI is queued
              and before it is used, e.g. if a rejection is changed to a score.

       detail This is any detail text associated with the RI.  It is used  both
              in  logging and in presenting a line-item list of reasons as part
              of an SMTP reply.

HOOKS
       At certain points in its execution, mvmtr may invoke  specifically-named
       mfl  functions  in  order to give user or admin options at these control
       points.  In most cases, the hook function is  invoked  via  one  of  the
       checks   in   an  annotated  checklist  --  e.g.,  you  may  define  the
       "smtp_server_mail_check" control to include the "mail-hook"  check,  and
       this will likely result in calling the "$hook_mail_from" hook as part of
       running checks at MAIL FROM time.

       In a small number of other cases, the hook is simply called at a defined
       point  in  mvmtr's execution if the appropriately-named MFL function ex-
       ists (i.e., if you have defined it in the startup file or if it  can  be
       found in the hook search path).

   Mail Disposition Values
       Some hook functions deal with a mail disposition value (also known as an
       acceptance  value).   This  is a string, one of the following (most have
       fairly obvious meanings):

       dunno -- no decision.

       accept -- accept.

       reject -- reject.

       pass -- accept, and also exempt the sender from some checks.

       known -- address is known, but  neither  accepted  nor  rejected.   This
       value is sometimes interpreted as a deferral request.

       unknown -- address is unknown (probably foreign).

       error -- some error has occured.

       Often, the mail disposition value can be preceded with a tilde character
       (~)  to  indicate  a  tentative  decision that can be overridden by some
       later step that chooses to.

   hook dialog reply
       Many hooks are documented as returning a  "dialog  reply".   This  means
       that  the  function  should  be  defined  as returning a string, and the
       string that is returned should match this form:

              mdv[:keyword[:detail]]

       Here, mdv is a mail disposition value, as  previously  discussed.   key-
       word,  if  given, is a keyword to associate with this reply, and detail,
       if given, is a line of text that gives more detail about  that  keyword.
       In  most (all?) cases, the keyword and detail elements are only relevant
       for rejections.

       If keyword is given without detail, the keyword is added as a  log  item
       to the current result information set (RISET) with some default text.

       If keyword and detail are both provided, they are added as both log item
       and return item to the current result information set.

   Hooks
       The hooks are:

       $hook_client
              is  called via the "client-hook" check function (e.g. in an anno-
              tated checklist) to make a judgement about the connecting client.
              This hook is defined as

                  string $hook_client( string mdv, string ip ) { ... };

              mdv is any mail disposition value already determined  (which  the
              hook  can  choose to take into account).  ip is the stringized IP
              address (a.b.c.d) to check.  This may be  passed  as  0.0.0.0  or
              255.255.255.255 if unknown.
              This function is expected to return a dialog return string, typi-
              cally one of "dunno", "accept", or "reject".

       An example:

           string $hook_client( string mdv, string ip ) {

            // Reject if it appears on some DNSBL.  Better is to score
            //  multiple DNSBLs, as you might find in some examples
            //  outside this man page.
            if ( sieve { dnsbl :ip [ip] "spamcop" "std" } )
                return ( "reject:spamcop" );

            return ( mdv );
           };

       $hook_data
              is  called  after  mvmtr receives an SMTP "DATA" command from the
              client.  This hook is defined as

                  string $hook_data( string mdv ) { ... };

              mdv is any mail disposition value already determined  (which  the
              hook can choose to take into account).  This function is expected
              to  return  a  dialog return string.  The only legitimate mdv re-
              turns are "dunno", "accept", and "reject".

       An example:

           string $hook_data( string mdv ) {
            if ( sieve { not exists "To" } )
                return ( "reject:no-to" );     // We reject mail without "to"

            // Send the message through clamav.  Assumes that the cusp
            //  has been defined, and that string variables s and *sP
            //  and constant NULL have been declared.
            s = $cuspu_message( "clamdif" );
            if ( s != "" ) {
                sP = $str_find_token_delimited( s, "", " " );
                sP = $str_find_token_delimited( s, "", " " );
                if ( sP != NULL )
                 return ( (string)"reject:clamav:detected " + *sP );
            }

            return ( mdv );
           };

       $hook_generic_ip
              may be called to help  determine  whether  an  IP  address  looks
              generically assigned.  This hook is defined as

                  string $hook_generic_ip( string mdv, string ip, string hname ) { ... };

              mdv  is  any mail disposition value already determined (which the
              hook can choose to take into account).  ip is the  stringized  IP
              address  (a.b.c.d)  to  check.   This may be passed as 0.0.0.0 or
              255.255.255.255 if unknown.  hname is the hostname to check.   In
              some  cases  this  function  might  be called several times for a
              given IP address, e.g. if there are multiple PTR records for  the
              IP address.

              This  function is expected to return a dialog return string.  The
              only legitimate mdv returns are "dunno", "accept", "reject",  and
              "pass".

       An example:

           string $hook_generic_ip( string mdv, string ip, string hname ) {
            // Override any bad judgement about this IP
            if ( ip == "127.0.0.1" )
                return ( "accept" );

            // Cancel any bad judgement about names containing ".staticip."
            if ( hname =?^ "*.staticip.*" )
                return ( "dunno" );

            // Accept the already-determined disposition
            return ( mdv );
           };

       Before  calling  this  hook,  mvmtr  makes  an internal assessment about
       whether the IP address looks generic.  It makes this assessment based on
       whether the reverse DNS name(s) seem to declare the IP address as  being
       generically assigned.  Primarily, it checks to see whether the name con-
       tains  3 or 4 of the adjacent IP address octets in decimal or hex repre-
       sentation, separated by zero or more other characters, either in forward
       or reverse order.  If this sort of pattern is  found,  it  then  applies
       some  tests  to  try to disprove the assessment by looking for a few key
       strings (such as "static") that will not ordinarily  appear  in  generi-
       cally assigned names.

       Note  that this initial assessment may be overly broad for most environ-
       ments.  This hook may be used to further  disprove  a  positive  initial
       judgement.   The hook can also completely disregard the initial internal
       assessment and make one of its own, etc.

       Note also that if an IP address has multiple reverse names in  the  DNS,
       each  name  is  tested until one is declared not to be generic (or until
       all names have been tested).  This means that a  non-generic  assessment
       always wins.

       $hook_helo
              is  called  via the "helo-hook" check (e.g. appearing in an anno-
              tated checklist), in order  to  make  some  judgement  about  the
              HELO/EHLO  name that the client has given to mvmtr.  This hook is
              defined as

                  string $hook_helo( string mdv, string heloname ) { ... };

              mdv is any mail disposition value already determined  (which  the
              hook  can  choose  to  take  into account).  heloname is the helo
              string given in the "HELO" command.  This function is  expect  to
              return  a  dialog return string.  The only legitimate mdv returns
              are "dunno", "accept", and "reject".

       An example:

           string $hook_helo( string mdv, string heloname ) {
               if ( heloname ==^ "friend" )
                return ( (string)"reject:spamsign:
       HELO (" + heloname + ") is a spam sign." );

            if ( $cdbu_get_string( "bad-helo.cdb", heloname ) != 0 )
                return ( "reject:bad-helo.cdb" );

            return ( mdv );
           };

       $hook_mail_from
              is called via the "mail-hook" check (e.g. appearing in  an  anno-
              tated  checklist),  in order to make some judgement about the ad-
              dress that the client has given to mvmtr in the  MAIL  FROM  com-
              mand.  This hook is defined as

                  string $hook_mail_from( string mdv, string rpath ) { ... };

              mdv  is  any mail disposition value already determined (which the
              hook can choose to take into account).  rpath is  the  email  ad-
              dress given in the "MAIL FROM" command.

       Some  firm decisions made by this hook may still be overridden.  For ex-
       ample, this hook may not refuse a null MAIL FROM address.  This function
       is expect to return a dialog return string.  The only legitimate mdv re-
       turns are "dunno", "accept", and "reject".

       An example:

           string $hook_mail_from( string mdv, string rpath ) {
               if ( rpath =?^ "*@optinrealbig.com" ) {
                   return ( "reject:blocked:sender domain is blocked" );
            return ( mdv );
           };

       $hook_rcpt_to
              is called via the "rcpt-hook" check (e.g. appearing in  an  anno-
              tated  checklist), in order to make some judgement about the lat-
              est address that the client has given to mvmtr  in  the  RCPT  TO
              command.  This hook is defined as

                  string $hook_rcpt_to( string mdv, string addr ) { ... };

              mdv is any already-determined mail disposition value value.  addr
              is  the email address given in the "RCPT TO" command.  This func-
              tion is expect to return a dialog return string.  The only legit-
              imate mdv returns  are  "dunno",  "accept",  and  "reject".   The
              "known" disposition value will be interpreted as a request to de-
              fer  the  RCPT  TO; "unknown" indicates a relay attempt that will
              only be honored if the client is OKed for relaying.

       An example:

           string $hook_rcpt_to( string mdv, string addr ) {
               if ( addr =?^ "nobody@*" ) {
                   return ( "reject:silly" );
            return ( mdv );
           };

       Your $hook_rcpt_to hook should be sure to accept the naked  "postmaster"
       address,  per RFC2821, unless you specifically want to violate that rule
       on your own say-so.  Internally, mvmtr will accept "postmaster"  if  the
       hook  hasn't  made a decision; other policy hooks (such as deferred HELO
       name checks, etc) may still be able to override this decision.  In  this
       hook  you  might  also  want  to  make  note  of  certain addresses that
       shouldn't be subject to later filtering.

BUILT-IN MFL FUNCTIONS
       mvmtr defines a number of built-in functions for use by MFL  code  (e.g.
       in for use in hooks).  These are described in this section.

       $mvmtr_log
              Writes an entry to the mvmtr log.  Each log entry has a number of
              components,  including  a category (with disposition), a keyword,
              and some detail text.  The category string represents the general
              area of thing being logged, e.g. "RCPT" along with some  disposi-
              tion  indication  such  as a "+" for acceptance or "-" for rejec-
              tion.  Ordinarily the category and disposition are separate,  but
              for this function they are combined for simplicity.

              The function is defined as

                  BOOL $mvmtr_log( string cat, string keyword, string detail )

              and might be used like this:

                  $mvmtr_log( "INFO", "startup", "mvmtr starting up" );

       $smtpd_riset_add
              Adds  an  RI  to  the current RISET (see the RISET section).  The
              function is defined:

                  BOOL $smtpd_riset_add( string type, string cat, string catdisp,
                                 string kwd, string detail)

              type is the RI type, either "log" or "reply".   cat  is  the  log
              category  string for use with "log" type RIs.  This may be passed
              as blank to use an appropriate default.  catdisp is a disposition
              string somewhat indicative of the action taken; this is often "-"
              or "+".  kwd is the RI keyword, and detail is the RI detail.

              For an example, let's say you have a client-hook that  is  called
              at  RCPT-TO  time  and  it checks to see if the client address is
              listed on a mythical DNSBL which we'll call the "zbl".  It  might
              contain this fragment:

                  if ( $dns_query( $ip_rev(ip) + ".zbl.example.org", "a" ) != 0 ) {
                   $smtpd_riset_add( "reply", "", "", "zbl", "Your IP address is on the zbl" );
                   $smtpd_riset_add( "log", "", "-", "zbl", "IP is on the ZBL" );
                   return ( "reject" );
                  }

       $smtpd_score1_set
              This  sets the "score1" value.  Each check that contributes to an
              annotated namelist set can  declare  a  score  value,  which  the
              namelist  processing  can take into account.  This score value is
              called the "score1" value since it is associated with that single
              check and not with the entire namelist.  If you have an MFL  hook
              that is returning a reject, you might want to have it declare the
              score1 value.  This function is defined as:

                  BOOL $smtpd_score1_set( int value )

              where value is the value to set.

FILES
       /usr/local/sys/mvmf/mvmtr/mvmtr.mfl is the default startfile.
       /usr/local/sys/mvmf/mvmtr/addrmap.cdb is the address map file.

SEE ALSO
       mfl -- the mfl language description.
       http://www.mvmf.org/ -- the official web site.

CREDITS TO
       M. Mallett  (mem@mvmf.org)    2003-2007,2023-2025

BUGS
       You tell me..

                                                                       MVMTR(1)