Provided by: libnet-daemon-perl_0.49-2_all bug

NAME

       Net::Daemon - Perl extension for portable daemons

SYNOPSIS

         # Create a subclass of Net::Daemon
         require Net::Daemon;
         package MyDaemon;
         @MyDaemon::ISA = qw(Net::Daemon);

         sub Run ($) {
           # This function does the real work; it is invoked whenever a
           # new connection is made.
         }

DESCRIPTION

       Net::Daemon is an abstract base class for implementing portable server applications in a very simple way.
       The module is designed for Perl 5.005 and threads, but can work with fork() and Perl 5.004.

       The Net::Daemon class offers methods for the most common tasks a daemon needs: Starting up, logging,
       accepting clients, authorization, restricting its own environment for security and doing the true work.
       You only have to override those methods that aren't appropriate for you, but typically inheriting will
       safe you a lot of work anyways.

   Constructors
         $server = Net::Daemon->new($attr, $options);

         $connection = $server->Clone($socket);

       Two constructors are available: The new method is called upon startup and creates an object that will
       basically act as an anchor over the complete program. It supports command line parsing via Getopt::Long
       (3).

       Arguments of new are $attr, an hash ref of attributes (see below) and $options an array ref of options,
       typically command line arguments (for example \@ARGV) that will be passed to Getopt::Long::GetOptions.

       The second constructor is Clone: It is called whenever a client connects. It receives the main server
       object as input and returns a new object. This new object will be passed to the methods that finally do
       the true work of communicating with the client. Communication occurs over the socket $socket, Clone's
       argument.

       Possible object attributes and the corresponding command line arguments are:

       catchint (--nocatchint)
           On some systems, in particular Solaris, the functions accept(), read() and so on are not safe against
           interrupts  by  signals.  For  example, if the user raises a USR1 signal (as typically used to reread
           config files), then the function returns an error EINTR.  If the catchint option is on (by default it
           is, use --nocatchint to turn this off), then the package will ignore EINTR errors whereever possible.

       chroot (--chroot=dir)
           (UNIX only)  After doing a bind(), change root directory to the given directory by doing a  chroot().
           This  is  usefull  for  security  operations,  but  it  restricts programming a lot. For example, you
           typically have to load external Perl extensions before doing a chroot(), or you need to  create  hard
           links  to  Unix  sockets. This is typically done in the config file, see the --configfile option. See
           also the --group and --user options.

           If you don't know chroot(), think of an FTP server where you can see a certain  directory  tree  only
           after logging in.

       clients
           An  array  ref  with  a  list of clients. Clients are hash refs, the attributes accept (0 for denying
           access and 1 for permitting) and mask, a Perl regular expression for the clients  IP  number  or  its
           host name. See "Access control" below.

       configfile (--configfile=file)
           Net::Daemon  supports  the  use of config files. These files are assumed to contain a single hash ref
           that overrides the arguments of the  new  method.  However,  command  line  arguments  in  turn  take
           precedence over the config file. See the "Config File" section below for details on the config file.

       debug (--debug)
           Turn debugging mode on. Mainly this asserts that logging messages of level "debug" are created.

       facility (--facility=mode)
           (UNIX only) Facility to use for Sys::Syslog (3). The default is daemon.

       group (--group=gid)
           After  doing  a bind(), change the real and effective GID to the given.  This is usefull, if you want
           your server to bind to a privileged port (<1024), but don't want the server to execute as  root.  See
           also the --user option.

           GID's can be passed as group names or numeric values.

       localaddr (--localaddr=ip)
           By  default  a  daemon  is  listening  to  any IP number that a machine has. This attribute allows to
           restrict the server to the given IP number.

       localpath (--localpath=path)
           If you want to restrict your server to local services only, you'll  prefer  using  Unix  sockets,  if
           available.  In  that  case  you  can  use  this  option for setting the path of the Unix socket being
           created.  This option implies --proto=unix.

       localport (--localport=port)
           This attribute sets the port on which the daemon is listening. It must be given somehow,  as  there's
           no default.

       logfile (--logfile=file)
           By default logging messages will be written to the syslog (Unix) or to the event log (Windows NT). On
           other  operating systems you need to specify a log file. The special value "STDERR" forces logging to
           stderr.

       loop-child (--loop-child)
           This option forces creation of a new child for loops. (See the loop-timeout option.) By  default  the
           loops are serialized.

       loop-timeout (--loop-timeout=secs)
           Some  servers need to take an action from time to time. For example the Net::Daemon::Spooler attempts
           to empty its spooling queue every 5 minutes. If this option is set to a positive  value  (zero  being
           the default), then the server will call its Loop method every "loop-timeout" seconds.

           Don't  trust  too  much  on  the  precision  of  the  interval: It depends on a number of factors, in
           particular the execution time of the Loop() method. The loop  is  implemented  by  using  the  select
           function.  If  you  need  an  exact interval, you should better try to use the alarm() function and a
           signal handler. (And don't forget to look at the catchint option!)

           It is recommended to use the loop-child option in conjunction with loop-timeout.

       mode (--mode=modename)
           The Net::Daemon server can run in three different modes, depending on the environment.

           If you are running Perl 5.005 and did compile it for threads, then  the  server  will  create  a  new
           thread  for  each  connection.  The thread will execute the server's Run() method and then terminate.
           This mode is the default, you can force it with "--mode=ithreads" or "--mode=threads".

           If threads are not available, but you have a working fork(), then the server will behave  similar  by
           creating  a  new process for each connection.  This mode will be used automatically in the absence of
           threads or if you use the "--mode=fork" option.

           Finally there's a single-connection mode: If the server has accepted a connection, he will enter  the
           Run()  method.  No other connections are accepted until the Run() method returns. This operation mode
           is useful if you have neither threads nor fork(),  for  example  on  the  Macintosh.   For  debugging
           purposes you can force this mode with "--mode=single".

           When  running  in mode single, you can still handle multiple clients at a time by preforking multiple
           child processes. The number of childs is configured with the option "--childs".

       childs
           Use this parameter to let Net::Daemon run in prefork mode, which means it forks the number of  childs
           processes you give with this parameter, and all child handle connections concurrently. The difference
           to  fork  mode is, that the child processes continue to run after a connection has terminated and are
           able to accept a new connection.  This  is  useful  for  caching  inside  the  childs  process  (e.g.
           DBI::ProxyServer connect_cached attribute)

       options
           Array ref of Command line options that have been passed to the server object via the new method.

       parent
           When  creating an object with Clone the original object becomes the parent of the new object. Objects
           created with new usually don't have a parent, thus this attribute is not set.

       pidfile (--pidfile=file)
           (UNIX only) If this option is present, a PID file will be created at the given location.

       proto (--proto=proto)
           The transport layer to use, by default tcp or unix for a Unix socket.  It  is  not  yet  possible  to
           combine both.

       socket
           The  socket  that  is connected to the client; passed as $client argument to the Clone method. If the
           server object was created with new, this attribute can be undef, as long as  the  Bind  method  isn't
           called.  Sockets are assumed to be IO::Socket objects.

       user (--user=uid)
           After  doing  a bind(), change the real and effective UID to the given.  This is usefull, if you want
           your server to bind to a privileged port (<1024), but don't want the server to execute as  root.  See
           also the --group and the --chroot options.

           UID's can be passed as group names or numeric values.

       version (--version)
           Supresses  startup  of  the  server; instead the version string will be printed and the program exits
           immediately.

       Note that most  of  these  attributes  (facility,  mode,  localaddr,  localport,  pidfile,  version)  are
       meaningfull only at startup. If you set them later, they will be simply ignored. As almost all attributes
       have appropriate defaults, you will typically use the localport attribute only.

   Command Line Parsing
         my $optionsAvailable = Net::Daemon->Options();

         print Net::Daemon->Version(), "\n";

         Net::Daemon->Usage();

       The  Options  method returns a hash ref of possible command line options.  The keys are option names, the
       values are again hash refs with the following keys:

       template
           An option template that can be passed to Getopt::Long::GetOptions.

       description
           A description of this option, as used in Usage

       The Usage method prints a list of all possible options and returns.   It  uses  the  Version  method  for
       printing program name and version.

   Config File
       If the config file option is set in the command line options or in the in the "new" args, then the method

         $server->ReadConfigFile($file, $options, $args)

       is  invoked.  By  default  the  config file is expected to contain Perl source that returns a hash ref of
       options. These options override the "new" args and will in  turn  be  overwritten  by  the  command  line
       options, as present in the $options hash ref.

       A typical config file might look as follows, we use the DBI::ProxyServer as an example:

           # Load external modules; this is not required unless you use
           # the chroot() option.
           #require DBD::mysql;
           #require DBD::CSV;

           {
               # 'chroot' => '/var/dbiproxy',
               'facility' => 'daemon',
               'pidfile' => '/var/dbiproxy/dbiproxy.pid',
               'user' => 'nobody',
               'group' => 'nobody',
               'localport' => '1003',
               'mode' => 'fork'

               # Access control
               'clients' => [
                   # Accept the local
                   {
                       'mask' => '^192\.168\.1\.\d+$',
                       'accept' => 1
                   },
                   # Accept myhost.company.com
                   {
                       'mask' => '^myhost\.company\.com$',
                       'accept' => 1
                   }
                   # Deny everything else
                   {
                       'mask' => '.*',
                       'accept' => 0
                   }
               ]
           }

   Access control
       The  Net::Daemon  package  supports  a  host  based  access control scheme. By default access is open for
       anyone. However, if you create an attribute $self->{'clients'}, typically in the config file, then access
       control is disabled by default. For any connection the client list is processed: The clients attribute is
       an array ref to a list of hash refs. Any of the hash refs may contain arbitrary attributes, including the
       following:

       mask    A Perl regular expression that has to match the clients IP number or its host name. The  list  is
               processed  from the left to the right, whenever a 'mask' attribute matches, then the related hash
               ref is choosen as client and processing the client list stops.

       accept  This may be set to true or  false  (default  when  omitting  the  attribute),  the  former  means
               accepting the client.

   Event logging
         $server->Log($level, $format, @args);
         $server->Debug($format, @args);
         $server->Error($format, @args);
         $server->Fatal($format, @args);

       The  Log  method  is an interface to Sys::Syslog (3) or Win32::EventLog (3). It's arguments are $level, a
       syslog level like debug, notice or err, a format string in the style of printf  and  the  format  strings
       arguments.

       The  Debug  and Error methods are shorthands for calling Log with a level of debug and err, respectively.
       The Fatal method is like Error, except it additionally throws the given message as exception.

       See Net::Daemon::Log(3) for details.

   Flow of control
         $server->Bind();
         # The following inside Bind():
         if ($connection->Accept()) {
             $connection->Run();
         } else {
             $connection->Log('err', 'Connection refused');
         }

       The Bind method is called by the application when the server should start. Typically  this  can  be  done
       right after creating the server object $server. Bind usually never returns, except in case of errors.

       When  a  client connects, the server uses Clone to derive a connection object $connection from the server
       object. A new thread or process is created that uses the connection object to call  your  classes  Accept
       method. This method is intended for host authorization and should return either FALSE (refuse the client)
       or TRUE (accept the client).

       If  the  client  is accepted, the Run method is called which does the true work. The connection is closed
       when Run returns and the corresponding thread or process exits.

   Error Handling
       All methods are supposed to throw Perl exceptions in case of errors.

MULTITHREADING CONSIDERATIONS

       All methods are working with lexically scoped data and handle data only, the exception being the  OpenLog
       method  which  is  invoked  before threading starts. Thus you are safe as long as you don't share handles
       between threads. I strongly recommend that your application behaves similar. (This doesn't apply to  mode
       'ithreads'.)

EXAMPLE

       As  an  example  we'll  write  a  simple  calculator server. After connecting to this server you may type
       expressions, one per line. The server evaluates the expressions and prints the result. (Note this  is  an
       example, in real life we'd never implement such a security hole. :-)

       For  the  purpose  of  example  we  add  a command line option --base that takes 'hex', 'oct' or 'dec' as
       values: The servers output will use the given base.

         # -*- perl -*-
         #
         # Calculator server
         #
         use strict;

         require Net::Daemon;

         package Calculator;

         our $VERSION = '0.01';
         our @ISA = qw(Net::Daemon); # to inherit from Net::Daemon

         sub Version ($) { 'Calculator Example Server, 0.01'; }

         # Add a command line option "--base"
         sub Options ($) {
             my($self) = @_;
             my($options) = $self->SUPER::Options();
             $options->{'base'} = { 'template' => 'base=s',
                                    'description' => '--base                  '
                                           . 'dec (default), hex or oct'
                                     };
             $options;
         }

         # Treat command line option in the constructor
         sub new ($$;$) {
             my($class, $attr, $args) = @_;
             my($self) = $class->SUPER::new($attr, $args);
             if ($self->{'parent'}) {
                 # Called via Clone()
                 $self->{'base'} = $self->{'parent'}->{'base'};
             } else {
                 # Initial call
                 if ($self->{'options'}  &&  $self->{'options'}->{'base'}) {
                     $self->{'base'} = $self->{'options'}->{'base'}
                 }
             }
             if (!$self->{'base'}) {
                 $self->{'base'} = 'dec';
             }
             $self;
         }

         sub Run ($) {
             my($self) = @_;
             my($line, $sock);
             $sock = $self->{'socket'};
             while (1) {
                 if (!defined($line = $sock->getline())) {
                     if ($sock->error()) {
                         $self->Error("Client connection error %s",
                                      $sock->error());
                     }
                     $sock->close();
                     return;
                 }
                 $line =~ s/\s+$//; # Remove CRLF
                 my($result) = eval $line;
                 my($rc);
                 if ($self->{'base'} eq 'hex') {
                     $rc = printf $sock ("%x\n", $result);
                 } elsif ($self->{'base'} eq 'oct') {
                     $rc = printf $sock ("%o\n", $result);
                 } else {
                     $rc = printf $sock ("%d\n", $result);
                 }
                 if (!$rc) {
                     $self->Error("Client connection error %s",
                                  $sock->error());
                     $sock->close();
                     return;
                 }
             }
         }

         package main;

         my $server = Calculator->new({'pidfile' => 'none',
                                       'localport' => 2000}, \@ARGV);
         $server->Bind();

KNOWN PROBLEMS

       Most, or even any, known problems are related to the Sys::Syslog module which  is  by  default  used  for
       logging events under Unix. I'll quote some examples:

       Usage: Sys::Syslog::_PATH_LOG at ...
           This problem is treated in perl bug 20000712.003. A workaround is changing line 277 of Syslog.pm to

             my $syslog = &_PATH_LOG() || croak "_PATH_LOG not found in syslog.ph";

AUTHOR AND COPYRIGHT

         Net::Daemon is Copyright (C) 1998, Jochen Wiedmann
                                            Am Eisteich 9
                                            72555 Metzingen
                                            Germany

                                            Phone: +49 7123 14887
                                            Email: joe@ispsoft.de

         All rights reserved.

         You may distribute this package under the terms of either the GNU
         General Public License or the Artistic License, as specified in the
         Perl README file.

SEE ALSO

       RPC::pServer(3), Netserver::Generic(3), Net::Daemon::Log(3), Net::Daemon::Test(3)

perl v5.36.0                                       2022-10-13                                   Net::Daemon(3pm)