(Generated by docutils(1))

S-Postman README

An end-user mail processor

Manual section:1
Manual group:S-Postman Manual
Version: 0.4.0-beta6
Date: 2012-12-10

Synopsis

s-postman.py [OPTIONS] [--fetchall]
s-postman.py [OPTIONS] --fetchloop
s-postman.py --help|--doc|--version
s-postman.py [OPTIONS] --check-only
s-postman.py [OPTIONS] --fetch=ACCOUNT [:--fetch=ACCOUNT:]
s-postman.py [OPTIONS] --dispatch=BOX[=TYPE] [::]
s-postman.py --gitmail=ACCOUNT -- GIT-SEND-COMMAND-AND-ARGS
s-postman.py [OPTIONS] --fingerprint=ACCOUNT [::]
s-postman.py [OPTIONS] --foreign=HOST[:PORT] [::]
s-postman.py [OPTIONS] --match-host=PATTERN [::]
s-postman.py [OPTIONS] --convert SOURCE-BOX[=TYPE] TARGET-BOX[=TYPE]

Description

S-Postman is a python tool which is capable to fetch, process and send mail. It is ment for normal end-users (behind an administrated account). What does this mean?

It's configuration is simplicistic and easy to understand. Nonetheless fewest lines of configuration directives should be sufficient to express a relatively complex multi-account mail dispatching situation. It is a portable monolithic script with builtin documentation, directly usable and under full control of the user that is actually using it.

S-Postman doesn't even try to minimize network traffic, it always downloads all of your mails to local storage first. Any action is then applied on that locally stored mails. This is a safe approach. No data-loss has ever been seen until the time of this writing, even at earliest development stages. But in modern times one surely wants to have some spam elimination on the server-side first.

It also means that it's fetching capabilities do not reach those of fetchmail, nor do it's processing capabilities reach those of procmail. And it's sending capabilities don't match sendmail. But it may still be sufficient for most users.

Options

-f DIR, --folder=DIR
 specify the output mail DIRectory to be used
-k, --keep-archives
 don't treat digest (archive) mails as such, even if a [rule] matches which is configured to split them up. (Splitted digest mails are entirely stored in memory..)
-r FILE, --resource=FILE, --rc=FILE
 specify the resource FILE to be used. If this option is missing the S_POSTMAN_RC environment variable is tried, falling back to ~/.s-postmanrc as a last option
-s START, --start=START
 To be used after abnormal program exit, this specifies the ticket number where to start --dispatch'ing. E.g. if the program is interrupted after processing 20 tickets then --start=21 can be used to resume at ticket 21
-V, --verbose be verbose, given twice even more
--cafile=CAFILE
 For --fingerprint and --foreign modes, this optionally specifies a CAFILE which contains a concatenated sequence of PEM (Privacy Enhanced Mail) formatted certificates. If not given the certificates are not verified and thus the calculated fingerprint(s) do not offer any real security. If all else fails you can find a reasonably current CAFILE at http://sourceforge.net/projects/s-cacert
--fatal-errors, --ignore-errors
 automatically handle some errors non-interactively instead of prompting the user. If --ignore-errors is set continuable errors are only logged but don't cause program exit. If --fatal-errors is set instead errors are always fatal. Note that the exit status code will always report any error
--tmpdir=DIR In --fetch or --fetchloop mode this can be used to specify a temporary directory. Please do also see the documentation of the tmpdir configuration variable for more

Modes

-h, --help print usage information and exit
-d, --doc

print rST documentation (long output) and exit. If you have docutils (http://docutils.sourceforge.net) installed, you may use one of the various rst2XY programs to produce a nicely formatted version of it, e.g. you may issue a command line like

$ s-postman.py -d | rst2man.py | groff -mman -Tascii | less

-v, --version print version information and exit
-C, --check-only
 load and process the resource configuration file and exit. Useful in conjunction with -VV to test a setup
-D BOX, --dispatch=BOX
 

open BOX and process it with the configured rules. It is undefined behaviour if BOX may itself match as a target for any [rule]. The mailbox type defaults to mbox, but it is possible to give this parameter as a BOX=TYPE tuple, e.g. --dispatch=somefile=maildir would treat somefile as a mailbox in maildir format - please see --doc for all available mailbox types. As an example, this is what an UNIX user may do to process her local mail:

$ s-postman.py --verbose --keep-archives --dispatch=$MAIL

-F ACCOUNT, --fetch=ACCOUNT
 fetch new mail for the [account] ACCOUNT
-A, --fetchall fetch new mail for all configured [account]s. This is the default mode of operation
-L, --fetchloop
 enter a loop which periodically performs --fetchall. (You can use the job control of your POSIX compliant shell to place the postman in the background - i.e., this is not a 24/7/365 daemon, but only a convenient mode)
--fingerprint=ACCOUNT
 print the SHA-1 fingerprint for the certificates of all (encrypted) services of the [account] ACCOUNT. The output of this command is suitable for adding to the [hostfingerprints] configuration section via copy and paste
--foreign=HOST convenient supplement to --fingerprint: print the SHA-1 and SHA-256 fingerprints of the HOST:PORT pair, e.g. --foreign=google.com:443; if :PORT is omitted it defaults to the default HTTPS port (443). Note this will work only for client-initiated services, not for special protocols like e.g. OpenSSH.
--gitmail=ACCOUNT, --gitmailcc=ACCOUNT
 

convenient way to feed git(1)'s send-email command with necessary arguments for ACCOUNT. The command line after the -- is executed and replaces the postman process. --gitmailcc is identical to --gitmail, but it also produces a Cc: header entry for the fullname of the user. Try the following for a starter:

$ s-postman.py --gitmail=ACCOUNT -- echo hello git

--match-host=PATTERN
 search in [hostfingerprints] for hosts matching the glob-style PATTERN, e.g., *goog*
--convert this is a convenience mode which does not read the configuration file etc. It expects two remaining arguments on the command line: SOURCE-BOX[=TYPE] TARGET-BOX[=TYPE], and then simply reads in SOURCE-BOX sequentially and appends all messages therein to TARGET-BOX. If no =TYPE (see --dispatch) is seen, MBOX is assumed

Configuration

Because the resource file may contain account credentials S-Postman will panic if any other user but the owner can read that file. This is still insufficient to ensure that user credentials remain secure, though - see the ask-user configuration directive for more on security.

Syntax of the resource file

The resource file is treated as a sequence of lines. Lines starting with # are comments. Comments and empty lines are discarded. Lines consisting of [section-name] create/switch to a configuration section named section-name. Other lines are expected to consist of key = value pairs; note that whitespace before and after key and before value is discarded. value lines can be continued over as many lines as required if the newlines are "escaped" with a backslash, as in:

some-key = this value line spreads over multiple lines.\
    At the end of a line, and only there, a backslash may itself \
    be escaped with backslash, just like this: \\

All leading whitespace of follow lines is discarded, but not any trailing whitespace before the backslash.

Directives

Remarks: an "UID" is an "Unique IDentifier", which may consist of characters, digits, hyphens (-), underscores (_) and dots (.) only, and unless otherwise explicitly documented.

# [default] is active by default, but it can always be re-switched to and
# continued by explicitly stating [default] on a line of it's own
[default]

# Overwritten by --folder
# If neither --folder nor this option is set, the S_POSTMAN_FOLDER
# environment variable is inspected; the last fallback is ~/mail.
# Tilde expansion ("~" a.k.a. user home directory) is performed first.
# Finally the result is transformed to an absolute path name
folder = PATH

# Overwritten by --tmpdir (defaults to system's standard temporary dir,
# but for real in tempfile.gettempdir() - see "$ pydoc3 tempfile")
# If the empty string, it'll be set to the (final) value of *folder*.
# (It's getting more and more common that temporary filesystems are only
# memory-based: thus, upon a crash of the operating system, all data
# therein is lost.  But the temporary mailbox of all the downloaded mail
# data is possibly something which should survive a system crash ...)
tmpdir = PATH

# Optional (defaults to mbox; case-insensitive)
# Default type of mailbox.  S-Postman handles MBOX by itself, all other
# mailbox types cause loading of the Python builtin mailbox module
box-type = mbox|Maildir|Babyl|MH|MMDF

# Optional (defaults to false)
# After writing an entire message is completed, fsync(2) is called to
# ensure that disk state is synchronized.  On some operating systems this
# is not enough to ensure data integrity, though;  e.g. on Mac OS X the
# special F_FULLFSYNC fcntl(2) must be issued, which is a very slow task.
# So, whereas during --fetch'ing of data "safe-fsync" is always used (if
# the S-Postman states "sync" it means exactly that), dispatching uses
# the more laxe approach by default (if it fails, rerun with --start)
safe-fsync = BOOLEAN
# *But only for testing purposes!* (defaults to true - of course!)
fetch-safe-fsync = BOOLEAN

# Optional
# If this is given (and enabled) then the [account] entries don't need
# to specify *user* and *password* (so that malicious administrators
# can't figure them out).
# All operation modes which need [account] data (e.g. --fetch, --send)
# will instead prompt on standard input for all (missing) user credent-
# ials of all required accounts before the real operation starts
ask-user = BOOLEAN

## --fetch mode ##

# Optional (defaults to 1000000)
# Whereas --fetch always stores data in a (temporary) MBOX file, it'll
# keep the mail data in memory and use that directly instead of the file
# for the dispatch phase, unless the in-memory size of all the data
# exceeds this limit - thereafter only the file-based backend is used
fetch-memory-limit = NUMBER

# Optional (either of them may be set) TODO fetch hooks are missing
# If set, mail data is piped into STDIN of a hook and read again from the
# hook's STDOUT.  It is treated as a fatal error if the hook fails with
# an exit status that is not 0 or if it does not consume all of the data.
# The raw data passed through to the hook has the native line ending of
# the running system, and that's what the postman expects to get back.
# Note: using hooks is an expensive task, especially in respect to memory
# usage; there are programs which reject working with large files (e.g.
# spamassassin doesn't like mails which are larger than 500KB)
fetch-hook = PATH_TO_PROGRAM
fetch-hook-largemail = PATH_TO_PROGRAM
# Optional (defaults to 242000)
# Size a mail has to have to make the *fetch-hook-largemail* switch occur
fetch-hook-treshold = NUMBER

## --fetchloop mode ## TODO missing

# Optional (defaults to the first [account] ever defined)
# Which [account] shall receive notification mails?
loop-postmaster = uid-of-an-[account]
# Optional (default to 1200 and 300, respectively)
# The time in seconds to wait before looking for new mail
loop-normal = SECONDS
loop-fast = SECONDS
# Optional (defaults to 1)
# How many mails are needed to switch forth to *loop-fast*
# The switch back from *loop-fast* to *loop-normal* is applied in steps;
# each mail that is received during this stepping-period causes the
# interval to be switched to *loop-fast* once again
loop-treshold = NUMBER
# Optional
# If this is set it is treated as a command (and arguments) to be run
# (by the shell) if new mail has been downloaded and dispatched
loop-hook-newmail = ogg321 path_to_mail_arrived_sound.ogg

## [service] ##

# A [service] describes a single fetch or send service (-server)
[service]
uid = UID
# Optional address of the server, e.g. smtp.gmail.com (defaults to *uid*)
url = NAME

# Protocol to use (pop=POP3, imap=IMAP4) TODO IMAP missing
# For fetching: pop, pops, imap, imaps, [test]
# For sending: smtp, smtps, imap, imaps
proto = proto
# Optional port number (defaults to the default of *proto*):
# POP3: 110, POP3S: 995, IMAP4: 143, IMAP4S: 993, SMTP: 25, SMTPS: 465
port = NUMBER

# Optional (if applicable, defaults to true)
# For protocols which don't use SSL/TLS from the start (pop, imap, smtp),
# it may still be possible for the postman to upgrade the connection to
# a secure one (e.g. by using the POP STLS command).  Trying that is
# however an expensive task, and if it is known that a server doesn't
# support SSL/TLS this variable can be used to turn off any check/try
upgrade-secure = BOOLEAN

# IMAP/IMAPS (fetch mode, defaults to INBOX), POP (ditto, fixed: INBOX)
# This can be used to specify several input mailboxes for the IMAP
# protocol.  If set, then INBOX is *not* queried automatically, but
# *must* be included in the list of folders to be fetched
#
# (There is a fetch pseudo-protocol "test": if it's then these are treated
# as paths to MBOX files so that --fetch=ACCOUNT == [:--dispatch=MBOX:])
fetch-folders = mailbox, another-mailbox, ...

# Protocol-dependend options ("else" meaning *any* other value):
# * POP/POPS: no-apop, delete; default: delete.
#   If "delete" is not set, the mails are left alone - this is perfect
#   if the user can control the action for "downloaded messages" on the
#   server-side, e.g. GoogleMail supports several actions for this;
#   since the postman does not and will not support POP UIDL the no-op
#   "action" is a no-go otherwise, since all messages will be downloaded
#   over and over again in this case - if you plan to keep mails on the
#   server you should use the IMAP protocol instead!
#   Note that POP/POPS servers only perform the "delete" action once the
#   connection is closed normally - if a network or other problem occurs
#   before the postman can shutdown the session normally, then the mails
#   will not be consumed but be downloaded once again!
#   "no-apop" can be used to suppress usage of the APOP login - this is to
#   overcome buggy servers which state that they support APOP but fail to
#   do so for real (APOP is used if available because it saves a handshake)
# * IMAP/IMAPS (fetch): delete, seen, else; default: delete.
#   "delete" erases the mail, "seen" (or the empty string) mark it seen.
#   Any other value is treated as the name of a target mailbox on the
#   server, which *must* already exist!  A message will be downloaded,
#   then be copied on the server, then marked deleted in INBOX
# * IMAP/IMAPS (send): name of upload folder - value required.
#   IMAPv4 implements mail sending via the APPEND command, which saves
#   (appends) a message in (to) a named mailbox (directory) on the
#   server, which *must* already exist!
# * SMTP/SMTPS (unused)
options = protocol-dependend (comma separated list of options)

## [account] ##

# [account] links user credentials and some policies to [service]s.
[account]
# *uid* effectively serves as an alias, because --send will expand a
# mail's "From: *uid*" line to "From: *fullname* <*address*>".
uid = UID

# User credentials (also see *ask-user* directive in [default])
# Note: a *user* or *password* which is defined to an empty (whitespace
# only) value is treated as being defined!
user = name-of-user-at-somewhere
password = password-of-user-at-somwhere

# Optional (defaults to *user*).
# The user's full name, mostly for expansion purposes in "From:" lines
fullname = Some Long Name

# The mail address of the account.
# Used for logging and expansion purposes in "From:" lines
address = user@somewhere.com

# Support for --fetch and --send.  At least one of them must be defined
# It is possible to specify multiple services for fetching, but only one
# may be specified for sending
fetch = uid-of-a-[service], uid-of-another-[service], ...
send = uid-of-a-[service]

# Optional (by default inherited from [default] variables of equal name)
# You may override the global interval settings on a per-[account] base.
# Note: due to implementation simplicity this clones the global values
# which are active once any of these is overwritten; thus: either set
# the global ones before any [account] or specify all values explicitly
loop-normal = SECONDS
loop-fast = SECONDS
loop-treshold = NUMBER

## [box] ##

# [box]: a local mailbox
# Note 1: a mailbox with uid NULL always exists - it's a data sink
# Note 2: [box] is effectively optional: if one refers to the *uid* of
# a box which is not defined, then a "virtual" [box] with that *uid*
# (and none of the optional fields) is created (verbose mode logs this).
[box]
uid = UID

# Optional (defaults to concatenation of [default] *folder* and *uid*)
# If set "~" user home directory expansion is performed and the
# resulting path is made absolute (*folder* can be bypassed like that).
# If PATH starts with "+", then that step is omitted and the path is
# relative to *folder* (always true if *path* is created from *uid*).
# Intermediate directories are *not* created
path = PATH

# Optional (defaults to global *box-type*)
type = same as [default] box-type

## [rule] ##

# [rule]s combine a series of commands to be applied against mails.
[rule]
uid = UID
COMMANDS
# .. COMMANDS are described in the section "Command syntax" below

## [ruleset] ##

# [ruleset] is the dispatch work pipeline.  All mails are piped through
# it, [rule]s are applied in the order in which they are specified here.
# The values specify the list of active target [box]es to which mails
# will be saved if the [rule] matches (but see "Command syntax" below)
# Note 1: [ruleset] is single instance, but it can be continued by
# re-opening the [ruleset] section as often as necessary.
# Note 2: the [ruleset] must contain at least one rule; that however
# may be the special ANY rule
[ruleset]
uid-of-a-[rule] = uid-of-a-[box]
uid-of-another-[rule] = uid-of-a-[box], uid-of-another-[box], ...

# The next line specifies the ANY rule: if a mail reaches it (has not
# been consumed by one of the [rule]s) it'll be saved directly in the
# mentioned [box]es.  If no [box] is set in the value, or there is no
# ANY rule last, then mails which reach this point will disappear in
# a NULL data sink.  The ANY rule must be the last rule in [ruleset]
$ = uid-of-a-[box]

## %include statements ##

# The next line includes the file .fingerprints, which is looked up
# relative to the directory where .s-postmanrc has been loaded from.
# "~" user home directory expansion is however also performed.
# Recursive inclusions are supported.
# Access checks just as for the resource file itself are not performed,
# but it's a fatal error if the file to be included doesn't exist.
# Note that an %include finishs the currently active [section]
%include .fingerprints

## [hostfingerprints] ##

# [hostfingerprints] is single instance, but it can be continued by
# re-opening the [hostfingerprints] section as often as necessary.
# HOSTNAME is the hostname to connect to, i.e., pop.gmail.com.
# It may be a shell-style pattern (for fnmatch(3)), i.e. *.gmail.com;
# *NOTE:* this would match "a.gmail.com" *but also* "a.b.c.gmail.com"!!
# FINGERPRINT is the fingerprint of the server's certificate
[hostfingerprints]
HOSTNAME = FINGERPRINT
HOSTNAME2 = FINGERPRINT2

Tip: to fill in the [hostfingerprints] section --fingerprint is provided. If you're on a POSIX system with a POSIX compliant shell, and have OpenSSL tools and sed(1) installed, you may also do something like this instead:

$ ( echo GET / | \
    openssl s_client -showcerts -connect SERVER:PORT ) 2>/dev/null | \
  sed -e '/^-----BEGIN CERTIFICATE-----$/b CERT' -e 'd' -e ':CERT' \
      -e 'n; /^-----END CERTIFICATE-----$/q; b CERT' | \
  openssl x509 -fingerprint -sha1 -noout

Rule command syntax

Where a regular expression is required a valid python re is expected; issue a "$ pydoc3 re" on your command line for an overview. The most important note for normal usage however is that literal dots must be escaped with a backslash, as in \. or python\.org. And a wildcard match can be achieved with a (unescaped) dot followed by a star, as in .*google.*\.com, which would match all of google.com, googlemail.com and googlecode.com, but also bad-bad-intruder-fakes-google.com. And be aware that the regular expression is compiled case-insensitive (re.IGNORECASE).

PASS: ?header-field[,header-field] = regular expression
Break off this rule and return control to the [ruleset] if the regular expression does not match one of the specified header fields.
HIT: !header-field[,header-field] = regular expression
End rule processing and save the mail in all active [box]s if the regular expression matches against the header fields. This "consumes" the mail, meaning that the [ruleset] will immediately start to match the next mail (ticket).
DELETE: ~header-field[,header-field] = regular expression
End rule processing and delete the mail if one of the given header fields matches the regular expression.
BRANCH: @uid-of-a-[rule][@header-field,..] = [regular expression]
Branch off to the specified rule if the regular expression matches. @header-field(s) and regular expression are optional - if only @uid-of-a-[rule] is given the branch is performed unconditionally; otherwise it is performed only if one of the header fields matches. When branching off to another rule the list of active [box]s is copied, but no other state. When the branch returns because the mail has not been consumed inside of it, then the state is restored to exactly the same that it was before the branch has been followed. It is verified that nesting of rules does not exceed 99 levels; that is so to avoid endless loops in rule branching.
ANY: $ = value-ignored
End rule processing and save mail in all active [box]s. If this is used it must be the last rule, and it is only valid after a PASS, HIT, DELETE or BRANCH has been seen (in the rule).
SPLITTER: * = name-of-splitter (or no value)

Change the [rule]'s idea of what splitter is used to split archive mails. I.e., one may register to the daily or weekly digest of a mailing-list and use a splitter to turn these into individual mails again, which is nice for displaying threads and of course easier for responding purposes. You should be aware of the fact that mails that are splitted off such digests are entirely stored in memory, though. Without giving any value this turns off archive splitting. The command line option --keep-archives can be used to globally disable splitting of mails regardless of chosen splitters. Supported mail-digest archive splitters are:

  • text-digest. All RFC 934/1153 ("Digest Message Format") compliant mailing list digests should do. (ezmlm-idx, Majordomo 2, GNU Mailman and Ecartis are known to work. Ecartis however does not implement correct header reordering. And GNU Mailman produces trailers which are not covered by any standard. Therefore S-Postman implements a rather laxe algorithm.)
  • mime-digest TODO this is missing (anybody really using it?)
PLUG: : = uid-of-a-[box] (or no value)
Change the rule's list of active targets to uid-of-a-[box]. If value is omitted it resets the targets to the list which was active at entry of the [rule].
PLUG-ADD: :+ = uid-of-a-[box]
Adds a box to the list of active targets. NULL is not allowed.
PLUG-SUB: :- = uid-of-a-[box]
Removes a box from the active targets. NULL is not allowed.

E.g. the following [ruleset]/[rule] combination does the following:

  1. The ruleset will start to match mail against the rule SomeDomain.
  2. The rule lets mail PASS which comes From: @SomeDomain.org, goes To: this server or which is carbon-copied (Cc:) to there. If this does not match the rule returns processing to the ruleset.
  3. It will be a HIT if To: or Cc: contain the word announce (optionally preceeded by owner-), causing the mail to be saved in box-uid-one, the only entry in the list of currently active targets. If this command matches then the mail is consumed.
  4. PLUG changes the list of targets to box-uid-two (exclusively).
  5. SPLITTER defines the text-digest splitter to be used from now on.
  6. If the Subject: of a mail contains the string digest, go and pipe it's contents through the text-digest splitter and save all splitted mails in box-uid-two; note that mails which have been splitted off digests do not reenter [ruleset], and are thus saved in those targets in which the archive mail would have been saved! If this command matches then the mail is consumed.
  7. SPLITTER disables use of splitters again (empty value).
  8. ANY matches all other @SomeDomain.org mails and thus consumes any mail which reaches this point.
  9. Ruleset starts rule GMail.
  10. Rule GMail will HIT for all mail which comes from @gmail.com or @googlemail.com.
  11. The rule is completed. If the mail reaches this point, then processing control is passed back to the [ruleset].
  12. Ouch - no ANY rule! Any mail which reaches this point will disappear in the NULL data sink!
[ruleset]
SomeDomain = box-uid-one
GMail = box-uid-three

[rule]
uid = SomeDomain
?from,to,cc = @SomeDomain\.org
!to,cc = (owner-)?announce
: = box-uid-two
* = text-digest
!subject = digest,
* =
$ =

[rule]
uid = GMail
!from = @g(oogle)?mail\.com

Note that the subject header-field may be abbreviated with sub for convenience.

Exit Codes

The used exit codes are a subset of those of fetchmail. Note that this means that 1 (NOMAIL) cannot be used to simply mean "failure" in all modes which are not somehow --fetch related; thus a normal error is almost always "mapped" to 5 (SYNTAXENV).

0 (OK)
One or more mails were successfully retrieved and dispatched. In other modes than --fetch this indicates success. Errors are not masked: this value is only used if no errors occurred; conversely, if multiple errors occur, the status code of the last error will be returned
1 (NOMAIL)
The contacted servers did not advertise any mail for downloading
2 (CONNECTION)
It was impossible to create a connection to a server, or a certificate authentification failed, or a login was denied
4 (FATAL)
The unspecific and fuzzy catch-all error
5 (SYNTAXENV)
There was a syntax error in a resource file, or command line arguments were falsely used, or some kind of environmental error occurred, such as a missing resource file
6 (PERMISSION)
The resource file has been found to have bad permissions, or a file or directory cannot be created due to missing permissions, or access to a path was denied
23 (BUG)
Users should not see S-Postman bugs. Really sorry if you do

TODO:

  • Maybe: offer os.path.expandvars for RC values?

  • With a --fetch-dispatch-local (or so) the S-Postman could be used as a plain fetchmail(1) replacement; i.e. with a fetch-dispatch-hook config-var class Dispatch could call the hook to forward downloaded mails into the local mail queue. But i dunno why anybody would like to use mail-local/procmail instead of normal dispatch processing though :-)

  • Once the --send mode is implemented, .s-postmanrc (or one of it's %include's) is the only file which stores user-credentials necessary for mail processing. S-Postman yet offers the possibility to read credentials from STDIN as necessary. Even better would be if it would support ssh-agent or gpg-agent interaction to query credentials, via a credential-hook config-var proxy!

  • --dbtalk: after --send is done this will be the last module of S-Postman. It'll use a SQLite3 database to archive mails in a compressed form and will offer accessibility via an email interface. I.e. one sends a mail with From:ACCOUNT and To:SPECIAL and Subject:VERY_SPECIAL, and S-Postman will swallow this mail and enter some special processing mode.

    • Mummify: creates a TOC mail of requested [box]es like this:

      Ticket NUMBER
      # From:
      # To:
      # Date:
      # Subject:
      ...
      

      The user edits the mail in-place and replies, and all tickets which are not commented out will be removed from the [box] and stored in the database in a compressed form.

    • Resurrect: same game, but the TOC listing is from the DB. It is planned that a special syntax can be used to specify the SELECT statement to be used for creating the TOC. Resurrected mails will be moved directly to the [box] which they have been stripped from (no dispatching).

    • Drop: Like resurrect, but move to NULL.

S-Postman v0.4.0-beta6
Copyright (c) 2011 - 2012 Steffen "Daode" Nurpmeso.
All rights reserved.
This software is provided under the terms of the ISC license.
Please mail any report to <sdaoden@users.sf.net>

Copyright (c) 1997 - 2016, Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>
@(#)code-postman.html-w42 1.8 2015-09-23T12:39:43+0000