=head1 NAME

inn.conf - Configuration data for InterNetNews programs

=head1 DESCRIPTION

F<inn.conf> in I<pathetc> is the primary general configuration file for
all InterNetNews programs.  Settings which control the general operation
of various programs, as well as the paths to all portions of the news
installation, are found here.  The INNCONF environment variable, if set,
specifies an alternate path to F<inn.conf>.

This file is intended to be fairly static.  Any changes made to it will
generally not affect any running programs until they restart.  Unlike
nearly every other configuration file, F<inn.conf> cannot be reloaded
dynamically using ctlinnd(8); innd(8) must be stopped and restarted for
relevant changes to F<inn.conf> to take effect (C<ctlinnd xexec innd> is
the fastest way to do this.)

Blank lines and lines starting with a number sign (C<#>) are ignored.  All
other lines specify parameters, and should be of the following form:

    <name>: <value>

(Any amount of whitespace can be put after the colon and is optional.)
If the value contains embedded whitespace or any of the characters C<<
[]<>{}"\:; >>, it must be enclosed in double quotes ("").  A backslash (C<\>)
can be used to escape quotes and backslashes inside double quotes.  <name>
is case-sensitive; C<server> is not the same as C<Server> or C<SERVER>.
(F<inn.conf> parameters are generally all in lowercase.)

If <name> occurs more than once in the file, the first value is used.
Some parameters specified in the file may be overridden by environment
variables.  Most parameters have default values if not specified in
F<inn.conf>; those defaults are noted in the description of each
parameter.

Many parameters take a boolean value.  For all such parameters, the value
may be specified as C<true>, C<yes>, or C<on> to turn it on and may be any
of C<false>, C<no>, or C<off> to turn it off.  The case of these values is
significant.

This documentation is extremely long and organized as a reference manual
rather than as a tutorial.  If this is your first exposure to INN and
these parameters, it would be better to start by reading other man pages
and referring to this one only when an F<inn.conf> parameter is explicitly
mentioned.  Those parameters which need to be changed when setting up a
new server are discussed in F<INSTALL>.

=head1 PARAMETERS

=head2 General Settings

These parameters are used by a wide variety of different components of
INN.

=over 4

=item I<domain>

This should be the domain name of the local host.  It should not have a
leading period, and it should not be a full host address.  It is used only if
a fully qualified domain name cannot be found.  INN first tries to retrieve it
from the INN_HOSTNAME environment variable if set, then from gethostname(3)
and getaddrinfo(3) calls.  The check is very simple; if the retrieved
hostname contains a period, then it is assumed to have the full domain name.
Otherwise, a dot followed with the value of I<domain> is appended to the
retrieved hostname.  The default value is unset.

You are encouraged to declare your fully qualified domain name in
F</etc/hostname>, or in the INN_HOSTNAME environment variable if you can't.

The intent is to obtain a hostname guaranteed to be unique, so a value
like C<localhost.localdomain> for the hostname or C<localdomain> for the
I<domain> parameter should be avoided.  Ideally, a domain affiliated with the
administrators of the news server should be used.

This parameter is not meant to be used to affect the right-hand side
of autogenerated Message-IDs; you have to directly use I<domain> in
readers.conf(5) instead, for backward compatibility reasons.  (The name of this
parameter in F<readers.conf> will likely be changed in a future major release
to disambiguate its use.)

=item I<innflags>

The flags to pass to B<innd> on startup.  See innd(8) for details on the
possible flags.  The default value is unset.

Note that these flags are only used when B<innd> is started from B<rc.news>
or B<nntpsend>.

=item I<mailcmd>

The path to the program to be used for mailing reports and errors to the news
administrator.  The default is I<pathbin>/innmail.  This should not normally
need to be changed.

=item I<mta>

The command to use when sending a mail (e.g. mailing postings to moderators,
gatewaying news to mail, sending statistics to the TOP1000 project, mailing
errors and reports to the news administrator).  Some programs use innmail(1)
which in turn runs the command in the I<mta> parameter.  The message, with its
headers, will be piped into this I<mta> program.  Depending on the calling
program, additional header fields may be added when appropriate, like To,
Subject or Auto-Submitted header fields.

The string C<%s>, if present, will be replaced by the expected recipientZ<>(s)
like the e-mail address of the moderator or of a remote list.  It's strongly
recommended for this command to end with C<%s> on the command line rather
than, when not present, use the addresses in the To and Cc header fields of
the message, since the latter approach allows the news server to be abused as
a mechanism to send mail to arbitrary addresses and will result in unexpected
behaviour.  There is no default value for this parameter; it must be set in
F<inn.conf> or a fatal error message will be logged via syslog.

For most systems, C</usr/lib/sendmail -oi -oem %s> (adjusted for the correct
path to B<sendmail>, and between double quotes) is a good choice.

To improve deliverability of sent mails, especially moderated group
submissions, you are encouraged to install a modern and full-featured MTA
like Postfix instead of a frugal MTA like Nullmailer.  You'll then be able
to configure bounces and benefit from DSN (Delivery Status Notifications).
Useful flags to add, if your I<mta> program supports them, are C<-N failure>
(to only return a DSN on failure, not delay), C<-F 'Newsmaster'> (to set
the full name of the notification), C<-fnewsmaster@server.com> (to set the
envelope sender address), and C<-opnobodyreturn> (a privacy option to only
return headers in the DSN).  Feel free to add any other options you think
appropriate.

=item I<pathhost>

What to put into the Path header field to represent the local site.  This path
identity is added to the Path header field body of all articles that pass
through the system, including locally posted articles, and is also used when
processing some control messages and when naming the server in status reports.
There is no default value; this parameter must be set in F<inn.conf> or INN
will not start.  A good value to use is the fully qualified hostname of the
system.

The main purpose of the path identity is to avoid being proposed by your peers
articles that already contain your path identity in their Path header fields.

In case you are running several internal news servers, you may want to also
set I<pathcluster> so as to define the primary path identity to advertise
to your peers for their use in correctly identifying your news servers and
adding the right path diagnostic (see S<Section 3.2.1> of S<RFC 5537> for more
details about path diagnostics).

=item I<runasgroup>

The group under which the news server will run.  The default is C<news>
(or the group specified at configure time) and should not normally need
to be changed.

=item I<runasuser>

The user under which the news server will run.  The default is C<news>
(or the user specified at configure time) and should not normally need
to be changed.

=item I<server>

The name of the default NNTP server.  If I<nnrpdposthost> is not set and
UNIX domain sockets are not supported, B<nnrpd> tries to hand off
locally-posted articles through an INET domain socket to this server.

B<actsync>, B<getlist>, B<inews>, and B<nntpget> also use this value as
the default server to connect to.  In the latter cases, the value of the
NNTPSERVER environment variable, if it exists, overrides this.  The default
value is unset.  You may want to set it to C<localhost> or the fully qualified
domain name of your local news server or of a remote news server.

B<rnews> uses this value as a fallback when I<nnrpdposthost> is not set, and
there's no localhost server.

=item I<syntaxchecks>

A list of values controlling the level of checks performed by B<innd>
and B<nnrpd>.  For instance:

    syntaxchecks: [ no-laxmid ]

The last occurrence of a given value takes precedence, that is to say
if C<no-laxmid laxmid> is listed, I<laxmid> takes precedence.

Only one check can currently be enabled/disabled:

=over 4

=item I<laxmid> / I<no-laxmid>

The default is I<no-laxmid>, that is to say INN only accepts syntactically
valid Message-IDs.  It strictly follows the standard regarding syntax checks
and will neither accept articles with a syntactically invalid Message-ID nor
propagate them to remote peers.  This setting has the best interoperability.

When I<laxmid> is set, the only requirements on Message-IDs are their length
(between 3 and 250 octets), the presence of surrounding angle brackets, and
the use of allowed printable characters (no matter the order they appear
in the Message-ID).  Notably, Message-IDs containing several consecutive
dots, several C<@> or even no C<@> at all will be accepted.  You shouldn't
set I<laxmid> unless you really need it for special use cases like dealing
with very old articles dating back to B News or having to cope with some
non-compliant news posters which generate such syntactically invalid
Message-IDs, especially in binary newsgroups.  With I<laxmid> set, some of
your remote peers may reject articles you feed them because they enforce more
rules on the syntax of Message-IDs.

Note that even with I<laxmid> set, B<nnrpd> will still ensure that Message-IDs
contain at least an C<@> though.

=back

=back

=head2 Feed Configuration

These parameters govern incoming and outgoing feeds: what size of
articles are accepted, what filtering and verification is performed on
them, whether articles in groups not carried by the server are still
stored and propagated, and other similar settings.

=over 4

=item I<artcutoff>

Articles older than this number of days are dropped.  The default value
is C<10>, which means that an incoming article will be rejected if its
posting date is farther in the past than ten days.

In order to disable that check on date, you can set this parameter to C<0>.

The number on the C</remember/> line in F<expire.ctl> should probably
be one more than that number in order to take into account articles
whose posting date is one day into the future.

=item I<bindaddress>

Which IP address innd(8) should bind itself to.  This must be in
dotted-quad format (nnn.nnn.nnn.nnn).  If set to C<all> or not set, innd
defaults to listening on all interfaces.  The value of the
INND_BIND_ADDRESS environment variable, if set, overrides this setting.
The default value is unset.

This parameter has no effect when systemd socket activation is used.

=item I<bindaddress6>

Like I<bindaddress> but for IPv6 sockets.  If only one of the I<bindaddress>
and I<bindaddress6> parameters is used, then only the socket for the
corresponding address family is created.  If both parameters are used then
two sockets are created.  If neither of them is used, the list of sockets to
listen on will be determined by the system library I<getaddrinfo(3)> function.
The value of the INND_BIND_ADDRESS6 environment variable, if set, overrides
this setting.  The default value is unset.

Note that you will generally need to put double quotes ("") around this
value if you set it, since IPv6 addresses contain colons.

This parameter has no effect when systemd socket activation is used.

=item I<docancels>

This parameter is intended for sites concerned about abuse of cancels, or that
wish to enforce a mechanism to authenticate cancels.  This parameter does not
change how NoCeM notices are processed by perl-nocem(8), and only applies to
cancel articles (with a Control header field) and supersede requests (with a
Supersedes header field).

Unless rejected by the use of a filter hook, B<innd> always accepts and
propagates cancel articles and supersede requests.  However, actually
processing such articles on the local news server depends on this parameter
which can take the following values:

=over 4

=item C<require-auth>

Only articles originally protected by the Cancel-Lock authentication
mechanism can be withdrawn by a valid authenticated cancel article or a valid
authenticated supersede request.  Withdrawals of articles not originally
protected by Cancel-Lock will not be executed.

This is the default value if B<innd> knows how to authenticate cancels
(that is to say if INN was built with Cancel-Lock support).  Otherwise, the
behaviour will be the same as C<none>.

=item C<auth>

Withdrawals of articles not originally protected by the Cancel-Lock
authentication mechanism will always be executed.  However, if the original
article is protected, only a valid authenticated cancel article or a valid
authenticated supersede request will permit withdrawing it.  (If INN was not
built with Cancel-Lock support, such protected articles won't be withdrawn.)

=item C<none>

Neither cancel articles nor supersede requests will be processed; no articles
will be withdrawn.

This is the default value if B<innd> does not know how to authenticate cancels
(that is to say if INN was not built with Cancel-Lock support) as it has no
means to ensure that these withdrawal requests are legitimate.

=item C<all>

B<innd> will process all cancel articles and supersede requests, even if
unauthenticated, forged or with bad authentication.  You should be sure of
what you are doing if you choose that value as any article can be withdrawn
(even by someone who is not the author of the article).

=back

=item I<dontrejectfiltered>

Normally innd(8) rejects incoming articles when directed to do so by
any enabled article filters (Perl or Python).  However, this parameter
causes such articles I<not> to be rejected; instead filtering can be
applied on outbound articles.  If this parameter is set, all articles
will be accepted on the local machine, but articles rejected by the
filter will I<not> be fed to any peers specified in F<newsfeeds> with
the C<Af> flag.  The default value is false.

If this parameter is set, you may also use the I<filtered> key of storage
method entries in F<storage.conf> to store filtered articles in dedicated
storage classes.

=item I<hiscachesize>

If set to a value other than C<0>, a hash of recently received Message-IDs
is kept in memory to speed history lookups.  The value is the amount of
memory to devote to the cache in kilobytes.  The cache is only used for
incoming feeds and a small cache can hold quite a few Message-IDs, so
large values aren't necessarily useful unless you have incoming feeds that
are badly delayed.  B<innreport> can provide useful statistics regarding
the use of the history cache, especially when it misses.  A good value
for a system with more than one incoming feed is C<256>; systems with
only one incoming feed should probably set this to C<0>.  The default
value is C<256>.

=item I<ignorenewsgroups>

Whether newsgroup creation control messages (newgroup and rmgroup) should
be fed as if they were posted to the newsgroup they are creating or
deleting rather than to the newsgroups listed in the Newsgroups header field.
If this parameter is set, the newsgroup affected by the control message
will be extracted from the Control header field and the article will be fed as
if its Newsgroups header field contained solely that newsgroup.  This is useful
for routing control messages to peers when they are posted to irrelevant
newsgroups that shouldn't be matched against the peer's desired newsgroups
in F<newsfeeds>.  This is a boolean value and the default is false.

=item I<immediatecancel>

When using the timecaf storage method, article cancels are normally just
cached to be cancelled, not cancelled immediately.  If this is set to
true, they will instead by cancelled as soon as the cancel is processed.
This is a boolean value and the default is false.

This setting is ignored unless the timecaf storage method is used.

=item I<linecountfuzz>

If set to something other than C<0>, the line count of the article is
checked against the Lines header field body of the article (if present) and the
article is rejected if the values differ by more than this amount.  A
reasonable setting is C<5>, which is the standard maximum signature length
plus one (some injection software calculates the Lines header field before
adding the signature).  The default value is C<0>, which tells INN not to
check the Lines header field of incoming articles.

=item I<maxartsize>

The maximum size of article (headers and body) that will be accepted by
the server, in bytes.  A value of C<0> allows any size of article, but
note that B<innd> will crash if system memory is exceeded.  The default
value is C<1000000> (approximately S<1 MB>).  This is checked against the
article in wire format (CRLF at the end of each line, leading periods
protected, and with the trailing "\r\n.\r\n" at the end).  See also
I<localmaxartsize>.

=item I<maxconnections>

The maximum number of incoming NNTP connections innd(8) will accept.  The
default value is C<50>.

=item I<pathalias>

If set, this value is prepended as a path identity immediately to the right of
I<pathhost> in the Path header field body of accepted articles if it doesn't
already appear in the Path header field.  The default value is unset.

The main purpose of this parameter is when there is some other path identity
that you want to add to the Path header field of every article passing through
your news serverZ<>(s) for some reason, maybe because you used to have some
other path identity and you have peers that are configured to not send you
articles that have already passed through that entity, and you can't get them
to update to your current path identity for some reason.

=item I<pathcluster>

If set, this value is appended as a path identity immediately to the left
of I<pathhost> in the Path header field body of accepted articles if it
isn't already present as the leftmost element of the Path header field body.
The default value is unset.

The main purpose of this parameter is to set the name that you are using
to identify yourself to peers (i.e. the path identity they should expect to
see from you) in the cases where that doesn't match the main path identity
I<pathhost> for this news server.  (The most common case where that happens
is when you have multiple news servers that you want to present as a "united
front" to the outside world and identify as the same virtual server, but you
still want distinct path identities so those servers can internally feed each
other.  Also, even without internal feeds, I<pathcluster> could be set to an
organization name if the organization has multiple news servers.)

=item I<pgpverify>

Whether to enable PGP verification of control messages other than cancel.
This is a boolean value and the default in the F<inn.conf> sample file is
based on whether configure found B<pgp>, B<pgpv>, B<pgpgpg>, B<gpgv>,
B<gpgv1>, B<gpgv2>, B<gpg>, B<gpg1> or B<gpg2>.  Note that if the
parameter is not present in the configuration file, it defaults to false.

=item I<port>

What TCP port innd(8) should listen on.  The default value is C<119>, the
standard NNTP port.

=item I<remembertrash>

By default, innd(8) records rejected articles in history so that, if
offered the same article again, it can be refused before it is sent.  If
you wish to disable this behavior, set this to false.  This can cause a
substantial increase in the amount of bandwidth consumed by incoming news
if you have several peers and reject a lot of articles, so be careful with
it.  Even if this is set to true, INN won't log some rejected articles to
history if there's reason to believe the article might be accepted if
offered by a different peer, so there is usually no reason to set this to
false (although doing so can decrease the size of the history database).  This
is a boolean value and the default is true.

=item I<sourceaddress>

Which local IP address to bind to for outgoing NNTP sockets (used by
innxmit(8) among other programs, as well as innfeed(8) as long as not
overridden by I<bindaddress> in innfeed.conf(5)).  This must be in
dotted-quad format (nnn.nnn.nnn.nnn).  If set to C<all>, the operating
system will choose the source IP address for outgoing connections.  The
default value is unset.

=item I<sourceaddress6>

Like I<sourceaddress> but for IPv6 sockets.  Note that you will generally
need to put double quotes ("") around this value if you set it, since IPv6
addresses contain colons.

=item I<verifygroups>

Set this to true to reject incoming articles which contain an unknown
newsgroup in the whole list of newsgroups to which they are posted.
In case I<wanttrash> is set to true, such articles will still be rejected.
This is a boolean value, and the default is false.

=item I<wanttrash>

Set this to true if you want to file articles posted to unknown newsgroups
(newsgroups not in the F<active> file) into the C<junk> newsgroup rather
than rejecting them.  This is sometimes useful for a transit news server
that needs to propagate articles (according to the setting of C<Aj> in
the F<newsfeeds> feed pattern) in all newsgroups regardless if they're
carried locally.  This is a boolean value and the default is false.

The I<logtrash> parameter specifies whether such articles should be logged
as posted to unwanted newsgroups in the F<news> log file.

=item I<wipcheck>

If INN is offered an article by a peer on one channel, it will return
deferral responses (code 436) to all other offers of that article for this
many seconds.  (After this long, if the peer that offered the article
still hasn't sent it, it will be accepted from other channels.)  The
default value is C<5> and probably doesn't need to be changed.

=item I<wipexpire>

How long, in seconds, to keep track of message IDs offered on a channel
before expiring articles that still haven't been sent.  The default value
is C<10> and probably doesn't need to be changed.

=back

=head2 History Settings

The following parameters affect the history database.

=over 4

=item I<hismethod>

Which history storage method to use.  The supported values are C<hisv6>
and, when INN is built with SQLite, C<hissqlite>.  There is no default
value; this parameter must be set.

=over 4

=item C<hisv6>

Stores history data in the INN history v6 format: history(5) text
file and a number of I<dbz> database files; this may be in true history
v6 format, or tagged hash format, depending on the build
options.  Separation of these two is a project which has not yet been
undertaken.

=item C<hissqlite>

Stores history data in a single SQLite database file, as an alternative
to C<hisv6>.  This requires INN to be built with SQLite support.  See
hissqlite(5).

=back

=item I<hissqlitecachesize>

The SQLite page cache size in kilobytes for the B<innd> writer connection
when the C<hissqlite> history method is used.  The default value is C<65536>
(64 MB).  See hissqlite(5).

=item I<hissqlitemmapsize>

The maximum number of bytes of the C<hissqlite> history database that SQLite
will memory-map, for both the writer and the direct readers.  The default
value of C<0> disables memory-mapped I/O (as with ovsqlite); see hissqlite(5)
for the trade-offs before enabling it.

=item I<hissqlitepagesize>

The SQLite page size in bytes for a newly created C<hissqlite> history
database; it has no effect on an existing one.  Must be a power of two
between 512 and 65536.  The default value is C<4096>, which matches the
common filesystem block size; for best results pair it with the storage
block size (on ZFS, a C<recordsize=4k> dataset, which I<pathhistory> can
point into).  See hissqlite(5).

=item I<hissqlitereadercachesize>

The SQLite page cache size in kilobytes for each B<nnrpd> reader process
using the C<hissqlite> history method.  Each reader has its own cache, so
this is typically kept small.  The default value is C<2000> (about 2 MB).
See hissqlite(5).

=back

=head2 Article Storage

These parameters affect how articles are stored on disk.

=over 4

=item I<cnfscheckfudgesize>

If set to a value other than C<0>, the claimed size of articles in CNFS
cycbuffs is checked against I<maxartsize> plus this value, and if larger,
the CNFS cycbuff is considered corrupt.  This can be useful as a sanity
check after a system crash, but be careful using this parameter if you
have changed I<maxartsize> recently.  The default value is C<0>.

=item I<enableoverview>

Whether to write out overview data for articles.  If set to false, INN
will run much faster, but reading news from the system will be impossible
(the server will be for news transit only).  If this option is set to
true, I<ovmethod> must also be set.  This is a boolean value and the
default is true.

=item I<expirebloomfp>

Controls the Bloom filter used by B<expireover> to accelerate overview
expiration.  The value is the reciprocal of the desired false positive
rate: for example, C<10000> means a 1-in-10,000 (0.01%) false positive
rate.  Higher values use more memory but produce fewer false positives.
At the default of C<10000>, memory usage is approximately 20 bits per
article in the history database (e.g., S<48 MB> for 20 million articles,
S<2.4 GB> for 1 billion articles).

Setting this to C<0> disables the Bloom filter entirely, falling back
to per-article history lookups (the pre-existing behavior).  This is
not recommended for large spools as it results in random I/O into the
C<hisv6> F<history> file or random SQL requests into the C<hissqlite>
history database for every article in the overview database.

The Bloom filter has no effect when B<expireover> is run with the B<-s>
flag (which forces a filesystem stat of every article).

This is a non-negative integer, and the default is C<10000>.

=item I<expiretombstone>

Whether INN tools record cancellation tombstones so a subsequent
B<expire> run can skip per-article storage existence checks.  When
enabled (and I<groupbaseexpiry> is also true), two log files in
I<pathdb> capture every cancellation:

=over 4

=item F<expireover.tombstone>

Written by B<expireover> after each successful C<SMcancel> in
group-based expiry, atomically renamed into place on a clean run.
When B<expireover> runs with the B<-z> flag (delayed removal), the
C<SMcancel> calls are deferred to B<fastrm> via B<expirerm>;
B<expireover> writes the entries up front and B<expirerm> performs
the atomic rename after B<fastrm> succeeds, so the same speedup
applies to delayrm setups.  After B<expire> has consumed this file, it
is unlinked and re-seeded as a header-only successor, matching
the on-disk presence of F<cancels.tombstone>; the next
B<expireover> run overwrites the seeded file with its full
content.

=item F<cancels.tombstone>

Appended continuously by B<innd> when it processes cancel control
messages, and by B<sm -r> for manual cancellations.  Appenders take
a shared fcntl POSIX lock; B<expire> snapshots the file by atomic
rename to F<cancels.tombstone.processing> under an exclusive fcntl
lock, unlinks the snapshot after a successful consume, then recreates
F<cancels.tombstone> as a header-only file under an exclusive lock
so B<nnrpd>'s per-connection fast path stays active through quiet
inter-cancel periods.  An appender that raced a cancel into a new live
file between the rename and the recreate has its content preserved
verbatim below the restored header.  Append atomicity relies on
POSIX guaranteeing that each C<write(2)> to a regular file opened
with C<O_APPEND> is atomic with respect to other writers; this holds
for any size of single C<write> on local filesystems.  Cross-client
atomicity over NFS is not guaranteed: if I<pathdb> is on NFS, lines
from concurrent writers on different clients can in theory interleave.
In practice INN's cancel sources (B<innd> on a single host plus
occasional B<sm -r> on the same host) write from one client.

=back

The next B<expire> invocation loads both files into a single hashset
and treats every article in either log as already gone, avoiding an
C<SMretrieve(RETR_STAT)> call per history entry.  For storage methods
where the stat is a file-system call (tradspool, timehash), this turns
a billion C<access(2)> calls into a few thousand hash lookups; for
storage methods that self-expire (CNFS), the stat call remains because
articles can vanish through wrap-around without going through
C<SMcancel>.

In normal operation, every cancellation path participates in
tombstone tracking, so all articles removed from the spool are
recorded.  Residual orphans can only accumulate from events outside
the tracked paths: a process crash in the narrow window between
C<SMcancel> and the tombstone append, manual filesystem-level
deletes that bypass B<sm -r>, or filesystem corruption.  When such
orphans do appear, they are harmless (B<nnrpd> returns "no such
article" to readers that hit them) and exist only as small history
entries.  No regular reconciliation cadence is needed.  If an
operator suspects orphan accumulation after admin intervention or a
storage incident, B<expire> can be re-run with this option disabled
in F<inn.conf> to perform an exhaustive C<SMretrieve(RETR_STAT)>
scan; this is an exceptional operation, not a scheduled one.

Footprint: S<~38 bytes> per entry on disk, S<~50 bytes> in expire's
hash table.  For instance, 1 million cancels per run needs S<~38 MB>
for the tombstone and S<~50 MB> for the hash.

This is a boolean value and the default is false; sites should opt in
after validating the option's behaviour against their workload.

=item I<extraoverviewadvertised>

Besides the seven standard overview fields (which are in order C<Subject>,
C<From>, C<Date>, C<Message-ID>, C<References>, C<:bytes> and
C<:lines>) and the eighth C<Xref:full> field required by INN in order
to handle crossposts, it is possible to add other fields in the
overview database.  This parameter expects a list of such header field
names.  Overview data for these additional header fields will be generated
for each new article at the time of arrival.  For instance, if you specify:

    extraoverviewadvertised: [ Path Newsgroups ]

it implies that B<nnrpd> will advertise C<Path:full> and C<Newsgroups:full>
as the ninth and tenth fields in response to LIST OVERVIEW.FMT and that these
two header field bodies will be stored in the overview database for each
new article.  It may be a useful configuration to have as some news readers
do article scoring with rules based on these two header fields.  Having them
in the overview database permits being faster at scoring for these readers,
without having to separately request them, but on the other hand these
additional fields are also present in overview requests of all the other
readers, which slightly slows their reading.

The default value is an empty list (no additional fields are stored).
Owing to optimizations when B<innd> parses the articles it receives, it
is possible that all the values in the list are not recognized by B<innd>
as standard header field names.  In such cases, B<innd> will log an error
in F<news.err> at startup and the unrecognized fields will be discarded.
Moreover, the deprecated C<Bytes> and C<Lines> header fields, already present
in the standard overview fields as metadata items, cannot be added.

You should advertise only fields for which the overview database
is consistent, that is to say it records the content or absence
of these fields for I<all> articles, including those already existing
in the news spool.  Consequently, if you decide to add or remove a field
from your overview database, you should either modify
I<extraoverviewadvertised> and rebuild your overview database with
makehistory(8) after removing all existing overview files, or implement
a transition period by first using I<extraoverviewhidden> as described below.

Use of a transition period can accommodate most overview reconfigurations,
but certain drastic changes may still require a complete overview rebuild.

If for instance you want to store the content of the Injection-Info header
field body in addition to the fields already stored above, you should use:

    extraoverviewadvertised: [ Path Newsgroups ]
    extraoverviewhidden:     [ Injection-Info ]

This way, C<Injection-Info:full> will not be advertised by B<nnrpd> but
will be stored for each new article.  Once you know that all articles in
your overview database record the content or absence of that new field (if
expire.ctl(5) is parameterized so that all your articles expire within
S<30 days>, you can assume the database is in such a state after S<30 days>
S<-- however>, note that time to expiration can be unpredictable with CNFS and
you then have to use C<cnfsstat -a> for checking on when buffers have rolled
over), you should put:

    extraoverviewadvertised: [ Path Newsgroups Injection-Info ]
    extraoverviewhidden:     [ ]

The C<Injection-Info> value must be added at the end of the list because
order matters and fields mentioned in I<extraoverviewhidden>
are generated after those mentioned in I<extraoverviewadvertised>.
B<nnrpd> will now advertise C<Injection-Info:full> in response to the LIST
OVERVIEW.FMT command (C<full> indicates that the header field name appears
followed by its value).

Now suppose you want to remove the content of the Newsgroups header field
from the overview.  As order matters, the overview database will no longer
be consistent for the Injection-Info header field.  Therefore, you need to
specify:

    extraoverviewadvertised: [ Path ]
    extraoverviewhidden:     [ Injection-Info ]

And once overview data is accurate for all articles, you should use:

    extraoverviewadvertised: [ Path Injection-Info ]
    extraoverviewhidden:     [ ]

Note that you have to restart B<nnrpd> if it runs as a daemon
whenever you change the value of I<extraoverviewadvertised>; a mere
C<ctlinnd xexec innd> is not enough.

=item I<extraoverviewhidden>

This parameter should be used in conjunction with I<extraoverviewadvertised>
(see above for more details).  It expects a list of header field names.
Overview data for these header fields will be generated for each new
article at the time of arrival but, contrary to the fields mentioned in
I<extraoverviewadvertised>, B<nnrpd> will not advertise them in response to
the LIST OVERVIEW.FMT command.  It also implies that B<nnrpd> will not look in
the overview database for fields mentioned in I<extraoverviewhidden> when it
handles HDR, XHDR and XPAT requests as the overview database is not considered
consistent yet for these fields; B<nnrpd> will have to parse the headers
of the requested articles in the news spool, which is slower than directly
querying the overview database.

The default value is an empty list (no additional fields are stored).
Owing to optimizations when B<innd> parses the articles it receives, it
is possible that all the values in the list are not recognized by B<innd>
as standard header field names.  In such cases, B<innd> will log an error
in F<news.err> at startup and the unrecognized fields will be discarded.
Moreover, the deprecated C<Bytes> and C<Lines> header fields, already present
in the standard overview fields as metadata items, cannot be added.

=item I<groupbaseexpiry>

Whether to enable newsgroup-based expiry.  If set to false, article expiry
is done based on storage class of storing method.  If set to true (and
overview information is available), expiry is done by newsgroup name.
This affects the format of F<expire.ctl>.  This is a boolean value and the
default is true.

=item I<mergetogroups>

Whether to file all postings to C<to.*> groups in the pseudonewsgroup
C<to>.  If this is set to true, the newsgroup C<to> must exist in the
F<active> file or INN will not start.  (See the discussion of C<to.>
groups in innd(8) under CONTROL MESSAGES.)  This is a boolean value and
the default is false.

=item I<nfswriter>

For servers writing articles, determine whether the article spool is
on NFS storage.  If set, INN attempts to flush articles to the spool
in a more timely manner, rather than relying on the operating system
to flush things such as the CNFS article bitmaps.  You should only set
this parameter if you are attempting to use a shared NFS spool on a
machine acting as a single writer within a cluster.  This is a boolean
value and the default is false.

=item I<overcachesize>

How many cache slots to reserve for open overview files.  If INN is
writing overview files (see I<enableoverview>), I<ovmethod> is set to
C<tradindexed>, and this is set to a value other than C<0>, INN will keep
around and open that many recently written-to overview files in case more
articles come in for those newsgroups.  Every overview cache slot consumes
two file descriptors, so be careful not to set this value too high.  You
may be able to use the C<ulimit -n> command to see how many open file
descriptors your operating system allows.  innd(8) also uses an open file
descriptor for each incoming feed and outgoing channel or batch file, and
if it runs out of open file descriptors, it may throttle and stop accepting
new news.  The default value is C<128> (which is probably still too low if
you have a large number of file descriptors available).

Please have a look at the documentation of the I<rlimitnofile> parameter,
as increasing the default value may lead to an exhaustion of usable file
descriptors.

This setting is ignored unless I<ovmethod> is set to C<tradindexed>.

=item I<ovgrouppat>

If set, restricts the overview data stored by INN to only the newsgroups
matching this comma-separated list of I<uwildmat> expressions.  Newsgroups not
matching this setting may not be readable, and if I<groupbaseexpiry> is
set to true and the storage method for these newsgroups does not have
self-expire functionality, storing overview data will fail.
The default is unset.

=item I<ovflushcount>

How many articles received between flushing their overview data to disk.
This parameter is only used for the buffindexed overview storage method, and
defaults to C<50>.  (Flushing to disk is parameterized differently for other
methods: I<txn_nosync> in F<ovdb.conf>, I<transrowlimit> and I<transtimelimit>
in F<ovsqlite.conf>, and always after each article arrival for tradindexed.)

See I<icdsynccount> (related to flushes of the F<active> and C<hisv6>
F<history> files) for more information about this trade-off between faster
speed and more data loss if B<innd> crashes.

=item I<ovmethod>

Which overview storage method to use.  Currently supported values are
C<buffindexed>, C<ovdb>, C<ovsqlite> and C<tradindexed>.  There is no
default value; this parameter must be set if I<enableoverview> is true
(the default).

=over 4

=item C<buffindexed>

It stores overview data and index information into preconfigured large files
like CNFS.  Fast at writing, the C<buffindexed> overview storage method can
keep up with a large feed more easily and never consumes additional disk space
beyond that allocated to these buffers.  The downside is that these buffers
are hard to recover in case of corruption and somewhat slower for readers and
the expiry process.  Also, overview data is limited to S<8 KB> per article,
which may lead to the lack of integration of a few articles with headers of
unusual length into the overview database.  See the buffindexed.conf(5) man
page for more details, and notably how to create the buffers.

=item C<ovdb>

It stores overview information into a S<Berkeley DB> database, whose
development pace has stalled these last years.  This method is fast
and very robust, but may require more disk space, unless compression
is enabled.  Overview data is fetched one article at a time, which makes
this method a bit slower than C<ovsqlite> for readers.  See the ovdb(5)
man page for more details.

=item C<ovsqlite>

It stores overview information into an SQLite database, known for its
long-term stability and compatibility.  Robust and faster than C<ovdb>
at reading ranges of overview data (since overview data is transferred in
128-kilobyte chunks between B<ovsqlite-server> and B<nnrpd>) but somewhat
slower at writing, this method may require more disk space, unless
compression is enabled.  See the ovsqlite(5) man page for more details.

=item C<tradindexed>

It uses two files per newsgroup, one containing the overview data
and one containing the index.  Fast for readers, but slow to write to
because it has to update two files for each incoming article.  Its main
advantage is to be the best tested, the most reliable and the method
with the best recovery tools (B<tdx-util>).

=back

=item I<storeonxref>

If set to true, articles will be stored based on the newsgroup
names in the Xref header field body rather than in the Newsgroups
header field body.  This affects what the patterns in F<storage.conf>
apply to.  The primary interesting effect of setting this to true is
to enable filing of all control messages according to what storage
class the control pseudogroups are filed in rather than according to
the newsgroups the control messages are posted to.  This is a boolean
value and the default is true.

If the tradspool article storage method is used, I<storeonxref> must
be true.

=item I<useoverchan>

Whether to innd(8) should create overview data internally through
libinnstorage(3).  If set to false, innd creates overview data by itself.  If
set to true, innd does not create; instead overview data must be created
by overchan(8) from an appropriate entry in F<newsfeeds>.  Setting to true
may be useful, if innd cannot keep up with incoming feed and the
bottleneck is creation of overview data within innd.  This is a boolean
value and the default is false.

=item I<wireformat>

Only used with the tradspool storage method, this says whether to write
articles in wire format.  Wire format means storing articles with C<\r\n> at
the end of each line and with periods at the beginning of lines doubled,
the article format required by the NNTP protocol.  Articles stored in this
format are suitable for sending directly to a network connection without
requiring conversion, and therefore setting this to true can make the
server more efficient.  The primary reason not to set this is if you have
old existing software that looks around in the spool and doesn't
understand how to read wire format.  Storage methods other than tradspool
always store articles in wire format.  This is a boolean value and the
default is true.

=item I<xrefslave>

Whether to act as the slave of another server.  If set, INN duplicates exactly
the article numbering of the server feeding it by looking at the Xref header
field body of incoming articles and assigning the same article numbers
to articles as was noted in the Xref header field body from the upstream
server.  If there is no Xref header field or it is unparsable, the article is
rejected.  The result is that clients should be able to point at either server
interchangeably (using some load balancing scheme, for example) and see the
same internal article numbering.

Servers with this parameter set should generally only have one upstream
feed, and should always have I<nnrpdposthost> set to hand locally posted
articles off to the master server.  The upstream server should be careful
to feed articles in order so as to keep the history database of the slave
server chronologically ordered as the expiration process is based on the
arrival time of the articles (unless the B<-p> flag is given to B<expire> and
B<expireover> to make expiration decisions relative to posting dates instead,
but self-expiring storage methods like CNFS will wrap anyway and remove
articles in the same order they have arrived).  This is a boolean value and
the default is false.

See F<doc/FAQ> (subject 6.4) for an example of use of this parameter
when feeding all articles on a server to another server, keeping their
chronological ordering.

=back

=head2 Reading

These parameters affect the behavior of INN for readers.  Most of them are
used by nnrpd(8).  There are some special sets of settings that are broken
out separately after the initial alphabetized list.

=over 4

=item I<allownewnews>

Whether to allow use of the NEWNEWS command by clients.  This command used
to put a heavy load on the server in older versions of INN, but is now
reasonably efficient, at least if only one newsgroup is specified by the
client.  This is a boolean value and the default is true.  If you use the
I<access> parameter in F<readers.conf>, be sure to read about the way it
overrides I<allownewnews>.

=item I<articlemmap>

Whether to attempt to mmap() articles.  Setting this to true will give
better performance on most systems, but some systems have problems with
mmap().  If this is set to false, articles will be read into memory before
being sent to readers.  This is a boolean value and the default is true.

=item I<clienttimeout>

How long (in seconds) a client connection can be idle before it exits.
When setting this parameter, be aware that some newsreaders use the same
connection for reading and posting and don't deal well with the connection
timing out while a post is being composed.  If the system isn't having a
problem with too many long-lived connections, it may be a good idea to
increase this value to C<3600> (an hour).  The default value is C<1800>
(thirty minutes).

=item I<initialtimeout>

How long (in seconds) B<nnrpd> will wait for the first command from a
reader connection before dropping the connection.  This is a defensive
timeout intended to protect the news server from badly behaved reader
clients that open and abandon a multitude of connections without every
closing them.  The default value is C<10> (ten seconds), which may need to
be increased if many clients connect via slow network links.

=item I<msgidcachesize>

How many cache slots to reserve for message-IDs to storage token
translations.  When serving overview data to clients (NEWNEWS, OVER,
etc.), nnrpd(8) can cache the storage token associated with a message-ID
and save the cost of looking it up in the history database; for some
configurations, setting this parameter can save more than 90% of the
wall clock time for a session.  The default value is C<64000>.

=item I<nfsreader>

For servers reading articles, determine whether the article spool is
on NFS storage.  If set, INN will attempt to force articles and
overviews to be read directly from the NFS spool rather than from
cached copies.  You should only set this parameter if you are
attempting to use a shared NFS spool on a machine acting as a reader
within a cluster.  This is a boolean value and the default is false.

=item I<nfsreaderdelay>

If I<nfsreader> is set, INN will use the value of I<nfsreaderdelay>
to delay the apparent arrival time of articles to clients by this amount.
Note that only answers to GROUP and NEWNEWS commands are affected.  This
value should be tuned based on the NFS cache timeouts locally.  The default
is C<60>, that is to say one minute.

=item I<nnrpdcheckart>

Whether B<nnrpd> should check the existence of an article before listing it
as present in response to an NNTP command (HDR, LISTGROUP, NEWNEWS, OVER,
XPAT).  The primary use of this setting is to prevent B<nnrpd> from returning
information about articles which are no longer present on the server but which
still have overview data available.  Checking existence with an unconditional
C<SMretrieve> slows down the overview commands; with I<expiretombstone> also
enabled (see below) the check uses an in-memory hash lookup instead and is
cheaper than disabling the check on tradspool/timehash/timecaf backends.
The trade-off remains: enabling this reduces the number of "article is
missing" errors seen by the client.  This is a boolean value and the default
is true.

When I<expiretombstone> is also enabled, B<nnrpd> consults the
F<cancels.tombstone> log file in I<pathdb> on the article-existence check
path: a token recorded as cancelled is reported as gone without an
C<SMretrieve> call, and a token absent from the tombstone is
trusted to still exist (skipping the syscall) for storage methods
that do not self-expire.  Self-expiring backends (CNFS) still go
through C<SMretrieve> because cyclic-buffer wrap-around bypasses
the tombstone.  The tombstone is loaded lazily on first use per
connection and refreshed by C<stat> on each call; the parsed
hashset is rebuilt only when the file's mtime or size changes.
Statting the same path is dentry-cache resident and far cheaper
than the per-article syscalls the fast path elides, so cancellations
recorded by other processes become visible to long-lived
connections on the next existence check.

Each B<nnrpd> connection holds an independent copy of the parsed
hashset, costing roughly 50 bytes per cancel; sites with very large
cancel volumes between B<expire> runs and many concurrent readers
should size memory accordingly.  Loss relative to the unconditional
C<SMretrieve> path is bounded to out-of-band events the tombstone
cannot see (manual filesystem deletes that bypass B<sm -r>,
filesystem corruption); admin-initiated B<sm -r> and B<innd>
cancels are tracked.

Important: on non-self-expiring backends, the fast path treats a
tombstone-miss as proof that the article is still on disk, without
verifying.  Admins must remove articles via B<sm -r> (which records
the cancel in the tombstone), not by direct C<rm> on the spool, or
readers will be told a deleted article still exists until the next
B<expireover> reconciles overview.

Note that the fast path is also gated on I<expiretombstone>; both
must be true to take effect.  The B<nnrpdoverstats> C<artcheck>
counter reflects only the slow C<SMretrieve> path, so the syslog
field will appear smaller when the fast path is doing most of the
work.

You may also want to see the I<groupexactcount> parameter in readers.conf(5)
which controls the computing of the estimated article count returned in NNTP
commands (GROUP, LIST COUNTS, LISTGROUP).

=item I<nnrpdflags>

When nnrpd(8) is spawned from innd(8), these flags are passed as
arguments to the nnrpd process.  This setting does not affect instances
of nnrpd that are started in daemon mode, or instances that are started
via another listener process such as inetd(8) or xinetd(8).  Shell
quoting and metacharacters are not supported.  This is a string value
and the default is unset.

=item I<nnrpdloadlimit>

If set to a value other than C<0>, connections to nnrpd will be refused
if the system load average is higher than this value.  The default value
is C<16>.

=item I<noreader>

Normally, innd(8) will fork a copy of nnrpd(8) for all incoming
connections from hosts not listed in F<incoming.conf>.  If this parameter
is set to true, those connections will instead be rejected with a 502
error code.  This should be set to true for a transit-only server that
doesn't support readers, or if nnrpd is running in daemon mode or being
started out of inetd.  This is a boolean value and the default is false.

=item I<readerswhenstopped>

Whether to allow readers to connect even if the server is paused or
throttled.  This is only applicable if nnrpd(8) is spawned from innd(8)
rather than run out of inetd or in daemon mode.  This is a boolean value
and the default is false.

=item I<readertrack>

Whether to enable the tracking system for client behavior.  Tracked
information is recorded to I<pathlog>/tracklogs/log-I<ID>, where ID is
determined by nnrpd's PID and launch time.  Currently the information
recorded includes initial connection and posting; only information about
clients listed in F<nnrpd.track> is recorded.  In addition, every posted
article will be saved in I<pathlog>/trackposts/track.I<message-id>, where
I<message-id> is the message ID of the post.  This is a boolean value and
the default is false.

=item I<tradindexedmmap>

Whether to attempt to mmap() tradindexed overviews articles.  Setting
this to true will give better performance on most systems, but some
systems have problems with mmap().  If this is set to false, overviews
will be read into memory before being sent to readers.  This is a
boolean value and the default is true.

=back

INN has optional support for generating keyword information automatically
from article body text and putting that information in overview for the use of
clients that know to look for it (HDR, OVER and XPAT commands).  The following
parameters control that feature, which should be considered I<experimental>.
Its very simple text tokenization works only on plain-text ASCII articles,
and totally lacks of understanding of anything other than English.  Articles
encoded in Base64 or Quoted-Printable, having a MIME structure, or farther
afield from English will have garbage in the generated Keywords header field.

This feature may be too slow if you're taking a substantial feed, and
probably will not be useful for the average news reader; enabling this is not
recommended unless you have some specific intention to take advantage of it.

=over 4

=item I<keywords>

Whether the keyword generation support should be enabled.  This is a
boolean value and the default is false.

If an article already contains a Keywords header field, no keyword
generation is done and the original Keywords header field is kept untouched.

In order to use this feature, the regex library should be available
and INN configured with the B<--enable-keywords> flag.  Otherwise,
no keywords will be generated, even though this boolean value is set
to true.  You also have to add the Keywords header field into the
overview with I<extraoverviewadvertised> or I<extraoverviewhidden>.

=item I<keyartlimit>

Articles larger than this value in bytes will not have keywords generated
for them (since it would take too long to do so).  The default value is
C<100000> (approximately S<100 KB>).

=item I<keylimit>

Maximum number of bytes allocated for keyword data.  If there are more
keywords than will fit into this many bytes when separated by commas, the
rest are discarded.  The default value is C<512>.

=item I<keymaxwords>

Maximum number of keywords that will be generated for an article.  (The
keyword generation code will attempt to discard "noise" words in English,
so the number of keywords actually written into the overview will usually
be smaller than this even if the maximum number of keywords is found.)
The default value is C<250>.

=back

=head2 Posting

These parameters are only used by nnrpd(8), inews(1), and other programs
that accept or generate postings.  There are some special sets of settings
that are broken out separately after the initial alphabetized list.

=over 4

=item I<addinjectiondate>

Whether to add an Injection-Date header field to all local posts.
This is a boolean value and the default is true.

Note that no Injection-Date header fields will be added to local posts
already containing both a Message-ID header field and a Date header
field.  This is done in conformance with standards, to help minimize
the possibility of a loop in e-mail gatewaying and ensure that a newly
injected article is not treated as a new, separate article in case of
multiple injection of the same article to different injecting agents.

=item I<addinjectionpostingaccount>

Whether to add a posting-account attribute to the Injection-Info header
field body to all local posts giving the username assigned to the user
at connection time or after authentication.  This is a boolean value and
the default is false.  There is no intrinsic support for obfuscating the
value.  That has to be done with a user-written Perl filter, if desired.

=item I<addinjectionpostinghost>

Whether to add a posting-host attribute to the Injection-Info header
field body to all local posts giving an FQDN (when known, by reverse
lookup of the client IP address) and IP address of the system from which
the post was received.  This is a boolean value and the default is true.
Note that INN either does not add this attribute or adds the name (when
known) and IP address of the client.  There is no intrinsic support
for obfuscating the name of the client.  That has to be done with a
user-written Perl filter, if desired.

When this parameter is set to true, an FQDN (obtained by reverse
lookup of the client IP address or, if unknown, the IP address itself)
of the client is also added to the Path header field body, after the
C<!.POSTED> diagnostic.

=item I<checkincludedtext>

Whether to check local postings for the ratio of new to quoted text and
reject them if that ratio is under 50%.  Included text is recognized by
looking for lines beginning with C<E<gt>>, C<|>, or C<:>.  This is a
boolean value and the default is false.

=item I<complaints>

The value of the mail-complaints-to attribute of the Injection-Info
header field added to all local posts.  The default is the newsmaster's
e-mail address.  (If the newsmaster, selected at configure time and
defaulting to C<usenet>, doesn't contain C<@>, the address will consist
of the newsmaster, an C<@>, and the value of I<fromhost>.)

=item I<fromhost>

Contains a domain used to construct e-mail addresses.  The address of the
local news administrator will be given as <user>@I<fromhost>, where <user>
is the newsmaster user set at compile time (C<usenet> by default).  This
setting will also be used by mailpost(8) to fully qualify addresses and by
inews(1) to generate the Sender header field (and the From header field
if missing).  The value of the FROMHOST environment variable, if set,
overrides this setting.  The default is the fully qualified domain name
of the local host.

=item I<localmaxartsize>

The maximum article size (in bytes) for locally posted articles.  Articles
larger than this will be rejected.  A value of C<0> allows any size of
article, but note that B<nnrpd> and B<innd> will crash if system memory is
exceeded.  See also I<maxartsize>, which applies to all articles including
those posted locally.  The default value is C<1000000> (approximately S<1 MB>).

=item I<moderatormailer>

The address to which to send submissions for moderated groups.  It is only
used if the F<moderators> file doesn't exist, or if the moderated group to
which an article is posted is not matched by any entry in that file, and
takes the same form as an entry in the F<moderators> file.  In most cases,
C<%s@moderators.isc.org> is a good value for this parameter (C<%s> is
expanded into a form of the newsgroup name).  See moderators(5) for more
details about the syntax.  The default is unset.  If this parameter isn't
set and an article is posted to a moderated group that does not have a
matching entry in the F<moderators> file, the posting will be rejected
with an error.

=item I<nnrpdauthsender>

Whether to generate a Sender header field based on reader authentication.  If
this parameter is set, a Sender header field will be added to local posts
containing the identity assigned by F<readers.conf>.  If the assigned
identity does not include an C<@>, the reader's hostname is used.  If this
parameter is set but no identity is assigned, the Sender header field will
be removed from all posts even if the poster includes one.  This is a
boolean value and the default is false.

=item I<nnrpdposthost>

If set, nnrpd(8) and rnews(1) will pass all locally posted articles to the
specified host rather than trying to inject them locally.  See also
I<nnrpdpostport>.  This should always be set if I<xrefslave> is true.  The
default value is unset.

=item I<nnrpdpostport>

The port on the remote server to connect to to post when I<nnrpdposthost>
is used.  The default value is C<119>.

=item I<organization>

What to put in the Organization header field body if it is left blank
by the poster.  The value of the ORGANIZATION environment variable,
if set, overrides this setting.  The default is unset, which tells INN
not to insert an Organization header field.

=item I<spoolfirst>

If true, nnrpd(8) will spool new articles rather than attempting to send
them to innd(8).  If false, nnrpd will spool articles only if it receives
an error trying to send them to innd.  Setting this to true can be useful
if nnrpd must respond as fast as possible to the client; however, when
set, articles will not appear to readers until they are given to innd.
nnrpd won't do this; C<rnews -U> must be run periodically to take the
spooled articles and post them.  This is a boolean value and the default
is false.

=item I<strippostcc>

Whether to strip To, Cc, and Bcc header fields out of all local posts via
nnrpd(8).  The primary purpose of this setting is to prevent abuse of the
news server by posting to a moderated group and including To or Cc
header fields in the post so that the news server will send the article to
arbitrary addresses.  INN now protects against this abuse in other ways
provided I<mta> is set to a command that includes C<%s> and honors it, so
this is generally no longer needed.  This is a boolean value and the
default is false.

=back

nnrpd(8) has support for controlling high-volume posters via an
exponential backoff algorithm, as configured by the following parameters.

Exponential posting backoff works as follows: news clients are indexed
by IP address (or username, see I<backoffauth> below).  Each time a post
is received from an IP address, the time of posting is stored (along
with the previous sleep time, see below).  After a configurable number
of posts in a configurable period of time, nnrpd(8) will begin to sleep
for increasing periods of time before actually posting anything (posting
backoff is therefore activated).  Posts will still be accepted, but at an
increasingly reduced rate.

After backoff has been activated, the length of time to sleep is computed
based on the difference in time between the last posting and the current
posting.  If this difference is less than I<backoffpostfast>, the new
sleep time will be 1 + (previous sleep time * I<backoffk>).  If this
difference is less than I<backoffpostslow> but greater than
I<backoffpostfast>, then the new sleep time will equal the previous sleep
time.  If this difference is greater than I<backoffpostslow>, the new
sleep time is zero and posting backoff is deactivated for this poster.
(Note that this does not mean posting backoff cannot be reactivated later
in the session.)

Exponential posting backoff will not be enabled unless I<backoffdb> is set
and I<backoffpostfast> and I<backoffpostslow> are set to something other
than their default values.

Here are the parameters that control exponential posting backoff:

=over 4

=item I<backoffauth>

Whether to index posting backoffs by user rather than by source IP
address.  You must be using authentication in nnrpd(8) for a value of true
to have any meaning.  This is a boolean value and the default is false.

=item I<backoffdb>

The path to a directory, writeable by the news user, that will contain the
backoff database.  There is no default for this parameter; you must
provide a path to a creatable or writeable directory to enable exponential
backoff.

=item I<backoffk>

The amount to multiply the previous sleep time by if the user is still
posting too quickly.  A value of C<2> will double the sleep time for each
excessive post.  The default value is C<1>.

=item I<backoffpostfast>

Postings from the same identity that arrive in less than this amount of
time (in seconds) will trigger increasing sleep time in the backoff
algorithm.  The default value is C<0>.

=item I<backoffpostslow>

Postings from the same identity that arrive in greater than this amount of
time (in seconds) will reset the backoff algorithm.  Another way to look
at this constant is to realize that posters will be allowed to generate at
most 86400/I<backoffpostslow> posts per day.  The default value is C<1>.

=item I<backofftrigger>

This many postings are allowed before the backoff algorithm is triggered.
The default value is C<10000>.

=back

=head2 TLS/SSL Support for Reading and Posting

Here are the parameters used by nnrpd(8) to provide TLS/SSL support.

The parameters related to certificates are:

=over 4

=item I<tlscafile>

The path to a file containing certificate authority root certificates,
used to present a trust chain to a TLS client.  This parameter is only
used if B<nnrpd> is built with TLS/SSL support.  The default value is an
empty string.

=item I<tlscapath>

The path to a directory containing certificate authority root
certificates.  Each file in the directory should contain one CA
certificate, and the name of the file should be the CA subject name hash
value.  See the OpenSSL documentation for more information.  This
parameter is only used if B<nnrpd> is built with TLS/SSL support.  The
default value is I<pathetc>.

=item I<tlscertfile>

The path to a file containing the server certificate to present to
TLS clients.  This parameter is only used if B<nnrpd> is built with TLS/SSL
support.  The default value is I<pathetc>/cert.pem.

If you want to use a complete certificate chain, you can directly put
it in I<tlscertfile> (like Apache's I<SSLCertificateFile> directive).
Alternately, you can put a single certificate in I<tlscertfile> and use
I<tlscafile> for additional certificates needed to complete the chain,
like a separate authority root certificate.

More concretely, when using S<Let's Encrypt> certificates, Certbot's
files can be installed as follows:

    tlscapath:      /etc/letsencrypt/live/news.server.com
    tlscertfile:    /etc/letsencrypt/live/news.server.com/fullchain.pem
    tlskeyfile:     /etc/letsencrypt/live/news.server.com/privkey.pem

or:

    tlscapath:      /etc/letsencrypt/live/news.server.com
    tlscafile:      /etc/letsencrypt/live/news.server.com/chain.pem
    tlscertfile:    /etc/letsencrypt/live/news.server.com/cert.pem
    tlskeyfile:     /etc/letsencrypt/live/news.server.com/privkey.pem

Make sure that the permission rights are properly set so that the
news user or the news group can read these directories and files
(typically, he should access F</etc/letsencrypt/live/news.server.com> and
F</etc/letsencrypt/archive/news.server.com> where the real keys are located,
and the private key should not be world-readable).

If you prefer to point to files outside the directory of S<Let's Encrypt>, you
may add a post-renewal hook for S<Let's Encrypt> to copy the generated files
to another location, and give them the expected rights.

=item I<tlskeyfile>

The path to a file containing the encryption key for the server
certificate named in I<tlscertfile>.  This may be the same as
I<tlscertfile> if, when you created the certificate, you put the key in
the same file (if, for example, you gave the same file name to both the
B<-out> and B<-keyout> options to C<openssl req>).  This parameter is only
used if B<nnrpd> is built with TLS/SSL support.  The default value is
I<pathetc>/key.pem.

This file must only be readable by the news user or B<nnrpd> will refuse to
use it.

=back

Finally, here are the parameters that can be used to tighten the level
of security provided by TLS/SSL in case new attacks exploitable in NNTP
on the TLS protocol or some supported cipher suite are discovered:

=over 4

=item I<tlsciphers>

The string describing the cipher suites OpenSSL will support for S<TLS
1.2> and below.  See OpenSSL's ciphers(1) command documentation for
details.  The default is unset, which uses OpenSSL's default cipher
suite list.

=item I<tlsciphers13>

The string describing the cipher suites OpenSSL will support for S<TLS
1.3>.  See OpenSSL's ciphers(1) command documentation for
details.  The default is unset, which uses OpenSSL's default cipher
suite list.

Note that a separate cipher suite configuration parameter is needed for
S<TLS 1.3> because S<TLS 1.3> cipher suites are not compatible with
S<TLS 1.2>, and vice-versa.  In order to avoid issues where legacy
S<TLS 1.2> cipher suite configuration configured in the I<tlsciphers>
parameter would inadvertently disable all S<TLS 1.3> cipher suites,
the F<inn.conf> configuration has been separated out.

=item I<tlscompression>

Whether to enable or disable TLS/SSL-level compression support, if
the negotiated protocol supports it (notably, S<TLS 1.3> no longer
supports it).  This is a boolean and the default is false, that is to say
compression is disabled, so as to follow the best current practices for
a secure use of TLS in application protocols (see S<RFC 8143> for NNTP).

Note that enabling TLS/SSL-level compression will be possible only if
the OpenSSL library INN has been built with, supports that feature.

=item I<tlseccurve>

The name of the elliptic curve to use for ephemeral key exchanges.
To see the list of curves supported by OpenSSL, use C<openssl ecparam
-list_curves>.

The default is unset, which means an appropriate curve is auto-selected.

This option is only effective if your OpenSSL version has ECDH support.

=item I<tlspreferserverciphers>

Whether to let the client or the server decide the preferred cipher
suite, signature algorithm or elliptic curve to use for an incoming
connection.  This is a boolean and the default is true, that is to say
the server will choose following its own preferences.

=item I<tlsprotocols>

The list of TLS/SSL protocol versions to support.  Valid protocols are
B<SSLv3>, B<TLSv1>, B<TLSv1.1>, B<TLSv1.2> and B<TLSv1.3>.  For compatibility
with older versions of INN, B<SSLv2> may also be listed, but this will have
no effect.

The default value is to only allow secure TLS protocols:

    tlsprotocols: [ TLSv1.2 TLSv1.3 ]

Note that the listed protocols will be enabled only if the OpenSSL
library INN has been built with, supports them.  In case OpenSSL supports
protocols more recent than TLSv1.3, they will be automatically enabled
(which anyway is fine regarding security, as newer protocols are supposed
to be more secure).

C<SSLv2> was formally deprecated by S<RFC 6176> in 2011, C<SSLv3>
by S<RFC 7568> in 2015, C<TLSv1.0> and C<TLSv1.1> by S<RFC 8996> in 2021.

=back

=head2 Monitoring

These parameters control the behavior of innwatch(8), the program that
monitors INN and informs the news administrator if anything goes wrong
with it.

=over 4

=item I<doinnwatch>

Whether to start innwatch(8) from rc.news.  This is a boolean value, and
the default is true.

=item I<innwatchbatchspace>

Free space in I<pathoutgoing>, in inndf(8) output units (normally
kilobytes), at which innd(8) will be throttled by innwatch(8), assuming a
default F<innwatch.ctl>.  The default value is C<4000>.

=item I<innwatchlibspace>

Free space in I<pathdb> and I<pathhistory>, in inndf(8) output units
(normally kilobytes), at which innd(8) will be throttled by innwatch(8),
assuming a default F<innwatch.ctl>.  The default value is C<25000>.

=item I<innwatchloload>

Load average times 100 at which innd(8) will be restarted by innwatch(8)
(undoing a previous pause or throttle), assuming a default
F<innwatch.ctl>.  The default value is C<1000> (that is, a load average of
10.00).

=item I<innwatchhiload>

Load average times 100 at which innd(8) will be throttled by innwatch(8),
assuming a default F<innwatch.ctl>.  The default value is C<2000> (that
is, a load average of 20.00).

=item I<innwatchpauseload>

Load average times 100 at which innd(8) will be paused by innwatch(8),
assuming a default F<innwatch.ctl>.  The default value is C<1500> (that
is, a load average of 15.00).

=item I<innwatchsleeptime>

How long (in seconds) innwatch(8) will sleep between each check of INN.
The default value is C<600>.

=item I<innwatchspoolnodes>

Free inodes in I<patharticles> at which innd(8) will be throttled by
innwatch(8), assuming a default F<innwatch.ctl>.  The default value is
C<200>.

=item I<innwatchspoolspace>

Free space in I<patharticles> and I<pathoverview>, in inndf(8) output
units (normally kilobytes), at which innd(8) will be throttled by
innwatch(8), assuming a default F<innwatch.ctl>.  The default value is
C<25000>.

=back

=head2 Logging

These parameters control what information INN logs.

=over 4

=item I<docnfsstat>

Whether to start cnfsstat(8) when innd(8) is started.  cnfsstat will log
the status of all CNFS cycbuffs to syslog on a periodic basis (frequency
is the default for C<cnfsstat -l>, currently 600 seconds).  This is a
boolean value and the default is false.

=item I<htmlstatus>

Whether B<innd> should write the status report as HTML file or in plain text.
The HTML status file goes to I<pathhttp>/inn_status.html, while the plain
text status file is written to I<pathlog>/inn.status.  This is a boolean
value and the default is true (an HTML status file is written).  Also see
the I<status> parameter.

=item I<incominglogfrequency>

How many articles to process on an incoming channel before logging the
activity.  The default value is C<200>.

=item I<logartsize>

Whether the size of accepted articles (in bytes) should be written to the
article log file.  This is useful for flow rate statistics and is
recommended.  This is a boolean value and the default is true.

=item I<logcancelcomm>

Set this to true to log C<ctlinnd cancel> commands to syslog.  This is a
boolean value and the default is false.

=item I<logcycles>

How many old logs scanlogs(8) keeps.  scanlogs(8) is generally run by
news.daily(8) and will archive compressed copies of this many days worth
of old logs.  The default value is C<3>.

=item I<logipaddr>

Whether the verified name of the remote feeding host should be logged to
the article log for incoming articles rather than the last entry in the
Path header field body.  The only reason to ever set this to false is due
to some interactions with F<newsfeeds> flags; see newsfeeds(5) for more
information.  This is a boolean value and the default is true.

=item I<logsitename>

Whether the names of the sites to which accepted articles will be sent
should be put into the article log file.  This is useful for debugging and
statistics.  This is a boolean value and the default is true.

=item I<logstatus>

Whether B<innd> should write a shortened version of its status report
to syslog every I<status> seconds.  This is a boolean value and the default
is true.  If set to true, see the I<status> parameter for more details
on how to enable status reporting.

=item I<logtrash>

Whether B<innd> should add a line in the F<news> log file to report
unwanted newsgroups (that is to say newsgroups not locally carried by the
news server).  This is a boolean value and the default is true.  It may
be useful to set it to false when I<wanttrash> is set to true.

=item I<nnrpdoverstats>

Whether nnrpd overview statistics should be logged via syslog.  This can
be useful for measuring overview performance.  This is a boolean value and
the default is true.

=item I<nntplinklog>

Whether to put the storage API token for accepted articles (used by
nntplink) in the article log.  This is a boolean value and the default is
false.

=item I<stathist>

Where to write history statistics for analysis with the B<stathist> program in
the F<contrib> directory; this can be modified with ctlinnd(8) while B<innd>
is running.  Logging does not occur unless a path is given, and there is no
default value.

=item I<status>

How frequently (in seconds) innd(8) should write out a status
report.  The report is written to I<pathhttp>/inn_status.html or
I<pathlog>/inn.status depending on the value of I<htmlstatus>.  If this
is set to C<0> or C<false>, status reporting is disabled.  The default
value is C<600> (that is to say reports are written every 10 minutes).

=item I<timer>

How frequently (in seconds) innd(8) should report performance timings
to syslog.  If this is set to C<0>, performance timing is disabled.
Enabling this is highly recommended, and innreport(8) can produce a nice
summary of the timings.  If set to C<0>, performance timings in nnrpd(8)
are also disabled, although B<nnrpd> always reports statistics on exit
and therefore any non-zero value is equivalent for it.  The default
value is C<600> (that is to say performance timings are reported every
10 minutes).

=back

=head2 System Tuning

The following parameters can be modified to tune the low-level operation
of INN.  In general, you shouldn't need to modify any of them except
possibly I<rlimitnofile> unless the server is having difficulty.

=over 4

=item I<badiocount>

How many read or write failures until a channel is put to sleep or
closed.  The default value is C<5>.

=item I<blockbackoff>

Each time an attempted write returns EAGAIN or EWOULDBLOCK, innd(8) will
wait for an increasing number of seconds before trying it again.  This is
the multiplier for the sleep time.  If you're having trouble with channel
feeds not keeping up, it may be good to change this value to C<2> or C<3>,
since then when the channel fills INN will try again in a couple of
seconds rather than waiting two minutes.  The default value is C<120>.

=item I<chaninacttime>

The time (in seconds) to wait between noticing inactive channels.  The
default value is C<600>.

=item I<chanretrytime>

How many seconds to wait before a channel restarts.  The default value is
C<300>.

=item I<datamovethreshold>

The threshold for deciding whether to move already-read data to the top of
buffer or extend the buffer.  The buffer described here is used for reading
NNTP data.  Increasing this value may improve performance, but it should
not be increased on Systems with insufficient memory.  Permitted values
are between C<0> and C<1048576> (out of range values are treated as
C<1048576>) and the default value is C<16384>.

=item I<icdsynccount>

How many article writes between updating the F<active> and C<hisv6> F<history>
files.  The default value is C<10>.

This is a trade-off between faster speed and more data loss if B<innd> crashes
(or the system crashes, or loses power, etc.).  The higher this parameter
is, the less frequent syncs are done.  It is essentially the frequency of
checkpoints: the maximum number of articles that may be orphaned in case of a
crash as they wouldn't have been recorded in the F<history> file.  Besides,
the missing updates to the F<active> file would cause other problems later,
such as duplicate article numbers and corresponding errors when storing new
articles.  (If B<innd> has crashed, you can fix these errors by rebuilding the
F<history> file and overview with makehistory(8).  The F<active> file will be
automatically be renumbered after that operation.)

This setting is not used for the C<hissqlite> history method whose writes are
in autocommit mode.

=item I<keepmmappedthreshold>

When using buffindexed, retrieving overview data (that is, responding to
OVER or running expireover) causes mmapping of all overview data blocks
which include requested overview data for newsgroup.  But for high volume
newsgroups like control.cancel, this may cause too much mmapping at once
leading to system resource problems.  To avoid this, if the amount to be
mmapped exceeds I<keepmmappedthreshold> (in KB), buffindexed mmap's just
one overview block (S<8 KB>).  This parameter is specific to buffindexed
overview storage method.  The default value is C<1024> (S<1 MB>).

=item I<maxcmdreadsize>

If set to anything other than C<0>, maximum buffer size (in bytes) for
reading NNTP command will have this value.  It should not be large on
systems which are slow to process and store articles, as that would lead
to innd(8) spending a long time on each channel and keeping other channels
waiting.  The default value is BUFSIZ defined in stdio.h (usually between
C<1024> and C<8192> in most environments, see setbuf(3)).

=item I<maxforks>

How many times to attempt a fork(2) before giving up.  The default value
is C<10>.

=item I<maxlisten>

How many incoming connections can queue up in the listen backlog
for B<innd>, B<nnrpd> and two overview storage methods (C<ovdb> and
C<ovsqlite>).  The default value is C<128> and should be raised in case
you notice that some connection requests get dropped.

=item I<nicekids>

If set to anything other than C<0>, all child processes of innd(8) will
have this nice(2) value.  This is usually used to give all child processes
of innd(8) a lower priority (higher nice value) so that innd(8) can get
the lion's share of the CPU when it needs it.  The default value is C<4>.

=item I<nicenewnews>

If set to anything greater than C<0>, all nnrpd(8) processes that receive
and process a NEWNEWS command will nice(2) themselves to this value
(giving other nnrpd processes a higher priority).  The default value is
C<0>.  Note that this value will be ignored if set to a lower value than
I<nicennrpd> (or I<nicekids> if nnrpd(8) is spawned from innd(8)).

=item I<nicennrpd>

If set to anything greater than C<0>, all nnrpd(8) processes will nice(2)
themselves to this value.  This gives other news processes a higher
priority and can help overchan(8) keep up with incoming news (if that's
the object, be sure overchan(8) isn't also set to a lower priority via
I<nicekids>).  The default value is C<0>, which will cause nnrpd(8)
processes spawned from innd(8) to use the value of I<nicekids>, while
nnrpd(8) run as a daemon will use the system default priority.  Note that
for nnrpd(8) processes spawned from innd(8), this value will be ignored if
set to a value lower than I<nicekids>.

=item I<pauseretrytime>

Wait for this many seconds before noticing inactive channels.
Wait for this many seconds before innd processes articles when it's paused
or the number of channel write failures exceeds I<badiocount>.  The
default value is C<300>.

=item I<peertimeout>

How long (in seconds) an innd(8) incoming channel may be inactive before
innd closes it.  The default value is C<3600> (an hour).

=item I<rlimitnofile>

The maximum number of file descriptors that innd(8) or innfeed(8) can
have open at once.  If innd(8) or innfeed(8) attempts to open more file
descriptors than this value, it is possible the program may throttle or
otherwise malfunction or suffer reduced functionality.  The number of open
file descriptors is roughly the maximum number of incoming feeds and outgoing
batches for innd(8) added to the number of outgoing streams for innfeed(8)
and, if you are using the tradindexed overview method, the value of the
I<overcachesize> parameter.  If I<rlimitnofile> is set to a negative value,
the default limit of the operating system will be used; this will normally be
adequate on systems other than Solaris.  Nearly all operating systems have
some hard maximum limit beyond which this value cannot be raised, usually
either 256, 1024, or 65536.  The default value of this parameter is C<-1>.

Setting this parameter to C<256> on Solaris systems is
highly recommended for 32-bit Solaris versions or 32-bit
applications running on 64-bit Solaris, as well as 64-bit Solaris
versions prior to 11.0.  See the L<Solaris documentation about file
descriptors|https://support.oracle.com/knowledge/Sun%20Microsystems/1005979_1.html>
for more details.

Note for expert users building INN from sources: if you need using more than
C<FD_SETSIZE> file descriptors (as defined in the F<sys/select.h> system
header, usually defaulting to 1024), you can increase this value for instance
to C<4096> by rebuilding INN with the C<-DLARGE_FD_SETSIZE=4096> option given
to the compiler.

=back

=head2 Paths Names

=over 4

=item I<patharchive>

Where to store archived news.  The default value is I<pathspool>/archive.

=item I<patharticles>

The path to where the news articles are stored (for storage methods other
than CNFS).  The default value is I<pathspool>/articles.

=item I<pathbin>

The path to the news binaries.  The default value is I<pathnews>/bin.

=item I<pathcontrol>

The path to the files that handle control messages.  The code for handling
each separate type of control message is located here.  Be very careful
what you put in this directory with a name ending in C<.pl>, as it can
potentially be a severe security risk.  The default value is
I<pathbin>/control.

=item I<pathdb>

The path to the database files used and updated by the server (currently,
F<active>, F<active.times>, F<newsgroups>, and, unless I<pathhistory> is
set elsewhere, the F<history> database).  The default value is
I<pathnews>/db.

=item I<pathetc>

The path to the news configuration files.  The default value is
I<pathnews>/etc.

=item I<pathfilter>

The path to the Perl and Python filters.  The default value is
I<pathbin>/filter.

=item I<pathhistory>

The path to the history database files (the history(5) text file and its
I<dbz> indices with the C<hisv6> history method, or F<history.sqlite> and its
WAL files with C<hissqlite>).  Pointing this somewhere other than I<pathdb>
lets the history database live on its own file system or, with hissqlite,
on a dedicated ZFS dataset with a matching I<recordsize> (see hissqlite(5)).
The directory must exist and be writable by the news user; the installation
process only creates the default one.  The default value is the value of
I<pathdb>.

=item I<pathhttp>

Where any HTML files (such as periodic status reports) are placed.  If the
news reports should be available in real-time on the web, the files in
this directory should be served by a web server.  The default value is
the value of I<pathnews>/http.

=item I<pathincoming>

Location where incoming batched news is stored.  The default value is
I<pathspool>/incoming.

=item I<pathlog>

Where the news log files are written.  The default value is
I<pathnews>/log.

=item I<pathnews>

The home directory of the news user and usually the root of the news
hierarchy.  There is no default; this parameter must be set in F<inn.conf>
or INN will refuse to start.

=item I<pathoutgoing>

Default location for outgoing feed files.  The default value is
I<pathspool>/outgoing.

=item I<pathoverview>

The path to news overview files.  The default value is
I<pathspool>/overview.

=item I<pathrun>

The path to files required while the server is running and run-time state
information.  This includes lock files and the sockets for communicating
with innd(8).  This directory and the control sockets in it should be
protected from unprivileged users other than the news user.  The default
value is I<pathnews>/run.

=item I<pathspool>

The root of the news spool hierarchy.  This used mostly to set the
defaults for other parameters, and to determine the path to the backlog
directory for innfeed(8).  The default value is I<pathnews>/spool.

=item I<pathtmp>

Where INN puts temporary files.  For security reasons, this is not the
same as the system temporary files directory (INN creates a lot of
temporary files with predictable names and does not go to particularly
great lengths to protect against symlink attacks and the like; this
is safe provided that normal users can't write into its temporary
directory).  The default value is set at configure time and defaults to
I<pathnews>/tmp.

=back

=head1 EXAMPLE

Here is a very minimalist example that only sets those parameters that are
required.

    mta:                "/usr/lib/sendmail -oi -oem %s"
    ovmethod:           tradindexed
    pathhost:           news.example.com
    pathnews:           /usr/local/news
    hismethod:          hisv6

For a more comprehensive example, see the sample F<inn.conf> distributed
with INN and installed as a starting point; it contains all of the default
values for reference.

=head1 HISTORY

Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews and since
modified, updated, and reorganized by innumerable other people.

=head1 SEE ALSO

inews(1), innd(8), innwatch(8), libinn_dbz(3), libinn_uwildmat(3),
makehistory(8), nnrpd(8), rnews(1).

Nearly every program in INN uses this file to one degree or another.  The
above are just the major and most frequently mentioned ones.

=cut
