\input texinfo @c -*-texinfo-*- @smallbook @c %**start of header @setfilename gsc.info @settitle GSC @c %**end of header @setchapternewpage odd @syncodeindex fn cp @syncodeindex vr cp @syncodeindex ky cp @syncodeindex pg cp @syncodeindex tp cp @include version.texi @include rendition.texi @ifinfo @direntry * gsc: (gsc). Gray's script collection @end direntry @end ifinfo @copying Published by the Free Software Foundation, 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA Copyright @copyright{} 2005 Sergey Poznyakoff Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``A GNU 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 FSF's Back-Cover Text is: ``You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development.'' @end copying @titlepage @title GSC @subtitle version @value{VERSION}, @value{UPDATED} @author Sergey Poznyakoff. @page @vskip 0pt plus 1filll @insertcopying @end titlepage @page @summarycontents @page @contents @node Top, Intro, (dir), (dir) @ifinfo @chapter GSC This edition of the @cite{GSC Manual}, last updated @value{UPDATED}, documents GSC Version @value{VERSION}. @end ifinfo @menu * Intro:: What is GSC? * CVS Tools:: Various CVS-related Tools. * Source Tree Utilities:: Batch Modifications to the Source Files. * Root Utilities:: Various system-related utilities for use by root. * Startup Scripts:: * User Tools:: Just that. * Reporting Bugs:: How to Report a Bug. Appendices * Copying This Manual:: The GNU Free Documentation License. * Concept Index:: Index of Concepts. Here are some other nodes which are really inferiors of the ones already listed, mentioned here so you can get to them in one step: @detailmenu --- The Detailed Node Listing --- CVS Tools * mksnapshot:: Create Snapshot Tarballs from the CVS or SVN repository. * Sync WWW:: Synchronize a Directory with a CVS Module Upon Commit. Sync WWW * sv_sync_www_schedule:: Schedule a CVS to WWW Sync Job. * sv_sync_www:: Synchronize CVS Directories with the Corresponding WWW Directories. * CVS Sync Example:: How to Set Up CVS synchronization framework. * sv_www_loginfo:: Update CVSROOT/loginfo Files. sv_sync_www * Single job:: * Cron job:: * Invocation:: Source Tree Utilities * fixnamespace:: Fix Global Namespace of a Project. * fsf-move:: Update FSF Postal Mail Address in (L)GPL Copyright Statements. Root Utilities * bind replication:: A Framework for Replicating Master @command{bind} Server. * firewall:: M4 Wrappers For Setting Firewalls. * session-cleanup:: Manage PHP Sessions. firewall * Primitives:: A set of primitives defined in @file{firewall.m4} Startup Scripts * rc.inet1:: A Replacement for Slackware @command{rc.inet1}. * rc.autofs:: Automounter Setup. * rc.ntpd:: @command{Ntpd} Setup. * rc.local:: Local Startup. * rc.firewall:: Firewall Setup. * rc.ipacct:: @command{ipacct} setup. * rc.ppp:: Set up a @acronym{PPP} connection. * rc.tagr:: @command{tagr} setup. User Tools * dict-setup:: Setup a set of @command{aspell} dictionaries. * consoleconf:: Simple Tool for Console Font/Keyboard Mapping Switching. * ppp:: A Framework for Setting Up a Dial-up Connection. @end detailmenu @end menu @node Intro, CVS Tools, Top, Top @chapter Introduction to GSC @cindex @acronym{GSC} defined @acronym{GSC} stands for @dfn{Gray's Script Collection}. It is a collection of various mostly unrelated tools and configuration files I use in system administration and software development. The tools are mainly for my own use, however I'd be glad if you find them useful too. The package is distributed under GPL, for exact license terms and conditions see file @file{COPYING} in the main distribution directory. This manual documents version @value{VERSION} of the package. It is distributed under GFDL, @xref{Copying This Manual}. @node CVS Tools, Source Tree Utilities, Intro, Top @chapter CVS Tools This set of tools is designed to facilitate some tasks related to @acronym{CVS} and Savane maintenance. @menu * mksnapshot:: Create Snapshot Tarballs from the CVS or SVN repository. * Sync WWW:: Synchronize a Directory with a CVS Module Upon Commit. @end menu @node mksnapshot @section mksnapshot @pindex mksnapshot @cindex snapshots, creating for CVS and SVN @cindex CVS and SVN snapshots, creating This @command{mksnapshot} utility creates source tarballs from modules in @acronym{CVS} and/or @acronym{SVN} repositories. This is useful, for example, to create daily snapshots from the repository. The program looks for modules in the @acronym{CVS} repository. For each module found, it checks out first line of @file{ChangeLog} file, and if it presents a date later than the one when the last snapshot was made, it checks out the module into a temporary directory, tars its contents and places the resulting archive into the distribution directory. The resulting archive is named @file{@var{project}-@var{DATE}.tar.gz}, where @var{project} is the name of the module and @var{date} is latest @file{ChangeLog} date in @samp{YYYY-MM-DD} format. In addition, a symbolic link to the latest snapshot is created. The link is named @file{@var{project}-latest.tar.gz}. The actual compression method, and the tarball suffix are configurable (see the description of @code{COMPRESS} variable below). If the module is not found in the @acronym{CVS}, @command{mksnapshot} tries out the @acronym{SVN} repository, if it is configured. The repository last change date is checked using @command{svn info} command, and if it is later than the date of the last snapshot, the new snapshot is made, as described above. The program takes a single argument, a name of the configuration file. This file should declare several environment variables that control @command{mksnapshot} behavior. @defvar CVSROOT This variable specifies the @acronym{CVS} root directory name. @end defvar @defvar SVNROOT This variable specifies the @acronym{SVN} root directory name. @end defvar @defvar WD A working directory for extracting repository data. @end defvar @defvar FTP Target directory where tarballs should be placed. @end defvar @defvar MAXSNAPSHOTS Maximum number of snapshots to keep for each project. This variable is optional. It defaults to 3. @end defvar @defvar REPOSITORY Type of @acronym{CVS repository}. This variable is optional. Set @code{REPOSITORY=PLAIN} if you use classic ``plain'' @acronym{CVS} repository, and @code{REPOSITORY=SAVANE}, if you use Savane-based repository. Lower-case values are accepted as well. Default is @samp{SAVANE}. @emph{Warning:} setting @code{REPOSITORY=PLAIN} works only with @acronym{CVS} repositories. @end defvar @defvar COMPRESS Name of the compress program to use. Recognized values are @samp{compress}, @samp{gzip} (default), and @samp{bzip2}. Any other value is also accepted, provided that you also set the @code{ZSUFFIX} variable (see below). @end defvar @defvar ZSUFFIX Additional suffix for compressed tarballs (without leading dot). Default values depend on the value of the @code{COMPRESS} variable, as shown in the table below: @multitable @columnfractions 0.6 0.4 @headitem COMPRESS value @tab Suffix @item compress @tab Z @item gzip @tab gz @item bzip2 @tab bz2 @end multitable @end defvar @defvar VERBOSE Set verbosity level. Allowed values are @samp{yes}, @samp{no}, or any decimal number. The bigger the number, the more information is displayed. The value of @samp{yes} is equivalent to @samp{1}, that of @samp{no} is equivalent to @samp{0}. Default is @samp{no}. @end defvar The behaviour of @command{mksnapshot} differs depending on the type of repository used. For plain repositories, @command{mksnapshot} processes all the modules in the repository, except @code{CVSROOT}. Obviously, this approach works only for @acronym{CVS} repositories. For Savane repositories, the program first gets the list of user's groups, then for each group it looks up a module of this name. When found, such module is processed as described above. Thus, only those modules are selected, in which the current user participates. @node Sync WWW @section Sync WWW @cindex CVS synchronization The programs in this section form a framework for automatic update of a directory upon @acronym{CVS} commit. This is useful, for example, to keep a mirror of a module. Puszcza (@url{http://puszcza.gnu.org.ua}) uses this for automatic update of projects' home pages. This works as follows: suppose that each project keeps publicly available data (@acronym{html} pages, etc) in directory @file{/software/@var{project}}. These data are under @acronym{CVS} control in directory @file{/webcvs/@var{project}}. Upon commit, @acronym{CVS} server executes @file{CVSROOT/loginfo} which calls @command{sv_sync_www_schedule}. This utility schedules an update job. Another program, @command{sv_sync_www} is called as a @command{cron} job. This program flushes all jobs scheduled so far. For each project it changes to the project public directory and performs @command{cvs update} (well, actually it does much more than that... @pxref{sv_sync_www}). The following subsections describe each utility in detail. @menu * sv_sync_www_schedule:: Schedule a CVS to WWW Sync Job. * sv_sync_www:: Synchronize CVS Directories with the Corresponding WWW Directories. * CVS Sync Example:: How to Set Up CVS synchronization framework. * sv_www_loginfo:: Update CVSROOT/loginfo Files. @end menu @node sv_sync_www_schedule @subsection sv_sync_www_schedule @pindex sv_sync_www_schedule @cindex Scheduling a CVS synchronization job @cindex CVS synchronization job, scheduling The program @command{sv_sync_www_schedule} schedules a @command{CVS} synchronization job for further execution. The jobs are stored in directory @file{/var/spool/savane/}. This directory must have sufficient permissions for @command{sv_sync_www_schedule} to access it. Normally, this means adding each @acronym{CVS} user to a common group, e.g. @samp{svusers} and setting directory access mode to 0775: @smallexample @group $ ls -ld /var/spool/savane drwxrwxr-x 2 root svusers 25 Aug 18 18:00 savane/ @end group @end smallexample @cindex @file{loginfo}, setting up for scheduled CVS synchronization The program takes three arguments: user name@footnote{not used currently}, file name of the @acronym{CVS} repository, and the list of files changed by the commit. The program is supposed to be invoked by each commit. The proper way to do so is to add the following line to the project's @file{CVSROOT/loginfo} file: @smallexample ALL /bin/sv_sync_www_schedule $@{USER@} $@{CVSROOT@} %s @end smallexample @command{sv_sync_www_schedule} logs errors via @command{syslog} channel @code{local1.error}. @node sv_sync_www @subsection sv_sync_www @pindex sv_sync_www @UNREVISED{} The program @command{sv_sync_www} is the main engine for @acronym{CVS} synchronization. It operates in two modes: in @dfn{single job} mode it synchronizes a single @acronym{CVS} commit (called @dfn{job}), in @dfn{cron job} mode it processes a set of accumulated jobs at once. Whatever the mode is, the processing of a single job looks as follows: the program determines @acronym{CVS} root directory, subdirectory and files affected by the commit, changes to the directory where the synchronization must be performed (a @dfn{destination directory}, and runs @command{cvs update} with appropriate arguments. After update, @command{sv_sync_www} recursively searches for files named @file{.symlinks} under the destination directory. Each such file specifies the symbolic links that should be created @emph{within a directory, where it resides}. @cindex @file{.symlinks} In a @file{.symlinks} file any empty lines and lines starting with @samp{#} or @samp{;} are ignored. Rest of lines must contain two words: the name of the file to create the link from, and the name of the link to be created. Thus, the following @command{.symlinks} file: @smallexample @group # comment gsc.html index.html @end group @end smallexample @noindent will create a link named @file{index.html}, pointing to the file @file{gsc.html}. Notice that the linking is allowed only within or under the directory containing @file{.symlinks} file. In particular, @command{sv_sync_www} will refuse to create links whose names begin with the directory separator or contain @samp{..}. @menu * Single job:: * Cron job:: * Invocation:: @end menu @node Single job @subsubsection Single job @cindex @command{sv_sync_www}, single job mode Single job mode is the default mode for @command{sv_sync_www}. It operates in this mode, unless @option{-s} command line option is specified. It takes one or two command line arguments. A single command line argument is parsed as a @code{%s} parameter in @file{loginfo} invocation, i.e. it must consist of the project directory name and the whitespace separated list of files, affected by the commit. The project directory name can be absent, which is indicated by the leading whitespace. The list of files can have two special forms: @samp{- New directory} and @samp{- Imported sources}. @cindex @command{sv_sync_www}, invoking from @file{loginfo} @cindex @file{loginfo}, invoking @command{sv_sync_www} @cindex @file{loginfo}, setting up for real time CVS synchronization In order to invoke @command{sv_sync_www_flush} on each commit, the @file{loginfo} file must contain a line similar to the following: @smallexample @group ALL (date; cat; (sleep 2; /bin/sv_sync_www %s ) \ &\ ) >> /var/log/sync_www.log 2>&1 @end group @end smallexample @noindent There are two notes on this example. First, programs like @command{sv_sync_www} must be run in the background, otherwise they will cause dead lock conditions due to the use of lock files. Secondly, this example shows only the minimal invocation of @command{sv_sync_www}. You will always need to pass it the commited file name or names (see @samp{%s} above). However, depending on the actual configuration you may need to pass it some configuration options as well. @node Cron job @subsubsection Cron job @cindex @command{sv_sync_www}, cron job mode @UNREVISED{} @command{Sv_sync_www} starts in cron job mode when it is given @option{-s} command line argument. It takes a single optional argument, specifying the @dfn{spool directory} to use (defaults to @file{/var/spool/savane}. @node Invocation @subsubsection Invocation @UNREVISED{} @cindex @command{sv_sync_www}, default settings First of all, @command{sv_sync_www} assumes some default settings that you should know about. Namely, it supposes that both @acronym{CVS} repository and update directory (hereinafter called @dfn{WWW directory}) are located on the same server. Further, it supposes that the former is called @file{/webcvs} and the latter is called @file{/home/puszcza/software}. And, finally, it invokes @command{cvs} binary using the following command line: @smallexample CVS_RSH=ssh cvs -q -z3 @end smallexample Of course, any of these defaults can be changed from the command line. @cindex @command{sv_sync_www}, command line options @cindex @command{sv_sync_www}, specifying WWW directory @cindex @option{-w}, @command{sv_sync_www} option To specify another @acronym{WWW} directory, use @option{-w} option. @cindex @command{sv_sync_www}, specifying repository directory @cindex @option{-R}, @command{sv_sync_www} option To specify a repository directory, use @option{-R}. The argument to this option should be a directory name itself, without any access method prefix. See below for a way to specify this. In particular, if you use @command{Savane}-like @acronym{CVS} layout and wish to use immediate synchronization, your @file{loginfo} would contain: @smallexample @group ALL (date; cat; (sleep 2; /bin/sv_sync_www -R $@{CVSROOT@} %s ) \ &\ ) >> /var/log/sync_www.log 2>&1 @end group @end smallexample The @command{sv_sync_www_flush} script passes this option by default. @cindex @option{-H}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, specifying update server name If the repository and @acronym{WWW} directory are located on different servers, the IP address of host name of the server containing @acronym{WWW} directory must be specified via @option{-H}. @cindex @option{-r}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, specifying remote shell binary @cindex @command{sv_sync_www}, accessing remote WWW server In this case @command{sv_sync_www} will invoke @command{cvs} binary on the @acronym{WWW} server using @command{ssh} (more precisely: @command{/usr/bin/ssh}). The name of the @command{ssh} binary can be set using @option{-r} option. @cindex @option{-m}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, specifying remote repository access method Further, invoked @command{cvs} will need to access @emph{remote} @acronym{CVS} repository. The directory name of this repository can be specified using @option{-R} option, described above. To specify access method, use @option{-m} option. The argument to this option will be prepended to the repository directory (either default one or the one specified using @option{-R} option), so make sure you end it with a colon. @cindex @option{-c}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, specifying CVS command. By default, @command{sv_sync_www} will assume that @command{cvs} should use @command{ssh} for accessing the remote server (see the default @command{cvs} invocation above). If it is not the case, you can use @option{-c} command line option. The @command{cvs} commands will be appended to the supplied command verbatim. Finally, please notice that using remote @acronym{WWW} server you will have to set up an access from the @acronym{CVS} to @acronym{WWW} and from the @acronym{WWW} to @acronym{CVS} without passwords (usually this means setting up @command{ssh} for public keys authentication). To illustrate these concepts, suppose that the name of the remote @acronym{WWW} server is @indicateurl{www.foo.org}, it should be accessed using @command{rsh} (Note: @emph{do not use it} in real life. It is unsecure), the repository itself should be accessed using @samp{gserver} method, and all @acronym{CVS} interactions should use maximal compression. Then, the command line for @command{sv_sync_www} will be: @smallexample @group sv_sync_www -H www.foo.org -m :gserver:cvs.foo.org: \ -r rsh -c 'cvs -q -z9' -R $@{CVSROOT@} %s @end group @end smallexample @cindex @option{-n}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, dry run @cindex @option{-x}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, debugging When setting up unusual configurations, it is often useful to be able to run @command{sv_sync_www} without actually changing anything. This mode is called @dfn{dry run}, and it is turned on by @option{-n} option. In dry run mode, @command{sv_sync_www} does not change anything, instead it just prints what it would have done. Additional debugging diagnostics can be enabled using @option{-x} option. @cindex @option{-h}, @command{sv_sync_www} option @cindex @command{sv_sync_www}, obtaining help summary Finally, running @code{sv_sync_www -h} displays a short usage summary. @node CVS Sync Example @subsection Seting Up CVS synchronization framework. @subsubheading Loginfo file @smallexample ALL /usr/local/bin/sv_sync_www_schedule $@{USER@} $@{CVSROOT@} %s @end smallexample @subsubheading Crontab @smallexample @group # Flush WWW synchronisation jobs, scheduled by sv_sync_www_schedule # once an hour 0 */1 * * * /usr/local/bin/sv_sync_www -s @end group @end smallexample @node sv_www_loginfo @subsection sv_www_loginfo @pindex sv_www_loginfo The program @command{sv_www_loginfo} scans @file{loginfo} files of all the projects in the repository and replace the default ones (i.e. the ones whose contents is entirely commented out) with the contents described in the previous subsection. This is to avoid directly modfifying @command{Savane} sources and to achieve, at the same time, the desired @acronym{WWW} synchronization functionality. Once @command{Savane} is flexible enough to allow for user-configurable @file{CVSROOT} contents, the need for this program will go away. At the time of this writing, @command{sv_www_loginfo} is called from @file{crontab} as follows: @smallexample @group 30 */2 * * * sv_groups --cron && \ sv_users --cron && \ sv_www_loginfo --cron @end group @end smallexample The program assumes the @acronym{CVS} repository under @file{/webcvs}. It takes the following command line options: @table @option @item --cron Run as a cron job. All diagnostics is in this case reported via @command{syslog} channel @code{local1.info}. Without this option it goes directly to @code{stderr}. @item --help Display short usage summary. @end table @node Source Tree Utilities, Root Utilities, CVS Tools, Top @chapter Source Tree Utilities Programs described in this chapter perform a set of global replacements on all the files within a project. The operation is being performed in a separate directory, which is populated by @code{make distdir} command. After the replacement, @code{make distcheck} is run to ensure that the operation did not break integrity of the project. If @code{distcheck} passes successfully, the resulting update can be left in the temporary directory for further inspection, archived in a @command{tar} archive, or propagated back to the original project. Prerequisites for running these programs are: @enumerate 1 @item Project must conform to GNU Coding Standards. In particular, it must support @command{make distdir} and @command{make distcheck} and these two goals must be built successfully on the unmodified project. @item The program must be run in the project top source directory @end enumerate The usage synopsis is similar for both programs. The following command line options are supported: @cindex @command{fixnamespace}, command line options @cindex @command{fsf-move}, command line options @table @option @item -k @cindex @option{-k}, @command{fixnamespace} and @command{fsf-move} command line option Leave modified project in the temporary working directory. The name of the working directory is formed as @var{prefix}-@var{program}, where @var{prefix} is the base name of the projects top source directory (unless overridden by @option{-p}, see below) and @var{program} is the name of the invoked program. @item -r @cindex @option{-r}, @command{fixnamespace} and @command{fsf-move} command line option Propagate the changed files to the original progect. This option requires GNU @command{tar} version 1.15.1 or newer. @item -t @cindex @option{-t}, @command{fixnamespace} and @command{fsf-move} command line option Store modified project tree in tar archive named @file{@var{prefix}-@var{program}.tar.gz}. @item -p @var{prefix} @cindex @option{-p}, @command{fixnamespace} and @command{fsf-move} command line option Specify name prefix for temporary working directory and tar archive (see options @option{-k} and @option{-t}). @item -h Display short usage summary. @end table @cindex @option{--configure}, @command{fixnamespace} and @command{fsf-move} command line option The command line options to @command{configure} can be given using @option{--configure}. This option can be specified several times, arguments of multiple @option{--configure} options are concatenated in a whitespace separated list. The very first @option{--configure} option should be preceeded by a double-dash: @smallexample -- --configure --with-prog @end smallexample Any non-option arguments containing an equals sign, and any non-option arguments beginning with double-dash (@samp{--}) are considered to be additional @command{make} arguments and are passed to @command{make} verbatim. @menu * fixnamespace:: Fix Global Namespace of a Project. * fsf-move:: Update FSF Postal Mail Address in (L)GPL Copyright Statements. @end menu @node fixnamespace @section fixnamespace @pindex fixnamespace @cindex Fixing a project namespace. @command{Fixnamespace} utility replaces all global identifiers in a project by prefixing them with a given string. This is useful for creating a common namespace if a project contains a loadable library, hence the name of the utility. Notice that only those symbols are modified, that do not already begin with the prefix. @dfn{Global identifiers} are any functions, variables and typedefs declared in the header files of the project. To locate these, @command{fixnamespace} uses @dfn{tag files}, created by @command{etags} utility (@pxref{Tags,,Tags Tables,emacs,GNU Emacs Manual}). Thus, to use @command{fixnamespace} you must have Emacs version 21.3 or newer installed on your system. @cindex @command{fixnamespace}, invocation The utility takes two or more arguments. First argument is the prefix to be appended to all symbols. Rest of arguments specify the header files where to look for global symbols. Only file names should be given, without any directory prefixes. @cindex @command{fixnamespace}, command line options. Apart from the command line options common for all source-tree utilities, @command{fixnamespace} understands following option: @table @option @item -x @var{symbol} Exclude @var{symbol} from replacement. This option can be given multiple times. @end table Example of using this program: @smallexample fixnamespace -x scm_long2num mu_ message.h mailbox.h body.h list.h @end smallexample Final notice: when too many header files are specified in the command line, the number of created Lisp variable bindings can exceed Emacs capacity; in this case @command{emacs} will signal an error. To overcome this, increase value of @code{max-specpdl-size} variable in @file{fixnamespace.el} near line 215. @node fsf-move @section fsf-move @pindex fsf-move During my activity as a free software programmer, the Free Software Foundation has twice changed its locations. Each such move implied a change of postal mail address, and, consequently, a need for updating each file in any free software project, since the standard @acronym{GPL} or @acronym{LGPL} copyright header refers to it. Such a work can be very tedious for large projects, so when the @acronym{FSF} has recently changed its location again, I decided to automate the process once and for all. This is what @command{fsf-move} is for. The program does not take any special command line options or arguments beside those described above (@pxref{Source Tree Utilities}). Currently it is tuned to change postal mail address from @quotation 59 Temple Place, Suite 330 Boston, MA 02110-1301 USA. @end quotation @noindent to @quotation 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. @end quotation Should @acronym{FSF} move again, you will have to change these defaults by modifying @file{fsf-move}:177 and @file{fsf-move.awk}:21-22. The program implements a sophisticated search-and-replace algorithm, if it knows a syntax of the language a file is written in. The purpose of the algorithm is to allow for arbitrary splitting of lines in the address and to preserve alignment and formatting of comments. This algorithm is applied to files whose names match following regexps: @table @asis @item *.[chyl] C sources; @item *.m4|*.ac|*.at M4 sources; @item *.sh Shell scripts; @item *.awk AWK sources; @item *.exp|*.tcl TCL sources; @item *.am|Makefile.tmpl Automake sources; @item *.el|*.scm*|*.lisp Various dialects of Lisp; @end table PO files (@asis{*.po}), and their derivatives are ignored. The rest of files is processed using @dfn{fuzzy search} algorithm, which is able to find the postal address in the majority of cases, though not always. Such files should probably be inspected after @command{fsf-move} finishes its work. @node Root Utilities, Startup Scripts, Source Tree Utilities, Top @chapter Root Utilities This chapter describes a set of utilities useful in system administration. @menu * bind replication:: A Framework for Replicating Master @command{bind} Server. * firewall:: M4 Wrappers For Setting Firewalls. * session-cleanup:: Manage PHP Sessions. @end menu @node bind replication @section bind replication @UNREVISED{} @node firewall @section firewall @cindex firewall The @file{firewall} subdirectory of the source tree contains an @command{m4} wrapper over GNU/Linux @command{iptables} utility. The basic idea behind it is to create a framework that could be used without changes on any platform, no matter what the underlying firewall implementation is. Currently it is implemented only for @command{iptables}. The support for @acronym{BSD}-style @command{ipfw} and, eventually, more will be added soon. The framework is based on a set of @command{m4} wrappers. From the point of view of a final user, its usage is as follows. First, the administrator creates a set of firewall rules using the primitives supplied by @file{firewall.m4}. Then he processes @file{firewall.m4} using @command{m4} and obtains a set of implementation-dependent firewall rules that can be fed to the shell. You will probably not need to process @file{firewall.m4} manually, we recommend to use @command{rc.firewall} instead (@pxref{rc.firewall}). However, for the sake of completeness, here is how it should be invoked: @smallexample m4 [-DSYSCONFDIR=@var{dir}] -DACTION=@var{action} firewall.m4 @end smallexample @noindent This command generates a set of implementation-dependent firewall rules that can be fed to the shell. Its arguments are: @defvar ACTION Specifies which set of commands @command{firewall.m4} is to create. Possible values are: @table @asis @item status List actual firewall rules. @item flush Flush the firewall rules. @item @var{filename} Read in and process file @file{@var{filename}}. @end table @end defvar Optional variable @code{SYSCONFDIR} specifies a directory where @file{rule.d} subdirectory is located (@pxref{rule.d}). It defaults to @file{/etc/firewall}. @menu * Primitives:: A set of primitives defined in @file{firewall.m4} @end menu @node Primitives @subsection Firewall Primitives @UNREVISED{} @deffn {Firewall Primitive} ACCEPT chain, srcip, srcport, dstip, dstport, proto, log @end deffn @deffn {Firewall Primitive} REJECT chain, srcip, srcport, dstip, dstport, proto, log @end deffn @deffn {Firewall Primitive} DENY chain, srcip, srcport, dstip, dstport, proto, log @end deffn @deffn {Firewall Primitive} LIST @end deffn @deffn {Firewall Primitive} port_setup rule ip @anchor{rule.d} @end deffn @node session-cleanup @section Manage PHP Sessions @cindex session-cleanup The script @command{session-cleanup} provides flexible garbage collection for @acronym{PHP} session files. It is designed first of all for managing session files stored in a deep directory structrure (i.e. when @code{session.save_path = @var{n};path} in @file{php.ini}), for which the built-in @acronym{PHP} garbage collection is turned off. Beside this, @command{session-cleanup} allows to set up different @dfn{TTL} (@dfn{time to live}) intervals for different session files, based on their contents. @cindex @option{-c} command line option, @command{session-cleanup} The script should be started at regular intervals as a cron job. Upon startup it obtains the value of @code{session.save_path} variable from @file{/etc/apache/php.ini}. If your @file{php.ini} is located elsewhere, specify its exact location using @option{-c} command line option. Then @command{session-cleanup} scans the storage directory and removes session files that were created more than @acronym{TTL} days ago. The exact value of @acronym{TTL} is determined using following rules: @cindex Session @acronym{TTL} @cindex @command{session-cleanup}, setting session @acronym{TTL} @enumerate 1 @item @cindex @command{session-cleanup}, configuration file @cindex configuration file for @command{session-cleanup} If the command line contains a non-option argument, it is taken as a name of @dfn{configuration file}. This file is scanned for a line that matches the contents of the session file. If such a line is found, it determines the @acronym{TTL} for this session. @item @cindex @option{-t} command line option, @command{session-cleanup} If @option{-t} is given in the command line, its argument specifies @acronym{TTL}. @item Otherwise, default value of 3 days is used. @end enumerate Configuration file has a simple line-oriented syntax. Blank lines and lines that begin with a hash character (@samp{#}) are ignored. The rest of lines is split into two fields. First field specifies a @dfn{regular expression} to search for in the session file. Second field gives the @acronym{TTL} value in days for files that match this regular expression. The first matching line is used. A sample configuration file follows: @smallexample # Regex TTL (days) ^gallery_session_.* 1 mprogh 62 @end smallexample @noindent If a regular expression contains whitespace, use @command{shell} escapes or quotes to protect it. @subheading Syntax @smallexample session-cleanup @var{options} [@var{config-file}] @end smallexample @noindent @var{options} are: @table @option @item -c @var{file} Use @var{file} instead of @file{/etc/apache/php.ini}. @item -h @cindex @option{-h} command line option, @command{session-cleanup} Display a short help summary. @item -n @cindex @option{-n} command line option, @command{session-cleanup} Dry run. Only display which files will be removed, do not actually remove them. @item -t @var{ttl} Set default session time to live. @var{ttl} is measured in days. @item -v @cindex @option{-v} command line option, @command{session-cleanup} Verbose mode. Useful for debugging in conjunction with @option{-n}. @end table @node Startup Scripts, User Tools, Root Utilities, Top @chapter Startup Scripts This chapter describes several startup files, designed mainly for GNU/Linux. To use any of them, first read its description, then copy it to the location where your startup scripts reside (@file{/etc/rc.d} on @asis{Slackware}) and make sure it is executed at startup. Then follow the script-specific recommendations set forth in the corresponding section. @menu * rc.inet1:: A Replacement for Slackware @command{rc.inet1}. * rc.autofs:: Automounter Setup. * rc.ntpd:: @command{Ntpd} Setup. * rc.local:: Local Startup. * rc.firewall:: Firewall Setup. * rc.ipacct:: @command{ipacct} setup. * rc.ppp:: Set up a @acronym{PPP} connection. * rc.tagr:: @command{tagr} setup. @end menu @node rc.inet1 @section rc.inet1 @pindex rc.inet1 The startup script @command{rc.inet1} sets up network interfaces. It was thought as a replacement for @asis{Slackware} startup script with the same name, which I find extremely inconvenient. To use the script, copy it to the location where your startup scripts reside (@file{/etc/rc.d} on @asis{Slackware}) and make sure it is executed at startup. The script itself does not use any configuration files. Instead, it consists of configurable and immutable parts. Both parts are clearly separated with appropriate comments. Configurable part contains a set of variable definitions. The variables are: @defvar if_list This variable contains a whitespace separated list of interface names to be configured. For example: @smallexample if_list="lo eth0" @end smallexample @noindent Each interface name must itself be a valid @command{shell} variable name. Names of almost all existing interfaces meet this condition. The common exception are ethernet aliases, which on GNU/Linux contain colon. To list such an interface name, replace the colon with underscore. For example to configure interfaces @code{lo}, @code{eth0} and @code{eth0:0}, one would write: @smallexample if_list="lo eth0 eth0_0" @end smallexample One more note: it is advisable to always keep @code{lo} in this list. @end defvar @defvar if_@var{iface} @cindex @code{if_@var{iface}} For each interface name @var{iface} in @code{if_list}, there must be defined a variable named @code{if_@var{iface}}. The value of this variable must be an @command{ifconfig} command line initializing given interface. The name of the interface itself should be omitted from the command line. Given the previous example, one might write: @smallexample @group # Configure three interfaces if_list="lo eth0 eth0_0" # Set up loopback interface if_lo="127.0.0.1" # Set up eth0 if_eth0="inet 192.168.10.1 netmask 255.255.255.224\ broadcast 192.168.10.31" # Set up eth0:0 if_eth0_0="inet 192.168.10.2 netmask 255.255.255.224\ broadcast 192.168.10.31" @end group @end smallexample @end defvar @defvar route_@var{iface} For each interface name @var{iface} in @code{if_list}, there can be defined a variable @code{route_@var{iface}}. If it is defined, it contains a @command{route} command line for setting up routing for this interface. Completing our previous example, for loopback interface one might write: @smallexample @group if_lo"127.0.0.1" route_lo="add -net 127.0.0.0 netmask 255.0.0.0 lo" @end group @end smallexample @end defvar @defvar default_gw This variable defines IP address of the default gateway. @end defvar @defvar static_routes @cindex @code{route_@var{id}}, @command{rc.inet1} configuration variable The variable @code{static_routes} declares @dfn{route identifiers} for each static route to be set up. A route identifier is an arbitrary word consisting of alphanumeric characters and underscores. For each identifier @var{id} in @code{static_routes} there must be declared variable @code{route_@var{id}}, whose value is @command{route} command line for setting up this route. For example: @smallexample @group static_routes="1" route_1="add -net 192.168.10.0 netmask 255.255.255.224 \ gw 192.168.10.10 metric 216 reject" @end group @end smallexample @end defvar @FIXME{As other configuration scripts, this one should probably take a command line argument @{@code{start}|@code{stop}|@code{status}@}. For the time being it always behaves as if invoked with @code{start}} @node rc.autofs @section rc.autofs @cindex @command{rc.autofs} The script @command{rc.autofs} controls GNU/Linux automounter facility. It accepts a single mandatory command line argument: @table @code @item start Start automounter. @item stop Stop automounter. @item status List configured and active automounter instances and mount points. Here is a sample output (long lines being split for readability): @smallexample @group Configured Mount Points: ------------------------ /usr/sbin/automount --timeout=1 \ /auto file /etc/automount/auto.misc Active Mount Points: -------------------- 1040 /usr/sbin/automount --timeout=1 \ /auto file /etc/automount/auto.misc @end group @end smallexample @item reload Reload current configuration, restarting @command{automount} daemon if necessary. @item restart Unconditionally restart @command{automount} daemon. @end table The script assumes following full file names: @table @file @item /usr/sbin/automount @vindex DAEMON, @command{rc.autofs} configuration variable The name of the @command{automount} binary. Adjust @code{DAEMON} variable if it is located elsewhere. @item /etc/automount @vindex CFGDIR, @command{rc.autofs} configuration variable Configuration directory. Adjust @code{CFGDIR} if you need another name. @item /etc/automount/master @vindex CFGFILE, @command{rc.autofs} configuration variable The name of the master configuration file. Adjust @code{CFGFILE} variable if you need another name. @item /var/lock/subsys/autofs @vindex LOCKFILE, @command{rc.autofs} configuration variable The name of the lock directory. Adjust @code{LOCKFILE} variable if necessary. @end table @node rc.ntpd @section rc.ntpd @pindex rc.ntpd @command{Rc.ntpd} controls the @dfn{network time protocol} daemon. It takes a single mandatory command line argument: @table @code @item start @vindex TIMEOUT, @command{rc.ntpd} configuration variable @vindex MAXRETRY, @command{rc.ntpd} configuration variable Start @command{ntpd}. Before starting it the script attempts to synchronize current date with the master servers by running @command{ntpdate}. If @command{ntpdate} fails, the script sleeps for a specified number of seconds and attempts to synchronize again. Such attempts are tried several times while increasing proportionally the initial delay between the attempts, so that the delay after @var{n}th attempt is @var{n} times the initial one. Two configuration variables are provided to control this behavior: @code{MAXRETRY} sets the maximum number of attempts, @code{TIMEOUT} sets the initial delay in seconds. If all attempts fail, @command{rc.ntpd} sends a mail to root and exits without trying to launch @command{ntpd}. @item stop Stop @command{ntpd}. @item status List running @command{ntpd} instances and display current date/time difference between the local machine and its servers. points. Here is a sample output (long lines being split for readability): @smallexample @group Running processes: ------------------ 1124 /usr/sbin/ntpd Current date diff: ------------------ server 10.10.10.1, stratum 2, offset -0.008749, delay 0.13557 @end group @end smallexample @item reload @itemx restart Restart @command{ntpd} daemon. @end table The script assumes following full file names: @table @file @item /usr/sbin/ntpd @vindex DAEMON, @command{rc.ntpd} configuration variable Name of the @command{ntpd} daemon. Kept in @code{DAEMON} variable. @item /etc/ntp.conf @vindex CONFIG, @command{rc.ntpd} configuration variable Main @command{ntpd} configuration file. Kept in @code{CONFIG} variable. @end table The script searches @command{ntpdate}, @command{mail} and @command{ps} binaries using usual path mechanism. You may need to update @code{PATH} settings at the beginning of the script. @node rc.local @section rc.local @pindex @command{rc.local} The @command{rc.local} script manages @dfn{local services}. For the purposes of this script, we call each service a @dfn{component}. It is also supposed that the component management is handled by a script, that takes a single word as its argument. A component name is used to locate its startup script. If a component name is a single word, @var{name}, then @command{rc.local} assumes the script name is @file{/etc/rc.d/rc.@var{name}}. Otherwise, if @var{name} is a full path name, then it is used as a script name. Additionally, if component name has the form @samp{@var{user}@@@var{name}}, where @var{user} is a valid user name and @var{name} is as described above, then the script will be executed with the privileges of @var{user}. The following table provides an example of valid component names along with their description. @table @asis @item mailman The script is named @file{/etc/rc.d/rc.mailman}. @item postmaster@@mailman The script is named @file{/etc/rc.d/rc.mailman} and is executed with the privileges of the user @samp{postmaster}. @item /usr/local/etc/rc.d/rc.mailman The script is named @file{/usr/local/etc/rc.d/rc.mta} @item postmaster@@/usr/local/etc/rc.d/rc.mailman Same as above, but executed from the @samp{postmaster} account. @end table @menu * local.conf:: Local Component Configuration File. * rc.local usage:: Inocation and Command Line arguments. @end menu @node local.conf @subsection local.conf file @cindex @file{local.conf} The configuration file @file{local.conf}, located in @file{/etc} directory, contains the configuration for the @command{rc.local}. The syntax is very simple: @enumerate 1 @item Empty lines and comments are ignored. @item Comments begin with @samp{#}. @item The file consists of one or more @dfn{sections}. @item Each section begins with @samp{[@var{name}]} on a line by itself, and ends on the beginning of the next section, or end of file, whichever occurs first. The @var{name} above is the section name. @item Each section contains a list of component names, each on a separate line. @end enumerate The section named @samp{components} is mandatory. It contains names of all components managed by @command{rc.local}. The components will be started in the same order as listed in the section, and stopped in the reverse order. For example, given the following configuration file: @smallexample [components] mta httpd postmaster@@mailman @end smallexample @noindent the order of startup is: @samp{mta}, @samp{httpd}, @samp{mailman}. The order of shutdown is: @samp{mailman}, @samp{httpd}, @samp{mta}. Additional sections may be provided to specify inter-component dependency. Such sections are named after a particular component and contain a list of components that depend on that component. For example, consider this file: @smallexample [components] map mysql mta httpd postmaster@@mailman [mta] map mysql @end smallexample The last section tells that @samp{mta} component depends on components @samp{map} and @samp{mysql}. If you run @samp{rc.local restart mta}, then the following sequence of commands will be performed: @node rc.local usage @subsection Inocation of @command{rc.local}. @node rc.firewall @section rc.firewall @pindex rc.firewall This startup script sets firewall using @command{m4} firewall wrappers (@pxref{firewall}). It tajes a single mandatory command line argument: @table @asis @item start @itemx restart Set up firewall. @item stop Flush all firewall rules. @item status List all installed firewall rules. @item check @itemx test Produce a list of shell commands that will be used to set up firewall rules. Equivalent to @command{rc.firewall -d start}. @end table Option @option{-d} can be given before the argument to make @command{rc.firewall} produce a list of shell commands it would have used to perform a given task. For example @smallexample rc.firewall -d start @end smallexample @noindent prints commands that would be executed by @command{rc.firewall start}. @vindex FWDIR The script searches for @command{m4} wrappers in @file{/etc/firewall}. This location can be changed by setting @code{FWDIR} environment variable. @vindex START The list of firewall rules is expected to be located in @file{@code{$FWDIR}/rules.m4}. This location can be changed by setting @code{START} environment variable. @node rc.ipacct @section rc.ipacct @pindex rc.ipacct This script controls the @command{ipacct} daemon (@FIXME-pxref{ipacct}). It takes a single mandatory command line argument indicating what action to take: @table @asis @item start Start the daemon. @item stop Stop the daemon. @item status Display @acronym{PID} of the current instance of @command{ipacct}. @item restart Unconditionally restart the daemon. @item reload @itemx reconfigure Tell @command{ipacct} to re-read its configuration file. @end table The script searches for @command{ipacct} binary in the current @code{PATH}. Two variables defined at the beginning of the script control its behavior: @defvar IFACE Interface where to install @command{ipacct}. Default is @asis{eth0}. @end defvar @defvar PIDFILE Location of @command{ipacct} @acronym{pid} file. Default is @file{/var/run/ipacct-@code{IFACE}.pid}. @end defvar @node rc.ppp @section rc.ppp @pindex rc.ppp This script sets up a set of @acronym{PPP} connections at start up. It reads configuration from the file @file{/etc/ppp.conf}. The configurations is expressed as a set of shell variables. @defvar ppp_list This variable contains a whitespace separated list of @dfn{identifiers} for @acronym{PPP} connections. Each identifier is an arbitrary word, such that it is a valid shell variable. For each identifier @var{id}, the configuration file must declare a shell variable @code{ppp@var{id}_options}, specifying command line options for @command{pppd}. @end defvar @defvar ppp@var{id}_options @cindex @code{ppp@var{id}_options}, @command{rc.ppp} configuration variable This variable specifies command line options for connection @var{id}. @end defvar A sample @file{ppp.conf} file follows: @smallexample @group ppp_list="0 1" ppp0_options="modem passive nodetach defaultroute crtscts \ lock 192.168.0.1:192.168.0.2 /dev/ttyS0 9600" ppp1_options="modem lock 192.168.0.1:192.168.0.3 /dev/ttyS1 57600" @end group @end smallexample @node rc.tagr @section rc.tagr @pindex rc.tagr @command{Rc.tagr} controls @command{tagr} daemon (@FIXME-pxref{tagr}). It takes a single mandatory command line argument indicating what action to take: @table @asis @item start Start the daemon. @item stop Stop the daemon. @item status Display @acronym{PID} of the current instance of @command{tagr}. @item restart Unconditionally restart the daemon. @item reload @itemx reconfigure Tell @command{tagr} to re-read its configuration file. @end table @vindex PIDFILE @vindex PROGRAM @vindex CMD The script searches for @command{tagr} binary in @file{/usr/local/sbin/tagr} and for its @acronym{PID} file in @file{/var/run/tagr.pid}. This can be changed by editing variables @code{PROGRAM}, @code{PIDFILE} and @code{CMD} at the beginning of the script. @node User Tools, Reporting Bugs, Startup Scripts, Top @chapter User Tools @menu * dict-setup:: Setup a set of @command{aspell} dictionaries. * consoleconf:: Simple Tool for Console Font/Keyboard Mapping Switching. * ppp:: A Framework for Setting Up a Dial-up Connection. @end menu @node dict-setup @section dict-setup @pindex dict-setup @command{Dict-setup} automates setting up a set of @command{aspell} dictonaries (@pxref{Top,,Overview,aspell,GNU Aspell Manual}). It takes a list of file names as its arguments. Each file must contain a list of languages for which spell checking dictionaries must be installed. The languages should be specified as ISO 639 language abbreviations, one per line. Empty lines and shell-style comments are ignored. For each language, @command{dict-setup} downloads its latest spell checking dictionary from @url{ftp://ftp.gnu.org.ua/gnu/aspell/dict}, builds and installs it. @cindex @option{-u} command line option, @command{dict-setup}. If you wish to use another @acronym{URL}, specify it via @option{-u} command line option, for example @smallexample dict-setup -u ftp://ftp.gnu.org FILE @end smallexample @vindex SUF To save bandwidth, @command{dict-setup} looks for dictionaries compressed via @command{bzip2} command. This can be altered by setting @code{SUF} variable to the desired file suffix, e.g. @code{SUF=.tar.gz}. @cindex @option{-c} command line option, @command{dict-setup}. By default, @command{dict-setup} installs the latest dictionary version. If this behavior is not desired, you can select which dictionary to install by invoking the program with @option{-c} option. @cindex @command{lynx} When run with this option, @command{dict-setup} prints a list of available dictionaries for each language and allows you to select one for download (it uses @command{lynx} to display the list, so make sure it is in your @code{PATH}). Use following commands to navigate through the list: @table @key @item v View index file. @item x Do not install dictionaries for this language. Proceed to the next language. @item q Abort installation immediately. @item @var{number} Install @var{number}th dictionary from the list. @end table @cindex @command{dict-setup} command line options Following is the complete list of @command{dict-setup} options: @table @option @item -c @cindex @option{-c} command line option, @command{dict-setup}. Run in confirm mode: for each language, present the user with a list of available dictionaries and allow him to select which one to install. @item -h @cindex @option{-h} command line option, @command{dict-setup}. Print a short usage summary and exit. @item -v @cindex @option{-v} command line option, @command{dict-setup}. Verbosely list each action executed. @item -u @var{url} @cindex @option{-u} command line option, @command{dict-setup}. Use @var{url} instead of the default @url{ftp://ftp.gnu.org.ua/gnu/aspell/dict}. @end table @node consoleconf @section consoleconf @pindex consoleconf @command{Consoleconf} sets console encoding and input method, for both text and X consoles. The program uses @command{kbd} package (@url{ftp://ftp.win.tue.nl/pub/linux-local/utils/kbd/}). @command{Consoleconf} consists of the following parts: @enumerate 1 @item @command{consoleconf} binary. It is normally installed as @command{$prefix/consoleconf}. @item Data directory with @dfn{language definition} files. It is normally installed as @file{$datadir/consoleconf}. @end enumerate @cindex @command{consoleconf}, usage @cindex @command{consoleconf}, invocation Usage of @command{consoleconf} is quite simple. Running: @smallexample consoleconf @var{lang} @end smallexample @noindent sets up the console for language @var{lang}, i.e. it sets keyboard map, optional screen map and screen font. Command line option @option{-c} can be used to specify encoding. For example: @smallexample consoleconf -c latin1 no @end smallexample @cindex @command{consoleconf}, available languages The package is shipped with support for the following languages: @table @asis @item da Danish @item es Spanish @item el Greek @item no Norwegian @item pl Polish @item ru Russian @item uk Ukrainian @end table @cindex @command{consoleconf}, adding new language To add a new language, create its @dfn{language description file} describing how to set up the console for this language. I suggest to use two-letter language codes as per ISO 639. The file has a regular @command{sh}(1) syntax. It should define following variables: @defvar {Consoleconf variable} KEYMAP Specifies the name of the keymap to use. Keymaps are usually stored in @file{/usr/share/kbd/keymaps/}, although the exact location may vary. @end defvar @defvar {Consoleconf variable} FONT Specifies the name of console font file to use when in text console. Console font files are usually located in @file{/usr/share/kbd/consolefonts/}, although the exact location may vary. @end defvar @defvar {Consoleconf variable} X11 @command{Setxkbmap} command line to use when under X11. @end defvar @defvar {Consoleconf variable} MOTD @dfn{Message of the day}. It is displayed after the console is set up. If it starts with commercial at sign, it is taken as a name of file whose contents is the message of the day. The file is looked up in @file{$datadir/consoleconf/motd}. This variable is optional. @end defvar For example, the following is the definition of Polish language: @smallexample @group KEYMAP=pl.map FONT="-m 8859-2 iso02.16.gz" X11="-rules xfree86 -model pc102 -layout pl" @end group @end smallexample @node ppp @section ppp @pindex start-ppp @cindex @file{/etc/ppp/pppscript.m4} This sub-package provides a framework for setting up a dial-up connection. At the core of it is @command{start-ppp}, a program which actually installs a connection. Various configuration data are supplied to it by several configuration files, normally located in @file{/etc/ppp}. When run, @command{start-ppp} interprets the file @file{/etc/ppp/pppscript.m4} to determine various configuration settings for the modem. There is normally no need to edit this file, as the actual configuration data are stored in two files it includes: @file{/etc/ppp/modem} and @file{/etc/ppp/login}. @cindex @file{/etc/ppp/modem} Modem configuration is kept in file @file{/etc/ppp/modem}. This file should define the following variables. @defvar MODEM_INITSTRING Initialization string for the modem. @end defvar @defvar MODEM_TIMEOUT Default modem timeout in seconds. @end defvar @defvar MODEM_DIALPREFIX Dial prefix, @samp{t} for tone dialing, @samp{p} for pulse dialing @end defvar @defvar AREA_CODE Optional area code. @end defvar @cindex @file{/etc/ppp/login} This file defines dial-up user credentials. These are kept in two variables: @defvar LOGIN Specifies user login name. @end defvar @defvar PASSWORD Specifies user password. @end defvar @cindex @file{/etc/ppp/numbers} @cindex @file{./numbers} Finally, the list of numbers to dial is supplied by file @file{/etc/ppp/numbers}. This file must contain one number per line. Empty lines and shell-style comments are allowed. The numbers from this file are tried in turn until dialing one of them succeeds or the end of file is reached. By default, @command{start-ppp} first looks up the file @file{numbers} in current working directory. If it is found, it is read instead of @file{/etc/ppp/numbers}. @node Reporting Bugs, Copying This Manual, User Tools, Top @chapter How to Report a Bug As I said, this is not a package on its own. Rather @command{gsc} is a collection of scripts for my own use. However, I will be pleased if you will find it useful, and even more pleased if you will send me your suggestions or bug reports. If you decide to do so, write to @email{gray@@gnu.org.ua}. As the purpose of bug reporting is to improve software, please be sure to include maximum information when reporting a bug. The mimimum information needed is: @itemize @item Topmost date from the @file{ChangeLog} file. @item Conditions under which the bug appears. @end itemize @node Copying This Manual, Concept Index, Reporting Bugs, Top @include fdl.texi @node Concept Index, , Copying This Manual, Top @comment node-name, next, previous, up @unnumbered Concept Index This is a general index of all issues discussed in this manual @printindex cp @bye Local Variables: compile-command: "makeinfo -DPROOF gsc.texi" End: