SPAMC(1)

๐Ÿ’Œ SPAMC(1) โ€” the spamd client, but make it make sense

okay bestie, welcome to spamc, the client half of the legendary spamc/spamd duo โœจ like, this is the manual page for it, and we're gonna get through it together, no cap.

๐ŸŒธ NAME ๐ŸŒธ

spamc โ€” client for spamd ๐Ÿซถ

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

spamc [options] < message

๐Ÿ’… DESCRIPTION ๐Ÿ’…

So spamc is literally the client half of the spamc/spamd pair, periodt. You use it instead of spamassassin when you're scripting mail processing, and it's giving "same job, way less overhead."

Here's the vibe: it reads the mail from STDIN, spools it over to its connection to spamd, then reads the result back and prints it to STDOUT. And the way that it loads is so fast โ€” like, extremely low overhead โ€” so it should load way, way quicker than the whole entire spamassassin program. iconic behavior honestly ๐Ÿ”ฅ

If you want the full lore, there's a README file in the spamd directory of the SpamAssassin distribution with more details. iykyk ๐Ÿ’–

โœจ OPTIONS โœจ

Every single option below can be passed as a command line argument or live inside a configuration file โ€” the CONFIGURATION FILE section below explains that whole situation.

heads up bestie: the long options (the --long-options style ones) are new as of SpamAssassin 3.2.0, so they were not a thing in earlier versions. don't come for me, that's just the facts ๐Ÿ™ˆ
  • -B, --bsmtp โ€” assumes the input is a single BSMTP-formatted message. In other words, spamc pulls out everything between the DATA line and the lone-dot line to feed to spamd, then places the spamd output back in the same envelope. so like, any SIZE extension in your BSMTP file will cause many problems โ€” consider yourself warned ๐Ÿ’€
  • -c, --check โ€” just checks if the message is spam or not. the process exitcode gets set to 1 if the message is spam, and 0 if it's not spam or a processing failure occurs. it prints score/threshold to stdout (as ints), or 0/0 if there was an error. also: combining -c and -E is a no-op, because -c already implies the behavior of -E. slay ๐Ÿ’…
  • -d host[,host2], --dest=host[,host2] โ€” in TCP/IP mode, connects to the spamd server on the given host (default: localhost). you can specify several hosts if you separate them with commas.

If a host resolves to multiple addresses, spamc will fail-over to the other addresses if the first one can't be connected to. it tries all the addresses of one host before moving on to the next one in the list. but ngl, this fail-over behavior is incompatible with -x โ€” if that switch is used, fail-over will not occur. not me warning you twice ๐Ÿ˜ญ

  • -4 โ€” uses IPv4 only for connecting to the server. it restricts domain name resolution of the spamd server host(s) to address family AF_INET through the hints.ai_family flag in the call to getaddrinfo(3).
  • -6 โ€” uses IPv6 only for connecting to the server. it restricts domain name resolution of the spamd server host(s) to address family AF_INET6 through the hints.ai_family flag in the call to getaddrinfo(3).
  • -e command [args], --pipe-to command [args] โ€” instead of writing to stdout, pipes the output to the command's standard input. but babes, there's a very slight chance mail will be lost here, because if the fork-and-exec fails there's no place to put the mail message ๐Ÿซ 

Also, this must be the LAST command line option, because everything after the -e is taken as arguments to the command (it's like rxvt or xterm, if you know those).

this option is not supported on Win32 platforms. ๐Ÿ’€
  • -E, --exitcode โ€” filters according to the other options, but sets the process exitcode to 1 if the message is spam, 0 if it's not spam or a processing failure occurs.
  • -F /path/to/file, --config=path โ€” specifies a configuration file to read additional command-line flags from. see CONFIGURATION FILE below ๐Ÿ‘‘
  • -h, --help โ€” prints this help message and terminates without doing anything. the "no thoughts, just vibes" option.
  • -H, --randomize โ€” for TCP/IP sockets, randomizes the IP addresses returned for the hosts given by the -d switch. this gives you a simple kind of load balancing. it will only try three times though โ€” three strikes and it's out, bestie ๐ŸŒˆ
  • -l, --log-to-stderr โ€” sends log messages to stderr instead of to the syslog.
  • -L learn type, --learntype=type โ€” sends the message to spamd for learning. the learn type can be either spam, ham or forget. the exitcode for spamc is set to 0 if the message was learned or if it had already been learned. non-zero exitcodes indicate an actual failure of some sort.
note that spamd must run with the --allow-tell option for this to work. no --allow-tell, no telling โœ‹
  • -C report type, --reporttype=type โ€” reports or revokes a message to one of the configured collaborative filtering databases. the report type can be either report or revoke.
same deal: spamd must run with the --allow-tell option for this to work ๐Ÿ’œ
  • -p port, --port=port โ€” in TCP/IP mode, connects to the spamd server listening on the given port (default: 783).
  • -r, --full-spam โ€” just outputs the SpamAssassin report text to stdout, if the message is spam. if the message is ham (non-spam), nothing gets printed. the first line of the output is the message score and the threshold, in this format:
score/threshold
  • -R, --full โ€” just outputs the SpamAssassin report text to stdout, for all messages. see -r for the details of the output format used. equal opportunity reporting, we love to see it โœจ
  • -s max_size, --max-size=max_size โ€” sets the maximum message size that will be sent to spamd. anything bigger than this threshold and the message will be returned unprocessed (default: 500 KB). if spamc gets handed a message bigger than this, it won't be passed to spamd. the maximum message size is 256 MB.

the size is specified in bytes, as a positive integer greater than 0. for example, -s 500000.

  • --connect-retries=retries โ€” retries connecting to spamd retries times. the default is 3 times.
  • --retry-sleep=sleep โ€” sleeps for sleep seconds between attempts to connect to spamd. the default is 1 second.
  • --filter-retries=retries โ€” retries filtering retries times if the spamd process fails (usually times out). this differs from --connect-retries in that it times out the transaction after the TCP connection has been established successfully. the default is 1 time (ie. one attempt and no retries).
  • --filter-retry-sleep=sleep โ€” sleeps for sleep seconds between failed spamd filtering attempts. the default is 1 second.
  • -S, --ssl โ€” if spamc was built with support for SSL, encrypts data to and from the spamd process with SSL; spamd must support SSL as well. secure the bag ๐Ÿ”’
  • --ssl-cert=certfile โ€” authenticates to the spamd server with a SSL client certificate. specify the certificate file to use.
  • --ssl-key=keyfile โ€” authenticates to the spamd server with a SSL client certificate. specify the certificate key file to use.
  • --ssl-ca-file=cafile โ€” uses the specified Certificate Authority certificate to verify the server certificate. the server certificate must be signed by this certificate.
  • --ssl-ca-path=capath โ€” uses the Certificate Authority certificate files in the specified set of directories to verify the server certificate. the server certificate must be signed by one of these Certificate Authorities. see the man page for IO::Socket::SSL for additional details.
  • -t timeout, --timeout=timeout โ€” sets the timeout for spamc-to-spamd communications (default: 600, 0 disables). if spamd takes longer than this many seconds to reply to a message, spamc aborts the connection and treats this as a failure to connect; in other words the message will be returned unprocessed.
  • -n timeout, --connect-timeout=timeout โ€” sets the timeout for spamc-to-spamd connection establishment (default: 600, 0 disables). if spamc takes longer than this many seconds to establish a connection to spamd, spamc aborts the connection and treats this as a failure to connect; in other words the message will be returned unprocessed.
  • -u username, --username=username โ€” to have spamd use per-user-config files, run spamc as the user whose config files spamd should load; by default the effective user-ID is sent to spamd. but if you're running spamc as some other user (eg. root, mail, nobody, cyrus, etc.) then you may use this flag to override the default. main character energy for your user ID ๐Ÿ‘‘
  • -U socketpath, --socket=path โ€” connects to spamd via UNIX domain socket socketpath instead of a TCP/IP connection.
not supported on Win32 platforms ๐Ÿ’€
  • -V, --version โ€” reports the version of this spamc client. if built with SSL support, an additional line will be included noting this, like so:
SpamAssassin Client version 3.0.0-rc4
  compiled with SSL support (OpenSSL 0.9.7d 17 Mar 2004)
  • -x, --no-safe-fallback โ€” disables the 'safe fallback' error-recovery method, which passes through the unaltered message if an error occurs. instead, it exits with an error code and lets the MTA queue up the mails for a retry later. see also EXIT CODES.
also, this disables the TCP fail-over behavior from -d. yeah, the one i mentioned earlier. told you ๐Ÿ’…
  • -X, --unavailable-tempfail โ€” when disabling 'safe fallback' with -x, this option turns EX_UNAVAILABLE errors into EX_TEMPFAIL. this may allow your MTA to defer mails with a temporary SMTP error instead of bouncing them with a permanent SMTP error. see also EXIT CODES.
  • -y, --tests โ€” just outputs the names of the tests hit to stdout, on one line, separated by commas. like a little receipt of chaos ๐Ÿ“
  • -K โ€” performs a keep-alive check of spamd, instead of a full message check. just checking it's still breathing, bestie ๐Ÿซถ
  • -z โ€” uses gzip compression to compress the mail message sent to spamd. this is useful for long-distance use of spamc over the internet. note that this relies on zlib being installed on the spamc client side, and the Compress::Zlib perl module on the server side; an error will be returned otherwise.
  • --headers โ€” performs a scan, but instead of allowing any part of the message (header and body) to be rewritten, it limits rewriting to only the message headers. this is much more efficient in bandwidth usage, since the response message transmitted back from the spamd server will not include the body. efficiency queen ๐ŸŒธ
ngl this only makes sense if you're using report_safe 0 in the scanning configuration on the remote end; with report_safe 1, it is likely to result in corrupt messages. so like, don't do that ๐Ÿ™ˆ

๐ŸŽ€ CONFIGURATION FILE ๐ŸŽ€

okay so bestie, plot twist: all those command-line switches we were just talking about? They can also be loaded from a configuration file. iconic, right? ๐Ÿ’…

The format of the file is similar to the SpamAssassin rules files. Blank lines and lines beginning with # are ignored. Any space-separated words are considered additions to the command line, and are prepended. Newlines are treated as equivalent to spaces. Existing command line switches will override any settings in the configuration file. no cap โœจ

If the -F switch is specified, that file will be used. Otherwise, spamc will attempt to load spamc.conf in SYSCONFDIR (default: /etc/mail/spamassassin). If that file doesn't exist, and the -F switch is not specified, no configuration file will be read.

Example:

# spamc global configuration file

# connect to "server.example.com", port 783
-d server.example.com
-p 783

# max message size for scanning = 350k
-s 350000

๐Ÿ’€ EXIT CODES ๐Ÿ’€

By default, spamc will use the safe fallback error recovery method. That means it will always exit with an exit code of 0, even if an error was encountered. If any error occurs, it will simply pass through the unaltered message. lowkey comforting tbh ๐Ÿซถ

The -c and -E options modify this; instead, spamc will use an exit code of 1 if the message is determined to be spam.

If one of the -x, -L or -C options are specified, safe fallback will be disabled, and certain error conditions related to communication between spamc and spamd will result in an error code. highkey important bestie ๐Ÿ‘‘

The exit codes used are as follows:

EX_USAGE        64  command line usage error
EX_DATAERR      65  data format error
EX_NOINPUT      66  cannot open input
EX_NOUSER       67  addressee unknown
EX_NOHOST       68  host name unknown
EX_UNAVAILABLE  69  service unavailable
EX_SOFTWARE     70  internal software error
EX_OSERR        71  system error (e.g., can't fork)
EX_OSFILE       72  critical OS file missing
EX_CANTCREAT    73  can't create (user) output file
EX_IOERR        74  input/output error
EX_TEMPFAIL     75  temp failure; user is invited to retry
EX_PROTOCOL     76  remote error in protocol
EX_NOPERM       77  permission denied
EX_CONFIG       78  configuration error

* The EX_TOOBIG error level is never used.  If spamc receives a message
  that is too big, the exit code will be 0.

EX_TOOBIG       98  message was too big to process (see --max-size)
bestie please clock the EX_TOOBIG note: that error level is never used, and if spamc receives a message that is too big, the exit code will be 0. the way that's giving exception-to-the-rule energy ๐Ÿ˜ญ

๐ŸŒˆ SEE ALSO ๐ŸŒˆ

spamd(1) spamassassin(1) Mail::SpamAssassin(3)


๐Ÿฆ‹ PREREQUISITES ๐Ÿฆ‹

Mail::SpamAssassin


๐Ÿ‘‘ AUTHORS ๐Ÿ‘‘

The SpamAssassin(tm) Project <https://spamassassin.apache.org/>


SpamAssassin is distributed under the Apache License, Version 2.0, as described in the file LICENSE included with the distribution.


and that's the whole vibe, bestie โ€” page brought to you by perl v5.42.0, dated 2025-08-31, footer flexing SPAMC(1). slay, read the manual, stay hydrated ๐Ÿ’–โœจ๐ŸŽ€๐Ÿฆ‹๐Ÿ’…

๐Ÿ“ฆ where this page comes from