@c This file is part of the Mailfromd manual.
@c Copyright (C) 2007--2025 Sergey Poznyakoff
@c See file mailfromd.texi for copying conditions.
@c *******************************************************************
@pindex mtasim
  The @command{mtasim} utility is a @acronym{MTA} simulator for testing
@command{mailfromd} filter scripts.  By default it operates in
@dfn{stdio} mode, similar to that of @command{sendmail -bs}.  In this
mode it reads @acronym{SMTP} commands from standard input and sends
its responses to the standard output.  There is also another mode,
called @dfn{daemon}, where @command{mtasim} opens a @acronym{TCP}
socket and listens on it much like any @acronym{MTA} does.  In both
modes no actual delivery is performed, the tool only simulates the
actions an @acronym{MTA} would do and responses it would give.

  This tool is derived from the program @command{mta}, which I wrote
for GNU Anubis test suite.

@menu
* interactive mode::
* expect commands::
* traces::
* daemon mode::
* command summary::
* option summary::
@end menu

@node interactive mode
@section @command{mtasim} interactive mode mode

  If you start @command{mtasim} without options, you will see the
following:

@example
@group
220 mtasim (mailfromd @value{VERSION}) ready
(mtasim) _
@end group
@end example

@cindex readline
@cindex GNU Readline
  The first line is an usual @acronym{RFC} 2821 reply.  The second one is
a prompt, indicating that @command{mtasim} is in interactive mode and
ready for input.  The prompt appears only if the package is compiled
with GNU Readline and @command{mtasim} determines that its standard
input is connected to the terminal.  This is called @dfn{interactive
mode} and is intended to save the human user some typing by offering
line editing and history facilities (@pxref{Command Line Editing, ,
Command Line Editing, readline, GNU Readline Library}).  If the package
is compiled without GNU Readline, you will see:

@example
@group
220 mtasim (mailfromd @value{VERSION}) ready
_
@end group
@end example

@noindent
where @samp{_} represents the cursor.  Whatever the mode,
@command{mtasim} will wait for further input.

@cindex @code{HELP}, @command{mtasim} statement
  The input is expected to consist of valid @acronym{SMTP} commands
and special @command{mtasim} statements.  The utility will act exactly
like a @acronym{RFC} 2821-compliant @acronym{MTA}, except that it will
not do actual message delivery or relaying.  Try typing @code{HELP} to
get the list of supported commands.  You will see something similar
to:

@example
250-mtasim (mailfromd @value{VERSION}); supported SMTP commands:
250- EHLO
250- HELO
250- MAIL
250- RCPT
250- DATA
250- HELP
250- QUIT
250- HELP
250  RSET
@end example

 You can try a simple @acronym{SMTP} session now:

@example
220 mtasim (mailfromd @value{VERSION}) ready
(mtasim) @kbd{ehlo localhost}
250-pleased to meet you
250 HELP
(mtasim) @kbd{mail from: <me@@localhost>}
250 Sender OK
(mtasim) @kbd{rcpt to: <him@@domain>}
250 Recipient OK
(mtasim) @kbd{data}
354 Enter mail, end with `.' on a line by itself
(mtasim) @kbd{.}
250 Mail accepted for delivery
(mtasim) @kbd{quit}
221 Done
@end example

  Notice, that @command{mtasim} does no domain checking, so such thing
as @samp{rcpt to: <him@@domain>} was eaten without complaints.

@anchor{mtasim milter port}
@mtasimopt{port, described}
  So far so good, but what all this has to do with
@command{mailfromd}?  Well, that's what we are going to explain.  To
make @command{mtasim} consult any milter, use @option{--port}
(@option{-X}) command line option.  This option takes a single
argument that specifies the milter port to use.  The port can be given
either in the usual Milter format (@xref{milter port specification},
for a short description), or as a full @file{sendmail.cf} style
@code{X} command, in which case it allows to set timeouts as well:

@example
$ @kbd{mtasim --port=inet:999@@localhost}
# @r{This is also valid}:
$ @kbd{mtasim --port='mailfrom, S=inet:999@@localhost, F=T, T=C:100m;R:180s'}
@end example

  If the milter is actually listening on this port, @command{mtasim}
will connect to it and you will get the following initial prompt:

@example
@group
220-mtasim (mailfromd @value{VERSION}) ready
220 Connected to milter inet://localhost:999
(mtasim)
@end group
@end example

  Notice, that it makes no difference what implementation is listening
on that port, it may well be some other filter, not necessarily
@command{mailfromd}. 

@cindex @command{mtasim} auto mode
  However, let's return to @command{mailfromd}.  If you do not want to
connect to an existing @command{mailfromd} instance, but prefer
instead to create a new one and run your tests with it (a preferred
way, if you already have a stable filter running but wish to test a
new script without disturbing it), use @option{--port=auto}.  This
option instructs @command{mtasim} to do the following:

@enumerate 1
@item Create a unique temporary directory in @file{/tmp}.
@item Start a new instance of @command{mailfromd}.  This instance is
configured to communicate over a UNIX socket in that temporary
directory.  Additional arguments and options for the new instance may
be given in the command line after a double-dash marker (@samp{--}).
@item Connect to that filter.
@end enumerate

  When @command{mtasim} exits, it terminates the subsidiary
@command{mailfromd} process and removes the temporary directory it has
created.  For example, the following command will start
@command{mailfromd -I. -I../mflib test.rc}:

@example
@group
$ @kbd{mtasim -Xauto -- -I. -I../mflib test.rc}
220-mtasim (mailfromd @value{VERSION}) ready
220 Connected to milter unix:/tmp/mtasim-j6tRLC/socket
(mtasim)
@end group
@end example

@anchor{statedir mtasim option}
@mtasimopt{statedir, described}
  The @file{/tmp/mtasim-j6tRLC} directory and any files within it will
exist as long as @command{mtasim} is running and will be removed when
you exit from it.@footnote{However, this is true only if the program
is exited the usual way (via @code{QUIT} or end-of-file).  If it is
aborted with a signal like @code{SIGINTR}, the temporary directory is
not removed.}  You can also instruct the subsidiary
@command{mailfromd} to use this directory as its state directory
(@pxref{statedir}).  This is done by @option{--statedir} command line
option:

@example
$ @kbd{mtasim -Xauto --statedir -- -I. -I../mflib test.rc}
@end example

@noindent
(notice that @option{--statedir} is the @command{mtasim} option,
therefore it must appear @emph{before} @samp{--})

  You can use an existing directory instead of creating a temporary
one.  To do so, use the @option{-Xdir:@var{name}} option, e.g.:
  
@example
$ @kbd{mtasim -Xdir:/var/lib/teststate --statedir -- -I. -I../mflib test.rc}
@end example

@mtasimopt{user, described}
@mtasimopt{group, described}
  Special care should be taken when using @command{mtasim} from root
account, especially if used with @option{-Xauto} and
@option{--statedir}.  The @command{mailfromd} utility executed by it
will switch to privileges of the user given in its configuration
(@pxref{Starting and Stopping}) and will not be able to create data in
its state directory, because the latter was created using @samp{root}
as owner.  To help in this case, @command{mtasim} understands
@option{--user} and @option{--group} command line options, that have
the same meaning as for @command{mailfromd}.  

  Now, let's try @code{HELP} command again:

@example
250-mtasim (mailfromd @value{VERSION}); supported SMTP commands:
250- EHLO
250- HELO
250- MAIL
250- RCPT
250- DATA
250- HELP
250- QUIT
250- HELP
250- RSET
250-Supported administrative commands:
250- \Dname=value [name=value...]       Define Sendmail macros
250- \Ecode [regex]                     Expect given SMTP reply code
250- \L[name] [name...]                 List macros
250- \Uname [name...]                   Undefine Sendmail macros
250  \Sfamily hostname address [port]   Define sender socket address
@end example

@cindex @command{mtasim} administrative commands
  While the @acronym{SMTP} commands do not need any clarification, some words
about the @dfn{administrative commands} are surely in place.  These
commands allow to define, undefine and list arbitrary Sendmail macros.
Each administrative command consists of a backslash followed by a command
letter.  Just like @acronym{SMTP} ones, administrative commands are
case-insensitive.  If a command takes arguments, the first argument
must follow the command letter without intervening whitespace.
Subsequent arguments can be delimited by arbitrary amount of
whitespace.

@anchor{D command}
@cindex D, @code{\D}, a @command{mtasim} command
@cindex @command{mtasim}, defining Sendmail macros
For example, the @code{\D} command defines Sendmail macros:

@example
(mtasim) @kbd{\Dclient_addr=192.168.10.1 f=sergiusz@@localhost i=testmsg}
(mtasim) 
@end example

@noindent
Notice that @command{mailfromd} does not send any response to the
command, except if there was some syntactic error, in which case it
will return a @samp{502} response.

@anchor{L command}
@cindex L, @code{\L}, a @command{mtasim} command
@cindex @command{mtasim}, listing Sendmail macros
  Now, you can list all available macros:

@example
(mtasim) @kbd{\L}
220-client_addr=192.168.10.1
220-f=sergiusz@@localhost
220 i=testmsg
(mtasim)
@end example

@noindent
or just some of them:

@example
(mtasim) @kbd{\Lclient_addr}
220 client_addr=192.168.10.1
(mtasim)
@end example

@cindex U, @code{\U}, a @command{mtasim} command
@cindex @command{mtasim}, undefining Sendmail macros
  To undefine a macro, use @command{\U} command:

@example
(mtasim) @kbd{\Ui}
(mtasim) @kbd{\l}
220-client_addr=192.168.10.1
220 f=sergiusz@@localhost
(mtasim)    
@end example

@anchor{S command}
@cindex S, @code{\S}, a @command{mtasim} command
@cindex @command{mtasim}, declare sender socket
  The @code{\S} command declare sender socket and host name.  These
parameters are passed to the @code{connect} handler, if one is
declared (@pxref{connect handler}).  To give you a chance to use this
command, @command{mtasim} does not invoke @code{connect} handler right
after connecting to the milter.  Instead it waits until either the
@code{\S} command or any @acronym{SMTP} command (except @samp{HELP})
is given.  After calling @code{connect} handler the @code{\S} is
disabled (to reflect it, it also disappears from the @code{HELP}
output).

  The @code{\S} command takes 1 to 4 arguments.  The first argument
supplies the socket family (@pxref{socket-families}).  Allowed values
are: @samp{stdio}, @samp{unix}, @samp{inet}, @samp{inet6} or
numbers from @samp{0} to @samp{3}.

  The @code{\S stdio} (or @code{\S 0}) command needs no additional
arguments.  It indicates that the @acronym{SMTP} connection is
obtained from the standard input.  It is the default if sender socket
is not declared explicitly.

  The command @code{\S unix} indicates that the connection is accepted
from a UNIX socket.  It requires two more argument.  The first one
supplies sender host name and the second one supplies full
path name of the socket file.  For example:

@example
\S unix localhost /var/run/smtp.sock
@end example

  The commands @code{\S inet} and @code{\S inet6} indicate that the
connection came from an @samp{INET} IPv4 or IPv6 socket,
correspondingly@footnote{Depending on how @command{mailfromd} is
configured, @samp{inet6} may be not available.}.  They require all
four arguments to be specified.  The additional arguments are:
host name, IP address, and port number, in that order.  For example:

@example
\S inet relay.gnu.org.ua 213.130.31.41 34567
@end example

or

@example
\S inet6 relay.gnu.org.ua 2001:470:1f0a:1be1::2 34567
@end example

  Sender socket address can also be configured from the command
line (@pxref{option summary, sender-socket}).  

  Now, let's try a real-life example.  Suppose you wish to test the
greylisting functionality of the filter script described in @ref{Filter Script
Example}.  To do this, you start @command{mtasim}:

@example
$ @kbd{mtasim -Xauto -- -I. -I../mflib test.rc}
220-mtasim (mailfromd @value{VERSION}) ready
220 Connected to milter unix:/tmp/mtasim-ak3DEc/socket
(mtasim)
@end example

  The script in @file{test.rc} needs to know @code{client_addr} macro,
so you supply it to @command{mtasim}:

@example
(mtasim) @kbd{\Dclient_addr=10.10.1.13}
@end example

Now, you try an @acronym{SMTP} session:

@example
(mtasim) @kbd{ehlo yahoo.com}
250-pleased to meet you
250 HELP
(mtasim) @kbd{mail from: <gray@@yahoo.com>}
250 Sender OK
(mtasim) @kbd{rcpt to: <gray@@localhost>}
450 4.7.0 You are greylisted for 300 seconds
@end example

  OK, this shows that the greylisting works.  Now quit the session:

@example
(mtasim) @kbd{quit}
221 Done
@end example

@node expect commands
@section @command{mtasim} expect commands

@cindex expect mode, @command{mtasim}
@cindex @command{mtasim} expect mode
@cindex E, @code{\E}, a @command{mtasim} command
  Until now we were using @command{mtasim} interactively.  However, it
is often useful in shell scripts, for example the @command{mailfromd}
test suite is written in shell and @command{mtasim}.  To avoid the
necessity to use auxiliary programs like @command{expect} or
@command{DejaGNU}, @command{mtasim} contains a built-in expect
feature.  The administrative command @code{\E} introduces the
@acronym{SMTP} code that the next command is expected to yield.  For
example,

@example
@group
\E250
rcpt to: <foo@@bar.org>
@end group
@end example

@noindent
tells @command{mtasim} that the response to @code{RCPT TO} command
must begin with @samp{250} code.  If it does, @command{mtasim}
continues execution.  Otherwise, it prints an error message and
terminates with exit code 1.  The error message it prints looks like:

@example
Expected 250 but got 470
@end example

  The expected code given with the @code{\E} command may have less than
3 digits.  In this case it specifies the first digits of expected
reply.  For example, the command @samp{\E2} matches replies
@samp{200}, @samp{220}, etc. 

  If @code{\E} is passed two arguments, the second one is treated as
an extended regular expression.  The subsequent command will then
succeed if its return code matches the one supplied as the first
argument, and its extended SMTP code and textual message match the
supplied regular expression.  If the regular expression contains
whitespace, enclose it in a pair of double quotes.  Within double
quotes, backslash can be used to escape double quote, and backslash
character.

  This feature can be used to automate your tests.  For example, the
following script tests the greylisting functionality (see the previous
section):

@example
# @r{Test the greylisting functionality}
#
\E220
\Dclient_addr=10.10.1.13
\E250
ehlo yahoo.com
\E250
mail from: <gray@@yahoo.com>
\E450
rcpt to: <gray@@localhost>
\E221
quit
@end example

  This example also illustrates the fact that you can use
@samp{#}-style comments in the @command{mtasim} input. 

@cindex @command{mtasim}, using in shell scripts
@command{mtasim} scripts can be used in shell programs, for example:

@example
@group
mtasim -Xauto --statedir -- -P../mflib test.rc < @file{scriptfile}
if $? -ne 0; then
  echo "Greylisting test failed"
fi
@end group
@end example

@node traces
@section Trace Files

@cindex trace file, @command{mtasim}
  It is possible to log an entire @acronym{SMTP} session to a file.
This is called @dfn{session tracing}.  Two options are provided for
this purpose: 

@table @option
@mtasimopt{trace-file, described}
@item --trace-file=@var{file}
  Sets the name of the trace file, i.e. a file to which the session
transcript will be written.  Both the input commands, and the
@command{mtasim} responses are logged.  If the file @var{file} exists,
it will be truncated before logging.  This, however, can be changed
using the following option:

@mtasimopt{append, described}
@item -a
@itemx --append
  If the trace file exists, append new trace data to it.
@end table

@node daemon mode
@section Daemon Mode

@mtasimopt{daemon, described}
@cindex @command{mtasim} daemon mode
  To start @command{mtasim} in @dfn{daemon} mode, use the
@option{--daemon} (or @option{-bd}) command line option.  This mode
is not quite the same as Sendmail @option{-bd} mode.  When started in
@dfn{daemon} mode, @command{mtasim} selects the first available
@acronym{TCP} port to use from the range @samp{1024 -- 65535}.
It prints the selected port number on the standard output and
starts listening on it.  When a connection comes, it serves a
@emph{single} @acronym{SMTP} session and exits immediately when it is
ended.

  This mode is designed for use in shell scripts and automated test
cases.

@node command summary
@section Summary of the @command{mtasim} Administrative Commands

This section provides a summary of administrative commands available
in @command{mtasim}.

@deffn {mtasim command} \D name=value [name=value...]
Defines Sendmail macro @var{name} to the given @var{value}.  Any number
of @var{name}=@var{value} pairs can be given as arguments.

@xref{D command}.
@end deffn

@deffn {mtasim command} \E code [regex]
Instructs @command{mtasim} to expect next @acronym{SMTP} command to
return given @var{code} (a three-digit decimal number).  Optional
@var{regex} argument is an extended POSIX regular expression.  If
supplied, the program will also require that the extended SMTP
code (if any) and textual message returned by the command match this
expression.

@xref{expect commands}.
@end deffn

@deffn {mtasim command} \L [name...]
Lists defined macros.  @xref{L command}.
@end deffn

@deffn {mtasim command} \U name [name...]
Undefines macros given as its arguments.
@end deffn

@deffn {mtasim command} \S family [hostname address [port]]
Declares the sender socket parameters.  @xref{S command}, for a
detailed description and examples.

This command is available only at the initial stage of a
@command{mtasim} session, before the first @acronym{SMTP} command was
given.  It is disabled if the @option{--sender-socket} option was
given in the command line (@pxref{option summary, sender-socket}).
The @code{help} output reflects whether or not this command is available.

If neither this command nor the @option{--sender-socket} option were
given, @command{mtasim} behaves as if given the @code{\S stdio}
command.

The @var{family} argument
supplies the socket family, i.e. the first argument to the
@code{connect} handler (@pxref{connect handler}).  It can have either
literal or numeric value, as described in the table below:

@float Table, S-command-socket-families
@caption{Socket families}
@multitable @columnfractions 0.25 .10 0.45
@headitem Literal @tab Numeric @tab Meaning
@item stdio @tab  0    @tab Standard input/output (the @acronym{MTA} is
run with @option{-bs} option) 
@item unix  @tab  1    @tab @acronym{UNIX} socket
@item inet  @tab  2    @tab @acronym{IP}v4 protocol
@item inet6 @tab  3    @tab @acronym{IP}v6 protocol
@end multitable
@end float

See also @ref{socket-families}.

Depending on the @var{family}, the rest of arguments supply additional
parameters:

@table @asis
@item stdio
The @var{hostname} argument can be specified.  It defines the first
argument of the @code{connect} handler (@pxref{hostname in connect
handler}).

@item inet
@itemx inet6
All arguments must be specified.

@multitable @columnfractions 0.25 0.10 0.45
@headitem argument @tab @code{connect} argument @tab meaning
@item hostname @tab 1 @tab Sender host name
@item address  @tab 4 @tab Sender IP address
@item port     @tab 3 @tab Sender port number
@end multitable

@item unix
@var{Hostname} and @var{address} must be supplied.  The @var{address}
argument must be a full pathname of the UNIX socket.
@end table

@end deffn

@node option summary
@section @command{mtasim} command line options

  This section summarizes all available @command{mtasim} command line options.

@table @option
@mtasimopt{append, summary}
@mtindex a, -a, @command{mtasim} option, summary
@item --append
@itemx -a 
  Append to the trace file.  @xref{traces}.

@mtasimopt{body-chunk, summary}  
@item --body-chunk=@var{number}
  Set the body chunk length (bytes) for @code{xxfi_body} calls.

@mtasimopt{daemon, summary}
@mtindex bs, -bd, @command{mtasim} option, summary
@item --daemon
@itemx -bd
  Run as daemon.  @xref{daemon mode}.

@mtasimopt{define, summary}
@mtindex D, -D, @command{mtasim} option, summary
@item --define=@var{macro}=@var{value}
@itemx -D @var{macro}=@var{value}
  Define Sendmail macro @var{macro} to the given @var{value}.  It is
similar to the @code{\D} administrative command (@pxref{D command})

@mtasimopt{gacopyz-log, summary}
@item --gacopyz-log=@var{level}
Set desired logging level for @command{gacopyz} library
(@pxref{Gacopyz}).  @xref{gacopyz-log option}, for a detailed
description of @var{level}.  Notice, that unless this option is used,
the @option{--verbose} (@option{-v}) command line option implies
@option{--gacopyz-log=debug}.

@mtasimopt{group, summary}
@mtindex g, -g, @command{mtasim} option, summary
@item --group=@var{name}
@itemx -g @var{name}
When switching to user's privileges as requested by the
@option{--user} command line option, retain the additional group
@var{name}.  Any number of @option{--group} options may be given to
supply a list of additional groups.

@mtasimopt{user, summary}
@mtindex u, -u, @command{mtasim} option, summary
@item --user=@var{name}
@itemx -u @var{name}
Run with this user privileges.  This option and the @option{--group}
option have effect only if @command{mtasim} was started with root
privileges. 

@item --help
@itemx -?
  Display a short help summary

@mtasimopt{milter-version, summary}
@item --milter-version=@var{version}
  Force using the given Milter protocol version number.  The
@var{version} argument is either a numeric version (e.g.@: @samp{2}), or
a version string in form @samp{@var{major}.@var{minor}[.@var{patch}]},
where square brackets indicate optional part.  The default is
@samp{1.0.0}.  If @var{version} is any of @samp{2}, @samp{3} or
@samp{1.0.0}, the default protocol capabilities and actions for that
version are set automatically.  This option
is intended for development and testing of the Gacopyz library
(@pxref{Gacopyz}).

@mtasimopt{milter-proto, summary}
@item --milter-proto=@var{bitmask}
Set Milter protocol capabilities.  See @file{gacopyz/gacopyz.h} for
the meaning of various bits in the @var{bitmask}.  Look for the C
macros with the prefix @samp{SMFIP_}.

@mtasimopt{milter-timeout, summary}
@item --milter-timeout=@var{values}
Set timeouts for various Milter operations.  @var{Values} is a
comma-separated list of assignments @samp{@var{T}=@var{V}}, where
@var{T} is a @dfn{timeout code}, indicating which timeout to set, and
@var{V} is its new value.  Valid timeout codes are:

@table @asis
@item C
Timeout for connecting to a filter.

@item W
@itemx S
Timeout for sending information from the simulator to a filter.

@item R
Timeout for reading reply from the filter.

@item E
Overall timeout between sending end-of-message to filter and receiving
final acknowledgment.  Indirectly, it configures the upper
limit on the execution time of the @code{eom} handler (@pxref{eom handler}).
@end table

@mtasimopt{milter-actions, summary}
@item --milter-actions=@var{bitmask}
Set Milter actions.  See @file{gacopyz/gacopyz.h} for
the meaning of various bits in the @var{bitmask}.  Look for the C
macros with the prefix @samp{SMFIF_}.

@mtasimopt{no-interactive, summary}
@item --no-interactive
  Not-interactive mode (disable readline).  @xref{Command Line Editing, ,
Command Line Editing, readline, GNU Readline Library}.

@mtasimopt{port, summary}
@mtindex X, -X, @command{mtasim} option, summary
@item --port=@var{port}
@itemx -X @var{port}
  Communicate with given Milter @var{port}.  Valid values for
@var{port} are:

@table @asis
@item port specification
@xref{milter port specification}, for a detailed discussion.  Example:

@example
--port inet:999@@localhost
@end example

@item @file{sendmail.cf} @command{X} command format
For example:

@example
--port='mailfrom, S=inet:999@@localhost, F=T, T=C:100m;R:180s'
@end example

@item @code{auto}
Create a temporary directory and start an instance of
@command{mailfromd} configured to communicate over a UNIX socket in
that directory.  If @option{--statedir} is also given, the created
@command{mailfromd} instance will use that directory as its state
directory (@pxref{statedir}).  Additional arguments for
@command{mailfromd} may be supplied after the @code{--} delimiter.

Before termination, @command{mtasim} will stop the @command{mailfromd}
instance it created and remove the temporary directory.

@item @code{dir}:@var{dirname}
Same as @code{auto}, except that instead of the temporary directory
the directory @var{dirname} is used.  This directory is not removed
when @command{mtasim} terminates.  Example:

@example
--port dir:/tmp/state
@end example
@end table

@xref{mtasim milter port}, for a detailed discussion of the
@option{--port} option and its use.

@mtasimopt{prompt, summary}
@item --prompt=@var{string}
  Set readline prompt.  The default prompt string is @samp{(mtasim) }.

@mtasimopt{sender-socket, summary}
@item --sender-socket=@var{family}[,@var{hostname},@var{address}[,@var{port}]]
  Declare sender socket address.  This option has the same effect as
the @code{S command}.  @xref{S command}, for a detailed discussion
and a description of its arguments.

@mtasimopt{statedir, summary}
@item --statedir
  When using @option{-Xauto}, use the temporary directory name as
@command{mailfromd} state directory (@pxref{statedir mtasim option}).

@mtasimopt{stdio, summary}
@mtindex bs, -bs, @command{mtasim} option, summary
@item --stdio
@itemx -bs
  Use the @acronym{SMTP} protocol on standard input and output.  This
is the default mode for @command{mtasim}.  @xref{interactive mode}.

@mtasimopt{trace-file, summary}
@item --trace-file=@var{file}
  Set name of the trace file.  @xref{traces}.

@item --usage
  Display option summary

@mtasimopt{verbose, summary}  
@mtindex v, -v, @command{mtasim} option, summary
@item --verbose
@itemx -v
  Increase verbosity level.  Implies @option{--gacopyz-log=debug},
unless that option is used explicitly.

@item --version
@itemx -V
  Print program version

@end table


