\input texinfo @c -*-texinfo-*-
@smallbook
@c %**start of header
@setfilename cfpeek.info
@settitle Cfpeek User Manual
@c %**end of header
@setchapternewpage odd

@defcodeindex pr
@defcodeindex op
@defcodeindex kw
@defcodeindex fl

@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex ky cp
@syncodeindex pg cp
@syncodeindex tp cp
@syncodeindex op cp
@syncodeindex pr cp
@syncodeindex kw cp
@syncodeindex fl cp

@include version.texi
@include rendition.texi
@include macros.texi

@ifinfo
@dircategory Individual utilities
@direntry
* cfpeek: (cfpeek).                 Parse Structured Configuration Files.
@end direntry
@end ifinfo

@copying
Copyright @copyright{} 2011--2021 Sergey Poznyakoff

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover texts being ``Cfpeek User Manual'',
and with the Back-Cover Texts as in (a) below.  A copy of the license
is included in the section entitled ``GNU Free Documentation License''.

(a) The Back-Cover Text is: ``You have freedom to copy and modify
this manual, like Free Software.''
@end copying

@titlepage
@title Cfpeek User Manual
@subtitle version @value{VERSION}, @value{UPDATED}
@author Sergey Poznyakoff.
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@ifnothtml
@page
@summarycontents
@page
@end ifnothtml
@contents

@ifnottex
@node Top
@top Cfpeek

This edition of the @cite{Cfpeek User Manual}, last updated @value{UPDATED},
documents Cfpeek Version @value{VERSION}.
@end ifnottex

@menu
* Intro::                   Introduction.
* Overview::                Overview of this Manual.
* Tutorial::                Cfpeek Tutorial.
* Formats::                 Supported Configuration File Formats
* Invocation::              Cfpeek Command Line Syntax.
* Exit Codes::              Cfpeek Exit Codes.
* Scripting::               Scripting Extends Cfpeek Functionality.

* Reporting Bugs::          How to Report a Bug.

Appendices

* Copying This Manual::  The GNU Free Documentation License.
* Concept Index::        Index of Concepts.

@detailmenu
 --- The Detailed Node Listing ---

Tutorial

* Basic Notions::
* Pathnames::              Pathnames Identify Statements in a Parse Tree.
* Example Configuration::  Configuration File Used in Subsequent Sections.
* Listing::                How to Produce File Listing.
* Lookups::                Statement Lookups.
* Pattern Lookups::        Searches Using Wildcard Patterns.
* Parsers::                Using Various Parsers.
* Nodes to Print::
* Scripts::                Using Scheme to Extend Cfpeek Functionality.

Using Scripts

* Scripting Example::

Supported Configuration File Formats

* grecs::
* path::
* bind::
* dhcpd::
* meta1::
* git::

Cfpeek Command Line Syntax

* Patterns::
* Output Control::
* Modifiers::
* Scripting Options::
* Preprocessor Control Options::
* Debugging Options::
* Informational Options::

@end detailmenu
@end menu

@node Intro
@chapter Introduction
@cindex structured configuration file
@cindex simple statements
Many programs keep their configurations in files with hierarchical
structure.  Such files normally define sections, which keep logically
separated blocks of statements.  These statements may in turn contain
subsections, and so on.  On the lowest level of hierarchy are
@dfn{simple statements}, which normally define some basic configuration
settings.

Quite often a need arises to parse such files outside of their owner
program.  For example, one may need to retrieve some configuration
settings to use them in a start-up script for that program, to
produce a similar configuration file with some settings changed in
order to use it on another machine, or to convert entire file into
another format for interaction with some other utility.

@command{Cfpeek} is a utility designed to handle any of these tasks.

@node Overview
@chapter Overview of this Manual

This book consists of the three main parts.  The first part is a
tutorial, which provides a gentle (as far as possible) introduction
for those who are new to @command{cfpeek}.  The tutorial should help
the reader to familiarize himself with the program and to start using
it.  It does not, however, cover some of the less frequently used
features of @command{cfpeek}.

The chapters that follow complement the tutorial.  They describe
various input file formats understood by the program and summarize
command line syntax and options available to it.  These two chapters
can be used as a reference by both beginners and for users
familiar with the package.

@node Tutorial
@chapter Tutorial
The following typographic conventions are used throughout this
tutorial.

In the examples, @samp{$} represents a typical shell prompt.  It
precedes lines you should type.  Both command line and lines which
represent the program output are shown in @samp{this font}.

The Scheme code is shown as follows:

@lisp
(do it)
@end lisp

In examples, the @result{} symbol indicates the value of a variable or
result of a function invocation, as in:

@lisp
x @result{} 2
@end lisp

@menu
* Basic Notions::
* Pathnames::              Pathnames Identify Statements in a Parse Tree.
* Example Configuration::  Configuration File Used in Subsequent Sections.
* Listing::                How to Produce File Listing.
* Lookups::                Statement Lookups.
* Pattern Lookups::        Searches Using Wildcard Patterns.
* Parsers::                Using Various Parsers.
* Nodes to Print::
* Scripts::                Using Scheme to Extend Cfpeek Functionality.
@end menu

@node Basic Notions
@section Basic Notions
@cindex simple statement
@cindex identifier
@cindex keyword
@cindex value
A structured configuration file contains entities of two basic types.
First of them is @dfn{simple statement}.  A simple statement conceptually
consists of an @dfn{identifier} (or @dfn{keyword}) and a @dfn{value}.
Depending on the syntactic requirements, some special token may be
required between them (such as an equals sign, for example), or at the
end of the statement.  The @dfn{value}, though we use the term in
singular, is not necessarily a single scalar value, it may as well be
a list of values (the exact form of that list depends on the
particular syntax of the configuration file).

@cindex compound statement
@cindex block statement
@cindex section
@cindex tag, in a compound statement
Another basic entity is @dfn{compound statement}, also known as
@dfn{block statement} or @dfn{section}.  Compound statement is
used for logical grouping of other statements.  It consists of
identifier, an optional tag and a list of statements.  The tag, if
present, is similar to the value in simple statements.  The same notes
that we made about values apply to tags as well.  Tags serve to
discern between the statements having the same identifier.  The @dfn{list of
statements} may include statements of both kinds: simple as well as
compound ones.  Thus, compound statements form a tree-like structure
of arbitrary depth, with simple statements as leaf nodes.

@cindex statement, subordinate
@cindex subordinate statement
@cindex substatement
@cindex child statement
@cindex parent statement
Each compound statement can have any number of @dfn{subordinate
statements}, which are called its @dfn{child} statements.  Each
statement (no matter simple or compound) has only one @dfn{parent
statement}, i.e. a compound statement of which it is a child.

@cindex root statement
A special implicit statement, called @dfn{root statement}, serves
as the parent for the statements at the topmost level of hierarchy.

@node Pathnames
@section Pathnames
@cindex pathname
Given this hierarchical structure, each statement can be identified by
the list of keywords and values (when present) of all compound
statements that must be traversed in order to reach that statement.
Such a list, written according to a set of conventions, is called a
@dfn{full pathname} of the statement.  The conventions are:

@enumerate 1
@item
Pathname is written from top down.
@item
An untagged statement is represented by its identifier.
@item
A tagged statement is represented by its identifier, immediately followed by an
equals sign, followed by the tag.
@item
Identifiers and values which contain whitespace, double quotes or dots
are enclosed in double quotes.
@item
Within double quotes, a double quote is represented as @samp{\"} and a
backslash is represented as @samp{\\}.
@item
Pathname components are separated by dots.
@end enumerate

@cindex pathname, absolute
@cindex absolute pathname
A pathname which begins with a component separator (@samp{.}) is
called @dfn{absolute pathname} and identifies the statement with
relation to the topmost level of hierarchy.

@cindex pathname, relative
@cindex relative pathname
A pathname beginning with an identifier is called @dfn{relative} and
identifies the statement in relation to the statement represented by
that identifier.

Examples of absolute pathnames are:

@example
.database.description
.acl=global.deny
.view=external.zone=com.type
@end example

Examples of relative pathnames are:

@example
description
zone=com.type
@end example

@node Example Configuration
@section Example Configuration
The following configuration file will assist us in further
discussion.  Its syntax is fairly straightforward:

A simple statement is written as identifier followed value.  The two
parts are separated by any amount of whitespace.  Simple statements
are terminated by semicolon.

A compound statement is written as identifier followed by a list of
subordinate statements in curly braces.  A tag (if present) is put
between the identifier and the opening curly brace.

These syntax conventions roughly correspond to the @dfn{Grecs
configuration format}, which @command{cfpeek} assumes by default
(@pxref{grecs}).

@float Example, Sample configuration file
@caption{Sample configuration file}
@example
@include sample.texi
@end example
@end float

@node Listing
@section Listing the Entire File
@cindex pathname-value listing
The only argument @command{cfpeek} requires is the name of the file to
parse.  If no other arguments are given, it produces on the standard
output a listing of that file in @dfn{pathname-value} form.  Each
simple statement in the input file is represented by a single line in
the output listing.  The line consists of two main parts: the full
pathname of that statement and its value.  The two parts are separated
by a colon and space character.  For example:

@runex{list1, cfpeek sample.conf}

@xopindex{format, H, introduced}
This output can be customized via the @option{--format} (@option{-H})
command line option.  This option takes a list of @dfn{output flags},
each of which modifies some aspect of the output.  Most output flags
are boolean, i.e. they enable or disable the given feature.  To
disable the feature, the flag must be prefixed with @samp{no}.

@kwindex path, format flag
To list only the pathnames, use

@runex{list2, cfpeek --format=path sample.conf}

The default output is equivalent to @option{--format=path,value,descend}.

@kwindex value
@kwindex descend
The flags @samp{path} and @samp{value} mean to print the pathname of
the statement and its value.  The @samp{descend} flag affects the
output of compound nodes.  If this flag is set and a node matching the
key is a compound node, @command{cfpeek} will output this node and all
nodes below it (i.e. its descendant nodes).  The @samp{descend} flag
is meaningful only if at least one lookup key is supplied.

@kwindex delim, format flag
You can also use @option{--format} to change the default component
delimiter.  For example, to use slash to delimit components:

@runex{list3, cfpeek --format=delim=/ sample.conf}

@node Lookups
@section Statement Lookups
@cindex search key
@cindex look-up key
@cindex statement look-up
When given more than one argument, @command{cfpeek} treats the rest of
arguments as @dfn{search keys}.  It then searches for statements with
pathnames matching each of the keys and outputs them.  A key can be
either a pathname, or a pattern.

The following command looks for the @samp{pidfile} statement at the
topmost level of hierarchy and prints it:

@runex{list4, cfpeek sample.conf .pidfile}

@xopindex{format, H, in statement look-ups}
As you see, it uses the same output format as with full listings.  If
you wish to change it, use the @option{--format} option, introduced in
the previous section.  For example, to retrieve only the value:

@runex{list5, cfpeek --format=value sample.conf .pidfile}

This approach is quite common when @command{cfpeek} is used in shell
scripts.  It will be illustrated in more detail below.

@xopindex{quiet,q,described}
If a key is not found, @command{cfpeek} prints a message on the standard
error and starts searching for the next key (if any).  When all keys
are exhausted, the program exits with status 1 to indicate that some
of them have not been found.  To suppress the diagnostics output, use
the @option{--quiet} (@option{-q}) option.

@cindex start-up scripts
To illustrate all this, the following example shows how to use
@command{cfpeek} in a start-up script to check whether a program has
already been started and to bring it down, if requested:

@example
#! /bin/sh
pidfile=`cfpeek -q --format=value sample.conf .pidfile`

if test -f $pidfile; then
  pid=`head -1 $pidfile`
else
  pid=
fi

case $1 in
start)  if test -n "$pid"; then
          echo >&2 "the program is already running"
        else
          # start the program
          sample-start
        fi
        ;;
status) if test -n "$pid"; then
          echo "program is running at pid $pid"
        else
          echo "program is not running"
        fi
        ;;
stop)   test -n "$pid" && kill -TERM $pid
        ;;
esac
@end example

@node Pattern Lookups
@section Pattern Lookups
@cindex pattern
@cindex %, a wildcard
Apart from literal pathname, a @dfn{pathname pattern} is allowed as a key.
A pattern can contain @dfn{wildcards} in place of path components.
Two wildcards are defined: @samp{*} and @samp{%}.  A @samp{%} matches
any single keyword:

@cindex *, a wildcard
@runex{list6, cfpeek sample.conf .%.pidfile}

A @samp{*} wildcard matches zero or more keywords appearing in its
place:

@runex{list7, cfpeek sample.conf .*.pidfile}

@cindex globbing pattern
In addition to these wildcards, tags in a pattern can contain
traditional globbing patterns, as described in
@ifhtml
@uref{http://www.manpagez.com/man/3/fnmatch}.
@end ifhtml
@ifnothtml
@ref{fnmatch,,match filename or pathname,fnmatch(3),
fnmatch(3) man page}.
@end ifnothtml

@runex{list8, cfpeek sample.conf '.program=[ab].pidfile'}

@anchor{literal}
@xopindex{literal, L, described}
Pattern lookups can be disabled using the @option{--literal}
(@option{-L}) command line option.  There may be two reasons for doing
so.  First, literal lookups are somewhat faster, so if you don't need
pattern matching using @option{--literal} can save you a couple of CPU
cycles.  Secondly, if any of your identifiers contain @samp{*} or @samp{%}
characters, you will have to use @option{--literal} to prevent them
from being treated as wildcards.

@node Parsers
@section Using Various Parsers
@cindex input formats
@cindex input parsers
@xopindex{parser,p,described}
@command{Cfpeek} can handle input files in various formats.  The
default one is @samp{Grecs} format, introduced in previous sections.
To process input files of another format, specify the @dfn{parser} to
use via the @option{--parser} (@option{-p}) command line option.  The
argument to this option is one of: @samp{grecs}, @samp{bind},
@samp{path}, @samp{meta1} or @samp{git}.  @xref{Formats}, for a
detailed description of each of these formats.

For example, to select zone statements from the @file{/etc/named.conf}
file:

@example
$ cfpeek --parser=bind /etc/named.conf '.*.zone'
@end example

@node Nodes to Print
@section Specifying Nodes to Output
Sometimes you may need to see not the node which matched the search
key, but its parent or other ancestor node.  Consider, for example,
the following task: select from the @file{/etc/named.conf} file the names
of all zones for which this nameserver is a master.  To do so, you
will need to find all @samp{zone.type} statements with the value
@samp{master}, ascend to the parent node and print its value.

@command{Cfpeek} provides several special formatting flags to that
effect: @code{up}, @code{down}, @code{parent}, @code{child} and
@code{sibling}.  They are called @dfn{relative movement} flags,
because they select another node in the tree, relative to the position
of the current node.

@kwindex up
The @code{up} flag takes an integer number as its argument.  It
instructs @command{cfpeek} to ascend that many parent nodes before
actually printing the node.  For example, @option{--format=up=1} means
``ascend to the parent of the matched node and print it''.  This is
exactly what we need to solve the above task, since the @samp{type}
statement is a child of a @samp{zone} statement.  Thus, the solution
is:

@example
cfpeek --format=up=1,nodescend,value --parser=bind \
       /etc/named.conf .*.type=master
@end example

@noindent
The @code{value} flag indicates that we want on output only values, without
the corresponding pathnames.  The @code{nodescend} flag tells
@command{cfpeek} to not descend into compound statements when
outputting them.  It is necessary since we want only values of all
relevant @samp{zone} statements, no their subordinate statements.

@kwindex down
A counterpart of this flag is @code{down=@var{n}} flag, which descends
@var{n} levels of hierarchy.

@kwindex parent
The @code{parent} flag acts in the similar manner, but it identifies
the ancestor by its keyword, instead of the relative nesting level.
The statement

@example
--format=parent=zone
@end example

@noindent
tells @command{cfpeek}, after finding a matching node, to ascend until
a node with the identifier @samp{zone} is found, and then print this node.

@kwindex child
The @code{child=@var{id}} statement does the opposite of
@code{parent}: it locates a child of the current node which has the
identifier @var{id}.

@kwindex sibling
Similarly, the @code{sibling} keyword instructs @command{cfpeek} to
find first sibling of the current node wich has the given identifier.
For example, to find names of the zone files for all master nodes in
the @file{named.conf} file:

@example
cfpeek --parser bind --format=sibling=file,value /etc/named.conf \
       '.*.zone.type=master'
@end example

A @samp{file} statement is located on the same nesting level as
@samp{type}, for example:

@example
zone "example.net" @{
        type master;
        file "db.example.net";
@};
@end example

@noindent
Thus, the above command first locates the @samp{type} statement, then
searches on the same nesting level for a @samp{file} statement, and
finally prints its value.

@node Scripts
@section Using Scripts
@cindex Scheme
@cindex Guile
@cindex scripts
@command{Cfpeek} offers a scripting facility, which can be used to
easily extend its functionality beyond the basic operations, described
in previous chapters.  Scripts must be written in Scheme, using @samp{Guile},
the @dfn{GNU's Ubiquitous Intelligent Language for Extensions}.  For
information about the language, refer to @ref{Top,,,r5rs,Revised(5)
Report on the Algorithmic Language Scheme}.  For a detailed
description of Guile and its features, see
@ref{Top,,Overview,guile,The Guile Reference Manual}.

This section assumes that the reader has sufficient knowledge about
this programming language.

@xopindex{expression,e,introduced}
@kwindex node, Guile variable
The scripting facility is enabled by the use of the @option{--expression}
(@option{-e}) of @option{--file} (@option{-f} command line options.
The @option{--expression} (@option{-e}) option takes as its argument a
Scheme expression, which will be executed for each statement matching
the supplied keys (or for each statement in the tree, if no keys were
supplied).  The expression can obtain information about the statement
from the global variable @code{node}, which represents a node in the
parse tree describing this statement.  The node contains complete
information about the statement, including its location in the source
file, its type and neighbor nodes, etc.  A number of functions is
provided to retrieve that information from the node.  These functions
are discussed in detail in @ref{Scripting}.

Let's start from the simplest example.  The following command prints all
nodes in the file:

@runex{list9, cfpeek --expression='(display node)(newline)' sample.conf}

The format shown in this example is the default Scheme representation
for nodes.  You can use accessor functions to format the output to
your liking.  For instance, the function @samp{grecs-node-locus}
returns the location of the node in the input file.  The returned
value is a cons, with the file name as its car and the line number as
its cdr.  Thus, you can print statement locations with the following
command:

@example
cfpeek --expr='(let ((loc grecs-node-locus)) 
                 (format #t "~A:~A~%"
                  (car loc) (cdr loc)))' \
       sample.conf
@end example

@xopindex{file,f,introduced}
Complex expressions are cumbersome to type in the command line,
therefore the @option{--file} (@option{-f}) option is provided.  This
option takes the name of the script file as its argument.  This file
must define the function named @code{cfpeek} which takes a node as its
argument.  The script file is then loaded and the @code{cfpeek}
function is called for each matching node.

Now, if we put the expression used in the previous example in
a script file (e.g.  @file{locus.scm}):

@lisp
(define (cfpeek node)
  (let ((loc grecs-node-locus))
    (format #t "~A:~A~%" (car loc) (cdr loc))))
@end lisp

@noindent
then the example can be rewritten as:

@example
$ cfpeek -f locus.scm sample.conf
@end example

@cindex @option{--file} and @option{--expression} used together
When both @option{--file} and @option{--expression} options are used in the
same invocation, the @code{cfpeek} function is not invoked by default.
In fact, it even does not need to be defined.  When used this way,
@command{cfpeek} first loads the requested script file, and then
applies the expression to each matching node, the same way it always
does when @option{--expression} is supplied.  It is the responsibility of
the expression itself to call any function or functions defined in the
file.  This way of invoking @samp{cfpeek} is useful for supplying
additional parameters to the script.  For example:

@example
$ cfpeek -f script.scm -e '(process-node node #t)' input.conf
@end example

It is supposed that the function @code{process-node} is defined
somewhere in @file{script.scm} and takes two arguments: a node and a
boolean.

@xopindex{init,i,described}
The @option{--init=@var{expr}} (@option{-i @var{expr}}) option
provides an initialization expression @var{expr}.  This expression is
evaluated once, after loading the script file, if one is specified,
and before starting the main loop.

@xopindex{done,d,described}
Similarly, the option @option{--done=@var{expr}} (@option{-d
@var{expr}}) introduces a Scheme expression to be evaluated at the end
of the run, after all nodes have been processed.

@menu
* Scripting Example::
@end menu

@node Scripting Example
@subsection Example: Converter to GIT Configuration Format
@cindex GIT Configuration Converter
Here is a more practical example of Scheme scripting.  This script
converts entire parse tree into a GIT configuration file format.  The
format itself is described in @ref{git}.

The script traverses entire tree itself, so it must be called only
once, for the root node of the parse tree.  The root node is denoted
by a single dot, so the invocation syntax is:

@example
cfpeek -f togit.scm sample.conf .
@end example

@kwindex grecs-node-next
@kwindex grecs-node-down
Traversal is performed by the main function, @code{cfpeek}, using the
@code{grecs-node-next} and @code{grecs-node-down} functions.  The
@code{grecs-node-next} function returns a node which follows its
argument at the same nesting level.  For example, if @var{n} is the
very first node in our sample parse tree, then:

@lisp
n @result{} #<node .user: "smith">
(grecs-node-next n) @result{} #<node .group: "mail">
@end lisp

Similarly, the @code{grecs-node-down} function returns the first
subordinate node of its argument.  For example:

@lisp
n @result{} #<node .logging>
(grecs-node-down n) @result{} #<node .logging.facility: "daemon">
@end lisp

Both functions return @samp{#f} if there are no next or subordinate
node, correspondingly.

@kwindex grecs-node-type
The @code{grecs-node-type} function is used to determine how to handle
that particular node.  It returns a @dfn{type} of the node given to it
as argument.  The type is an integer constant, with the following
possible values:

@multitable @columnfractions 0.4 0.6
@headitem Type @tab The node is
@item grecs-node-root @tab the root (topmost) node
@item grecs-node-stmt @tab a simple statement
@item grecs-node-block @tab a compound (block) statement
@end multitable

The @code{print-section} function prints a GIT section header
corresponding to its node.  It ascends the parent node chain
to find the topmost node and prints the traversed nodes in the correct
order.

To summarize, here is the listing of the @file{togit.scm} script:

@lisp
@include togit.texi
@end lisp

If run on our sample configuration file, it produces:

@runex{list10, cfpeek -f togit.scm sample.conf .}

@node Formats
@chapter Supported Configuration File Formats
@cindex input formats
@cindex format, input
@command{Cfpeek} is able to handle input files in several formats.
The supported formats differ mostly in syntax.  This chapter describes
them in detail.  If you know of any free software which uses a
structured configuration file not understood by @command{cfpeek},
please let us know (@pxref{Reporting Bugs}).

@menu
* grecs::
* path::
* bind::
* dhcpd::
* meta1::
* git::
@end menu

@node grecs
@section Grecs Configuration File
@cindex grecs configuration format
This is the default input format.  It is used, e.g., by GNU
Dico@footnote{@xref{Top, GNU Dico,, dico, GNU Dico Manual}.},
GNU Mailutils@footnote{@xref{Top, GNU Mailutils,, mailutils,
GNU Mailutils Manual}.},
GNU Radius@footnote{@xref{Top, GNU Radius,, radius, GNU Radius
Manual}.},
Mailfromd@footnote{@xref{Top, Mailfromd,, mailfromd, Mailfromd
Manual}.} and others.
@include grecs-syntax.texi

@node path
@section Path Configuration File
@cindex path configuration format
@cindex X-resources
A @dfn{pathname configuration file} format corresponds exactly to
the default output format of @command{cfpeek}, i.e. it lists each
terminal keyword as its full pathname, followed by a semicolon, a
single space and its value, as in the example below:

@example
.user: "smith"
.group: "mail"
.pidfile: "/var/run/example"
.logging.facility: "daemon"
.logging.tag: "example"
.program="a".command: "a.out"
.program="a".logging.facility: "local0"
.program="a".logging.tag: "a"
.program="b".command: "b.out"
.program="b".wait: "yes"
.program="b".pidfile: "/var/run/b.pid"
@end example

This format is similar to the one used in X-resources.

@node bind
@section BIND Configuration File
@cindex bind configuration format
This is the format used by the @sc{isc} @sc{bind} configuration files.
In general, it is pretty similar to the @samp{Grecs}, except that it
does not support neither here-documents, not list values.  Some of its
features, such as @samp{acls} and @samp{allow-*} lists do resemble
lists, but are not them in reality.  Such ``suspicious'' statements
are represented as simple statements.  For example, the following
statement in @file{named.conf}:

@example
allow-transfer @{
    allow-dns;
    !10.10.10.1;
    10.10.10.0/8;
@};
@end example

@example
.allow-transfer.allow-dns:
.allow-transfer.!: "10.10.10.1"
.allow-transfer."10.10.10.0/8":
@end example

Another exception is the @samp{controls} statement, which doesn't fall
well into the general syntax of @sc{bind} configuration file.
Therefore a special rule is applied to handle it.  In the effect, the
following statement:

@example
controls @{
    inet 127.0.0.1 port 953
        allow @{ 127.0.0.1; 127.0.0.2; @} keys @{ "rndc-key"; @};
@};
@end example

@noindent
produces

@example
.controls: (inet, 127.0.0.1, port, 953, allow, \
              (127.0.0.1, 127.0.0.2), keys, (rndc-key))
@end example

@node dhcpd
@section DHCPD Configuration File
@cindex dhcpd configuration format
This is the format used by the @sc{isc} @sc{dhcpd} configuration
files (@file{/etc/dhcpd.conf} and any files it might include).
It is very similar to @samp{Bind}, with some minor differences:

@itemize @bullet
@item Block statements do not end with a semicolon.
@item Tags or values can contain lists of quoted strings delimited by
commas.
@end itemize

@node meta1
@section MeTA1 Configuration File
@cindex MeTA1 configuration format
This type of configuration file is used by @dfn{MeTA1}, an advanced
MTA program.  See @uref{http://www.meta1.org} for details about the
program and its configuration.

The syntax is similar to both @samp{Grecs} and @samp{Bind} in that it
uses curly braces to delimit subordinate statements.  The syntax for
strings is similar to @samp{Grecs} (@pxref{Statements,,quoted
string}).  As in @samp{Grecs}, adjacent quoted strings are
concatenated to produce a single string.

The principal syntactic differences are:

@itemize @bullet
@item Only @samp{#} comments are understood.
@item An equal sign is required between identifier and value in simple
statements, e.g.:

@example
log_level = 12;
@end example

@item List values are enclosed in curly braces.
@item Here-document is not supported.
@end itemize

@node git
@section GIT Configuration File
@cindex git configuration format
This is the format used by Git (@uref{http://git-scm.com}).  It is
described in detail in
@ifhtml
@uref{http://www.kernel.org/pub/software/scm/git/docs/git-config.html}.
@end ifhtml
@ifnothtml
@xref{git-config,,CONFIGURATION FILE,git-config(1),
git-config(1) man page}.
@end ifnothtml

The syntax is line-oriented.  Comments are introduced by @samp{#} or
@samp{;} character and extend up to the next physical newline.
Statements are delimited by newlines.

The syntax for simple statement is:

@example
@var{ident} = @var{value}
@end example

Compound statements or @dfn{sections} begin with a @dfn{section
header}, i.e. a full pathname of that section using single space as a
separator and enclosed in a pair of square brackets.  Any identifier
in the path which contains whitespace characters must be quoted using
double quotes.  Double quotes and backslashes appearing in a section
name must be escaped as @samp{\"} and @samp{\\} correspondingly.
For example:

@example
[section "subsection name" subsubsection]
@end example

An alternative syntax for section headers is a full pathname of the
section using single dot as a separator and enclosed in a pair of
square brackets.  When this syntax is used, whitespace is not allowed
in section names:

@example
[section.subsection.subsubsection]
@end example

A section begins with the section headers and continues until the
start of next section or end of file, whichever occurs first.

Simple statements must occur only within a section.  In other words,
each non-empty configuration file must contain at least one section.

String values may be entirely or partially enclosed in double quotes,
similarly to shell syntax.  The following escape sequences are
recognized within a value:

@multitable @columnfractions 0.3 0.7
@headitem Sequence @tab Stands for
@item @samp{\"} @tab @samp{"}
@item @samp{\\} @tab @samp{\}
@item @samp{\b} @tab Backspace (ASCII 8)
@item @samp{\t} @tab Horizontal tab (ASCII 9)
@item @samp{\n} @tab Newline (ASCII 10)
@end multitable

A backslash immediately preceding a newline indicates line
continuation.  Both characters are removed and the remaining characters are
joined with line that follows.

@node Invocation
@chapter Cfpeek Command Line Syntax
The format of @command{cfpeek} invocation is:

@example
cfpeek @var{options} @var{file} [@var{keys}]
@end example

@noindent
where @var{options} are command line options, @var{file} is the
configuration file to operate upon, and optional @var{keys} are
pathnames of the keywords to locate in that configuration file.

If @var{keys} are supplied, @command{cfpeek}, for each @var{key},
looks up in the parse tree for any nodes matching the key and prints
them on the standard output.  An error message is displayed for any
key which has no matching statements in the input file.  In this case,
program continues iterating over the rest of @var{keys}.  When the
list is exhausted, @command{cfpeek} will exit with the status 1
(@pxref{Exit Codes}).

If either @option{-f} (@option{--file}) or @option{-e}
(@option{--expression}) has been given, a Scheme expression or the default
@code{cfpeek} function is evaluated for each matching node.  If
@option{-e} (@option{--expression}) is given, the node is passed to it in
the global @samp{node} variable.  Otherwise, if @option{-f}
(@option{--file}) is given, the node is passed as argument to
@code{cfpeek} function.

@cindex @option{--file} and @option{--expression} used together
If both @option{--file=@var{script}} and @option{--expression=@var{expression}}
options are given, the script file @var{script} is loaded first, and
the @var{expression} is evaluated for each matching node.  The
expression can then refer to any variables and call any functions
defined in the @var{script}.

If no keys are supplied, the program operates as if given a single
@samp{.*} key (@pxref{Patterns}), which matches any node in the parse
tree (i.e., it iterates over the entire parse tree).

@menu
* Patterns::
* Output Control::
* Modifiers::
* Scripting Options::
* Preprocessor Control Options::
* Debugging Options::
* Informational Options::
@end menu

@node Patterns
@section Patterns
@cindex pattern
@cindex wildcards
By default @command{cfpeek} treats keys as @dfn{wildcard patterns}.
When matching statement identifiers (keywords), two characters have special
meaning: @samp{%} and @samp{*}.

@kwindex %, a wildcard
A @samp{%} character in place of an identifier matches any single
keyword.  Thus, e.g.:

@example
cfpeek file.conf .%.bar.baz
@end example

@noindent
will match @samp{.foo.bar.baz}, @samp{.qux.bar.baz}, but will not match
@samp{.bar.baz} or @samp{.x.y.bar.baz}.

@kwindex *, a wildcard
A single @samp{*} character in place of a keyword matches zero or more
keywords appearing in its place, so that:

@example
cfpeek file.conf .*.bar.baz
@end example

@cindex globbing patterns
The tags in block statement are matched using the traditional globbing
patterns.
@ifhtml
See @uref{http://www.manpagez.com/man/3/fnmatch}.
@end ifhtml
@ifnothtml
@xref{fnmatch,,match filename or pathname,fnmatch(3),
fnmatch(3) man page}.
@end ifnothtml

For example, this:

@example
cfpeek file.conf .*.program="mh-*"
@end example

@noindent
will match any @samp{program} block statement whose tag begins with
@samp{mh-}.

@node Output Control
@section Output Control
@table @option
@opsummary{format,H}
@item -H @var{flags}
@itemx --format=@var{flags}
Set output format flags.  The argument is a comma-separated list of
format flags and @dfn{relative movement} options.  Relative movement
options select another node, relative to the one found.  They are:

@table @samp
@kwindex parent
@item parent=@var{id}
Find a parent of the matching node, which has @var{id} as its
identifier.

@kwindex child
@item child=@var{id}
Find a child of the matching node, which has @var{id} as its
identifier.

@kwindex sibling
@item child=@var{id}
Find a sibling of the matching node, which has @var{id} as its
identifier.

@kwindex up
@item up=@var{n}
Ascend @var{n} parent nodes and print the node at which the ascent stopped.
@end table

@kwindex down
@item descend=@var{n}
Descend @var{n} child nodes.

Any number of relative movement options can be specified.  They are
executed in the order of their appearance in the @option{--format}
statement.  For example, @option{--format=up=2,sibling=foo,child=bar}
means: ascend two levels of hierarchy, find a node named @samp{foo},
look for a node named @samp{bar} among the children of that node and
print the result.

If evaluation of the relative movement options results in an empty
node (e.g. the @samp{up} option attempts to go past the root of the
tree), nothing is output.

The @code{delim} flag controls how keyword paths is printed:

@table @samp
@kwindex delim
@item delim=@var{char}
Sets path component delimiter, instead of the default @samp{.}.
@end table

The following flags control the amount of information printed for each
node.  These are boolean flags: when prefixed with @samp{no} they have the
meaning opposite to the described.

@table @samp
@kwindex locus
@kwindex nolocus
@item locus
Print source location of each configuration statement.  A location is
printed as the file name, followed by a semicolon, followed by the line
number and another semicolon.  Locations are separated from the rest
of output by a single space character.
@kwindex path
@kwindex nopath
@item path
Print statement paths.
@kwindex value
@kwindex novalue
@item value
Print statement values.
@kwindex quote
@kwindex noquote
@item quote
Always quote string values.
@kwindex never-quote
@kwindex nonever-quote
@item never-quote
Never quote string values.
@kwindex quote-hex
@kwindex noquote-hex
@item quote-hex
Print non-printable characters as C hex escapes.  This option
is ignored if @samp{noquote} is set.
@kwindex descend
@kwindex nodescend
@item descend
Descend into subnodes.
@kwindex default
@kwindex nodefault
Set default options.
@end table

The default format options are: @samp{path,value,quote,descend}.

@opsummary{quiet,q}
@item -q
@itemx --quiet
Suppress error diagnostics.  @xref{Lookups,,quiet}.
@end table

@node Modifiers
@section Modifiers
The following options modify the way @command{cfpeek} processes the
parse tree and search keys.

@table @option
@opsummary{literal,L}
@item -L
@itemx --literal
Use literal matching, instead of pattern matching.  @xref{literal}.

@opsummary{sort,S}
@item -S
@itemx --sort
Before further processing, sort parse tree lexicographically in
ascending order.

@opsummary{matches,m}
@item -m
@itemx --matches=@var{number}
Output at most @var{number} matches for each key.

@opsummary{parser,p}
@item -p
@itemx --parser=@var{type}
Set parser type for the input file.  The argument is one of:
@samp{grecs}, @samp{path}, @samp{meta1}, @samp{bind}, @samp{dhcpd},
and @samp{git} (case-insensitive).  @xref{Formats}, for a description
of each type.

@opsummary{reduce,r}
@item -r
@itemx --reduce
Reduce the parse tree, so that each keyword occurs no more than once
at each tree level.

@opsummary{set,s}
@item -s @var{path}=@var{val}
@itemx --set=@var{path}=@var{val}
Set a keyword @var{path} to @var{value}.  The produced parse tree node
will be processed as usual.
@end table

@node Scripting Options
@section Scripting Options
The following options control the scripting facility of
@command{cfpeek}.

@table @option
@opsummary{expression,e}
@item -e @var{expression}
@itemx --expression=@var{expression}
@kwindex node
Apply this expression to each node found.  The global variable
@code{node} is set to the node being processed before evaluating.
When used together with @option{--file=@var{script}}, the expression
can refer to any variables and call any functions defined in the
@var{script} file.

@opsummary{file,f}
@item -f @var{file}
@itemx --file=@var{file}
@kwindex cfpeek, Scheme function
Load the script @var{file}.  Unless @option{--expression} is also given, the
script must define the function named @samp{cfpeek} which takes a node
as its only argument.  This function will be called for each matching node.

If @option{--expression} is given, this behavior is suppressed.  It is then the
responsibility of the expression to call any functions defined in this file.

@opsummary{init,i}
@item -i @var{expr}
@itemx --init=@var{expr}
The @option{--init=@var{expr}} (@option{-i @var{expr}}) option
provides an initialization expression @var{expr}.  This expression is
evaluated once, after loading the script file, if one is specified,
and before starting the main loop.

@opsummary{lang,l}
@item -l @var{script-language}
@item --lang=@var{script-language}
Select scripting language to use.  This option is reserved for further
use.  As of version @value{VERSION}, the only possible value for
@var{script-language} is @samp{scheme}.
@end table

@node Preprocessor Control Options
@section Preprocessor Control Options
@cindex preprocessor control
The options described below control the preprocessor facility.  They
are meaningful only for @samp{GRECS} and @samp{BIND} configuration
files.  Preprocessor is not used for another configuration file formats.

@table @option
@opsummary{define,D}
@item -D@var{name}[=@var{value}]
@itemx --define=@var{name}[=@var{value}]
Define the preprocessor symbol @var{name} as having @var{value}, or
empty.  @xref{Preprocessor}.

@opsummary{include-directory,I}
@item -I @var{dir}
@itemx --include-directory=@var{dir}
Add @var{dir} to include search path.

@xref{Pragmatic Comments, #include}.

@opsummary{no-preprocessor,N}
@item -N
@itemx --no-preprocessor
Disable preprocessor.  @pxref{Preprocessor}.

@opsummary{preprocessor,P}
@item -P @var{command}
@itemx --preprocessor=@var{command}
Use @var{command} instead of the default preprocessor.  @pxref{Preprocessor}.
@end table

@node Debugging Options
@section Debugging Options
The options below enable trace output which helps understand how
configuration parser works.  They are mainly useful for
@command{cfpeek} developers.

@table @option
@opsummary{debug-lexer,X}
@item -X
@itemx --debug-lexer
Trace configuration file lexer.

@opsummary{debug-parser,x}
@item -x
@itemx --debug-parser
Trace configuration file parser.
@end table

@node Informational Options
@section Informational Options

@table @option
@opsummary{help,h}
@item --help
@itemx -h
Print a concise usage summary and exit.

@opsummary0{usage}
@item --usage
Print a summary of command line syntax and exit.

@opsummary{version,V}
@item --version
@itemx -v
Print the program version and exit.
@end table

@node Exit Codes
@chapter Exit Codes
@cindex exit code
When cfpeek terminates, it reports the result of its invocation via
its exit code.  Exit code of 0 indicates normal termination.  Exit
code 1 indicates that not all search keys has been found.  Exit codes
greater than 1 indicate various error conditions.  The exact cause
of failure is reported on the standard error.

The exit codes are as follows:

@table @asis
@item 2
Error parsing the input file.
@item 3
Script failure.
@item 64
The command was used incorrectly, e.g., with the wrong number of
arguments, a bad option, a bad syntax in a parameter, or whatever.
@item 69
The requested script file does not exist, contains syntax errors, or
cannot be parsed for whatever other reason.
@item 70
An internal software error has occurred.  Please, report it, along
with any error diagnostics produced by the program, if you
ever stumble upon this error code.  @xref{Reporting Bugs}, for
detailed instructions.
@item 78
The script file parses correctly, but does not define all the symbols
required by @command{cfpeek}.
@end table

@node Scripting
@chapter Scripting
This chapter describes the Scheme functions available for use in
@command{cfpeek} scripts.  For an introduction to @command{cfpeek}
scripting facility, see @ref{Scripts}.
@include scripting.texi

@node Reporting Bugs
@chapter How to Report a Bug

Please, report bugs and suggestions to @email{bug-cfpeek@@gnu.org.ua}.

  You hit a bug if at least one of the conditions below is met:

@itemize @bullet
@item @command{cfpeek} terminates on signal 11
(SIGSEGV) or 6 (SIGABRT).
@item @command{cfpeek} terminates with exit code 70 (internal software
error).
@item The program fails to do its job as described in
this manual.
@end itemize

  If you think you've found a bug, please be sure to include maximum
information available to reliably reproduce it, or at least to analyze
it.  The information needed is:

@itemize
@item Version of the package you are using.
@item Command line options and input file (or files) used.
@item Conditions under which the bug appears.
@end itemize

  Any errors, typos or omissions found in this manual also qualify as
bugs.  Please report them, if you happen to find any.

@node Copying This Manual
@appendix GNU Free Documentation License
@include fdl.texi

@node Concept Index
@unnumbered Concept Index

This is a general index of all issues discussed in this manual

@printindex cp

@bye



