NAME
    yapfaq - Post FAQs to Usenet *(yet another postfaq)*

SYNOPSIS
    yapfaq [-cfhotsV] [-p *project name*[-n *newsgroup*] [OPTIONS]

REQUIREMENTS
    - Perl 5.8 or later with core modules

    - DateTime

    - Path::Tiny

    Furthermore you need access to a news server to actually post FAQs.

DESCRIPTION
    yapfaq can post (one or more) FAQs (or other texts) to Usenet every n
    days, weeks, months or years. The content (article body) for each text
    will be read from a project file, and headers (with some placeholders)
    will be read from another project file. Posting frequency can be defined
    as header, or in the body in form of a news.answers pseudo-header.

    Project status (last time posted, last used *Message-ID*) will be
    tracked in a config file for each project.

    Configuration can be done by modifying the source (disapproved), by
    adding a config file in your home directory or by overriding those
    options on the command line.

  Runtime configuration
    Options for yapfaq can be set by modifying the *configuration* section
    of the source or by using a config file located at
    $XDG_CONFIG_HOME/yapfaqrc, $HOME/.config/yapfaqrc or $HOME/.yapfaqrc (in
    order of precedence). Options in config files will override options in
    source. Both can be overridden by using command line options.

    datadir = *path*
      Path to the directory for all project files.

      Each project needs a *project*.hdr file with all headers and a
      *project*.txt file containing the content (body) to be posted. yapfaq
      will track the project status in a *project*.cfg file.

      You can override this option on the command line by using --datadir
      *path*.

    verbose = *0|1*
      Display some status messages on STDOUT if set to *1*.

      You can override this option on the command line by using --verbose
      (-v) or --noverbose accordingly.

      Don't use verbose if you want to pipe your text to another program!

    debug = *0|1*
      Display debug messages (and NNTP dialogue) on STDOUT if set to *1*.

      You can override this option on the command line by using --debug (-d)
      or --nodebug accordingly.

      Don't use debug if you want to pipe your text to another program!

    nntp-server = *hostname*
      News (NNTP) server to connect to.

      Can be overridden by setting *$NNTPSERVER* or *$NEWSHOST* in your
      environment.

      You can override this option on the command line by using
      --nntp-server *hostname*.

    nntp-port = *port*
      Port on nntp-server to connect to. Default is 119.

      yapfaq can't use NNTPS on port 563, but can use STARTTLS if available.

      Can be overridden by setting *$NNTPPORT* in your environment.

      You can override this option on the command line by using --nntp-port
      *port*.

    nntp-user = *user name*
      User name for AUTHINFO authentication.

      You can override this option on the command line by using --nntp-user
      *user name*.

    nntp-pass = *password*
      Password for AUTHINFO authentication.

      You can override this option on the command line by using --nntp-pass
      *password*.

    force-auth = *0|1*
      Force AUTHINFO authentication, even if the server reports that you may
      post. Necessary for some servers.

      You can override this option on the command line by using --force-auth
      or --noforce-auth accordingly.

    starttls = *0|1*
      Use a TLS encrypted connection (via STARTTLS) if available.

      You can override this option on the command line by using --starttls
      or --nostarttls accordingly.

    xtraheaders = *path*
      Path to a file with common headers for all project files. Those
      headers will be appended to each project.

      You can override this option on the command line by using
      --xtraheaders = *path*.

  Project files
    Each project needs a *project*.hdr and a *project*.text file, and will
    get a *project*.cfg file after the first posting. These files need to be
    in datadir.

   Headers file
    Needs to have at least *From:*, *Subject:* and *Newsgroups:* and can
    contain all other headers that the posting should have. Headers must
    conform to RFC 5536 and RFC 5322 and use MIME encoded words for 8bit
    characters. yapfaq won't convert headers, but will warn of unencoded
    8bit characters in --debug mode. Longer headers should be folded; yapfaq
    won't fold headers.

    The headers file must not contain any of the following headers: *Date:*,
    *User-Agent:*, *X-Newsreader:*, *X-Mailer:*, *Injection-Date:*,
    *Injection-Info:*, *NNTP-Posting-Date:*, *NNTP-Posting-Host:* or
    *X-Trace:*.

    *Subject:* may contain a *%LM* placeholder that will be replaced with
    the *Last-modified:* pseudo-header from the text file (see below), if
    present. If no *Last-modified:* pseudo-header is found, the placeholder
    (and surrounding brackets, angle brackets or curly brackets and spaces)
    is removed.

    If a *Message-ID:* header is present, placeholders in that header will
    be replaced: *%n* with the project name, *%y* with the current year
    (YYYY), *%m* with the current month (MM), *%d* with the current day
    (DD), *%p* with the current process ID (PID) of yapfaq and *%t* with a
    timestamp timestamp (seconds since epoch). If no *Message-ID:* header is
    present, the *Message-ID* will be generated with the hostname of the
    system yapfaq is running on and *%n-%y-%m-%d* as template for the left
    hand side. If the *Message-ID:* header in the headers file does not
    contain placeholders, the next repost will most probably fail.

    If an *Expires:* header is present, it must contain a time period of n
    days, weeks, months or years in the form of a number followed by *d*,
    *w*, *m* or *y*, e.g. *Expires: 4w* for four weeks: If no such
    *Expires:* header is present, no such header will be set.

    If a *Supersedes:* header is present (e.g. *Supersedes: yes*, it will be
    replaced with a *Supersedes:* header containing the *Message-ID* of the
    last posted article.

    If a *Posting-Frequency:* header is present, it must contain a time
    period in the same way as for *Expires:*, e.g. *Posting-Frequency: 1m*
    for a monthly posting, or the keyword none. The *Posting-Frequency:*
    header will be removed after parsing. Alternatively a
    *Posting-Frequency:* pseudo-header in the text file may be used (see
    below). If no *Posting-Frequency:* is set anywhere, the default ist one
    month (*1m*). *Posting-Frequency: none* disables automatic postings.

    Example headers file

        From: John Doe <john-doe@example.com>
        Reply-To: <john@doe.example>
        Subject: <%LM> FAQ for alt.example.discussions
        Newsgroups: alt.example.discussions
        Message-ID: <%n-%y-%m-%d@my-domain.example>
        Posting-frequency: 1w
        Expires: 1m
        Supersedes: yes
        Mime-Version: 1.0
        Content-Type: text/plain; charset=utf-8
        Content-Transfer-Encoding: 8bit

   Text file
    The content (body) of your FAQ or other text.

    It may contain pseudo-headers, starting on the first line and separated
    from the reamining content by a blank line.

    *Last-modified:* and *Posting-frequency* will be evaluated by yapfaq.

    If your content contains 8bit characters, you'll need suitable MIME
    headers in your headers file. yapfaq will warn of unencoded 8bit
    characters with missung MIME headers in --debug mode.

    Example text file with pseudo-headers

        Archive-name: alt-example/discussions-faq
        Posting-frequency: weekly
        Last-modified: 2025-12-15
        URL: https://doe.example/faqs/alt-example-discussions-faq.txt

        This is a list of frequently asked questions (FAQs) and their
        answers for the alt.example.discussions newsgroup.

        1. What is the topic of alt.example.discussions?

           We discuss examples.

        That's quite enought, isn't it?

OPTIONS
    -c, --config
        Display current runtime configuration from source or config file.

    -f, --force
        Post text unconditionally, even if not due according to the defined
        posting frequency. This refers either to all projects or just one
        defined by --project.

    -n, --newsgroup *newsgroup*
        Override the *Newsgroups:* header for all texts posted. Intended for
        testing purposes.

        Combine with --test to avoid updating project status and to get a
        unique *Message-ID:* (and no *Supersedes:* header).

    -o, --output
        Don't post via NNTP, but print to STDOUT.

        Use --test instead to avoid updating project status.

        Intended for testing purposes or to pipe in another program like
        *inews* or *tinews.pl*. If you want to pipe the output to another
        program, neither --verbose nor --debug should be set.

    -p, --project *project name*
        Run for just one project (FAQ, text). Default is running for all
        projects.

    -h, --help
        Display this man page and exit.

    -s, --simulation
        Simulation mode. Don't post, just show which projects would be due.
        Implies --test (without --output) and --verbose.

        Can be combined with --project to show if just one project is due.

    -t, --test
        Test mode. Don't update project status (time and Message-ID of last
        posting); if project is posted to Usenet, dont' add a *Supersedes:*
        header and modify the *Message-ID:* with a random part.

        Implies --output (to redirect output to STDOUT) as long as
        --newsgroup (to override the *Newsgroups:* header) is not set.

    -V, --version
        Display version and copyright information and exit.

    OPTIONS
        You can override all runtime configuration options set in the source
        or a config file from the command line, as described above.

EXAMPLES
    Post all FAQs that are due for posting:

        yapfaq.pl

    You may run this command daily from cron. If you add "-v", you'll get a
    report mailed which FAQs have been posted and which were not due.

    Pipe all FAQs that are due for posting to *inews* from INN instead:

        yapfaq.pl -o | inews

    You may run this command daily from cron, too.

    Show which FAQs are due for posting and the next due dates for those
    that are not:

        yapfaq.pl -s

    Do a test run of your *example* text and and print it on STDOUT (whether
    ist is due or not):

        yapfaq.pl -t -f -p example
        (or yapfaq.pl -tfp example)

    The same, with debugging output (add "-d"):

        yapfaq.pl -tfdp example

    Force a test post of your *example* text to *alt.test*, even if the text
    is not due to be posted (same as before, just add "-n alt-test"):

        yapfaq.pl -t -f -p example -n alt.test

    The same, with debugging output (add "-d"):

        yapfaq.pl -tfdp example -n alt.test

ENVIRONMENT
    $NEWSHOST
      Set to override the NNTP server configured in the source or config
      file. It has lower priority than $NNTPSERVER and should be avoided.
      The --nntp-server command line option overrides $NEWSHOST.

    $NNTPSERVER
      Set to override the NNTP server configured in the source or config
      file. This has higher priority than $NEWSHOST. The --nntp-server
      command line option overrides $NNTPSERVER.

    $NNTPPORT
      The NNTP TCP port to connect news to. This variable only needs to be
      set if the TCP port is not 119 (the default). The --nntp-port command
      line option overrides $NNTPPORT.

FILES
    bin/yapfaq.pl
      The script itself.

    $XDG_CONFIG_HOME/yapfaqrc $HOME/.config/yapfaqrc $HOME/.yapfaqrc
      Config file (on order of precedence).

    *datadir*/*project*.hdr
      Headers for *project*.

    *datadir*/*project*.txt
      Content (body) for *project*.

    *datadir*/*project*.cfg
      Status data of *project*.

BUGS
    Please report any bugs or feature requests to the author or use the bug
    tracker at <https://code.virtcomm.de/thh/yapfaq/issues>!

SEE ALSO
    <https://th-h.de/net/software/yapfaq/> will have the current version of
    this program.

    This program is maintained using the Git version control system at
    <https://code.virtcomm.de/thh/yapfaq/>.

AUTHOR
    Thomas Hochstein <thh@thh.name>

    Original author (up to version 0.5b, dating from 2003): Marc
    Brockschmidt <marc@marcbrockschmidt.de>

COPYRIGHT AND LICENSE
    Copyright (c) 2003 Marc Brockschmidt <marc@marcbrockschmidt.de>

    Copyright (c) 2010-2017, 2026 Thomas Hochstein <thh@thh.name>

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

    This program contains (modified) code from tinews.pl, copyright (c)
    2002-2024 Urs Janssen <urs@tin.org> and Marc Brockschmidt
    <marc@marcbrockschmidt.de>

    This program contains (modified) code from pgpverify.pl, written April
    1996, <tale@isc.org> (David C Lawrence), currently maintained by Russ
    Allbery <eagle@eyrie.org>

