Command-line client¶
Synopsis¶
sievemgr [server
] [command
]
[argument
…]
sievemgr -e expression
[…] [server
]
sievemgr -h
sievemgr -V
Description¶
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 -e
, or read from standard input or a file given
with -s
.
The server defaults to the host
set in sieve.cf or localhost
.
Operands¶
- server¶
URL of the form
[login[:passwd]@]host[:port][/owner]
.- login
defaults to the
login
set for host in sieve.cf or.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.
- argument¶
Argument to that command.
Options¶
- -C¶
Do not overwrite files.
- -N file¶
Use file as
.netrc
file.
- -V¶
Print version.
- -c file¶
Read configuration from file.
- -d¶
Enable debugging mode.
- -e expression¶
Execute expression on the server.
- -f¶
Overwrite and remove files without confirmation.
- -h¶
Print help.
- -i¶
Confirm removing or overwriting files.
- -o key=value¶
Set the configuration key to value.
-o key=yes
can be shortened to-o key
,-o key=no
to-o nokey
.See sieve.cf for a list of keys.
- -q¶
Be quieter.
- -s file¶
Execute expressions read from file.
- -v¶
Be more verbose.
Commands¶
- activate script¶
Mark script as active. This is the script run for incoming mail. Only one script can be active.
- cat [script ...]¶
Print each script.
- cd [localdir]¶
Change local working directory to localdir, which defaults to the current user’s home directory.
- check localscript¶
Check whether localscript is semantically valid.
- cmp script1 [...] scriptN¶
Check whether the given scripts are equal.
- cp [-f|-i] source target¶
Download source and re-upload it as target.
Options:
- -f¶
Overwrite target without confirmation.
- -i¶
Ask for confirmation before overwriting target.
- deactivate¶
Deactivate the active script
- diff [-C n|-U n|-c|-u] [-b] script1 script2¶
Show how script1 and script2 differ.
Options:
- -C n¶
Show n lines of copied context.
- -U n¶
Show n lines of unified context.
- -b¶
Ignore whitespace before a linefeed.
- -c¶
Show three lines of copied context.
- -u¶
Show three lines of unified context.
- echo word¶
Print each word.
- ed [-a] script [...]¶
Download script, edit it with a line editor, and re-upload it.
Options:
- -a¶
Also edit the active script.
- exit¶
Log out and exit.
- get [-f|-i] [-a] [-o file] [script ...]¶
Download scripts.
Options:
- -a¶
Also download the active script.
- -f¶
Overwrite files without confirmation.
- -i¶
Ask for confirmation before overwriting a file.
- -o¶
Save script as
file
.
- help [command]¶
Print help for command or list commands if command is omitted. Can be shortened to
?
.For example:
sieve://user@imap.foo.example> ?ls ls [script ...] - list scripts
- ls [-1aBl] [script ...]¶
List each script, or all scripts if no script is given, and mark the active one with an asterisk (”*”).
Options:
- -1 (number 1)¶
List one script per line and terminate output with a blank line. Implied if standard input is not a terminal.
- -a¶
Also list the active script.
- -B¶
Hide backups unless listing they were given as script.
- -l (lowercase "L")¶
List one flag-filename pair per line, separated by whitespace, and terminate output with
...
. The flaga
marks the active script,-
all others.
The active script is not marked with an asterisk if
-1
or-l
is given.Examples:
sieve://user@imap.foo.example> ls bar.sieve foo.sieve*
sieve://user@imap.foo.example> ls -l - bar.sieve a foo.sieve ...
- more [-aceis] [script ...]¶
Display each script page-by-page.
Options:
- -a¶
Also display the active script.
- -c¶
Clear screen instead of scrolling.
- -e¶
Exit immediately after writing the last line.
- -i¶
Ignore case in pattern matching.
- -s¶
Treat consecutive empty lines as a single empty line.
- mv [-f|-i] source target¶
Rename source to target.
Options:
- -f¶
Replace target without confirmation.
- -i¶
Ask for confirmation before replacing target.
- put [-a|-o name] [-f|-i] [localscript ...]¶
Upload scripts.
Options:
- -a¶
Replace the active script.
- -f¶
Replace scripts without confirmation.
- -i¶
Ask for confirmation before replacing a script.
- -o name¶
Upload localscript as name.
The server should reject syntactically invalid scripts and issue a warning for semantically invalid ones. Updates are atomic.
- python [-s]¶
Enter a Python read-evaluate-print loop (REPL) with the
sievemgr.SieveManager
object representing the current connection.Options:
- -s¶
Enter a REPL with the
sievemgr.SieveShell
object representing the shell.
- rm [-f|-i] [script ...]¶
Remove scripts.
Options:
- -f¶
Remove scripts without confirmation.
- -i¶
Ask for confirmation before removing a script.
- sh [command] [argument ...]¶
Run command. If command is omitted, enter a system shell. Can be shortened to
!
.Examples:
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
sieve://user@imap.foo.example> ! bash-2.0$
- su user¶
Manage the scripts of user. Requires elevated privileges.
- vi [-a] [-c command] [-R] script [...]¶
Download script, edit it with a visual editor, and re-upload it.
Options:
- -a¶
Also edit the active script.
- -c command¶
Execute command after the first script has been read.
- -R¶
Open scripts read-only.
- 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.
Word Splitting¶
Lines are split into words in the way they would be split by sh(1).
For example,
get foo bar
downloads the two files foo
and bar
.
But
get "foo bar"
downloads the single file foo bar
.
If a filename contains backslashes or quotes (single or double), they must be escaped. For example,
get foo\\bar\'
downloads the file foo\bar'
.
Pattern Expansion¶
If *
, ?
, or [
occur in an expression given with
-e
, read from a script given with -s
, or read from
standard input, they are expanded to local or remote filenames in the
way they would be expanded by 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,
put *.sieve
uploads every local file that matches *.sieve
.
But
get *.sieve
downloads every remote file that matches *.sieve
.
If a filename contains *
, ?
, or [
, those
characters must be escaped with a backslash (”\”) or the filename as a
whole must be quoted. For example,
get *.sieve
downloads every file that matches the pattern *.sieve
.
But
get "*.sieve"
downloads the file *.sieve
.
Scripting¶
Operations can be scripted by giving a command
, redirecting
standard input, or with -e
or -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.
Word Splitting and Patterns¶
Variables that are embedded in scripts are subject to word splitting and pattern expansion:
# $script could contain quotes
sievemgr -e"put '$script'" user@imap.foo.example
Either pass them as arguments
to sievemgr:
sievemgr user@imap.foo.example put "$script"
Or use xargs
:
sievemgr -e'xargs put' user@imap.foo.example <<EOF
$script
EOF
Comparing Scripts¶
Sieve scripts can be compared by checking cmp
’s exit status:
if sievemgr user@imap.foo.example cmp -s foo.sieve bar.sieve
then echo 'foo.sieve and bar.sieve are equal'
else echo 'foo.sieve and bar.sieve differ'
fi
Or by checking its output:
case $(sievemgr user@imap.foo.example cmp foo.sieve bar.sieve) in
(*equal) echo 'foo.sieve and bar.sieve are equal' ;;
(*differs) echo 'foo.sieve and bar.sieve differ' ;;
esac
Listing Scripts¶
Sieve script names cannot contain newlines, so ls -1
and
ls -l
can safely be used in scripts.
For example:
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 <pipe
wait $pid
rm pipe
Persistent Connections¶
A connection is opened each time sievemgr is called. So if multiple messages are going to be exchanged between the client and the server, it is more efficient to run sievemgr in the background and send and receive messages through pipes than to call sievemgr for each exchange.
Create one pipe for sending commands and another one for receiving responses:
mkfifo -m 0600 send recv
Start sievemgr and redirect its input and output to these pipes:
sievemgr user@imap.foo.example <send >recv & pid=$!
Open the pipes in the shell:
exec 3>send
exec 4<recv
Commands can now be sent by writing them to file descriptor (FD) 3:
echo ls -l >&3
And responses can be read from FD 4:
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:
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
caps
, cert
and ls -l
terminate output with ...
; ls -1
terminates output with a blank line. When using one of those
commands, check whether its output matches its terminator:
echo ls -1 >&3
nscripts=0
while read -r script && [ "$script" ]
do eval "script_${$((nscripts++))}"='$script'
done <&4
Also be careful to avoid races:
cat <<EOF >&3
xargs get
$script
EOF
# patch will run BEFORE the download of $script has finished
patch "$script" <patchfile
Use echo
to wait for previously sent commands to finish:
cat <<EOF >&3
xargs get
$script
echo done
EOF
while read -r line && [ "$line" != done ]
do :
done <&4
patch "$script" <patchfile
Note
read blocks, so this is not a busy wait.
Exit by sending exit
:
echo exit >&3
wait "$pid"
And abort using kill(1):
kill "$pid"
wait "$pid"
Sending exit
lets previously sent commands finish.
Aborting with kill exits right away.
Tip
Use the Python module instead.
Login¶
Logins can be automated by reading passwords from the
standard output of a command, sieve.cf,
or .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 sieve.cf
or .netrc
.
Password Managers¶
Set getpassword
to a command
to read the password
from the standard output of that command.
For example, add
getpassword pass $login@$host
to your sieve.cf to query pass for the password for the current host.
$host
and $login
are expanded to the given host
and the login for that host respectively.
The sieve.cf
File¶
Set password
to a string
to log
in using that string
as your password.
For example, add
account imap.foo.example
login user
password pencil
to your sieve.cf to automatically
log in as user
with the password pencil
on imap.foo.example
.
The .netrc
File¶
The .netrc
file is a traditional facility to automate logins.
For example, add
machine imap.foo.example
login user
password pencil
to your .netrc
to automatically log in as user
with
the password pencil
on 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 cert
to a file
that contains a TLS key and a TLS certificate:
account imap.foo.example
login user
cert cert.pem
To authenticate by sending that cerficiate, additionally
set saslmechs
to external
:
account imap.foo.example
login user
cert cert.pem
saslmechs external
See sieve.cf for details.
Exit Status¶
- 0
Success
- 1
Failure
- 2
Usage error
Environment¶
- COLUMNS¶
Terminal width in characters.
- HOME¶
Home directory of the current user.
- 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
LC_ALL
>LC_CTYPE
>LANG
.
- LINES¶
Terminal height in lines.
- LOGNAME¶
Login name of the current user.
- NETRC¶
Filename of the
.netrc
file (default:$HOME/.netrc
).
- XDG_CONFIG_HOME¶
X Desktop Group base configuration directory (default:
$HOME/.config
).
Files¶
/etc/sieve/config
,/etc/sieve.cf
,$XDG_CONFIG_HOME/sieve/config
,$HOME/.sieve/config
,$HOME/.sieve.cf
Default configuration files. Not read when
-c
is given.See sieve.cf for details.
.netrc
Login information.
Examples¶
Upload script.sieve
to imap.foo.example
and activate it:
$ 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:
sievemgr user@imap.foo.example <<EOF
put script.sieve
activate script.sieve
EOF
Edit the active script on imap.foo.example
:
sievemgr user@imap.foo.example vi -a
Download all scripts from imap.foo.example
:
sievemgr -e'get *' user@imap.foo.example
Delete the active script non-interactively:
sievemgr -e'ls -1a' -edeactivate user@imap.foo.example |
sievemgr user@imap.foo.example xargs rm -f
Standards¶
RFC 2195 (CRAM-MD5)
RFC 2244 (ACAP)
RFC 2782 (SRV records)
RFC 4013 (SASLprep)
RFC 4422 (SASL)
RFC 4616 (PLAIN)
RFC 5228 (Sieve)
RFC 5802 (SCRAM)
RFC 5804 (ManageSieve)
RFC 5019 (Lightweight OCSP)
RFC 6960 (OCSP)
RFC 7677 (SCRAM-SHA-256 and SCRAM-SHA-256-PLUS)
Security¶
Credentials are stored in memory so that they need not be entered again in case of a referral. However, because page-locking is unfeasible in Python, they may be swapped out to the disk.
Passwords can be queried from password managers to automate logins. However, any command that can be run by sievemgr can, at the very least, also be run by any application that can run python.
Privacy¶
Checking whether a server’s certificate has been revoked using OCSP enables the certificate issuer to infer that the server is accessed from your internet address.
OCSP is enabled by default. Set ocsp
to no to disable it.
Bugs¶
.netrc
records without a password
token wrongly trigger
a parse error in Python up to version 3.9.
Please report other bugs at <https://github.com/odkr/sievemgr/issues>.