<schema prefix="Zope2.Startup.datatypes"
        datatype=".root_config"
        handler="root_handler"
        extends="wsgischema.xml">

  <!-- type definitions -->

  <import package="tempstorage" condition="tempstorage"/>
  <import package="ZServer"/>
  <import package="ZServer.Zope2.Startup" file="warnfilter.xml"/>

  <sectiontype name="cgi-environment"
               datatype=".cgi_environment"
               keytype="identifier">
    <description>
     A section which allows you to define simple key-value pairs which
     will extend the CGI environment variables exposed by ZServer.
    </description>
    <key name="+" attribute="environ">
      <description>
        Use any key/value pair, e.g. 'HTTPS_PORT 443'
      </description>
    </key>
  </sectiontype>

  <sectiontype name="zoperunner">
    <description>
      This section describes the options for zopectl.  These options
      have no default value specified in the schema; in some cases,
      zopectl calculates a dynamic default, in others, the feature
      associated with the option is disabled.

      For those options that also have corresponding command-line
      options, the command line option (short and long form) are given
      here too.
    </description>

    <multikey name="program" required="no">
      <description>
       The program(s) that will be run by the runner
      </description>
    </multikey>

    <key name="daemon" datatype="boolean"
         required="no" default="true">
      <description>
        Command-line option: -d or --daemon.

        If this option is true, zdrun.py runs in the background as a
        true daemon.  It forks an child process which becomes the
        subprocess manager, while the parent exits (making the shell
        that started it believe it is done).  The child process also
        does the following:

        - if the directory option is set, change into that directory

        - redirect stdin, stdout and stderr to /dev/null

        - call setsid() so it becomes a session leader

        - call umask(022)
      </description>
    </key>

    <key name="backoff-limit" datatype="integer"
         required="no" default="10">
      <description>
        Command-line option: -b or --backoff-limit.

        When the subprocess crashes, zdrun.py inserts a one-second
        delay before it restarts it.  When the subprocess crashes
        again right away, the delay is incremented by one second, and
        so on.  What happens when the delay has reached the value of
        backoff-limit (in seconds), depends on the value of the
        forever option.  If forever is false, zdrun.py gives up at
        this point, and exits.  An always-crashing subprocess will
        have been restarted exactly backoff-limit times in this case.
        If forever is true, zdrun.py continues to attempt to restart
        the process, keeping the delay at backoff-limit seconds.

        If the subprocess stays up for more than backoff-limit
        seconds, the delay is reset to 1 second.
      </description>
    </key>

    <key name="forever" datatype="boolean"
         required="no" default="false">
      <description>
        Command-line option: -f or --forever.

        If this option is true, zdrun.py will keep restarting a
        crashing subprocess forever.  If it is false, it will give up
        after backoff-limit crashes in a row.  See the description of
        backoff-limit for details.
      </description>
    </key>

    <key name="user" datatype="string"
         required="no">
      <description>
        Command-line option: -u or --user.

        When zdrun.py is started by root, this option specifies the
        user as who the the zdrun.py process (and hence the daemon
        subprocess) will run.  This can be a user name or a numeric
        user id.  Both the user and the group are set from the
        corresponding password entry, using setuid() and setgid().
        This is done before zdrun.py does anything else besides
        parsing its command line arguments.

        NOTE: when zdrun.py is not started by root, specifying this
        option is an error.  (XXX This may be a mistake.)

        XXX The zdrun.py event log file may be opened *before*
        setuid() is called.  Is this good or bad?
      </description>
    </key>

    <key name="hang-around" datatype="boolean"
         required="no" default="false">
      <description>
        If this option is true, the zdrun.py process will remain even
        when the daemon subprocess is stopped.  In this case, zopectl
        will restart zdrun.py as necessary.  If this option is false,
        zdrun.py will exit when the daemon subprocess is stopped
        (unless zdrun.py intends to restart it).
      </description>
    </key>

    <key name="umask" datatype="zdaemon.zdoptions.octal_type"
         required="no"
         default="022">
      <description>
        Command-line option: -m or --umask.

        When daemon mode is used, this option specifies the octal umask
        of the subprocess.
      </description>
    </key>

    <key name="default-to-interactive" datatype="boolean"
         required="no" default="true">
      <description>
        If this option is true, zopectl enters interactive mode
        when it is invoked without a positional command argument.  If
        it is false, you must use the -i or --interactive command line
        option to zopectl to enter interactive mode.
      </description>
    </key>

    <key name="prompt" datatype="string"
         required="no" default="zopectl>">
       <description>
         The prompt shown by zopectl program.
       </description>
    </key>

    <key name="socket-name" datatype="existing-dirpath" required="no">
      <description>
        Command-line option: -s or --socket-name.

        The pathname of the Unix domain socket used for communication
        between zopectl.py and zdrun.py.  The default is relative to the
        current directory in which zdctl.py and zdrun.py are started.
        You want to specify an absolute pathname here.
      </description>
    </key>

  </sectiontype>

  <!-- end of type definitions -->

  <!-- schema begins  -->

  <multisection type="warnfilter" name="*" attribute="warnfilters">
    <!-- from zLOG -->
    <description>
    A multisection which allows a user to set up a Python "warning" filter.
    The following keys are valid within a warnfilter section:

      action:  one of the following strings:

           "error"   turn matching warnings into exceptions
           "ignore"  never print matching warnings
           "always"  always print matching warnings
           "default" print the first occurrence of matching warnings
                     for each location where the warning is issued
           "module"  print the first occurrence of matching warnings
                     for each module where the warning is issued
           "once"    print only the first occurrence of matching
                     warnings, regardless of location

      message:  a string containing a regular expression that the
                warning message must match (the match is compiled to
                always be case-insensitive)

      category: a Python dotted-path classname (must be a subclass of
                Warning) of which the warning category must be a subclass in
                order to match

      module:   a string containing a regular expression that the
                module name must match (the match is compiled to be
                case-sensitive)

      lineno:   an integer that the line number where the warning
                occurred must match, or 0 to match all line numbers
    </description>
  </multisection>

  <multikey name="products" datatype="existing-directory">
    <description>
      This specifies a product directory which is added to Products.__path__.
      Directories are added in the order in which they are specified.
    </description>
    <metadefault></metadefault>
  </multikey>

  <key name="extensions" datatype="existing-directory">
    <description>
      This provides a path to an Extensions directory.
    </description>
    <metadefault></metadefault>
  </key>
  
  <multikey name="path" datatype="string">
    <description>
      This specifies additional paths directories which are inserted into
      the beginning of Python's module search path.
    </description>
    <metadefault></metadefault>
  </multikey>

  <key name="pid-filename" datatype="existing-dirpath">
    <description>
      The full path to which the Zope process will write its
      OS process id at startup.
    </description>
    <metadefault>$clienthome/Z2.pid</metadefault>
  </key>

  <key name="lock-filename" datatype="existing-dirpath">
    <description>
      The full path to a file which the Zope process will attempt to lock
      at startup (used to signal to other processes that this Zope instance is
      currently running).
    </description>
    <metadefault>$clienthome/Z2.lock</metadefault>
  </key>

  <key name="effective-user">
    <description>
     If you intend to run Zope as the "root" user, you must supply this
     directive with an effective username or userid number to which Zope
     will 'suid' after the server ports are bound. This directive only
     has effect under UNIX and if Zope is started as the root user.
    </description>
    <metadefault>unset</metadefault>
  </key>

  <key name="enable-product-installation" datatype="boolean" default="off">
    <description>
     BBB Zope 5.0: This directive has no effect anymore.
    </description>
    <metadefault>off</metadefault>
  </key>

  <key name="zserver-threads" datatype="integer" default="2">
     <description>
     Specify the number of threads that Zope's ZServer web server will use
     to service requests. The default is 2.
    </description>
    <metadefault>2</metadefault>
  </key>

  <key name="zserver-read-only-mode" datatype="boolean" default="off">
    <description>
      If this variable is set, then the server will not create or write
      to any log, pid, or lock files when running.  Note that this option
      does *not* govern opening storages in read-only mode:  for that
      use, please use the appropriate flag in the section which configures
      each storage.
    </description>
  </key>

  <section type="cgi-environment" attribute="cgi_environment" name="*">
    <description>
     A section which allows a user to define arbitrary key-value pairs for
     use as the initial CGI environment variables. This setting is useful
     when you want to proxy requests from another web server to Zserver,
     and would like Zserver's CGI environment to reflect the CGI
     environment of the other web server.
    </description>
  </section>

  <key name="cgi-maxlen" default="0" handler="cgi_maxlen" datatype="integer">
    <description>
     Set the cgi.maxlen parameter to limit the number of data passed to
     cgi.escape(). This is helpful to prevent DoS attacks. Set the parameter
     to 0 for no restrictions.
    </description>
  </key>

  <key name="http-header-max-length" default="8192" handler="http_header_max_length" datatype="integer">
    <description>
     Maximum size of received HTTP header being processed by Zope
    </description>
  </key>

  <key name="enable-ms-public-header" datatype="boolean" handler="enable_ms_public_header" default="off">
     <description>
     Set this directive to 'on' to enable sending the "Public" header
     in response to an WebDAV OPTIONS request.

     Though recent WebDAV drafts mention this header, the original
     WebDAV RFC did not mention it as part of the standard. Very few
     web servers out there include this header in their replies, most
     notably IIS and Netscape Enterprise 3.6.

     Since many best practices documents out in the web mention
     turning off this header with the subject of "Mask Your Web Server
     For Enhanced Security", this setting is off by
     default. Presumably malicious people might take the presence of
     this header as indication of an IIS Web Server and try to attack
     your site, so be careful when turning it on.

     Recent versions of Microsoft Web Folders, updated after January
     2005, *do* require this header to be present in reply to the
     OPTIONS WebDAV request.
     (http://www.redmountainsw.com/wordpress/archives/webfolders-zope)

     To get a recent Microsoft Web Folders implementation, refer to
     Microsoft KB Article 907306.
     (Software Update for Web Folders: May 18, 2007).
     </description>
     <metadefault>off</metadefault>
  </key>

  <key name="dns-server" datatype=".dns_resolver" attribute="dns_resolver">
    <description>
     Specify the IP address of your DNS server in order to cause resolved
     hostnames to be written to Zope's access log. By default, Zope will
     not resolve hostnames unless this is set.
    </description>
  </key>

  <key name="ip-address" datatype="ipaddr-or-hostname">
    <description>
     The default IP address on which Zope's various server protocol
     implementations will listen for requests. If this is unset, Zope
     will listen on all IP addresses supported by the machine.
    </description>
  </key>

  <key name="maximum-number-of-session-objects" datatype="integer"
       default="1000" handler="maximum_number_of_session_objects">
     <description>
     An integer value representing the number of items to use as a
     "maximum number of subobjects" value of the
     '/temp_folder/session_data' transient object container within
     Zope's object database.
     </description>
     <metadefault>1000</metadefault>
  </key>

  <key name="session-add-notify-script-path"
       handler="session_add_notify_script_path">
     <description>
     An optional full Zope path name of a callable object to be set as the
     "script to call on object addition" of the session_data transient
     object container created in the '/temp_folder' folder at startup.
     </description>
     <metadefault>unset</metadefault>
  </key>

  <key name="session-delete-notify-script-path"
       handler="session_add_notify_script_path">
     <description>
     An optional full Zope path name of a callable object to be set as the
     "script to call on object deletion" of the sessioN_data transient
     object container created in the /temp_folder folder at startup.
     </description>
     <metadefault>unset</metadefault>
  </key>

  <key name="session-timeout-minutes" datatype="integer"
       default="20" handler="session_timeout_minutes">
     <description>
     An integer value representing the number of minutes to be used as the
     "data object timeout" of the '/temp_folder/session_data' transient
     object container in Zope's object database.
     </description>
     <metadefault>20</metadefault>
  </key>

  <key name="session-resolution-seconds" datatype="integer"
       default="20">
     <description>
     An integer value representing the number of seconds to be used as the
     "timeout resolution" of the '/temp_folder/session_data' transient
     object container in Zope's object database.
     </description>
     <metadefault>20</metadefault>
  </key>

  <key name="max-listen-sockets" datatype="integer"
       default="1000">
     <description>
       The maximum number of sockets that ZServer will attempt to open
       in order to service incoming connections.
     </description>
  </key>

  <key name="large-file-threshold" datatype="byte-size"
       handler="large_file_threshold" default="512KB">
     <description>
       Requests bigger than this size get saved into a temporary file
       instead of being read completely into memory.
     </description>
  </key>

  <multisection type="ZServer.server" name="*" attribute="servers"/>

  <key name="port-base" datatype="integer" default="0">
    <description>
      Base port number that gets added to the specific port numbers
      specified for the individual servers.
    </description>
  </key>

  <section type="zoperunner" name="*" attribute="runner"/>

  <key name="python" datatype="existing-path"
       required="no">
    <description>
      Path to the Python interpreter for use by zdaemon.
      Defaults to sys.executable.
      Needed for buildout-based instances to supply a python
      that has all the correct eggs on the path.
    </description>
  </key>

</schema>