\input texinfo   @c -*-texinfo-*-
@setfilename gnats.info   

@include version.texi

@ifinfo
@format
START-INFO-DIR-ENTRY
* Keeping Track: (gnats).	GNU Problem Report Management System
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@ifinfo
Copyright @copyright{} 1993, 1995, 2001, 2002, 2003 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries a copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ifinfo

@c NOTE TO ANYONE FORMATTING THIS DOCUMENT FOR PRINTING...
@c Comment the following line out if you don't have access to a
@c PostScript printer or viewer

@set POSTSCRIPT

@settitle Keeping Track
@setchapternewpage odd
@finalout
@titlepage
@title Keeping Track
@subtitle Managing Messages With @sc{gnats}
@subtitle The @sc{gnu} Problem Report Management System
@subtitle Version @value{VERSION}
@subtitle August 2003
@author Jeffrey M. Osier
@author Brendan Kehoe
@author Cygnus Support
@author Revised for GNATS 4 by Yngve Svendsen
@page

@vskip 0pt plus 1filll
Copyright @copyright{} 1993, 1995, 2001, 2002, 2003 Free Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.

@end titlepage

@contents

@node Top
@top Overview
@cindex overview to GNATS
@cindex foreword

This manual documents @sc{gnats}, the @sc{gnu} Problem Report Management
System, version @value{VERSION}.  @sc{gnats} is a bug-tracking tool
designed for use at a central @dfn{Support Site}.  Users who experience
problems use electronic mail, web-based or other clients communicating
with the @sc{gnats} network daemon running at the support site or direct
database submissions to communicate these problems to @dfn{maintainers}
at that Support Site.  @sc{gnats} partially automates the tracking of
these @dfn{Problem Reports} (@dfn{PR}s) by:

@itemize @bullet
@item
organizing problem reports into a database and notifying responsible
parties of suspected bugs;

@item
allowing support personnel and their managers to edit and query
accumulated bugs; and

@item
providing a reliable archive of problems (and their subsequent
solutions) with a given program.
@end itemize

@sc{gnats} offers many of the same features offered by more generalized
databases, including editing, querying, and basic reporting.  The
@sc{gnats} database itself is an ordered repository for problem reports;
each PR receives a unique, incremental @dfn{PR number} which identifies
it throughout its lifetime.  For a discussion on the working system
adopted by @sc{gnats}, see @ref{Paradigm,,The database paradigm}.

You can access the submitting, editing, and querying functions of
@sc{gnats} from within @sc{gnu} Emacs.  @xref{GNATS user tools,,The
@sc{gnats} user tools}.

@menu
* Introduction::          Introducing GNATS.
* GNATS user tools::      The GNATS user tools.
* Installation::          Installing GNATS.
* Management::            GNATS Administration.
* Locations::             Where GNATS lives.
* gnatsd::                The GNATS network server.
* Access Control::        Controlling access to GNATS databases.
* Regexps::               Querying using regular expressions.
* dbconfig recipes::      Useful dbconfig tricks.
* Support::               GNATS related sites and mailing lists.
* Index::
@end menu

@c ===============================================================
@node Introduction
@chapter Introducing @sc{gnats}
@cindex introduction to GNATS
@cindex rationale
@cindex database rationale

Any support organization realizes that a large amount of data flows back
and forth between the maintainers and the users of their products.  This
data often takes the form of problem reports and communication via
electronic mail.  @sc{gnats} addresses the problem of organizing this
communication by defining a database made up of archived and indexed
problem reports.

@sc{gnats} was designed as a tool for software maintainers.  It consists
of several utilities which, when used in concert, formulate and
administer a database of Problem Reports grouped by site-defined
@dfn{problem categories}.  It allows a support organization to keep
track of problems (hence the term @dfn{Problem Report}) in an organized
fashion.  Essentially, @sc{gnats} acts as an active archive for
field-separated textual data.

@menu 
* Paradigm::       The database paradigm
* Flowchart::      Flowchart of GNATS activities
* States::         States of Problem Reports
* Fields::         Problem Report format
@end menu

@node Paradigm
@section The database paradigm
@cindex paradigm
@cindex database paradigm
@cindex why GNATS
@cindex support site
@cindex maintenance
@cindex so what does it do

It is in your best interest as the maintainer of a body of work to
organize the feedback you receive on that work, and to make it easy for
users of your work to report problems and suggestions.

@sc{gnats} makes this easy by automatically filing incoming problem
reports into appropriate places, by notifying responsible parties of the
existence of the problem and (optionally) sending an acknowledgment to
the submitter that the report was received, and by making these Problem
Reports accessible to queries and easily editable.  @sc{gnats} is a
database specialized for a specific task.

@sc{gnats} was designed for use at a Support Site that handles a high
level of problem-related traffic.  It maintains Problem Reports in the
form of text files with defined @dfn{fields}
(@pxref{Fields,,@sc{gnats} data fields}).  The location of the database,
as well as the categories it accepts as valid, the maintainers for whom
it provides service, and the submitters from whom it accepts Problem
Reports, are all definable by the @dfn{Support Site}.
@xref{Management,,@sc{gnats} administration}.

@cindex what is a PR
Each PR is a separate file within a main repository
(@pxref{Locations,,Where @sc{gnats} lives}).  Editing access to the
database is regulated to maintain consistency.  To make queries on
the database faster, an index is kept automatically (@pxref{index
file,,The @code{index} file}).

We provide several software tools so that users may submit new Problem
Reports, edit existing Problem Reports, and query the database.

@itemize @bullet
@item 
@w{@code{send-pr}} is used by both product maintainers and the end users
of the products they support to submit PRs to the database.

@item 
@w{@code{edit-pr}} is used by maintainers when editing problem
reports in the database.

@item 
Maintainers, managers and administrators can use @w{@code{query-pr}} to
make inquiries about individual PRs or groups of PRs.  

@end itemize

Other interfaces to @sc{gnats} include Gnatsweb, a web-based tool which
provides features for submitting and editing PRs and querying the
database, and TkGnats, a Tcl/Tk-based frontend.  These tools are
distributed together with @sc{gnats}.

@cindex GNATS administrator
At the Support Site, a @sc{gnats} @dfn{administrator} is charged with the
duty of maintaining @sc{gnats}.  These duties are discussed in detail in
@ref{Management,,@sc{gnats} Administration}, and generally include
configuring @sc{gnats} for the Support Site, editing PRs that @sc{gnats}
cannot process, pruning log files, setting up new problem categories,
backing up the database, and distributing @code{send-pr} so that others
may submit Problem Reports.

Responsibility for a given Problem Report initially depends on the
category of the problem.  Optionally, an automated reminder can be
sent to the responsible person if a problem report is neglected for a
requisite time period.  @xref{GNATS configuration,,Overview of
@sc{gnats} configuration}.

@cindex @code{pending} directory
@cindex unparseable incoming PRs
@cindex incoming PRs that @sc{gnats} cannot parse
@sc{gnats} does not have the ability to decipher random text.
If there is no default category set, any
problem reports which arrive in a format @sc{gnats} does not recognize
are placed in a separate directory pending investigation by the
@sc{gnats} administrator (@pxref{Management,,@sc{gnats} Administration}).

Once a problem is recorded in the database, work can begin toward a
solution.  A problem's initial @dfn{state} type is @dfn{open}
(@pxref{States,,States of Problem Reports}).  An acknowledgment may be
sent to the originator of the bug report (depending on whether this
feature has been switched on in the @sc{gnats} configuration).
@sc{gnats} forwards copies of the report to the party responsible for
that problem category and to the person responsible for problems
arriving from that submitter.
@c (@pxref{Glossary,,Glossary}).

When a problem has been identified, the maintainer can change its state
to @dfn{analyzed}, and then to @dfn{feedback} when a solution is found.
@sc{gnats} may be configured so that each time the state of a PR
changes, the submitter of the problem report is notified of the reason
for the change.  If the party responsible for the PR changes, the
previous responsible party and the new responsible party receive notice
of the change.  The change and reason are also recorded in the
@code{Audit-Trail} field of the Problem Report.  (@xref{edit-pr,,Editing
existing Problem Reports}.  For information on the @code{Audit-Trail}
field, see @ref{Fields,,Problem Report format}.)

When the originator of the Problem Report confirms that the solution
works, the maintainer can change the state to @dfn{closed}.  If the PR
cannot be closed, the maintainer can change its state to @dfn{suspended}
as a last resort.  (For a more detailed description of the standard
states, see @ref{States,,States of Problem Reports}.)

It should be emphasized that what we describe here is the default way
that @sc{gnats} works, but as of version 4, @sc{gnats} is extremely
customizable, allowing sites to tailor almost every aspect of its
behavior.  See for instance @ref{dbconfig file,,The @code{dbconfig}
file} and @xref{States,,States of Problem Reports}.)

@node Flowchart
@section Flowchart of @sc{gnats} activities
@cindex flowchart of GNATS activities
@cindex visual map of data flow

This informal flowchart shows the relationships of the @sc{gnats} tools
to each other and to the files with which they interoperate.

@sp 2

@ifset POSTSCRIPT
@tex
\input epsf
\epsffile{flowchart.eps}
@end tex
@end ifset

@ifinfo
@clear POSTSCRIPT
@end ifinfo

@ifclear POSTSCRIPT
@cartouche
@smallexample
@include flowchart.txt
@end smallexample
@end cartouche

@end ifclear

@sp 2

@c ---------------------------------------------------------------

@include states.texi

@c ---------------------------------------------------------------
@include fields.texi

@c ===============================================================

@include p-usage.texi

@c ===============================================================

@node Installation
@chapter Installing @sc{gnats}
@include p-inst.texi

@c ===============================================================

@include p-admin.texi

@c ===============================================================

@node Locations
@appendix Where @sc{gnats} lives
@cindex locations
@cindex where @sc{gnats} lives
@cindex default installation locations

We use a few conventions when referring to the installation structure
@sc{gnats} uses.  These values are adjustable when you build and install
@sc{gnats} (@pxref{Installation,,Installing @sc{gnats}}).

@menu
* prefix::                      
* exec-prefix::                 
* gnats-adm::                  
* defaults::                    Default installation locations
@end menu

@node prefix
@section @var{prefix}
@cindex @var{prefix}

@var{prefix} corresponds to the variable @samp{prefix} for
@code{configure}, which passes it on to the @file{Makefile} it creates.
@var{prefix} sets the root installation directory for
@dfn{host-independent} files as follows:

@c FIXME - check these
@table @asis
@item the directory path of the default database
@file{@var{prefix}/com}@*

@item site-wide configuration files
@file{@var{prefix}/etc/gnats}@*

@item @code{man} pages
@file{@var{prefix}/man}

@item @code{info} documents
@file{@var{prefix}/info}

@item @code{include} files
@file{@var{prefix}/include}

@item @emph{etc@dots{}}
@end table

The default value for @var{prefix} is @w{@file{/usr/local}}, which can
be changed on the command line to @code{configure} using

@smallexample
configure --prefix=@var{prefix} @dots{}
@end smallexample

@noindent
@xref{Configure and make,,Configuring and compiling the software}.

@node exec-prefix
@section @var{exec-prefix}
@cindex @var{exec-prefix}

@var{exec-prefix} corresponds to the variable @samp{exec-prefix} for
@code{configure}, which passes it on to the @file{Makefile} it creates.
@w{@var{exec-prefix}} sets the root installation for
@dfn{host-dependent} files as follows:

@table @asis
@item @sc{gnats} user tools
@file{@var{exec-prefix}/bin}

@item administrative and support utilities
@file{@var{exec-prefix}/libexec/gnats}

@item compiled libraries 
@file{@var{exec-prefix}/lib}@*

@item @emph{etc@dots{}}
@end table

@code{configure} supports several more options which allow you to
specify in great detail where different files are installed.  The
locations given in this appendix do not take into account highly
customized installations, but fairly ordinary @sc{gnats} installations
should be covered by the material here.  For a complete list of options
accepted by @code{configure}, run @code{./configure --help} in the
@file{gnats} subdirectory of the distribution.

Since most installations are not intended to be distributed around a
network, the default value for @w{@var{exec-prefix}} is the value of
@samp{prefix}, i.e., @w{@file{/usr/local}}.  However, using
@var{exec-prefix} saves space when you are installing a package on
several different platforms for which many files are identical; rather
than duplicate them for each host, these files can be shared in a common
repository, and you can use symbolic links on each host to find the
host-dependent files.

Use @var{exec-prefix} in conjunction with @var{prefix} to share
host-independent files, like libraries and @code{info} documents.  For
example:

@smallexample
   @emph{for each host:}
configure --prefix=/usr/gnu --exec-prefix=/usr/gnu/H-@var{host}
make all install @dots{}
@end smallexample

@noindent
Using this paradigm, all host-dependent binary files are installed into
@w{@file{/usr/gnu/H-@var{host}/bin}}, while files which do not depend on
the host type for which they were configured are installed into
@w{@file{/usr/gnu}}.

You can then use a different symbolic link for @w{@file{/usr/gnu}}
on each host (@file{/usr} is usually specific to a particular machine;
it is always specific to a particular architecture).

@smallexample
  @emph{on host-1:}
ln -s /usr/gnu/H-@var{host-1} /usr/gnu
  @emph{on host-2:}
ln -s /usr/gnu/H-@var{host-2} /usr/gnu
@end smallexample

@noindent
To the end user, then, placing @w{@file{/usr/gnu/bin}} in her or his
@code{PATH} simply works transparently for each @var{host} type.

You can change @w{@var{exec-prefix}} on the command line to
@code{configure} using

@smallexample
configure --exec-prefix=@var{exec-prefix} @dots{}
@end smallexample

We recommend that you consult @ref{Using configure,,Using
@code{configure},configure,Cygnus configure}, before attempting this.

@node gnats-adm
@section The @file{gnats-adm} directory
@cindex @var{gnats-adm}

Each @sc{gnats} database located on a server has its own directory, as
listed in the @file{databases} (@pxref{databases file,,The
@code{databases} file} and given when the @code{mkdb} utility is invoked
to initialize the database (@pxref{mkdb,,Initializing a new database}).
This directory has several subdirectories, one of which is named
@file{gnats-adm}.  This directory contains all configuration files
related to this specific database, including the @file{categories},
@file{submitters}, @file{responsible}, @file{states}, @file{classes},
@file{dbconfig}, @file{addresses}, @file{states} and
@file{gnatsd.user_access}, as well as two
files generated and maintained by @sc{gnats}, @file{index} and
@file{current}.

@node defaults
@section Default installation locations
@cindex default installation locations

@table @asis
@item @var{prefix}
defaults to @file{/usr/local}; change using @code{configure}
(@pxref{Configure and make,,Configuring and compiling the software}).

@item @var{exec-prefix}
defaults to @var{prefix}; change using @code{configure}
(@pxref{Configure and make,,Configuring and compiling the software}).
@end table

@noindent
@sc{gnats} installs tools, utilities, and files into the following
locations.

@table @code

@item @var{exec-prefix}/bin

@table @code
@item send-pr
@xref{send-pr,,Submitting Problem Reports}.
@item edit-pr
@xref{edit-pr,,Editing existing Problem Reports}.
@item query-pr
@xref{query-pr,,Querying the database}.
@end table

@item @var{exec-prefix}/libexec/gnats

@table @code
@item at-pr
@xref{at-pr,,Timely reminders}.

@item check-db
@xref{check-db,,Checking database health}.

@item delete-pr
Tool for deleting PRs.  Deprecated.  Use the --delete-pr option of
@code{pr-edit} instead (@pxref{pr-edit,,The edit-pr driver}).

@item diff-prs
@xref{diff-prs,,The @code{diff-prs} tool}.

@item file-pr
@xref{file-pr,,Interface to pr-edit for filing new PRs}.

@item gen-index
@xref{gen-index,,Regenerating the index}.

@item gnatsd
The @sc{gnats} daemon.

@item gnats-pwconv
@xref{gnats-pwconv,,Converting old password files}.

@item mail-query
@xref{Aliases,,Setting up mail aliases}.

@item mkcat
@xref{mkcat,,Adding a problem category}.

@item mkdb
@xref{mkdb,,Script for creating new databases}.

@item pr-age
@xref{pr-age,,The @code{pr-age} tool}.

@item pr-edit
@xref{pr-edit,,The main PR processor}.

@item queue-pr
@xref{queue-pr,,Handling incoming traffic}.

@item rmcat
@xref{rmcat,,Removing categories}.
@end table

@item @var{exec-prefix}/lib/libiberty.a
The @sc{gnu} @code{libiberty} library.

@item @var{prefix}/etc/gnats

@table @file
@item databases
@xref{databases file,,The @file{databases} file}.

@item defaults
@xref{GNATS configuration,,Overview of @sc{gnats} configuration}.

@item gnatsd.host_access
@xref{gnatsd.host_access,,The @file{gnatsd.host_access} file}.

@item gnatsd.user_access
@xref{gnatsd.user_access,,The @file{gnatsd.user_access} file}.
@end table

@item @var{prefix}/share/emacs/site-lisp

@table @file
@item gnats.el
@itemx gnats.elc
The Emacs versions of the programs @code{send-pr}, @code{query-pr},
@code{edit-pr}, and @code{view-pr}.  @xref{GNATS user tools,,The
@sc{gnats} user tools}.  To change this directory you must change the
@code{lispdir} variable in @file{Makefile.in}; see @ref{Configure and
make,,Configuring and compiling the software}.
@end table

@item @var{prefix}/info

@table @file
@item gnats.info
@itemx send-pr.info
The @sc{gnats} manuals, in a form readable by @code{info} (the @sc{gnu}
hypertext browser).  @xref{Info,,Reading GNU Online
Documentation,infoman,GNU Online Documentation}.
@end table

@item @var{prefix}/man/man1
@itemx @var{prefix}/man/man8

@table @asis
@item @code{man} pages for all the @sc{gnats} tools and utilities.
@xref{GNATS user tools,,The @sc{gnats} user tools}.
@end table

@item Per-database directory

@table @file
@item gnats-adm
Administration and configuration data files that define behaviour of the
particular database.  The files

@table @file
@item categories

@item submitters

@item responsible

@item states

@item classes

@item dbconfig

@item addresses

@item states

@item gnatsd.user_access

@item index
(@emph{This file is created by @sc{gnats}.})

@item current
(@emph{This file is created by @sc{gnats}.})
@end table

@noindent exist here.
@xref{Other config files,,Other database-specific config files},
@ref{Admin files,,Administrative data files} and @ref{Access
Control,,Controlling access to databases}.

@item gnats-queue
Incoming Problem Reports are queued here until the next iteration of
@w{@samp{queue-pr -r}} (@pxref{queue-pr,,Handling incoming traffic}).

@item pending
If no default category is set, problem reports without a category are
reassigned to the category @samp{pending} and placed here pending
intervention by @sc{gnats} administrators.
@xref{Management,,@sc{gnats} administration}.

@item @var{category}
Each valid category has a corresponding subdirectory in the database.
All Problem Reports associated with that category are kept in that
subdirectory.
@end table

@end table

@c ===============================================================
@node gnatsd
@appendix The @sc{gnats} network server -- @code{gnatsd}
@cindex @code{gnatsd}

This section describes in details how the @sc{gnats} network daemon
works.  This information is mainly assumed to be useful for developers
of @sc{gnats} client software.

@menu
* Description of gnatsd::
* gnatsd options::
* gnatsd command protocol::
* gnatsd commands::
* gnatsd environment variables::
@end menu

@node Description of gnatsd
@section Description of @code{gnatsd}
@cindex @code{gnatsd} description

The @code{gnatsd} network daemon is used to service remote @sc{gnats}
requests such as querying PRs, PR creation, deletion, and editing, and
miscellaneous database queries.  It uses a simple ASCII-based command
protocol (similar to SMTP or POP3) for communicating with remote
clients.

It also provides a security model based either on IP-based
authentication (generally considered very weak) or username/passwords,
where passwords may be in cleartext, UNIX crypt or MD5 hash format.
Access through @code{gnatsd} is granted according to certain predefined
@dfn{access levels}.  Access levels are further discussed in @ref{Access
Control,,Controlling access to databases}.  It should be emphasized that
security has not been a focus of development until now, but future
versions are expected to address this more thoroughly.

All of the @sc{gnats} clients are capable of communicating via the @sc{gnats}
remote protocol to perform their functions.
@c XXX Add reference to remote tool installation section here.

@code{gnatsd} is usually started from the inetd facility and should run as
the @code{gnats} user (the actual username of this user is configurable
during installation, @pxref{Configure and make,,Configuring and
compiling the software} for details.)

@node gnatsd options
@section @code{gnatsd} options
@cindex @code{gnatsd} options

The daemon supports the following command-line options:

@smallexample
gnatsd [--database database | -d database]
       [--not-inetd | -n] [--max-access-level @var{level} | -m @var{level}]
       [--version | -V] [--help | -h]
@end smallexample

@cindex @code{gnatsd} startup options
@table @code
@item -V, --version
Prints the program version to stdout and exits.

@item -h, --help
Prints a short help text to stdout and exits.

@item -d, --database
Specifies the default database which is to be serviced by this
invocation of @code{gnatsd}. (The selected database may be changed via
the @code{CHDB} command; the name set with this option is simply the
default if no @code{CHDB} command is issued.)  If no database is
specified, the database named default is assumed. This option overrides
the database specified in the @code{GNATSDB} environment variable.

@item -n, --not-inetd
As its name suggests, indicates that @code{gnatsd} is not being invoked
from inetd. This can be used when testing @code{gnatsd}, or if it is
being run via ssh or some other mechanism.

This has the effect of using the local hostname where @code{gnatsd} is
being invoked for authentication purposes, rather than the remote
address of the connecting client.

@item --max-access-level, -m
Specifies the maximum access level that the connecting client can
authenticate to.  Authentication is as normal but if the user or host
authenticates at a higher level, access level is still forced to this
level.  See @ref{Access Control,,Controlling access to databases} for
details on access levels.
@end table

@node gnatsd command protocol
@section @code{gnatsd} command protocol
@cindex @code{gnatsd} command protocol

Commands are issued to @code{gnatsd} as one or more words followed by a
carriage-return/linefeed pair.  For example, the @code{CHDB} (change
database) command is sent as @samp{CHDB database<CR><LF>} (the
@code{CRLF} will not be explicitly written for future examples.)

Replies from @code{gnatsd} are returned as one or more response lines
containing a 3-digit numeric code followed by a human-readable string;
the line is terminated with a @code{<CR><LF>} pair.  For example, one
possible response to the @code{CHDB} command above would be:

@smallexample
210 Now accessing GNATS database 'database'.
@end smallexample

The three-digit code is normally followed by a single ASCII space
(character 0x20).  However, if additional response lines are to be
returned from the server, there will be a single dash @samp{-} instead
of the space character after the three-digit code.

Response code values are divided into ranges.  The first digit reflects
the general type of response (such as ''successful'' or ''error''), and
the subsequent digits identify the specific type of response.

@table @var
@item Codes 200-299
Positive response indicating that the command was successful.  No
subsequent data will be transmitted with the response.  In particular,
code 210 (@code{CODE_OK}) is used as the positive result code for most
simple commands.

Commands that expect additional data from the client (such as
@code{SUBM} or @code{VFLD}) use a two-step mechanism for sending the
data.  The server will respond to the initial command with either a 211
(@code{CODE_SEND_PR}) or 212 (@code{CODE_SEND_TEXT}) response line, or
an error code if an error occurred with the initial command.  The client
is then expected to send the remaining data using the same quoting
mechanism as described for server responses in the 300-349 range.  The
server will then send a final response line to the command.

@item Codes 300-399
Positive response indicating that the query request was successful, and
that a PR or other data will follow.  Codes 300-349 are used when
transmitting PRs, and 350-399 are used for other responses.

Codes in the 300-349 range are followed by a series of
@code{CRLF}-terminated lines containing the command response, usually a
PR.  The final line of the result is a single period @samp{.}.  Result
lines that begin with a period have an extra period prepended to them.

Codes in the 350-399 range use a different scheme for sending their
responses. The three-digit numeric code will be followed by either a
dash @samp{-} or a single space.  If the code is followed by a dash,
that indicates that another response line will follow.  The final line
of the response has a single space after the three-digit code.

In previous versions of the protocol the first line of a
@code{CODE_INFORMATION} (310) response was to be ignored.  This is no
longer the case.  Instead, any lines marked with code
@code{CODE_INFORMATION_FILLER} (351) are to be ignored.  This allows the
server to transmit additional headers or other human-readable text that
can be safely ignored by the clients.

@item Codes 400-599
An error occurred, usually because of invalid command parameters or
invalid input from the client, missing arguments to the command, or a
command was issued out of sequence.  The human-readable message
associated with the response line describes the general problem
encountered with the command.

Multiple error messages may be returned from a command; in this case the
@samp{-} continuation character is used on all but the last response
line.

@item Codes 600-799
An internal error occurred on the server, a timeout occurred reading
data from the client, or a network failure occurred.  These errors are
of the ''this should not occur'' nature, and retrying the operation may
resolve the problem.  Fortunately, most @sc{gnats} transactions are
idempotent; unfortunately, locking the database or a PR are not
repeatable actions (we cannot determine if an existing lock is the one
we originally requested, or someone else's).
@end table

@node gnatsd commands
@section @code{gnatsd} commands
@cindex @code{gnatsd} commands
@cindex @code{gnatsd} commands

Note that the set of @sc{gnats} commands and their responses is somewhat
inconsistent and is very much in flux.  At present the @sc{gnats}
clients are rather simple-minded and not very strict about processing
responses.  For example, if the server were to issue a code 300
(@code{CODE_PR_READY}) response to a @code{CHDB} command, the client
would happily expect to see a PR appear (and would print it out if one
was sent).

It is thus suggested that any clients that use the @sc{gnats} protocol
be equally flexible about the way received responses are handled; in
particular, only the first digit of the response code should be assumed
to be meaningful, although subsequent digits are needed in some cases
(codes 300-399).  No attempt should be made to parse the message strings
on error response lines; they are only intended to be read by humans,
and will be changed on a regular basis.

Almost every command may result in the response 440
(@code{CODE_CMD_ERROR}).  This indicates that there was a problem with
the command arguments, usually because of insufficient or too many
arguments being specified.

Access to most @code{gnatsd} commands requires a certain @dfn{access
level}.  For details of this, see @ref{Privileged gnatsd
commands,,Privileged @code{gnatsd} commands}.

@table @code
@item USER [@var{userid} @var{password}]
Specifies the userid and password for database access.  Either both a
username and password must be specified, or they both may be omitted; in
the latter case, the current access level is returned.

The possible server responses are:

@code{350 (CODE_INFORMATION)}
@*The current access level is specified.

@code{422 (CODE_NO_ACCESS)}
@*A matching username and password could not be found.

@code{200 (CODE_OK)}
@*A matching username and password was found, and the login was
successful.

@item QUIT
Requests that the connection be closed. Possible responses:

@code{201 (CODE_CLOSING)}
@*Normal exit.

The @code{QUIT} command has the dubious distinction of being the only command
that cannot fail.

@item LIST @var{list type}
Describes various aspects of the database.  The lists are returned as a
list of records, one per line.  Each line may contain a number of
colon-separated fields.

Possible values for @var{list type} include

@code{Categories}
@*Describes the legal categories for the database.

@code{Submitters}
@*Describes the set of submitters for the database.

@code{Responsible}
@*Lists the names in the responsible administrative file, including
their full names and email addresses.

@code{States}
@*Lists the states listed in the state administrative file, including
the state type (usually blank for most states; the closed state has a
special type).

@code{FieldNames}
@*Lists the entire set of PR fields.

@code{InitialInputFields}
@*Lists the fields that @emph{should} be present when a PR is
initially entered.

@code{InitialRequiredFields}
@*Lists fields that @emph{have} to be present and nonempty when a PR
is initially entered (fields containing only blank characters such as
spaces or newlines are considered empty.)

@code{Databases}
@*Lists the set of databases.

The possible responses are:

@code{301 (CODE_TEXT_READY)}
@*Normal response, followed by the records making up the list as
described above.

@code{416 (CODE_INVALID_LIST)}
@*The requested list does not exist.

@item FTYP @var{field} [@var{field} ...]
Describes the type of data held in the field(s) specified with the
command.  The currently defined data types are:

@code{Text}
@*A plain text field, containing exactly one line.

@code{MultiText}
@*A text field possibly containing multiple lines of text.

@code{Enum}
@*An enumerated data field; the value is restricted to one entry out of
a list of values associated with the field.

@code{MultiEnum}
@*The field contains one or more enumerated values.  Values are
separated with spaces or colons @samp{:}.

@code{Integer}
@*The field contains an integer value, possibly signed.

@code{Date}
@*The field contains a date.

@code{TextWithRegex}
@*The value in the field must match one or more regular expressions
associated with the field.

The possible responses are:

@code{350 (CODE_INFORMATION)}
@*The normal response; the supplied text is the data type.

@code{410 (CODE_INVALID_FIELD_NAME)}
@*The specified field does not exist.

If multiple field names were given, multiple response lines will be
sent, one for each field, using the standard continuation protocol; each
response except the last will have a dash @samp{-} immedately after the
response code.

@item FTYPINFO @var{field} @var{property}

Provides field-type-related information.  Currently, only the property
@samp{separators} for MultiEnum fields is supported.  When
@samp{separators} is specified, the possible return codes are:

@code{350 (CODE_INFORMATION)}
A proper MultiEnum @var{field} was specified and the returned text is
the string of separators specified for the field in the dbconfig file
(@pxref{Field datatypes}) quoted in @code{'}'s.

@code{435 (CODE_INVALID_FTYPE_PROPERTY)}
The @samp{separators} property is not defined for this field, i.e.  the
specified @var{field} is not of type MultiEnum.

Currently, specifying a different property than @samp{separators}
results in return code 435 as above.

@item FDSC @var{field} [@var{field} ... ]
Returns a human-readable description of the listed field(s).  The
possible responses are:

@code{350 (CODE_INFORMATION)}
The normal response; the supplied text is the field description.

@code{410 (CODE_INVALID_FIELD_NAME)}
The specified field does not exist.

Like the @code{FVLD} command, the standard continuation protocol will be
used if multiple fields were specified with the command.

@item FIELDFLAGS @var{field} [@var{field} ... ]
Returns a set of flags describing the specified field(s).  The possible
responses are either

@code{410 (CODE_INVALID_FIELD_NAME)}
@*meaning that the specified field is invalid or nonexistent, or

@code{350 (CODE_INFORMATION)}
@*which contains the set of flags for the field.  The flags may be
blank, which indicate that no special flags have been set for this
field.

Like the @code{FDSC} and @code{FTYP} commands, multiple field names may
be listed with the command, and a response line will be returned for
each one in the order that the fields appear on the command line.

The flags include:

@code{textsearch}
@*The field will be searched when a text field search is requested.

@code{allowAnyValue}
@*For fields that contain enumerated values, any legal value may be used
in the field, not just ones that appear in the enumerated list.

@code{requireChangeReason}
@*If the field is edited, a reason for the change must be supplied in
the new PR text describing the reason for the change. The reason must be
supplied as a multitext PR field in the new PR whose name is
@code{field-Changed-Why} (where @code{field} is the name of the field
being edited).

@code{readonly}
@*The field is read-only, and cannot be edited.

@item FVLD @var{field}
@*Returns one or more regular expressions or strings that describe the
valid types of data that can be placed in field.  Exactly what is
returned is dependent on the type of data that can be stored in the
field.  For most fields a regular expression is returned; for enumerated
fields, the returned values are the list of legal strings that can be
held in the field.

The possible responses are:

@code{301 (CODE_TEXT_READY)}
@*The normal response, which is followed by the list of regexps or
strings.

@code{410 (CODE_INVALID_FIELD_NAME)}
The specified field does not exist.

@item VFLD @var{field}
@code{VFLD} can be used to validate a given value for a field in the
database.  The client issues the @code{VFLD} command with the name of
the field to validate as an argument.  The server will either respond
with @code{212 (CODE_SEND_TEXT)}, or @code{410
(CODE_INVALID_FIELD_NAME)} if the specified field does not exist.

Once the @code{212} response is received from the server, the client
should then send the line(s) of text to be validated, using the normal
quoting mechanism described for PRs.  The final line of text is followed
by a line containing a single period, again as when sending PR text.

The server will then either respond with @code{210 (CODE_OK)},
indicating that the text is acceptable, or one or more error codes
describing the problems with the field contents.

@item INPUTDEFAULT @var{field} [@var{field} ... ]
Returns the suggested default value for a field when a PR is initially
created.  The possible responses are either @code{410
(CODE_INVALID_FIELD_NAME)}, meaning that the specified field is invalid
or nonexistent, or @code{350 (CODE_INFORMATION)} which contains the
default value for the field.

Like the @code{FDSC} and @code{FTYP} commands, multiple field names may
be listed with the command, and a response line will be returned for
each one in the order that the fields appear on the command line.

@item RSET
Used to reset the internal server state.  The current query expression
is cleared, and the index of PRs may be reread if it has been updated
since the start of the session.  The possible responses are:

@code{200 (CODE_OK)}
@*The state has been reset.

@code{440 (CODE_CMD_ERROR)}
@*One or more arguments were supplied to the command.

@code{6xx (internal error)}
@*There were problems resetting the state (usually because the index could
not be reread).  The session will be immediately terminated.

@item LKDB
Locks the main @sc{gnats} database.  No subsequent database locks will
succeed until the lock is removed.  Sessions that attempt to write to
the database will fail.  The possible responses are:

@code{200 (CODE_OK)}
The lock has been established.

@code{440 (CODE_CMD_ERROR)}
One or more arguments were supplied to the command.

@code{431 (CODE_GNATS_LOCKED)}
The database is already locked, and the lock could not be obtained after
10 seconds.

@code{6xx (internal error)}
An internal error occurred, usually because of permission or other
filesystem-related problems. The lock may or may not have been
established.

@item UNDB

Unlocks the database.  Any session may steal a database lock; no
checking of any sort is done.  The possible responses are:

@code{200 (CODE_OK)}
@*The lock has been removed.

@code{432 (CODE_GNATS_NOT_LOCKED)}
@*The database was not locked.

@code{440 (CODE_CMD_ERROR)}
@*One or more arguments were supplied to the command.

@code{6xx (internal error)}
@*The database lock could not be removed, usually because of permissions
or other filesystem-related issues.

@item LOCK @var{PR user} [@var{pid}]
Locks the specified @var{PR}, marking the lock with the @var{user} name
and the optional @var{pid}. (No checking is done that the @var{user} or
@var{pid} arguments are valid or meaningful; they are simply treated as
strings.)

The @code{EDIT} command requires that the PR be locked before it may be
successfully executed.  However, it does not require that the lock is
owned by the editing session, so the usefulness of the lock is simply as
an advisory measure.

The @code{APPN} and @code{REPL} commands lock the PR as part of the
editing process, and they do not require that the PR be locked before
they are invoked.

The possible responses are:

@code{440 (CODE_CMD_ERROR)}
@*Insufficient or too many arguments were specified to the command.

@code{300 (CODE_PR_READY)}
@*The lock was successfully obtained; the text of the PR (using the
standard quoting mechanism for PRs) follows.

@code{400 (CODE_NONEXISTENT_PR)}
@*The PR specified does not exist.

@code{430 (CODE_LOCKED_PR)}
@*The PR is already locked by another session.

@code{6xx (internal error)}
@*The PR lock could not be created, usually because of permissions or
other filesystem-related issues.

@item UNLK @var{PR}
Unlocks @var{PR}.  Any user may unlock a PR, as no checking is done to
determine if the requesting session owns the lock.

The possible responses are:

@code{440 (CODE_CMD_ERROR)}
@*Insufficient or too many arguments were specified to the command.

@code{200 (CODE_OK)}
@*The PR was successfully unlocked.

@code{433 (CODE_PR_NOT_LOCKED)}
@*The PR was not locked.

@code{6xx (internal error)}
@*The PR could not be unlocked, usually because of permission or other
filesystem-related problems.

@item DELETE @var{PR}
Deletes the specified @var{PR}. The user making the request must have
admin privileges (@pxref{Access Control,,Controlling access to
databases}).  If successful, the PR is removed from the filesystem and
the index file; a gap will be left in the numbering sequence for PRs.
No checks are made that the PR is closed.

The possible responses are:

@code{200 (CODE_OK)}
@*The PR was successfully deleted.

@code{422 (CODE_NO_ACCESS)}
@*The user requesting the delete does not have admin privileges.

@code{430 (CODE_LOCKED_PR)}
@*The PR is locked by another session.

@code{431 (CODE_GNATS_LOCKED)}
@*The database has been locked, and no PRs may be updated until the lock
is cleared.

@code{6xx (internal error)}
@*The PR could not be successfully deleted, usually because of
permission or other filesystem-related problems.

@item CHEK [initial]
Used to check the text of an entire PR for errors.  Unlike the
@code{VFLD} command, it accepts an entire PR at once instead of the
contents of an individual field.

The @code{initial} argument indicates that the PR text to be checked is
for a PR that will be newly created, rather than an edit or replacement
of an existing PR.

After the @code{CHEK} command is issued, the server will respond with
either a @code{440 (CODE_CMD_ERROR)} response indicating that the
command arguments were incorrect, or a @code{211 (CODE_SEND_PR)}
response code will be sent.

Once the @code{211} response is received from the server, the client
should send the PR using the normal PR quoting mechanism; the final line
of the PR is then followed by a line containing a single period, as
usual.

The server will then respond with either a @code{200 (CODE_OK)}
response, indicating there were no problems with the supplied text, or
one or more error codes listing the problems with the PR.

@item EDIT @var{PR}
Verifies the replacement text for @var{PR}.  If the command is
successful, the contents of @var{PR} are completely replaced with the
supplied text.  The PR must previously have been locked with the
@code{LOCK} command.

The possible responses are:

@code{431 (CODE_GNATS_LOCKED)}
@*The database has been locked, and no PRs may be updated until the lock
is cleared.

@code{433 (CODE_PR_NOT_LOCKED)}
@*The PR was not previously locked with the @code{LOCK} command.

@code{400 (CODE_NONEXISTENT_PR)}
@*The specified PR does not currently exist.  The @code{SUBM} command
should be used to create new PRs.

@code{211 (CODE_SEND_PR)}
@*The client should now transmit the replacement PR text using the
normal PR quoting mechanism.  After the PR has been sent, the server
will respond with either @code{200 (CODE_OK)} indicating that the edit
was successful, or one or more error codes listing problems either with
the replacement PR text or errors encountered while updating the PR file
or index.

@item EDITADDR @var{address}
Sets the e-mail address of the person communicating with
@code{gnatsd}.  The command requires at least the @code{edit} access
level.

The possible responses are:

@code{200 (CODE_OK)}
@*The address was successfully set.

@code{440 (CODE_CMD_ERROR)}
@*Invalid number of arguments were supplied.

@item APPN @var{PR} @var{field}
@itemx REPL @var{PR} @var{field}
Appends to or replaces the contents of @var{field} in @var{PR} with the
supplied text.  The command returns a @code{201 (CODE_SEND_TEXT)}
response; the client should then transmit the new field contents using
the standard PR quoting mechanism.  After the server has read the new
contents, it then attempts to make the requested change to the PR.

The possible responses are:

@code{200 (CODE_OK)}
@*The PR field was successfully changed.

@code{400 (CODE_NONEXISTENT_PR)}
@*The PR specified does not exist.

@code{410 (CODE_INVALID_FIELD_NAME)}
@*The specified field does not exist.

@code{402 (CODE_UNREADABLE_PR)}
@*The PR could not be read.

@code{431 (CODE_GNATS_LOCKED)}
@*The database has been locked, and no PRs may be updated until the lock
is cleared.

@code{430 (CODE_LOCKED_PR)}
@*The PR is locked, and may not be altered until the lock is cleared.

@code{413 (CODE_INVALID_FIELD_CONTENTS)}
@*The supplied (or resulting) field contents are not valid for the
field.

@code{6xx (internal error)}
@*An internal error occurred, usually because of permission or other
filesystem-related problems.  The PR may or may not have been altered.

@item SUBM
Submits a new PR into the database.  The supplied text is verified for
correctness, and if no problems are found a new PR is created.

The possible responses are:

@code{431 (CODE_GNATS_LOCKED)}
@*The database has been locked, and no PRs may be submitted until the
lock is cleared.

@code{211 (CODE_SEND_PR)}
@*The client should now transmit the new PR text using the normal
quoting mechanism.  After the PR has been sent, the server will respond
with either @code{351 (CODE_INFORMATION_FILLER)} and
@code{350 (CODE_INFORMATION)} responses indicating that the new PR
has been created and supplying the number assigned to it, or one or
more error codes listing problems with the new PR text.

@item CHDB @var{database}
Switches the current database to the name specified in the command.

The possible responses are:

@code{422 (CODE_NO_ACCESS)}
@*The user does not have permission to access the requested database.

@code{417 (CODE_INVALID_DATABASE)}
@*The database specified does not exist, or one or more configuration
errors in the database were encountered.

@code{220 (CODE_OK)}
@*The current database is now @var{database}.  Any operations performed
will now be applied to @var{database}.

@item DBLS
Lists the known set of databases.

The possible responses are:

@code{6xx (internal error)}
@*An internal error was encountered while trying to obtain the list of
available databases, usually due to lack of permissions or other
filesystem-related problems, or the list of databases is empty.

@code{301 (CODE_TEXT_READY)}
@*The list of databases follows, one per line, using the standard
quoting mechanism.  Only the database names are sent.

The @code{gnatsd} access level @samp{listdb} denies access until the
user has authenticated with the USER command.  The only other command
available at this access level is @code{DBLS}.  This access level
provides a way for a site to secure its @sc{gnats} databases while still
providing a way for client tools to obtain a list of the databases for
use on login screens etc.  @xref{Access
Control,,Controlling access to databases}.

@item DBDESC @var{database}
Returns a human-readable description of the specified @var{database}.

Responses include:

@code{6xx (internal error)}
@*An internal error was encountered while trying to read the list of
available databases, usually due to lack of permissions or other
filesystem-related problems, or the list of databases is empty.

@code{350 (CODE_INFORMATION)}
@*The normal response; the supplied text is the database description.

@code{417 (CODE_INVALID_DATABASE)}
@*The specified database name does not have an entry.

@item EXPR @var{query expression}
Specifies a @var{query expression} used to limit which PRs are returned
from the @code{QUER} command.  The expression uses the normal query
expression syntax, (@pxref{Query expressions}).

Multiple @code{EXPR} commands may be issued; the expressions are boolean
ANDed together.

Expressions are cleared by the @code{RSET} command.

Possible responses include:

@code{415 (CODE_INVALID_EXPR)}
@*The specified expression is invalid, and could not be parsed.

@code{200 (CODE_OK)}
@*The expression has been accepted and will be used to limit the
results returned from @code{QUER}.

@item QFMT @var{query format}
Use the specified @var{query format} to format the output of the
@code{QUER} command.  The query format may be either the name of a query
format known to the server (@pxref{Named query definitions}), or an
actual query format (@pxref{Formatting query-pr output}).  The possible
responses are:

@code{200 (CODE_OK)}
@*The normal response, which indicates that the query format is
acceptable.

@code{440 (CODE_CMD_ERROR)}
@*No query format was supplied.

@code{418 (CODE_INVALID_QUERY_FORMAT)}
@*The specified query format does not exist, or could not be parsed.

@item QUER [@var{PR}] [@var{PR}] [...]
Searches the contents of the database for PRs that match the
(optional) specified expressions with the @code{EXPR} command. If no
expressions were specified with @code{EXPR}, the entire set of PRs is
returned.

If one or more PRs are specified on the command line, only those PRs
will be searched and/or output.

The format of the output from the command is determined by the query
format selected with the @code{QFMT} command.

The possible responses are:

@code{418 (CODE_INVALID_QUERY_FORMAT)}
@*A valid format was not specified with the @code{QFMT} command prior to
invoking @code{QUER}.

@code{300 (CODE_PR_READY)}
@*One or more PRs will be output using the requested query format. The
PR text is quoted using the normal quoting mechanisms for PRs.

@code{220 (CODE_NO_PRS_MATCHED)}
@*No PRs met the specified criteria.

@item ADMV @var{field key} [@var{subfield}]
Returns an entry from an administrative data file associated with
@var{field}. @var{key} is used to look up the entry in the data file. If
@var{subfield} is specified, only the value of that subfield is
returned; otherwise, all of the fields in the adm data file are
returned, separated by colons @samp{:}.

The responses are:

@code{410 (CODE_INVALID_FIELD_NAME)}
The specified field does not exist.

@code{221 (CODE_NO_ADM_ENTRY)}
An adm entry matching the key was not found, or the field does not have
an adm file associated with it.

@code{350 (CODE_INFORMATION)}
The normal response; the supplied text is the requested field(s).
@end table

@node gnatsd environment variables
@section @code{gnatsd} environment variables
@cindex @code{gnatsd} environment variables
@cindex @code{GNATSDB}

@code{gnatsd} supports the @code{GNATSDB} environment varable,
@xref{Environment}, in almost the same way as the @sc{gnats} tools do.
This variable is used to determine which database to use.  For a local
database, it contains the name of the database to
access. @code{gnatsd} cannot service remote databases (though it might
be interesting if it could) so the database is always assumed to be
local.

If @code{GNATSDB} is not set and the @code{--database} option is not
supplied, it is assumed that the database is local and that its name is
@samp{default}.

@c ===============================================================
@node Access Control
@appendix Controlling access to databases

@menu
* Overview::
* Overall gnatsd access level::
* gnatsd.host_access::           Per-host access settings
* gnatsd.user_access::           Access levels per user
* Privileged gnatsd commands::
@end menu

@node Overview
@section Overview

@sc{gnats} supports granting various levels of access to the @sc{gnats}
databases served by the network daemon, @code{gnatsd}.

@sc{gnats} access can be controlled at these levels:

@table @code
@item deny
gnatsd closes the connection

@item none
no further access until userid and password given

@item listdb
only listing of available databases is allowed

@item view
query and view PRs with Confidential=no only

@item viewconf
query and view PRs with Confidential=yes

@item edit
full edit access

@item admin
full admin access
@end table

@noindent These access levels are used in the following settings:

@itemize @bullet
@item overall gnatsd access level

@item overall access level set by host name or IP address

@item overall access level set by userid and password

@item per-database access level set by userid and password
@end itemize

@node Overall gnatsd access level
@section Overall @code{gnatsd} access level

@noindent The overall @code{gnatsd} access level is set by starting @code{gnatsd}
with the option

@example
@code{-m} @var{level} or @code{--maximum-access-level}=@var{level},
@end example

@noindent where @var{level} is one of the six access levels listed
above.  This restricts any access to the @sc{gnats} daemon to levels up
to and including @var{level}, regardless of the settings in the access
control files discussed below.  If this option is left out, any access
levels set in the access control files will be allowed.

The discussion below assumes that the pre-build configure of @sc{gnats}
was done without altering the default values for the
@code{--with-gnatsd-user-access-file} and
@code{--with-gnatsd-host-access-file} options.  If non-default values
were given, substitute as appropriate below.

@node gnatsd.host_access
@section Overall access levels per host
@cindex @file{gnatsd.host_access}

The host access file (by default
@file{/usr/local/etc/gnats/gnatsd.host_access}) controls overall
access levels on a per-host basis, meaning that settings in this file
apply across all databases on the server.  Entries in this file are in
the following format:

@var{host:access-level:whatever}

@noindent @var{host} is the hostname or IP address of the host contacting
gnatsd.  Wildcard characters are supported: @samp{*} matches anything;
@samp{?} matches any single character.  By using wildcards, you can
specify access levels for entire network subnets and domains.  Note
that when @sc{gnats} authenticates hosts, it reads the entries in this
file in sequence until a match is found.  This means that wildcard
entries must be placed near the end of the file, otherwise, they
will override non-wildcard entries appearing after the wildcard
ones.

The second field is the access level of @var{host}.  The default is
@code{deny}.  If the user's hostname isn't in the file or its access
level is set to @code{deny}, the connection is closed immediately.

@sc{gnats} currently doesn't make use of the third field. Remember to
still include the second @samp{:} on the line if you choose to leave the third
field empty.

Whenever a @code{CHDB} command is processed (or defaulted), the user's
access level is set to the level for their host, as determined by the
values in the @file{gnatsd.host_access} file.  However, even if a host
is given the @code{none} access level, an individual can still give the
@code{USER} command to possibly gain a higher (but never lower) access
than is set for their host.  The gnatsd @code{USER} command takes two
arguments: @code{USER <userid> <passwd>}.

@node gnatsd.user_access
@section Access levels per user
@cindex @file{gnatsd.user_access}

Access levels per user can be set both across all databases on the
server or on a per-database basis.  The @file{gnatsd.user_access} file
in a database's @file{gnats-adm} directory specifies the user access
rules for that database.  If it doesn't exist, or doesn't contain the
user name given to @code{gnatsd}, then the overall user access file
(by default @w{@file{/usr/local/etc/gnats/gnatsd.user_access}})
specifying the per-user access levels across all the databases on the
server is checked.

The user access files can only @emph{increase} the access level
defined in the host access files for the given host, they can never
lower it.

If the access level is @code{none} after processing the userid and
password, the connection is closed.

The @file{gnatsd.user_access} files can contain plain text passwords, in
such a case they should be owned by the @sc{gnats} user with file
permission 600.

Wildcard characters are supported for the userid and password with
plain text passwords.  A null string or @samp{*} matches anything;
@samp{?} matches any one character.  Note that when @sc{gnats}
authenticates users, it reads the entries in this file in sequence
until a match is found.  This means that wildcard entries must be
placed near the end of the file, otherwise, they will override
non-wildcard entries appearing after the wildcard ones.

Entries in the database-specific @file{gnatsd.user_access} user access file
in the @file{gnats-adm} directory of the database have the following
general format:

@var{userid:password:access-level}

The overall @file{gnatsd.user_access} user access file adds a fourth
@var{databases} field:

@var{userid:password:access-level:databases}

@noindent @var{password} should either be in plain text, DES
@code{crypt()}@footnote{DES crypt is the standard password encryption
format used by most UNIX systems} or MD5 hash format@footnote{MD5 is
only supported on platforms that have a @code{crypt()} function that
supports MD5. Among others, this currently includes @sc{gnu} Linux and
OpenBSD.}.

If the password is in plain text format, it must be prefixed by
@samp{$0$} and if it is in MD5 format, it needs to be prefixed by the
string @samp{$1$}.@footnote{Some systems support even more encryption
methods.  In FreeBSD, for instance, a prefix of @samp{$2$} implies
Blowfish encoding.  @sc{gnats} will happily accept any encryption that
the OS supports.} Passwords encrypted by @code{crypt()} should have no
prefix. If no password is given then users can login with an empty
password string.

A @code{gnats-passwd} tool to manage @file{gnatsd.user_access} files is
planned.  In the meantime, @code{crypt()} passwords can be generated by
using standard UNIX passwords tools, while MD5 passwords can be
generated with the following little Perl snippet:

@example
perl -e 'use Crypt::PasswdMD5 ; print Crypt::PasswdMD5::unix_md5_crypt
"@var{password}" , time() % 100000000'
@end example

@noindent If your Perl installation doesn't have the Crypt module
installed, you need to install it.  On most systems, the following
command achieves this:

@example
perl -MCPAN -e 'install Crypt::PasswdMD5'
@end example

A tool for conversion of pre-version 4 @file{gnatsd.user_access} files is
distributed with @sc{gnats} 4.  @xref{gnats-pwconv,,Converting old
password files}.

@noindent The @var{access-level} field should contain one of the values listed at
the beginning of this appendix.  This overrides (increases but never
lowers) the access level given as the default for the user's host in the
global gnatsd.host_access file.

The following shows an example @file{gnatsd.user_access} file with
plain text passwords:

@example
rickm:$0$ruckm:edit
pablo:$0$pueblo:view
*::none
@end example

@noindent And this is the same file with MD5-encrypted passwords:
@example
rickm:$1$92388613$D7ZIYikzTUqd./dODTFrI.:edit
pablo:$1$92388652$QRfAhIBG5elT.FQjQKhj80:view
*::none
@end example

@noindent In these examples, anybody other than rickm and pablo get
denied access, assuming that the host access level is also @code{none}.
You could set the catch-all rule at the end to be @code{*::view} to
allow view access to anyone who does not supply a password.  Note the
important detail that such a rule would allow view access only to
persons who do not supply a password at all, i.e. if rickm or pablo tries
to log in but mistypes his password, this rule would not apply and
they would be denied access entirely.  This is by design, since people
might be surprised if they suddenly found themselves logged in, but with
a lower access level than they usually have.

The @var{databases} field contains a comma-separated list of database
names, as defined in the @file{databases} file (@pxref{databases
file,,The @code{databases} file}.  Wildcard characters are
supported. The databases listed in this field are the ones to which
the other settings on the same line will be applied.

@node Privileged gnatsd commands
@section Privileged @code{gnatsd} commands

Every @code{gnatsd} command has a minimum access level attached to
it.  If your access level is too low for a command, you get this
response:

@example
  LOCK 12
  422 You are not authorized to perform this operation (LOCK).
@end example

@noindent The commands @code{CHDB}, @code{USER} and @code{QUIT} are
unrestricted.

@noindent The @code{DBLS} command requires at least @code{listdb} access.

@noindent A user must have at least @code{edit} access for these commands:

@table @code
@item LKDB
lock the main @sc{gnats} database.

@item UNDB
unlock the main @sc{gnats} database.

@item LOCK @var{PR user pid}
lock @var{PR} for @var{user} and optional @var{pid} and return PR text.

@item UNLK @var{PR}
unlock @var{PR}.

@item EDIT @var{PR}
check in edited @var{PR}.

@item APPN @var{PR} @var{field}, REPL @var{PR} @var{field}
Appends to or replaces the contents of @var{field} in @var{PR}.
@end table

The @code{DELETE} @var{PR} command is special in that it requires
@code{admin} access.

@noindent All other commands require @code{view} access.

@code{edit-pr} and @code{query-pr} accept the command line arguments
@code{-v|--user} and @code{-w|--passwd}.  @xref{GNATS user tools,,The
@sc{gnats} User Tools}.

@c ===============================================================
@node Regexps
@appendix Querying using regular expressions
@cindex querying using regexps
@cindex regular expressions
@cindex syntax of regexps

See also @ref{Query expressions}.

Unfortunately, we do not have room in this manual for a complete
exposition on regular expressions.  The following is a basic summary of
some regular expressions you might wish to use.

@emph{NOTE: When you use query expressions containing regular
expressions as part of an ordinary query-pr shell command line, you need
to quote them with @code{''}, otherwise the shell will try to interpret
the special characters used, yielding highly unpredictable results.}

@xref{Regular Expression Syntax,,Regular Expression Syntax,regex,Regex},
for details on regular expression syntax.  Also see @ref{Regexps,,Syntax
of Regular Expressions,emacs,GNU Emacs Manual}, but beware that the
syntax for regular expressions in Emacs is slightly different.

All search criteria options to @code{query-pr} rely on regular
expression syntax to construct their search patterns.  For example,

@smallexample
query-pr --expr 'State="open"' --format full
@end smallexample

@noindent
matches all PRs whose @code{State} values match with the regular
expression @samp{open}.

We can substitute the expression @samp{o} for @samp{open}, according
to @sc{gnu} regular expression syntax.  This matches all values of
@code{State} which begin with the letter @samp{o}.

We see that

@smallexample
query-pr --expr 'State="o"' --format full
@end smallexample

is equivalent to

@smallexample
query-pr --expr 'State="open"' --format full
@end smallexample

@noindent
in this case, since the only value for @code{State} which matches
the expression @samp{o} in a standard installation is @samp{open}.
@samp{State="o"} also matches @samp{o}, @samp{oswald}, and even
@samp{oooooo}, but none of those values are valid states for a Problem
Report in default @sc{gnats} installations.

We can also use the expression operator @samp{|} to signify a logical
@code{OR}, such that

@smallexample
query-pr --expr 'State="o|a"' --format full
@end smallexample

@noindent
matches all @samp{open} or @samp{analyzed} Problem Reports.

Regular expression syntax considers a regexp token surrounded with
parentheses, as in @w{@samp{(@var{regexp})}}, to be a @dfn{group}.  This
means that @w{@samp{(ab)*}} matches any number (including zero) of
contiguous instances of @samp{ab}.  Matches include @samp{}, @samp{ab},
and @samp{ababab}.

Regular expression syntax considers a regexp token surrounded with
square brackets, as in @w{@samp{[@var{regexp}]}}, to be a @dfn{list}.
This means that @w{@samp{Char[(ley)(lene)(broiled)}} matches any of the
words @samp{Charley}, @samp{Charlene}, or @samp{Charbroiled} (case is
significant; @samp{charbroiled} is not matched).

Using groups and lists, we see that

@smallexample
query-pr --expr 'Category="gcc|gdb|gas"' --format full
@end smallexample

@noindent
is equivalent to

@smallexample
query-pr --expr 'Category="g(cc|db|as)"' --format full
@end smallexample

@noindent
and is also very similar to

@smallexample
query-pr --expr 'Category="g[cda]"' --format full
@end smallexample

@noindent
with the exception that this last search matches any values which begin
with @samp{gc}, @samp{gd}, or @samp{ga}.

The @samp{.} character is known as a @dfn{wildcard}.  @samp{.} matches
on any single character.  @samp{*} matches the previous character
(except newlines), list, or group any number of times, including zero.
Therefore, we can understand @samp{.*} to mean ``match zero or more
instances of any character.''

@smallexample
query-pr --expr 'State=".*a"' --format full
@end smallexample

@noindent
matches all values for @code{State} which contain an @samp{a}.  (These
include @samp{analyzed} and @samp{feedback}.)

Another way to understand what wildcards do is to follow them on their
search for matching text.  By our syntax, @samp{.*} matches any
character any number of times, including zero.  Therefore, @samp{.*a}
searches for any group of characters which end with @samp{a}, ignoring
the rest of the field.  @samp{.*a} matches @samp{analyzed} (stopping at
the first @samp{a}) as well as @samp{feedback}.

@emph{Note:} When using @samp{fieldtype:Text} or
@samp{fieldtype:Multitext} (@pxref{Query expressions}), you do not have
to specify the token @samp{.*} at the beginning of your expression to
match the entire field.  For the technically minded, this is because
these queries use @samp{re_search} rather than @samp{re_match}.
@samp{re_match} @dfn{anchors} the search at the beginning of the field,
while @samp{re_search} does not anchor the search.

For example, to search in the @code{>Description:} field for the text

@smallexample
The defrobulator component returns a nil value.
@end smallexample

@noindent
we can use

@smallexample
query-pr --expr 'fieldtype:Multitext="defrobulator.*nil"' --format full
@end smallexample

To also match newlines, we have to include the expression @samp{(.|^M)}
instead of just a dot (@samp{.}).  @samp{(.|^M)} matches ``any single
character except a newline (@samp{.}) @emph{or} (@samp{|}) any newline
(@samp{^M}).''  This means that to search for the text

@smallexample
The defrobulator component enters the bifrabulator routine
and returns a nil value.
@end smallexample

@noindent
we must use

@smallexample
query-pr --expr 'fieldtype:Multitext="defrobulator(.|^M)*nil"'
         --format full
@end smallexample

To generate the newline character @samp{^M}, type the following
depending on your shell:

@table @code
@item csh
@samp{@emph{control}-V @emph{control}-M}

@item tcsh
@samp{@emph{control}-V @emph{control}-J}

@item sh (@emph{or} bash)
Use the @key{RETURN} key, as in

@smallexample
(.|
)
@end smallexample
@end table

Again, see @ref{Regular Expression Syntax,,Regular Expression
Syntax,regex,Regex}, for a much more complete discussion on regular
expression syntax.

@c ===============================================================

@node dbconfig recipes
@appendix @file{dbconfig} recipes
@cindex dbconfig
@cindex @file{dbconfig} recipes

The @file{dbconfig} file (@ref{dbconfig file,,The @file{dbconfig}
file}) is the heart of any @sc{gnats} installation.  It contains some
very powerful machinery, something which this appendix tries to
illustrate.

We provide a range of examples that are both intended to be useful in
their own right and to serve as starting points or building blocks for
your own modifications.

@subsubheading Provide Gnatsweb URL in initial response

Sites that have Gnatsweb installed may wish to modify the response
e-mail which is sent to the submitter of a PR so that it includes a
URL where the status of the PR can be monitored.  In order to allow
this, you should first create an entry in @file{gnatsd.user_access}
which allows viewing of PRs in your database
(@xref{gnatsd.user_access,,The @file{gnatsd.user_access} file}.)

Next, locate the entry @code{mail-format
"initial-response-to-submitter"} in the @file{dbconfig} file of your
database and add the following @emph{before} the line reading ``The
individual assigned...'' in the @code{body} section:

@verbatim
\nYou can follow the status of this report on\n\
http://hostname/cgi-bin/scriptname?\n\
cmd=view&database=dbname&user=username&\n\
password=passwd&pr=%s\n\n\
@end verbatim

@noindent
Substitute @code{hostname}, @code{cgi-bin} and @code{scriptname} as
appropriate for the setup of your web server.  The part before the
@samp{?} would typically look something like
@code{http://www.example.com/cgi-bin/gnatsweb.pl}.  Substitute the
name of your database for @code{dbname}, and the username and password
of the user with @code{view} rights for @code{username} and
@code{passwd}.

@noindent
Next, add a @code{Number} to the @code{fields} list statement inside
the @code{body} so it reads as follows:

@verbatim
fields { "Category" "Number" "Number" "Responsible"
         "Category" "Responsible" "Synopsis"
         "Arrival-Date" }
@end verbatim

@subsubheading State full name of responsible in initial response

The initial e-mail response to the submitter of a PR identifies the
responsible person assigned to the PR as follows: ``The individual
assigned to look at your report is: @var{GNATS username}''.  Some
sites may wish to modify this so that the full name of the responsible
person is used instead of the @sc{gnats} user name.

The full name is contained in the @code{fullname} subfield of the
user's entry in the @file{responsible} file and can be accessed as
@code{Responsible[fullname]} (@pxref{administrative files,,Enumerated
field administrative files}.)

The change is achieved by editing the @file{dbconfig} item
@code{mail-format "initial-response-to-submitter"} and changing the
@code{fields} part of the @code{Body} from

@verbatim
fields { "Category" "Number" "Responsible"
         "Category" "Responsible" "Synopsis"
         "Arrival-Date" }
@end verbatim

@noindent
to

@verbatim
fields { "Category" "Number" "Responsible[fullname]"
         "Category" "Responsible" "Synopsis"
         "Arrival-Date" }
@end verbatim

@subsubheading Append-only Audit-Trail

The Audit-Trail of a PR is by default editable.  For some
applications, one might want to make the Audit-Trail append-only, so
it provides a full and unchangeable case history.  Also by default,
only certain changes, such as change of state and change of
responsible gets recorded in the Audit-Trail.  In some cases, it might
also be convenient to have a way of inserting comments directly into
the Audit-Trail.

The following procedure creates such an append-only Audit-Trail and
adds a PR field which makes it possible to register comments in the
Audit-Trail.

@noindent
First, add the keyword @code{read-only} to the Audit-Trail field
definition in @file{dbconfig}.

@noindent
Then, add the following field definition to @file{dbconfig}:

@verbatim
field "Add-To-Audit-Trail" {
   description "Add a log entry to the Audit Trail"
   multitext { default "\n" }
   on-change  {
        add-audit-trail
        audit-trail-format {
        format "**** Comment added by %s on %s ****\n %s\n\n"
        fields { "$EditUserEmailAddr" "$CurrentDate" "$NewValue"
        }
        }
    }
    on-change {
        set-field "Add-To-Audit-Trail" { "\n" }
    }
}
@end verbatim

@anchor{release-based support}
@subsubheading Supporting @sc{gnats} ``release-based'' fields

When installing @sc{gnats} version 3.x, it was possible to choose
whether to enable three optional fields: @code{Quarter}, @code{Keywords}
and @code{Date-Required}.  Default installations had these fields
switched off, and installations which had them were called
``release-based''.

The default @file{dbconfig} shipped with @sc{gnats} version 4 or newer
does not have these fields, so if you are upgrading from an old
release-based system, you need to add the following field definitions to
your @file{dbconfig} file:

@verbatim
field "Quarter" {
    description "What quarter does the PR fall into?"
    text
    query-default inexact-regexp
    textsearch
}

field "Keywords" {
    description "Keywords used to index this PR"
    text
    query-default inexact-regexp
    textsearch
}

field "Date-Required" {
    description "Date that the PR must be fixed by"
    date
}
@end verbatim

A side note: Pre-release versions of @sc{gnats} 4 also had a field
named @code{Cases}.  For those who may need it, here is the field
definition of @code{Cases}:

@verbatim
field "Cases" {
    text
    query-default inexact-regexp
    textsearch
}
@end verbatim
@c ===============================================================

@node Support
@appendix @sc{gnats} support

@cindex @sc{gnats} support
The @sc{gnats} home page is located at
@url{http://www.gnu.org/software/gnats}.  It contains all the
important references to the available information about @sc{gnats} and
the related software.

There is also a special page dedicated to the @sc{gnats} development
at @url{http://savannah.gnu.org/projects/gnats}.

@cindex mailing lists
There are several @sc{gnats} mailing lists.  The most important ones
are:

@table @email
@item info-gnats@@gnu.org
Announcements and other important information about @sc{gnats} and the
related software.  This is a very low volume moderated list.

@item bug-gnats@@gnu.org
The bug reporting mailing list on the @sc{gnats} itself.  Please note
that the preferred way to report @sc{gnats} bugs is to submit them via
the web interface at
@url{http://bugs.gnu.org/cgi-bin/gnatsweb.pl?database=gnats}.  New bug
reports submitted via the web interface are copied to the mailing list
automatically.

@item help-gnats@@gnu.org
General discussion about @sc{gnats}.  Anything related to @sc{gnats}
(user questions, development, suggestions, etc.) can be discussed
there.
@end table

The complete list of @sc{gnats} related mailing lists is available
from the web page at @url{http://savannah.gnu.org/project/gnats}.

@cindex bug reporting
When you report problems concerning @sc{gnats} itself, please do not
forget to provide especially the following information:

@itemize @bullet
@item
The @sc{gnats} version you are using.

@item
The @emph{exact} way how to reproduce the bug.

@item
Your configuration.

@item
If you encounter a compilation or build problem, it is especially
important to mention the operating system, compiler and possibly other
build utilities you use.
@end itemize

Providing this information in the initial report avoids further
unnecessary communication, saves our limited development resources and
helps to track down and fix the problem soon.

@c ===============================================================

@ignore
@c complete this someday...
@node Glossary
@unnumbered Glossary

@table @strong
@item PR
Short for ``Problem Report''.  An electronic mail message which reports
a problem.  A @dfn{record} in the @sc{gnats} database.

@item Support Site
A central site that provides resources for maintainers of a body of
work, such as a software package.  We refer to the Support Site as the
location where @sc{gnats} is installed and functional.

@item Database
An organized collection of information.

@item @sc{gnats}
The @sc{gnu} Problem Report Management System.

@item Field
A location for specific information.  A group of fields make up a
Problem Report.

@item Mail header
Defined by the Internet Internet standard RFC-822

@item Category
@item Submitter
@item Originator
@item Query
@item Report
@item Site
@item Edit
@item Submit
@item Bug
@item State
@item ID Number
@item Synopsis
@item Confidential
@item Severity
@item Priority
@item Responsible
@item Configuration
@item Class
@item Environment
@item Description
@item Audit-Trail
@item Unformatted
@item Fix
@item Release
@item Makefile
@item gnats-admin
@item pending
@item send-pr
@item edit-pr
@item Maintainers
@item timestamp
@item utility
@item tool

@end table

@end ignore

@node Index
@unnumbered Index

@printindex cp

@bye

