******************* Command-line client ******************* Synopsis ======== .. program:: sievemgr :command:`sievemgr` [:option:`server`] [:option:`command`] [:option:`argument` ...] :command:`sievemgr` :option:`-e expression` [...] [:option:`server`] :command:`sievemgr` :option:`-s file` [:option:`server`] :command:`sievemgr` :option:`-h` :command:`sievemgr` :option:`-V` Description =========== :command:`sievemgr` is a command-line client for uploading, downloading, and managing Sieve scripts using the ManageSieve protocol. If no command is given, a shell is entered; the shell supports tab-completion. See COMMANDS_ below for a list. Commands can be given either on the command line, as `expression` with :option:`-e`, or read from standard input or a `file` given with :option:`-s`. .. only:: man The `server` defaults to the :confvar:`host` set in :manpage:`sieve.cf(5)` or :samp:`localhost`. .. only:: not man The `server` defaults to the :confvar:`host` set in :doc:`sieve.cf ` or :samp:`localhost`. Operands ======== .. option:: server URL of the form :samp:`[{login}[:{passwd}]@]{host}[:{port}][/{owner}]`. `login` .. only:: man defaults to the :confvar:`login` set for `host` in :manpage:`sieve.cf(5)` or :file:`.netrc`, or to the current user. .. only:: not man defaults to the :confvar:`login` set for `host` in :doc:`sieve.cf ` or :file:`.netrc`, or to the current user. `passwd` is prompted for by default (see LOGIN_ for automation). `port` defaults to 4190 (the standard port for ManageSieve). `owner` defaults to `login`. .. danger:: Other users can see passwords given on the command line. .. option:: command Command to run (see COMMANDS_ below). .. option:: argument Argument to that command. Options ======= .. option:: -C Do *not* overwrite files. .. option:: -N file Use `file` as :file:`.netrc` file. .. option:: -V Print version. .. option:: -c file Read configuration from `file`. .. option:: -d Enable debugging mode. .. option:: -e expression Execute `expression` on the `server`. .. option:: -f Overwrite and remove files without confirmation. .. option:: -h Print help. .. option:: -i Confirm removing or overwriting files. .. option:: -o key=value Set the configuration `key` to `value`. :samp:`-o {key}=yes` can be shortened to :samp:`-o {key}`, :samp:`-o {key}=no` to :samp:`-o no{key}`. .. only:: man See :manpage:`sieve.cf(5)` for a list of keys. .. only:: not man See :doc:`sieve.cf ` for a list of keys. .. option:: -q Be quieter. .. option:: -s file Execute expressions read from `file`. .. option:: -v Be more verbose. :option:`-c`, :option:`-e`, :option:`-o`, :option:`-q`, and :option:`-v` can be given multiple times. Commands ======== .. sievecmd:: ! [command] [argument ...] Shorthand for :sievecmd:`sh`. .. sievecmd:: ? [command] Shorthand for :sievecmd:`help`. .. sievecmd:: activate script Mark `script` as active. This is the script run for incoming mail. Only one script can be active. .. sievecmd:: caps Print the server's capabilities (in YAML_). .. sievecmd:: cat [script ...] Print each `script`. .. sievecmd:: cd [localdir] Change local working directory to `localdir`, which defaults to the current user's home directory. .. sievecmd:: cert Print information about the server's TLS certificate (in YAML_). .. sievecmd:: check localscript Check whether `localscript` is semantically valid. .. sievecmd:: cmp script1 [...] scriptN Check whether the given scripts are equal. .. sievecmd:: cp [-f|-i] source target Download `source` and re-upload it as `target`. .. rubric:: Options: .. program:: cp .. option:: -f Overwrite `target` without confirmation. .. option:: -i Ask for confirmation before overwriting `target`. .. sievecmd:: deactivate Deactivate the active script .. sievecmd:: diff [-C n|-U n|-c|-u] [-b] script1 script2 Show how `script1` and `script2` differ. .. rubric:: Options: .. program:: diff .. option:: -C n Show `n` lines of copied context. .. option:: -U n Show `n` lines of unified context. .. option:: -b Ignore whitespace before a linefeed. .. option:: -c Show three lines of copied context. .. option:: -u Show three lines of unified context. .. sievecmd:: echo word Print each `word`. .. sievecmd:: ed [-a] script [...] Download `script`, edit it with a line editor, and re-upload it. .. rubric:: Options: .. program:: ed .. option:: -a Also edit the active script. .. sievecmd:: exit Log out and exit. .. sievecmd:: get [-f|-i] [-a] [-o file] [script ...] Download scripts. .. rubric:: Options: .. program:: get .. option:: -a Also download the active script. .. option:: -f Overwrite files without confirmation. .. option:: -i Ask for confirmation before overwriting a file. .. option:: -o Save `script` as :file:`file`. .. sievecmd:: help [command] Print help for `command` or list commands if `command` is omitted. Can be shortened to ``?``. For example: .. code:: none sieve://user@imap.foo.example> ?ls ls [script ...] - list scripts .. sievecmd:: ls [-1aBl] [script ...] List each `script`, or all scripts if no `script` is given, and mark the active one with an asterisk ("\*"). .. rubric:: Options: .. program:: ls .. option:: -1 (number 1) List one script per line and terminate output with a blank line. Implied if standard input is not a terminal. .. option:: -a Also list the active script. .. option:: -B Hide backups unless listing they were given as `script`. .. option:: -l (lowercase "L") List one flag-filename pair per line, separated by whitespace, and terminate output with :literal:`...`. The flag :literal:`a` marks the active script, :literal:`-` all others. The active script is *not* marked with an asterisk if :option:`-1 ` or :option:`-l ` is given. .. rubric:: Examples: .. code:: none sieve://user@imap.foo.example> ls bar.sieve foo.sieve* .. code:: none sieve://user@imap.foo.example> ls -l - bar.sieve a foo.sieve ... .. sievecmd:: more [-aceis] [script ...] Display each `script` page-by-page. .. rubric:: Options: .. program:: more .. option:: -a Also display the active script. .. option:: -c Clear screen instead of scrolling. .. option:: -e Exit immediately after writing the last line. .. option:: -i Ignore case in pattern matching. .. option:: -s Treat consecutive empty lines as a single empty line. .. sievecmd:: mv [-f|-i] source target Rename `source` to `target`. .. rubric:: Options: .. program:: mv .. option:: -f Replace `target` without confirmation. .. option:: -i Ask for confirmation before replacing `target`. .. warning:: :sievecmd:`mv` is only atomic if the :option:`server ` supports version 1.0 or above of the ManageSieve protocol (see :sievecmd:`caps`). .. sievecmd:: put [-a|-o name] [-f|-i] [localscript ...] Upload scripts. .. rubric:: Options: .. program:: put .. option:: -a Replace the active script. .. option:: -f Replace scripts without confirmation. .. option:: -i Ask for confirmation before replacing a script. .. option:: -o name Upload `localscript` as `name`. The server should reject syntactically invalid scripts and issue a warning for semantically invalid ones. Updates are atomic. .. sievecmd:: python [-s] Enter a Python read-evaluate-print loop (REPL) with the :mod:`sievemgr.SieveManager` object representing the current connection. .. rubric:: Options: .. program:: python .. option:: -s Enter a REPL with the :mod:`sievemgr.SieveShell` object representing the shell. .. sievecmd:: rm [-f|-i] [script ...] Remove scripts. .. rubric:: Options: .. program:: rm .. option:: -f Remove scripts without confirmation. .. option:: -i Ask for confirmation before removing a script. .. sievecmd:: sh [command] [argument ...] Run `command`. If `command` is omitted, enter a system shell. Can be shortened to ``!``. .. rubric:: Examples: .. code:: none sieve://user@imap.foo.example> cd sieve sieve://user@imap.foo.example> !pwd /home/user/sieve sieve://user@imap.foo.example> !ls foo.sieve bar.sieve sieve://user@imap.foo.example> put foo.sieve .. code:: none sieve://user@imap.foo.example> ! bash-2.0$ .. sievecmd:: su user Manage the scripts of `user`. Requires elevated privileges. .. sievecmd:: vi [-a] [-c command] [-R] script [...] Download `script`, edit it with a visual editor, and re-upload it. .. rubric:: Options: .. program:: vi .. option:: -a Also edit the active script. .. option:: -c command Execute `command` after the first `script` has been read. .. option:: -R Open scripts read-only. :option:`-c ` and :option:`-R ` require a :manpage:`vi(1)`-compatible editor. .. sievecmd:: xargs command [arg ...] Call `command` with the given arguments and each line from standard input as additional argument up to, but excluding, the first empty line or the end of input. Input is neither subject to `word splitting`_ nor to `pattern expansion`_. .. program:: sievemgr Word Splitting ============== Lines are split into words in the way they would be split by :manpage:`sh(1)`. For example, .. code:: none get foo bar downloads the two files :file:`foo` and :file:`bar`. But .. code:: none get "foo bar" downloads the single file :file:`foo bar`. If a filename contains backslashes or quotes (single or double), they must be escaped. For example, .. code:: none get foo\\bar\' downloads the file :file:`foo\\bar'`. Pattern Expansion ================= If :samp:`*`, :samp:`?`, or :samp:`[` occur in an expression given with :option:`-e`, read from a script given with :option:`-s`, or read from standard input, they are expanded to local or remote filenames in the way they would be expanded by :manpage:`sh(1)`. If a command operates on local scripts, patterns are expanded to matching scripts on the local system; if a command operates on remote scripts, patterns are expanded to matching scripts on the remote system. For example, .. code:: none put *.sieve uploads every *local* file that matches :samp:`*.sieve`. But .. code:: none get *.sieve downloads every *remote* file that matches :samp:`*.sieve`. If a filename contains :samp:`*`, :samp:`?`, or :samp:`[`, those characters must be escaped with a backslash ("\\") or the filename as a whole must be quoted. For example, .. code:: none get *.sieve downloads every file that matches the *pattern* :samp:`*.sieve`. But .. code:: none get "*.sieve" downloads the *file* :file:`*.sieve`. Scripting ========= .. program:: sievemgr Operations can be scripted by giving a :option:`command`, redirecting standard input, or with :option:`-e` or :option:`-s`. Comments start with a '#' and are ignored. Scripts abort if an error occurs. Confirmation Prompts -------------------- Confirmation is always prompted for on the controlling terminal, regardless of input/output redirection. If there is no controlling terminal, operations that require confirmation raise an error. .. tip:: :option:`-f` disables confirmation prompts. Use with :option:`-C` to avoid overwriting files. Word Splitting and Patterns --------------------------- Variables that are embedded in scripts are subject to `word splitting`_ and `pattern expansion`_: .. code:: bash # $script could contain quotes sievemgr -e"put '$script'" user@imap.foo.example Either pass them as :option:`arguments ` to :command:`sievemgr`: .. code:: bash sievemgr user@imap.foo.example put "$script" Or use :sievecmd:`xargs`: .. code:: bash sievemgr -e'xargs put' user@imap.foo.example <` and :sievecmd:`ls -l ` can safely be used in scripts. For example: .. code:: bash mkfifo pipe sievemgr user@imap.foo.example ls -l >pipe & pid=$! nscripts=0 while read -r flag script && [ "$script" ] do eval "script_${$((nscripts++))}"='$script' [ "$flag" = a ] && active="$script" done recv & pid=$! Open the pipes in the shell: .. code:: bash exec 3>send exec 4&3 And responses can be read from FD 4: .. code-block:: bash :emphasize-lines: 6 nscripts=0 while read -r flag script && [ "$script" ] do eval "script_${$((nscripts++))}"='$script' [ "$flag" = a ] && active="$script" done <&4 However, be careful to avoid deadlocks: .. code-block:: bash :emphasize-lines: 4 echo ls -1 >&3 nscripts=0 # The loop reads past the output of ls -1 and then waits forever while read -r script do eval "script_${$((nscripts++))}"='$script' done <&4 :sievecmd:`caps`, :sievecmd:`cert` and :sievecmd:`ls -l ` terminate output with :literal:`...`; :sievecmd:`ls -1 ` terminates output with a blank line. When using one of those commands, check whether its output matches its terminator: .. code-block:: bash :emphasize-lines: 3 echo ls -1 >&3 nscripts=0 while read -r script && [ "$script" ] do eval "script_${$((nscripts++))}"='$script' done <&4 Also be careful to avoid races: .. code-block:: bash :emphasize-lines: 7 cat <&3 xargs get $script EOF # patch will run BEFORE the download of $script has finished patch "$script" &3 xargs get $script echo done EOF while read -r line && [ "$line" != done ] do : done <&4 patch "$script" &3 wait "$pid" And abort using :manpage:`kill(1)`: .. code:: bash kill "$pid" wait "$pid" Sending :sievecmd:`exit` lets previously sent commands finish. Aborting with :command:`kill` exits right away. .. tip:: Use the :doc:`Python module ` instead. Login ===== .. only:: man Logins can be automated by reading passwords from the standard output of a command, :manpage:`sieve.cf(5)`, or :file:`.netrc`, or by using TLS client authentication. .. only:: not man Logins can be automated by reading passwords from the standard output of a command, :doc:`sieve.cf `, or :file:`.netrc`, or by using TLS client authentication. Files that contain passwords must be neither group- nor world-readable. .. danger:: Password should be stored in encrypted form only. Prefer using a password manager over :file:`sieve.cf` or :file:`.netrc`. Password Managers ----------------- Set :confvar:`getpassword` to a :samp:`{command}` to read the password from the standard output of that *command*. For example, add .. code:: none getpassword pass $login@$host .. only:: man to your :manpage:`sieve.cf(5)` to query pass_ for the password for the current `host`. .. only:: not man to your :doc:`sieve.cf ` to query pass_ for the password for the current `host`. :samp:`$host` and :samp:`$login` are expanded to the given `host` and the login for that `host` respectively. The :file:`sieve.cf` File ------------------------- Set :confvar:`password` to a :samp:`{string}` to log in using that :samp:`{string}` as your password. For example, add .. code:: none account imap.foo.example login user password pencil .. only:: man to your :manpage:`sieve.cf(5)` to automatically log in as :samp:`user` with the password :samp:`pencil` on :samp:`imap.foo.example`. .. only:: not man to your :doc:`sieve.cf ` to automatically log in as :samp:`user` with the password :samp:`pencil` on :samp:`imap.foo.example`. The :file:`.netrc` File ----------------------- The :file:`.netrc` file is a traditional facility to automate logins. For example, add .. code:: none machine imap.foo.example login user password pencil to your :file:`.netrc` to automatically log in as :samp:`user` with the password :samp:`pencil` on :samp:`imap.foo.example`. See the GNU Inetutils manual (chap. `11.7 `_) for details. TLS Authentication ------------------ There are two types of TLS client authentication. Sending a TLS certificate may be required *before* authentication by another mechanism is permitted or authentication may be performed *by* sending the certificate. To send a TLS certificate, set :confvar:`cert` to a :file:`{file}` that contains a TLS key and a TLS certificate: .. code:: none account imap.foo.example login user cert cert.pem To authenticate *by* sending that cerficiate, additionally set :confvar:`saslmechs` to ``external``: .. code:: none account imap.foo.example login user cert cert.pem saslmechs external .. only:: man See :manpage:`sieve.cf(5)` for details. .. only:: not man See :doc:`sieve.cf ` for details. Exit Status =========== 0 Success 1 Failure 2 Usage error Environment =========== .. envvar:: COLUMNS Terminal width in characters. .. envvar:: EDITOR Editor called by :sievecmd:`ed` (default: :command:`ed`). .. envvar:: HOME Home directory of the current user. .. envvar:: LANG, LC_ALL, LC_CTYPE Encoding for reading from/writing to the terminal and applications. Does *not* apply to Sieve scripts, which *must* be encoded as UTF-8. Order of preference is :envvar:`LC_ALL` > :envvar:`LC_CTYPE` > :envvar:`LANG`. .. envvar:: LINES Terminal height in lines. .. envvar:: LOGNAME Login name of the current user. .. envvar:: PAGER Pager called by :sievecmd:`more` (default: :command:`more`). .. envvar:: NETRC Filename of the :file:`.netrc` file (default: :file:`{$HOME}/.netrc`). .. envvar:: VISUAL Editor called by :sievecmd:`vi` (default: :command:`vi`). .. envvar:: XDG_CONFIG_HOME X Desktop Group base configuration directory (default: :file:`{$HOME}/.config`). Files ===== .. index:: pair: /etc/sieve/config; file .. index:: pair: /etc/sieve.cf; file .. index:: pair: $XDG_CONFIG_HOME/sieve/config; file .. index:: pair: $HOME/.sieve/config; file .. index:: pair: $HOME/.sieve.cf; file :file:`/etc/sieve/config`, :file:`/etc/sieve.cf`, :file:`{$XDG_CONFIG_HOME}/sieve/config`, :file:`{$HOME}/.sieve/config`, :file:`{$HOME}/.sieve.cf` Default configuration files. Not read when :option:`-c` is given. .. only:: man See :manpage:`sieve.cf(5)` for details. .. only:: not man See :doc:`sieve.cf ` for details. .. index:: pair: .netrc; file :file:`.netrc` Login information. Examples ======== Upload :file:`script.sieve` to :samp:`imap.foo.example` and activate it: .. code:: none $ sievemgr user@imap.foo.example sieve://user@imap.foo.example> put script.sieve sieve://user@imap.foo.example> activate script.sieve sieve://user@imap.foo.example> exit Reading commands from standard input: .. code:: bash sievemgr user@imap.foo.example <. .. only:: man See Also ======== :manpage:`sieve.cf(5)`