(Post Usenet FAQs following news.answers conventions)


postfaq [-hinv] [-d statusdir] [-s server] [-p program] [-U username -P password] faq [faq ...]

postfaq [-hinv] [-d statusdir] [-s server] [-p program] [-U username -P password] -f list


Perl 5.001 or later and the Net::NNTP and Net::Domain modules (both of which are included in Perl core as of 5.8.0 and are part of the libnet distribution on CPAN). Access to a news server is required to actually post FAQs, and it is assumed that Net::NNTP is configured correctly to point to your local news server by default (otherwise, use -s).

The hostfqdn() function of Net::Domain needs to return a reasonable hostname for your system. This means that your public domain name should be listed first in /etc/hosts, not something bogus like localhost.localdomain.


postfaq posts Usenet FAQs, with support for the news.answers conventions. Its basic operation is to read in a file containing the FAQ, which should include the standard Usenet headers such as Newsgroups, Subject, and From, and post it. A Message-ID header is added as described below.

If an Expires header is present in the FAQ, it is expected to contain a time period from the time of posting that the FAQ should remain in the newsgroup. Currently, the only time interval allowed is days, represented by d. So, for example, a header containing:

    Expires: 35d

when posted on 2002-07-22 00:15:17 -0000 would be converted to:

    Expires: 26 Aug 2002 00:15:17 -0000

in the actual post.

The first line of the post may be an RCS/CVS-style Id string; if so, it is not included in the final post, and is parsed for the version and last modification date of the FAQ. The version number is included only if it looks like a CVS or RCS version number (containing a period). Subversion version numbers aren't as useful, since they're a repository-wide version, and hence aren't included. If there is no Id string, the last modified time of the file is used instead.

If the beginning of the post body looks like additional headers (some number of alphanumerics and dashes followed by a colon and a space), the beginning of the body is assumed to be a subheader in the news.answers style. postfaq will add to the beginning of that subheader a Last-modified header, determined as described above. It will also add a Posted-by subheader giving its own version number and that of Perl. Any subheaders beginning with HTML- are stripped out of the post (as they're presumed to be for the HTML translation of the FAQ).

Information about the last post and about how to form message IDs for posts is stored in a file in a status directory ($HOME/data/faqs by default, which can be overridden with the -d option) which must exist. In that directory, one file per FAQ, with the same name as the FAQ filename, is written. Each of those status files will contain two lines, the first being the prefix used to generate message IDs and the second being the message ID of the last time that FAQ was posted. If this status file is present when a FAQ is posted and contains a message ID on the second line, a Supersedes header will be added to the post.

A Message-ID header will always be added to a posted FAQ, constructed from the first line of the status file as described above, the current time, the process ID, and the local hostname (obtained from Net::Domain::hostfqdn).

To post multiple FAQs at the same time, a list of files can be given on the command line. Alternately, the -f option can be given with an argument giving a file containing the list of FAQs to post. Usually those files should be listed one per line (and relative paths are considered relative to the path to the list file as given on the command line), but if multiple FAQs are given on the same line, they are considered related. All FAQs listed on that line after the first will have a References header added referring to the first post.


-d statusdir, --data=statusdir

Look for and store status information in the provided directory instead of in the default of $HOME/data/faqs.

-f list, --file=list

Take the list of FAQs to post from the file list instead of from the command line. This also enables posting FAQs as a group; see above for more details on how that works.

-i, --ihave

Post using IHAVE rather than POST. This requires that your local server accept IHAVE commands from the system on which this script is running (no authentication is used). A Date header corresponding to the current time (but in UTC, not in the local time zone) and a Path header containing only not-for-mail will be added to the article before posting.

-h, --help

Print out this documentation (which is done simply by feeding the script to perldoc -t).

-n, --dry-run, --just-print

Rather than posting the FAQs, just print them to stdout separated by lines of dashes. This can be used to preview what postfaq would do without embarassing yourself on Usenet. The status files are not updated when this option is given.

-p program, --program=program

Post using the external program program. The post will be fed to this program on standard input, and a 0 return value will be considered success. This option cannot be used with -i or -s (for obvious reasons).

-P password, --password=password

Authenticate to the news server using AUTHINFO with the password password. The username must also be specified with -U.

Please note: postfaq does not use an SSL-encrypted connection or any safe authentication mechanism and the password will be sent in clear-text over the network. Furthermore, the password will be visible to anyone else using the same system via ps. This option is only intended to be used with NNTP-only account passwords that don't have any significant value and where interception of the password is not a significant risk.

If you need to use a more secure authentication mechanism or post via SSL, you will need to use an external program that knows how to do that sort of posting and specify it with the -p option.

-s server, --server=server

Post to server rather than to the default server configured into News::NNTP, or set by the NNTPSERVER environment variable.

-U username, --username=username

Authenticate to the news server using AUTHINFO with the username username. The password must also be specified with -P. See the description of -P for additional security warnings and caveats.

-v, --version

Print out the version of postfaq and exit.


Post the FAQ contained in the file faqs/boating:

    postfaq faqs/boating

Do a dry run, showing what the FAQs would look like when posted for all of faqs/boating, faqs/food, and /www/htdocs/faqs/tolkien.txt:

    postfaq -n faqs/boating faqs/food /www/htdocs/faqs/tolkien.txt

Post all of the FAQs in faqs/.posts.01:

    postfaq -f faqs/.posts.01

I put a command like this in my personal crontab file and then don't have to change crontab when I add a new FAQ that I post on the 1st of each month. I just add the filename to that file.

Post the FAQ contained in the file faqs/boating using IHAVE:

    postfaq -i faqs/boating

In order to do this, you have to have permission to send IHAVE commands to your local news server.

Post that same FAQ using POST, authenticating with the username faq and the password sekret:

    postfaq -U faq -P sekret faqs/boating

Post the FAQ contained in the file faqs/boating using an external program called inews:

    postfaq -p /usr/bin/inews faqs/boating

Normally it's best to let postfaq post directly, but this can be useful if you have a posting script that does other things (such as adding PGPMoose signatures or posting via SSL).



Used to determine the default status directory ($HOME/data/faqs).


The default NNTP server to post to, used by the Net::NNTP module. You can also use -s to specify the server.



This directory (by default; this is set at the top of this script and can be changed there or with the -d option) is searched for status files for each FAQ that is posted. The status file should have the same name as the file name (without the directory portion) of the FAQ. This directory must exist, and the status file will be created on successful posting if it doesn't already exist.

The first line of the file will be the string used to form the message ID (the file name of the FAQ by default) and the second line will be the message ID of the last successful post of that FAQ.


Currently, the only time interval supported for Expires is d for days, and only one time interval is allowed in the header. It would be nice to support something like:

    Expires: 1m 15d

The default status directory works well for me but is likely not ideal for many other people.

There should be a way to post diffs from the previously posted version of the FAQ, as this is rather important for some types of FAQs.

There is no way to specify the hostname to use in message IDs if that shouldn't be the local hostname.

Supporting obtaining credentials from an .authinfo file would be nice.



<> will have the current version of this program.


Russ Allbery <>


Copyright 1999, 2002, 2003, 2004, 2008, 2013 Russ Allbery <>

This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.

Last spun 2013-07-01 from POD modified 2013-01-09