1. Installation
	
	
		1.1 Prerequisites
		
		Running 
JWhoisServer requires:
		
			- 
				Java Runtime: Developed using openjdk and java 1.6/6.0.
				The server should run with some minor restrictions on java 1.5/5.0. 
				Some (more or less) positive tests with earlier versions have been
				done using gij and other alternative VMs.
			
- 
				log4j java library
			
- 
				mysql-java-connector and / or jdbc drivers for the other supported RDBMS
			
- 
				Optional: if you intend to use velocity templates or if your building JWhoisServer from source, 
				you will have to install velocity (version 1.5 or greater) and the jars required by velocity 
				(min: commons-collections-*.jar and commons-lang-*.jar);
			
- 
				whois - client (whois, jwhois, ...)
			
		Building 
JWhoisServer from source additionally requires:
		
			- Java compiler (since version 0.3.0.0 jdk 1.5 is required)
- ant make tool (min. version 1.7)
- velocity and the dependent stuff
		To install this all on a debian system, run:
		
			apt-get install mysql-server velocity liblog4j1.2-java libmysql-java whois
			apt-get install ant openjdk-7-jdk
		
	 
	
	
	
	
	
	
		1.2 GnuPG / PGP Key
		
		All files released are signed using my sf.net GnuPG key.
		
		In order to verify the integrity of the files downloaded, you should import the key:
		
gpg --keyserver subkeys.pgp.net --recv-key ED7D414C
		or
		
wget -O - http://jwhoisserver.net/key.asc | gpg --import -
	 
	
	
	
	
	
	
		1.3 Installation From Source
		
		Download the source-file 
JWhoisServer-VERSION-src.tar.gz
		
		You may download the signature for the file and verify it:
		
gpg --verify JWhoisServer-VERSION-src.tar.gz.asc JWhoisServer-VERSION-src.tar.gz
		
		Extract the source package:
		
tar xvz -f JWhoisServer-VERSION-src.tar.gz
		Change working directory into the 
build 
		of the extracted source directory:
		
cd JWhoisServer-VERSION/build
		Use the following command to get some help about how to configure the right
		classpath and install-dirs:
		
ant help-classpath
ant help-install
		
		A comfortably way to configure some parameters may be to edit the file
		
build.properties or to pass them to the 
ant 
		invocation.
		
		Build and install:
		
ant -Dpackage.log4j.jar=/usr/share/java/log4j.jar \
	-Dpackage.jdbc.jar=/usr/share/java/mysql-connector.jar \
	-Dpackage.velocity.jar=/usr/share/java/velocitylibs/velocity-1.6.2/velocity-1.6.2.jar \
	-Dpackage.velocity.deps=/usr/share/java/velocitylibs/velocity-1.6.2/velocity-1.6.2-dep.jar \
	-Dpackage.installdir.etc=/etc/jwhoisserver \
	-Dpackage.installdir.init=/etc/init.d \
	jar install
		
		If you like to use for example postgreSQL instead of mysql, you must point the 
package.jdbc.jar
		property to the jdbc-jar for pgsql:
		
ant -Dpackage.log4j.jar=/usr/share/java/log4j.jar \
	-Dpackage.jdbc.jar=/usr/share/java/postgresql.jar \
	-Dpackage.velocity.jar=/usr/share/java/velocitylibs/velocity-1.6.2/velocity-1.6.2.jar \
	-Dpackage.velocity.deps=/usr/share/java/velocitylibs/velocity-1.6.2/velocity-1.6.2-dep.jar \
	-Dpackage.installdir.etc=/etc/jwhoisserver \
	-Dpackage.installdir.init=/etc/init.d \
	jar install
		
		Remark that the 
install target requires 
root privileges!
	
 
	
	
	
	
	
	
	
	
		1.4 Installation using .deb-Packages
		
		The debian packages are tested with 
debian lenny, 
debian squeeze and 
ubuntu 9.10
		
		Since version 
0.4.0.3 there exists 4 debian packages:
		
			- jwhoisserver_VERSION_all.deb containing the server
- jwhoisserver-tools_VERSION_all.deb containing the additional command-line tools
- libjwhoisserver-utils-java_VERSION_all.deb containing common stuff required by the server and the tools
- libjwhoisserver-utils-java-doc_VERSION_all.deb containing some documentation
		(in version 
0.3.3.0 the 
jwhoisserver-utils package was renamed to 
libjwhoisserver-utils-java)
		
		 
		
		In order to verify the signatures, please import the key:
		
		
gpg --export --armor ED7D414C | apt-key add - ;
		
		As a convenient and easy option for installation and updates, we provide a experimental deb repository for 
		
JWhoisServer.
		
		Add the line 
deb http://repo.jwhoisserver.net/deb ./ to the file
		
/etc/apt/sources.list in order to use the repository.
		
		
		Install required packages:
		
aptitude install debconf liblog4j1.2-java libmysql-java sun-java6-jre whois debianutils dbconfig-common
		If you like 
JWhoisServer to use a local mysql database, you will have 
		to install 
mysql-server:
		
aptitude install mysql-server
		If you like to use 
velocity, you will have to install velocity:
		
aptitude install velocity
		
			WARNING: debian lenny has only velocity version 1.4, but JWhoisServer requires min. 1.5!
			You may download the 
original libs and adjust the CLASSPATH in /etc/defaults/jwhoisserver
			or use the packages from squeeze/sid using apts pinning feature. 
		
 
		Download the .deb-packages for the server and the utils and install it:
		
dpkg -i libjwhoisserver-utils-java_VERSION_all.deb
dpkg -i jwhoisserver_VERSION_all.deb
		or install from the repository:
		
aptitude install jwhoisserver
		If you decide to use a local database answer yes to the question if 
		
dbconfig should automatically configure the database!
		
		Additionally you may install the tools:
		
dpkg -i jwhoisserver-tools_VERSION_all.deb
		or
		
aptitude install jwhoisserver-tools
	 
	
	
	
	
	
	
	
	
		1.5 Installation using .rpm-Packages
		
		Install all required software using your favourite package manager before you 
		install 
JWhoisServer!
		
		At the moment we supply RPMs for 
opensuse and 
fedora.
		
		If not yet done, import the key for RPM:
		
rpm --import http://jwhoisserver.net/key.asc
		
		Download the .rpm-packages matching your distribution, verify and install them:
		
rpm --checksig  jwhoisserver*-VERSION-RELEASE*.rpm
rpm -i jwhoisserver-utils-VERSION-RELEASE.noarch.rpm
rpm -i jwhoisserver-VERSION-RELEASE.noarch.rpm
		Additionally you may like to install the tools:
		
rpm -i jwhoisserver-tools-VERSION-RELEASE.noarch.rpm
		
		
			1.5.1 OpenSUSE .rpm-Packages
			
			You may like to add the OpenSUSE YUM repository for JWhoisServer to YAST.
			
 
			Use 
http://repo.jwhoisserver.net/opensuse/ as the URL for the repository.
			
			After doing this, you can install and update JWhoisServer using YAST.
		
 
		
			1.5.2 Fedora .rpm-Packages
			
			In order to use YUM to install JWhoisServer, you should add the YUM repository for Fedora to the repository list.
			
			
/etc/yum.repos.d/jwhoisserver.repo
			[jwhoisserver]
name=JWhoisServer YUM repository
baseurl=http://repo.jwhoisserver.net/fedora/
enabled=1
gpgcheck=1
gpgkey=http://jwhoisserver.net/key.asc
			Then you can run:
			
yum update;
yum install jwhoisserver jwhoisserver-tools;
		 
	 
	
	
	
	
	
	
		1.6 Installation of the .jar from a maven repository
		
		We provide a small maven repository holding the current version of JWhoisServer as a JAR file containing
		the server and the utils.
		
		Use 
http://repo.jwhoisserver.net/m2/ as the URL for the repository.
		
		The coresponding parts of a 
pom.xml may look like this:
		
		
<repositories>
	<repository>
		<id>jwhoisserver</id>
		<url>http://repo.jwhoisserver.net/m2/</url>
	</repository>
</repositories>
<dependencies>
	<dependency>
		<groupId>net.jwhoisserver</groupId>
		<artifactId>jwhoisserver</artifactId>
		<version>0.3.3.0</version>
	</dependency>
</dependencies>
	For versions prior to 0.3.3.0, use JWhoisServer as artifactId!
	
 
	
	
	
	
	
	
		1.7 Installation on Microsoft Windows using the installer
		
		The provided installer has to be considert as 
beta.
		
		The installer has been tested on Windows XP Pro and Windows 7 Enterprise x64.
		
		After installation you will have to configure the server (and the Database)
		and set the registered service to autostart if desired.
	
 
	
	
	
	
	
	
		1.8 Upgrade
		
		If you installed the 
.deb-package and choose to let dbconfig do the work for you
		this step is obsolete for you, so please skip it!
		
		If you upgrade 
JWhoisServer from a previous version take a look at the
		
sql-directory for files named 
		
update_$version.sql.
		
		
$version refers to the current 
		version of 
JWhoisServer. 
		
		So if you upgrade from 
0.2.0.0 to 
0.3.0.0
		you will have to apply the script 
		
update_0.3.0.0.sql.
		
mysql -u root -p jwhoisserver < update_0.3.0.0.sql
		
		Multiple update-files have to be applied in sequential order starting
		from the lowest version.
		
		The required SQL-scripts may be found at different locations depending on the 
		installation type:
		
			
				| SRC | sql directory of the extracted source | 
			
				| DEB | /usr/share/doc/jwhoisserver/ | 
			
				| RPM | /usr/share/doc/packages/jwhoisserver/ | 
		
	 
	
 
	2. Configure Database
	
	JWhoisServer uses a mysql database as storage backend.
	This requires some additional configuration steps.
	The description provided here assume that the database will be installed on the same
	host running 
JWhoisServer, but you can use a mysql-database running on a remote host.
	
	
		2.1 Create Database and User
		
		If you installed the 
.deb-package and choose to let dbconfig do the work for you
		this step is obsolete for you, so please skip it.
		
		The required SQL-scripts may be found at different locations depending on the 
		installation type:
		
			
				| SRC | sql directory of the extracted source | 
			
				| DEB | /usr/share/doc/jwhoisserver/sql/ | 
			
				| RPM | /usr/share/doc/packages/jwhoisserver/sql/ | 
		
		The default scripts are for 
mysql. For different DB-types you may find the scripts in the
		subdirectories or tgz-archives named according to the DB-type, but this scripts may be incomplete.
		
		Here a short description of the SQL-scripts:
		
			- 
				db.sql: create database
			
- 
				user.sql: create user 
					(you may like to edit this file to create the user with a different 
					password)
			
- 
				struct.sql: database structure (create tables)
			
- 
				data.sql: basic data
			
- 
				optional: test.sql: simple dataset to run first tests
			
- 
				optional: droptables.sql: erase all tables from DB
			
- 
				optional: collate.sql: set charset and collation to UTF8
			
		
		To create the database, user and table use the following commands:
		
mysql -u root -p < db.sql
mysql -u root -p < user.sql
mysql -u root -p jwhoisserver < struct.sql
mysql -u root -p jwhoisserver < data.sql
		
		
		To insert a small dataset for testing, read in 
test.sql
		mysql -u root -p jwhoisserver < test.sql
	 
	
	
	
	
	
	
		2.2 Configure DB-Settings for JWhoisServer
		
		To configure 
JWhoisServer to use the current created database edit the
		configuration file (default: 
/etc/jwhoisserver/server.cfg)
		and adjust the following settings if required (the values shown here are the defaults):
		
db.type=mysql
db.host=localhost
db.port=
db.name=jwhoisserver
db.user=jwhoisserver
db.pass=jwhois
		
		For additional settings see: 
server.cfg or 
sample.cfg
	 
	
 
	3. Start and Test it ...
	
	First test if 
JWhoisServer is configured right by starting 
	
JWhoisServer as user 
root
	(if you have installed 
JWhoisServer from source and configured an non-standard
	bin-directory, you may need to invoke 
jwhoisserver 
	using the full path):
	
jwhoisserver
	If the server starts fine, try your first query:
	
whois -h localhost -- test.tld
	
	
	
		3.1 init-script for jwhoisserver
		
		If every thing works, you may use the init-script 
		
/etc/init.d/jwhoisserver to start and control 
JWhoisServer:
		
# /etc/init.d/jwhoisserver 
Usage: /etc/init.d/jwhoisserver {start|stop|restart|force-reload|status|stats|statistics}
		
		status and 
stats|statistics
		require a 
whois-client in 
PATH
	 
	
	
	
	
	
	
		3.2 Command Line Arguments for jwhoisserver
		
		Command-Line arguments understood by 
JWhoisServer:
		
# jwhoisserver -?
Java Whois Server 0.4.1.3
(c) 2006 - 2015 Klaus Zerwes zero-sys.net
Syntax: 
 jwhoisserver [-h|-?] [-L] [-V] [-p|-j]
 jwhoisserver [-v|-d|-s|-q] [-c cfg [-c cfg [...]]] [-l lcgf] [-P p=v [-P p=v]]
        -c cfg  run using configuration from file cfg
                instead of the default: /etc/jwhoisserver/server.cfg
                this option may be repeated several times;
                the  files  will  be read  in the order of occurence 
                on the command line (properties will be replaced)
        -l lcfg run using configuration for log4j from file lcfg
                instead of the default: /etc/jwhoisserver/log4j.cfg
        -P p=v  set the property 'p' to the value 'v'
                this option may be used multiple times
        -d      debug
        -v      verbose
        -s      silent
        -q      quiet
        -h|-?   display help
        -L      display license
        -V      display version
        -p      print configuration
        -j      print a list of supported database types
		
	 
	
	
	
	
	
	
		3.3 Exit Codes of jwhoisserver
		
		
		
			| 0 | OK | 
			| 1 | ERROR: syntax error in invocation (wrong argument / missing parameter / ...) | 
			| 2 | ERROR: connection to the db failed | 
			| 3 | ERROR: unable to open socket | 
			| 4 | ERROR: unsupported db.type | 
			| 5 | ERROR: unsupported db.$DISPLAYOBJ.dspobj | 
			| 6 | ERROR: config file not found or not readable | 
			| 10 | ERROR: wrong server.bind | 
			| 11 | ERROR: wrong server.port | 
			| 12 | ERROR: syntax error at server.stats.allowfrom | 
			| 13 | ERROR: syntax error at server.html.allowfrom | 
			| 14 | ERROR: syntax error at server.shutdown.allowfrom | 
			| 15 | ERROR: db.objectlookupdefault has wrong value(s) | 
			| 17 | ERROR: syntax error at server.stats.numformat | 
			| 18 | ERROR: server.stats.numformat not set | 
			| 19 | ERROR: syntax error for a SimpleDateFormat pattern | 
			| 20 | ERROR: syntax error for the value of fieldlength in the global scope or for a displayobject | 
			| 21 | ERROR: syntax error in config for maxlenght value of a querytype | 
			| 22 | ERROR: syntax error in config for regex value of a querytype | 
			| 23 | ERROR: syntax error in config for lookupallowfrom value of a querytype | 
			| 24 | ERROR: syntax error in config for db.fkey.identify | 
			| 25 | ERROR: syntax error in config for server.loglevel.[connect|main|db] | 
			| 26 | ERROR: syntax error in config for server.buffer | 
			| 27 | ERROR: syntax error in config for server.stats.memconverter | 
			| 28 | ERROR: syntax error in config for server.sotimeout | 
			| 30 | ERROR: sql syntax error while building prepared statements | 
			| 31 | ERROR: missing prepared statement | 
			| 39 | ERROR: syntax error in config for transformquery value of a querytype | 
			| 40 | ERROR: the velocity template dir must exist and be readable if server.velocity.use is true | 
			| 41 | ERROR: init VelocityEngine | 
			| 42 | ERROR: velocitytemplate not found | 
			| 43 | ERROR: velocitytemplate parser error | 
			| 44 | ERROR: velocitytemplate error | 
			| 50 | ERROR: the directory defined in server.dbtypes.dir must exist and be readable | 
			| 51 | ERROR: server.dbtypes.glob syntax error | 
			| 52 | ERROR: DBServerType config file syntax error | 
			| 60 | ERROR: SQL error on trigger statement | 
			| 100 | ERROR: error closing socket on shutdown | 
		
		A up-to-date list may be found in the file 
EXITCODES.txt
	 
	
	
	
	
	
	
		3.4 Syntax of the whois-requests
		
		
$ whois -h localhost -- help
# HELP
# SYNTAX: whois [-h hostname] [-r] [-f] [-T t] key
# -r    suppress recursion in lookups
# -f    generate html-formatted display (maybe restricted access)
# -T t  lookup only for specified type t
#       implemented types:
#          dn|domain    domain (default)
# key   lookup for key
#       special keys:
#           HELP|?    display this help
#           STATUS    display status information
#           STATS     display statistical informations (restricted access)
		
		"implemented types" depend on the configuration of 
JWhoisServer.
		
		since version 0.3.1.0 a new config property is available:
server.clienthelp.adjust
		If this is set to 
true | 1 | yes, the help output send to the client will be adjusted 
		according the ACLs.
		
		Some lookups may be restricted using ACLs. See 
sample.cfg for details.
	
 
	
 
	4. Advanced Configuration
	
	For a complete List of available configuration properties see 
	
sample.cfg and / or the output of
	
jwhoisserver -p
	
	
		4.1 Advanced Configuration
		
		The provided DB-schema is only a sample. 
		In fact 
JWhoisServer may be configured to run on many different
		DB-schemas according to the registrar's DB structure.
		
		
			4.1.1 Configure Display-Objects
			
			JWhoisServer uses so called 
display-objects.
			
			The starting point for configuring 
display-objects is the
			configuration property 
db.objectlist.
			This should contain names of possible display-objects (usually tables).
			To configure multiple 
display-objects use a list separated 
			by the value of 
db.listseparator (default: 
;).
			
			
Example:db.objectlist=domain;person;mntnr;nameserver
			
			Each defined 
display-object may be configured using a subset of properties
			to 
db.$OBJECTNAME:
			
				
					| property | description | example | 
				
					| .table | SQL - table name for object; defaults to $OBJECTNAME | db.domain.table=domain | 
				
					| .key | Name of the key (used for key-queries); defaults to ${table}_key | db.domain.key=domain_key | 
				
					| .qfield | Define the query field for non-key-queries. (defaults to $OBJECTNAME) | db.domain.qfield=domain | 
				
					| .transformquery | if .objectlookup is configured,
						transform the request (default: to lower case) 
							to lower case: -1 lower lowercase tolower tolowercase uncapitalize uncapitalizedto upper case: 1 upper uppercase toupper touppercase capitalize capitalizeddo nothing: 0 ignore keep leave untouched | db.domain.domain=lower | 
				
					| .display | SQL - field-list used to display this object separated by db.listseparator.
						(defaults to $OBJECTNAME)
						The key will always be included in the query, he output is configurable by 
						.handleprefix | db.domain.display=domain;mntnr_fkey;changed | 
				
					| .displayshort | SQL - field - list used to generate a "non-recursive"
						display of this object separated by 
						db.listseparator.
						If not configured, .display
						will be used.
						This will be used to generate the display for non-recursive lookups. | domain;'active' AS status | 
				
					| .handleprefix | String as prefix for key to generate unique handle;
						If this property is set (even if it is a empty string)
						the key of the object will be displayed prefixed by the 
						value of the property. If the property is not configured,
						the key will be excluded from the output. | db.domain.handleprefix=DMN | 
				
					| .objectlookup | If this object should be a lookup-object 
						(selectable via -T), configure a list of
						lookup definitions separated by 
						db.listseparator | db.domain.objectlookup=domain;dn | 
				
					| .lookupallowfrom | If this object is configured as a lookup 
						and you like to restrict access to this lookup - type,
						list the IPs/networks allowed here separated by
						db.listseparator.
						IPs/networks may be single host or networks in CIDR (/25) or dotted decimals notation. | db.person.lookupallowfrom=10.10.10.101;192.168.2.0/24 | 
				
					| .match | If this object is configured as a lookup 
						you may like to define a regular expression
						to match a lookup. | db.domain.match=
^[a-z0-9]?+tld$ | 
				
					| .maxlength | Maximum allowed length of a lookup. | db.domain.maxlength=255 | 
				
					| .match.errorstring | String to be displayed as a error message if a lookup fails to match 
						defined regular expression. | db.domain.match.errorstring=ERROR\r\n | 
				
					| .parent.$PARENTOBJECTNAME | Define a SINGLE fieldname that will be used as a
						foreign key for the display-object $OBJECTNAME.
						The data will be displayed inline, that means
						instead of the defined field using a non-key-query
						on the object $PARENTOBJECTNAME. | db.domain.parent.nameserver=domain_fkey | 
				
					| .recursecondition | Define a SINGLE fieldname. The field will be added to the query for
						$OBJECTNAME and if the value for the field will not evaluate
						to "true" or 1 recursion will be disabled. | db.domain.recursecondition=publicviewabledata | 
				
					| .recurse.$RECURSEOBJECTNAME | Define a list of fields; Each field will be handled as a key
						for $RECURSEOBJECTNAME and a  new display-object of 
						type $RECURSEOBJECTNAME will be generated using a key-query. | db.domain.recurse.person=holder;admin_c;tech_c;zone_c | 
				
					| .whereaddition | Additional string to be appended to  WHERE-part of the query. | db.domain.whereaddition=\ AND disabled \= 0 | 
				
					| .tablejoin | Additional string appended after SELECT ... FROM tablename (useful for joins) | db.person.tablejoin=
LEFT JOIN country ON country_key\=country_fkey | 
				
					| .matchkey | stupid sql driver: 
						if you use tablename.fieldname in the select statement,
						getColumnLabel reports only fieldname
						so we need a special test some times | db.person.matchkey=id | 
			
		 
		
			Since version 
0.2.0.0 there exists 2 new configuration properties
			effecting the handling of non-recursive foreign keys:
			
				- db.fkey.identify: a string identifying a foreign key column name (defaults to: _fkey)
- db.fkey.replace: string (will be used as a replacement for db.fkey.identify) (defaults to empty string)
			These properties are considered as experimental and may be changed or removed in the future. They will be probably be extended per table/object. 
		
			Since version 
0.3.0.0 there exists 2 special configuration properties regarding inetlookups:
			
				- db.inetnum.bytelength: a string defining the fieldname for the bytelength value (defaults to: bytelength).
- 
					db.$OBJECTNAME.dspobj: a string defining the displayObject class to load for this object 
					(default: db.inetnum.dspobj=net.jwhoisserver.server.DisplayObjectInetNum)
					
 For the future I plan implementing a plugin-system for DisplayObjects that will make use of this property.
			Since version 0.3.3.0 the server may be configured for multiple default lookuptypes:
			
			db.objectlookupdefault: a list of default lookuptypes
			separated by the value of db.listseparator (default: ;).
			
			This property is used, in case the server recieves a request without a defined lookuptype
			(i.e. without the -T option).
			
			In this case, we will loop all displayobjects from the list and will use the first
			where the request string matches the configured regex. Therefore only the last element
			from the list may have a empty regex (as this will always match).
		
		
		
		
		
		
		
			4.1.2 Configure output format
			
			The output of 
JWhoisServer can be customized to some extend using some properties.
			If you need more flexibility, you may use velocity templates.
			
 
			This is a list of some properties usefull for formatting the output of 
JWhoisServer:
			
				
					| db.namevalueseparator | The value of this property is used to separate the fieldname and the value.
						Defaults to colon (:) | db.namevalueseparator=\: | 
				
					| db.paddstring | The value of this property is used to rightpadd the fieldname up to the 
						configured fieldlength. Defaults to whitespace | db.paddstring=\ | 
				
					| db.fieldlength | This property configures the length of the field name. 
						paddstring will be used to right padding the field name up to the configured length. | db.fieldlength=12 | 
				
					| db.transformnames | Transform the field- / columnnames in the response.
						Recognized values: 
							0 empty do nothing-1 lower lowercase tolower tolowercase uncapitalize uncapitalized to lower case1 upper uppercase toupper touppercase capitalize capitalized to upper case | db.transformnames=upper | 
			
			
				Since 0.3.1.1: 
				
db.fieldlength, 
db.paddstring and 
db.namevalueseparator are global settings.
				They may be changed on a per displayobject level using:
				
					- db.$OBJECTNAME.fieldlength
- db.$OBJECTNAME.paddstring
- db.$OBJECTNAME.namevalueseparator
				Since version 0.3.1.1 
JWhoisServer supports customizable formatting of Date-Fields in the output. 
				
					Fore each defined displayobject 
					
$OBJECTNAME 
					you can define a SimpleDateFormat pattern for each field you have configured using
					
db.$OBJECTNAME.display and  
db.$OBJECTNAME.displayshort
					
					For each field defined a format pattern using
					
					
db.$OBJECTNAME.dateformat.display.$FIELDNAME=FORMATPATTERN
					or 
					
db.$OBJECTNAME.dateformat.displayshort.$FIELDNAME=FORMATPATTERN
					
					depending where you have defined 
$FIELDNAME.
					 
					See 
http://java.sun.com/javase/6/docs/api/index.html?java/text/DateFormat.html
					for details about the format patterns.
				
				If you define a column in
				
db.$OBJECTNAME.display and  
db.$OBJECTNAME.displayshort 
				as a alias, you must refer to the alias of the fieldname in 
				
db.$OBJECTNAME.dateformat.display.$FIELDNAME
				or 
db.$OBJECTNAME.dateformat.displayshort.$FIELDNAME.
				
 
				This rule applies to other config properties too!
				
db.domain.display=domain;changed AS lastchanged
db.domain.dateformat.display.lastchanged=...
			
				Example:
				db.domain.fieldlength=20
db.domain.paddstring=.
db.domain.dateformat.display.last\ changed=EEE, d MMM yyyy HH:mm:ss Z
db.domain.display=domain;mntnr_fkey;changed AS "last changed";
db.nameserver.fieldlength=25
db.nameserver.paddstring=+
db.nameserver.namevalueseparator=#
				will result in a output like this:
				
domain:.............test10.tld
mntnr:..............MNTNR1
last changed:.......Thu, 17 Dec 2009 16:14:24 +0100
nameserver#++++++++++++++ns1.ns10.tld
nameserver#++++++++++++++ns2.ns10.tld
nameserver#++++++++++++++ns3.ns10.tld
			 
			
				Since version 
0.3.2.3, 
JWhoisServer supports customizable output for fields holding multiple lines. 
				
					Fore each defined displayobject 
					
$OBJECTNAME 
					you can define a list of fileds that should be handled as multi-line fileds.
					
db.$OBJECTNAME.multilinefields=filed1;filed2;...
					For each field defined here you can configure:
					
				
					Example:
					db.person.multilinefields=address
					will result in a output like this:
					
address:    street
address:    city
address:    country
				 
				
					Example:
					db.person.multilinefields=address
db.person.multilinefield.address.usespaces=true
					will result in a output like this:
					
address:    street
            city
            country
				 
			 
		
		
		
			4.1.3 Configure SQL statements triggered by queries
			
			Since version 0.4.1.3 
JWhoisServer supports triggering SQL insert/update statements on query events.
			
				Fore each defined displayobject
				$OBJECTNAME
				you can define a list of SQL insert/update statements where you should use
				? as a placeholder for the query string (i.e. domain).
				db.$OBJECTNAME.triggerstatements
			
			Please keep in mind that for this the db-user configured for 
JWhoisServer requires
			insert/update rights for the field(s)/table(s)/database used in the statements.
		
 
		
	 
	
	
	
	
	
	
		4.2 Configure JWhoisServer for inetlookup
		
		This chapter is about a new extension since version 0.3.0.0: 
inetlookup
		
		This feature should be considered as 
"work in progress".
		
		
			4.2.1 Configuration properties for inetlookup
			
			In order to enable 
inetlookup for 
jwhoisserver you will have to set some configuration properties.
			If you prefer to run a server only for 
inetlookup (i.e. no domain-lookups), see 
			
inetsample.cfg.
			
				
					| property | value | description | 
				
					| db.objectlist | domain;inetnum;person;mntnr;nameserver | extend the objectlist by inetnum | 
				
					| db.inetnum.table | inetnum | define the table for inetnum | 
				
					| db.inetnum.objectlookup | inetnum;inet | define the lookup type | 
				
					| db.inetnum.dspobj | net.jwhoisserver.server.DisplayObjectInetNum | define the class to be used for generating the display! | 
				
					| db.inetnum.qfield | inetnumstart | define the queryfield | 
				
					| db.inetnum.key | netname | define the key | 
				
					| db.inetnum.handleprefix | INET | define the prefix for the inetnum-handle | 
				
					| db.inetnum.bytelength | bytelength | define the field for the bytelength of a inetnum-object | 
				
					| db.inetnum.display | netname AS network;bytelength;inetnumstart;inetnumend;descr;source | define the display-fields | 
				
					| db.inetnum.recurse.person | admin_c;tech_c | recursive fields (foreign keys targeting the person table) | 
				
					| db.inetnum.match | \\A(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}(/[0-9]{1,2})*\\z | the regex to match a query string (see sample.cfg for IPv6 regex) | 
			
		 
		
		
		
		
		
		
			4.2.2 Notes regarding the MySQL-Table for inetlookup
			
			
			The table for inetlookup (inetnum) is only implemented for mysql, postgresql and hsqldb.
			If you need this using another RDBMS, you must create the table on your own!
			
			The default table is only suitable for IPv4 values, as it uses 
INTEGER UNSIGNED for 
inetnumstart
			and 
inetnumend. If you need to store values for IPv6, you must change the type of this two fields to 
			
DECIMAL( 39, 0 ) UNSIGNED!
			(see: 
inetnumIPv6.sql)
		
 
		
		
		
		
		
		
			4.2.3 Command-Line Tools
			
			JWhoisServer includes some small helper tools for 
inetlookup and IDN/ACE transformation:
			
				- IPCalc: a simple commandline tool to get a description of a network
- IP2UBI: convert one or more IPs to Unsigned Big Integer: for IPv4 this is compatible to the mysql-function INET_ATON
- UBI2IPv4: convert a Unsigned Big Integer to a IPv4: compatible to the mysql-function INET_NTOA
- UBI2IPv6: convert a Unsigned Big Integer to a IPv6
- IDN2ACE: convert a IDN string into his ACE representation (nameprep + punycode)
- ACE2IDN: convert a ACE string into his IDN representation (inverse punycode)
- 
					ClasspathTransform4Jar:  convert a (OS dep.) CLASSPATH string containing only
					absolute paths into a string usable for the Class-Path directive in the 
					MANIFEST of a jar-file.
			Like 
jwhoisserver, all this tools have a small man-page. If you installed using a .deb or .rpm,
			you can access the manpages in the usual way using the 
man command.
			Otherwise you can find the man-pages in the 
debian/ directory of the source package
			(unfortunately there is no 
install-doc target for the build).
		
 
		
		
		
		
		
		
			4.2.4 API regarding the InetLookup stuff
			
			The API for some helper classes developed for 
jwhoisserver, that may (or may not) be useful for others,
			can be found at 
http://jwhoisserver.sourceforge.net/api/
			
			The API documents:
			
				- InetIP2UBI: contains static functions to convert inetaddress 2 unsigned big int and back 
- InetNetwork: A utility class for InetAddress representing a network as a range of InetAddresses starting from a IP address and a netmask.
- IP2UBI: main class for the tool with the same name
- IPCalc: main class for the tool with the same name
- UBI2IPv4: main class for the tool with the same name
- UBI2IPv6: main class for the tool with the same name
 
		
	 
	
	
	
	
	
	
		4.3 Configure JWhoisServer for Velocity
		
		This chapter is about a new extension since version 0.3.1.0: 
Velocity Templates
		
		In order to use Velocity Templates, 
JWhoisServer requires min. Velocity Engine version 1.5.
		The recommended version is 1.6.2.
		
		This feature should be considered as 
"work in progress".
		
		
			4.3.1 Configuration properties for velocity
			
			
				
					| property | value | description | 
				
					| server.loglevel.velocity | -1 | finetuning of the loglevel for the velocity engine: 5 - fatal; 4 - error; 3 - warn, 2 - info; 1 - debug; 0 - OFF; -1 use the global loglevel
 | 
				
					| server.velocity.use | false|no|0|true|yes|1 | enable / disable the usage of velocity; the default value is:false | 
				
					| server.velocity.dir | /etc/jwhoisserver/velocity/ | the directory where the templates are stored | 
				
					| server.velocity.cfg |  | path to a special property file that should be passed to velocity | 
				
					| server.velocity.template.error |  | the name of the error template; if none defined, no template will be used | 
				
					| server.velocity.template.help |  | the name of the help template; if none defined, no template will be used | 
				
					| server.velocity.template.status |  | the name of the status template; if none defined, no template will be used | 
				
					| server.velocity.template.stats |  | the name of the statistics template; if none defined, no template will be used | 
				
					| server.velocity.template.default |  | the name of the template for the display-objects; if none defined, no template will be used | 
				
					| server.velocity.template.$OBJECTNAME |  | the name of the template that should be used for lookups for $OBJECTNAME; 
					if none defined, server.velocity.template.default will be used | 
			
		 
		
		
		
			4.3.2 Objects made available to the Velocity Templates
			
			
			For all templates the 
$server object is available (represents: VelocityWrapper) and offers some functions:
			
			
			| Method Summary | 
			
			|  java.lang.String | getAverageStats()
 | 
			
			|  java.lang.String | getBanner()
 | 
			
			|  java.lang.String | getClientHelp()
 | 
			
			|  java.net.InetAddress | getClientInetAddress()get the clients InetAddress
 | 
			
			|  java.lang.String | getClientInetAddressString()
 | 
			
			|  java.lang.String | getConStats()
 | 
			
			|  long | getCounterACLviolations()
 | 
			
			|  long | getCounterClientErrors()
 | 
			
			|  long | getCounterClientTime()
 | 
			
			|  long | getCounterConnections()
 | 
			
			|  long | getCounterConnErrors()
 | 
			
			|  long | getCounterConnTimeout()
 | 
			
			|  long | getCounterDBConnect()
 | 
			
			|  long | getCounterDBErrors()
 | 
			
			|  long | getCounterRegexErrors()
 | 
			
			|  long | getCounterRequestsHelp()
 | 
			
			|  long | getCounterRequestsHTMLFormat()
 | 
			
			|  long | getCounterRequestsNonRecursive()
 | 
			
			|  long | getCounterRequestsRecursive()
 | 
			
			|  long | getCounterRequestsStats()
 | 
			
			|  long | getCounterRequestsStatus()
 | 
			
			|  long | getCounterSQLErrors()
 | 
			
			|  long | getCounterSQLStatements()
 | 
			
			|  long | getCounterSQLTime()
 | 
			
			|  java.lang.String | getLegal()
 | 
			
			|  java.lang.String | getLookupKey()
 | 
			
			|  java.lang.String | getLookupType()
 | 
			
			|  java.lang.String | getMemStats()
 | 
			
			|  java.lang.String | getRequest()
 | 
			
			|  java.lang.String | getStats()
 | 
			
			|  java.lang.String | getUptime()
 | 
			
			|  java.lang.String | getVersion()
 | 
			
			|  boolean | isHtmlFormat()
 | 
			
			
			
			
			server.velocity.template.error-Template has in addition 2 variables:
			
				- $errormsg: the error message generated for the client
- 
					$errorcode: the error code:
					
					- 1 bad client behaviour
- 2 ACL deny
- 3 missing or unknown argument to -T
- 4 error parsing request
- 5 no search key supplied (in fact code error 1 should catch this ???)
- 6 internal error
- 10 regex error for displayobject
 
			
			server.velocity.template.status-Template has one additional variable:
			
				- $statusmsg: the status message
			
			for the 
server.velocity.template.default and 
server.velocity.template.$OBJECTNAME-Templates there is a complex data-structure available:
			
				- 
					$display: a VelocityDisplayLookup-Object holding all the data that may be used to generate a result-page.
					
					
				
				| Method Summary |  
				|  int | getErrorCode()get the error code:
				 
				 0 - everything is OK
				 1 - bad client behaviour
				 2 - ACL deny
				 3 - missing or unknown argument to -T
				 4 - error parsing request
				 5 - no search key supplied (in fact code error 1 should catch this ???)
				 6 - internal error
				 10 - regex error for displayobject
 |  
				|  java.lang.String | getErrorMessage()get the error message
 |  
				|  java.lang.String | getLookupType()Get the lookup type requested by the client: domain, inet, ...
 |  
				|  java.lang.String | getLookupValue()get the value of the lookup
 |  
				|  java.util.Vector<VelocityDisplayObject> | getResultList()Get all results as a Vector of VelocityDisplayObjects
 |  
				|  int | rowsCount()get the number of results found
 |  
 
- 
									each VelocityDisplayObject - object used by the $display provides some methods:
									
				
				| Method Summary |  
				|  java.util.HashMap<java.lang.String,java.util.Vector<VelocityDisplayObject>> | getAllParentObjects()get all parent objects as a HashMap: table-name => Vector of VelocityDisplayObjects
 |  
				|  java.util.HashMap<java.lang.String,java.util.Vector<VelocityDisplayObject>> | getAllSubObjects()get all sub-objects as a HashMap foreign key name => Vector of VelocityDisplayObjects
 |  
				|  java.util.LinkedHashMap<java.lang.String,java.lang.String> | getDisplayMap()get the result for this object as a Map field-name => field-value
 |  
				|  int | getErrorcode()Error code for this object:
				        0 - no error; 1 - error
 |  
				|  java.lang.String | getErrormsg()Error message for the error occurred for this Object
 |  
				|  java.lang.String | getName()get the name of the obj.
 |  
				|  VelocityDisplayObject | getNextSubObject(java.lang.String fkey)get the first VelocityDisplayObject for the specified foreign key and delete it from the vector
 |  
				|  java.util.Vector<VelocityDisplayObject> | getParentObjects(java.lang.String parentname)Get a Vector of VelocityDisplayObjects for a specified parent table name
 |  
				|  java.lang.String | getQfield()get the query-field
 |  
				|  java.util.Vector<VelocityDisplayObject> | getSubObjects(java.lang.String fkey)get the Vector of VelocityDisplayObjects for the specified foreign key
 |  
				|  java.lang.String | implodeParentObjects(java.lang.String parentname,
				                     java.lang.String field)get a list of all values for the specified field from the table parentname separated by spaces
 |  
				|  java.lang.String | implodeParentObjects(java.lang.String parentname,
				                     java.lang.String field,
				                     java.lang.String delimiter)get a list of all values for the specified field from the table parentname separated by delimiter
 |  
 
				Since version 
0.4.1.2 a new optional config setting is available:
				
server.velocity.context
				
				It may be configured as a list of class names that should be made available in the velocity context.
				
				
Example:
				server.velocity.context=org.apache.commons.lang.WordUtils
				will put a instance of 
org.apache.commons.lang.WordUtils into the velocity context as 
WordUtils
			 
		
	 
	
	
	
	
	
	
		4.4 Configure a additional lookup
		
		Lets assume you want to enable lookups on the 
person-object from
		
localhost, then you should extend your config:
		
db.person.objectlookup=person;pn
db.person.qfield=name
db.person.lookupallowfrom=127.0.0.1
		
		and try it out:
		
$ whois -h localhost -- -T pn persona non grata
This is JWhoisServer serving ccTLD tld
Java Whois Server 0.0.3.0    (c) 2006 - 2007 zero-sys.net Klaus Zerwes
...
handle:     PRSN1
mntnr:      MNTNR1
type:       PERSON
name:       persona non grata
address:    two dead ends
pcode:      NWR
country:    AX
phone:      +77 31 123454321
fax:        +77 31 123454321
email:      mail@domain.tld
changed:    2006-10-14 16:20:00
		
		As you can see the 
HELP-reply of the server will get automatically updated:
		
$ whois -h localhost -- help
# HELP
# SYNTAX: whois [-h hostname] [-r] [-f] [-T t] key
# -r    suppress recursion in lookups
# -f    generate html-formatted display (maybe restricted access)
# -T t  lookup for specified type t
#       implemented types:
#          dn|domain    domain (default)
#          pn|person    person
# key   lookup for key
#       special keys:
#           HELP|?    display this help
#           STATUS    display status information
#           STATS     display statistical informations (restricted access)
		
	 
	
	
	
	
	
	
		4.5 Configure JWhoisServer to run on a different database structure
		
		Using the informations above, you can configure 
JWhoisServer
		to run on your own database using your defined data-structure.
		
		The SQL statement are build this way:
		
			- 
				for each displayobject that is configured as a lookup using db.$OBJECTNAME.objectlookup we will build:
				
					- 
						sql for recursive lookups: 
						
 SELECT FIELDLIST FROM TABLE WHERE LOOKUPFIELD
 where
							- 
								FIELDLIST is build from:
								
									- db.$OBJECTNAME.selectaddition if defined
- db.$OBJECTNAME.display
- db.$OBJECTNAME.key (defaults to $OBJECTNAME + db.key.identify)
- db.$OBJECTNAME.recurse.$RECURSEOBJECTNAME
- db.$OBJECTNAME.recursecondition
 
- 
								TABLE is build from:
								
									- db.$OBJECTNAME.table (defaults to $OBJECTNAME)
- db.$OBJECTNAME.tablejoin if defined
 
- 
								LOOKUPFIELD is build from db.$OBJECTNAME.qfield
							
 
- 
						sql short for non-recursive lookups using the -r option if server.recursive.use is set to TRUE (default): 
						
 SELECT FIELDLIST FROM TABLE WHERE LOOKUPFIELD
 where
							- 
								FIELDLIST is build from:
								
									- db.$OBJECTNAME.selectaddition if defined
- db.$OBJECTNAME.displayshort (default: db.$OBJECTNAME.display)
- db.$OBJECTNAME.key (defaults to $OBJECTNAME + db.key.identify)
 
- 
								TABLE is build from:
								
									- db.$OBJECTNAME.table (defaults to $OBJECTNAME)
- db.$OBJECTNAME.tablejoin if defined
 
- 
								LOOKUPFIELD is build from db.$OBJECTNAME.qfield
							
 
 
- 
				for each displayobject that is configured as a parent for another using db.$X.parent.$OBJECTNAME we will build:
				
					- 
						sql short like above: (this will be changed in the next release!)
					
 
- 
				for each displayobject that is configured as a recurse for another using db.$X.recurse.$OBJECTNAME we will build:
				
					- 
						sql key-search: (this may be changed in the next release!) 
						
 SELECT FIELDLIST FROM TABLE WHERE LOOKUPFIELD
 where
							- 
								FIELDLIST is build from:
								
									- db.$OBJECTNAME.selectaddition if defined
- db.$OBJECTNAME.displayshort (default: db.$OBJECTNAME.display)
- db.$OBJECTNAME.key (defaults to $OBJECTNAME + db.key.identify)
 
- 
								TABLE is build from:
								
									- db.$OBJECTNAME.table (defaults to $OBJECTNAME)
- db.$OBJECTNAME.tablejoin if defined
 
- 
								LOOKUPFIELD is db.$OBJECTNAME.key
							
 
 
		Let's have a look on a sample database:
		
		The goal of the configuration is to provide:
		
			- a recursive domain lookup including informations about the handles assigned to the domain
- a simple non-recursive domain lookup
- a handle lookup
		Let us start configuring the displayobjects: 
		
db.objectlist=domain;handle;handlelookup
		
		Next step: configuring the domain object
		
db.domain.table=domains
db.domain.objectlookup=dn;name
db.domain.qfield=name
db.domain.key=id
db.domain.display=name;rdate AS registered;edate AS expires;cdate AS changed;
db.domain.displayshort=name;'connected' AS status
db.domain.recurse.handle=id
db.domain.whereaddition=
		
		Next step: configuring the recursion to the handles
		
db.handle.table=domain_handle_relation
db.handle.key=did
db.handle.display=type;handle;name;firstname
db.handle.tablejoin=\ JOIN handles ON hid=handles.id JOIN type ON tid=type.id
		
		Next step: configure the lookup for the handles
		
db.handlelookup.table=handles
db.handlelookup.objectlookup=handle
db.handlelookup.qfield=handle
db.handlelookup.key=id
db.handlelookup.display=handle;name;firstname
		
		
			Using the -d argument for the startup of JWhoisServer will enable debug and will print all
			SQL statements.
		
	 
	
 
	5. Notes: java versions
	
	The recommended java runtime to run 
JWhoisServer is 
	
		- sun jre 1.6/6.0
- openjdk 6
- openjdk 7
- openjdk 8 has been tested but not excessively in a real production environment
	Except some special features the server should run on sun jre 1.5/5.0.
	
	Support for jre 1.5/5.0 will be removed soon!
	
 
	Support for java version 1.4 was dropped since version 0.3.1.0!
	
	Short tests have been done using gij-4.3.
	
	Older versions have been (more or less) successfully tested using gij 4.1, 
	SableVM (1.13), JamVM (1.4.4) and kaffe VM (1.1.7).