ceki 01/08/09 13:16:31 Modified: docs FAQ.html HISTORY critique.html manual.html src/java/org/apache/log4j Category.java FileAppender.java Hierarchy.java PatternLayout.java src/java/org/apache/log4j/helpers Loader.java OptionConverter.java src/java/org/apache/log4j/net SyslogAppender.java src/java/org/apache/log4j/test propConfig src/java/org/apache/log4j/varia ExternallyRolledFileAppender.java Log: - Added new system property "log4j.configuratorClass". This property allows the user to specify the custom configurator at the default initialization phase. This property replaces the previous interpretation of the reference part of "log4j.configuration" as the custom configurator class. This interpretation was sometimes erroneous and caused headaches. [*] - Modified src/java/org/apache/log4j/test/propConfig to use the log4j.configuratorClass property. - Cleaned up warnings reported by javadoc. Revision Changes Path 1.10 +10 -38 jakarta-log4j/docs/FAQ.html Index: FAQ.html =================================================================== RCS file: /home/cvs/jakarta-log4j/docs/FAQ.html,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- FAQ.html 2001/05/25 19:39:02 1.9 +++ FAQ.html 2001/08/09 20:16:30 1.10 @@ -127,16 +127,9 @@ <p><li>Log4j is JDK 1.1.x compatible. - <p><li>Nevertheless, <code>RollingFileAppender</code> requires JDK - 1.2 or above. This will be fixed in future releases of log4j. If you - need <code>RollingFileAppender</code> to run under JDK 1.1 then you - can simply remove <code>RollingFileAppenderBeanInfo.class</code> - from log4j.jar. - - -<p><li>The DOMConfigurator is based on the DOM Level 1 API. The - DOMConfigurator.configure(Element) method will work with any - XML parser that will pass it a DOM tree. + <p><li>The DOMConfigurator is based on the DOM Level 1 API. The + DOMConfigurator.configure(Element) method will work with any XML + parser that will pass it a DOM tree. <p>The DOMConfigurator.configure(String filename) method and its variants require a JAXP compatible XML parser, for example <a @@ -144,41 +137,22 @@ parser. Compiling the DOMConfigurator requires the presence of a JAXP parser in the classpath. -<p><li>The <code>org.apache.log4j.net.SMTPAppender</code> relies on - the <a href="http://java.sun.com/products/javamail/">JavaMail + <p><li>The <code>org.apache.log4j.net.SMTPAppender</code> relies + on the <a href="http://java.sun.com/products/javamail/">JavaMail API</a>. It has been tested with JavaMail API version 1.2. The JavaMail API requires the <a href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans - Activation Framework</a> package. + Activation Framework</a> package. -<p><li>The <code>org.apache.log4j.net.JMSAppender</code> requires the -presence of the JMS API as well as JNDI. + <p><li>The <code>org.apache.log4j.net.JMSAppender</code> requires + the presence of the JMS API as well as JNDI. -<p><li>log4j test code relies on the <a -href="http://www.junit.org">JUnit</a> testing framework. + <p><li>log4j test code relies on the <a + href="http://www.junit.org">JUnit</a> testing framework. - </ul> - -<a name=javadoc><h4>Is there javadoc documentation for log4j?</h4> - -The javadoc <a href=api/index.html>documentation</a> is part of -the log4j package. There is also an <b><a -href="manual.html">introductory manual</a></b>. In case -problems make sure to have a look at <a href="TROUBLESHOOT.html">log4j -troubleshooting</a> document. - -<a name=alternatives><h4>What other logging packages are there?</h4> - -There are many other logging packages out there. I know of <a -href=http://www.homestead.com/JavaLog/>Grace Software's JavaLog</a>, -<a href=http://www.alphaworks.ibm.com/tech/loggingtoolkit4j>JLog</a>, -<a href=http://www.sw-zoo.org/>Software ZOO's toolkit</a>, <a -href=http://www.eli.sdsu.edu/java-SDSU/>SDSU logging package</a>. This -list is not exhaustive. - <a name=usageExample><h4>Is there example code for using log4j?</h4> <p>There is a directory containing examples in @@ -452,8 +426,6 @@ <p>Note by naming categories by locality one tends to name things by functionality, since in most cases the locality relates closely to functionality. - - <a name=className><h4>How do I get the fully-qualified name of a class in a static block?</a></h4> 1.57 +12 -0 jakarta-log4j/docs/HISTORY Index: HISTORY =================================================================== RCS file: /home/cvs/jakarta-log4j/docs/HISTORY,v retrieving revision 1.56 retrieving revision 1.57 diff -u -r1.56 -r1.57 --- HISTORY 2001/08/07 12:13:54 1.56 +++ HISTORY 2001/08/09 20:16:30 1.57 @@ -15,6 +15,18 @@ - Added event reporting capability to the Hierachy class. + - Added new system property "log4j.configuratorClass". This property + allows the user to specify the custom configurator at the default + initialization phase. This property replaces the previous + interpretation of the reference part of "log4j.configuration" + as the custom configurator class. This interpretation was sometimes + erroneous and caused headaches. [*] + + - Introduced the Mapped Diagnostic Context or MDC class. This class + is similar to the NDC except that the diagnistic context is based + on a map instead of a stack. Moreover the MDC is automatically + inherited by child threads under JDK 1.2 and above. + - Corrected a performance bug in the NDC class as observed by Dan Milstein. [*] - Removed deprecated methods setOptions and getOptionStrings defined 1.23 +2 -2 jakarta-log4j/docs/critique.html Index: critique.html =================================================================== RCS file: /home/cvs/jakarta-log4j/docs/critique.html,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- critique.html 2001/08/07 20:29:50 1.22 +++ critique.html 2001/08/09 20:16:30 1.23 @@ -528,8 +528,8 @@ <li><p><a href="pub-support/SandipGahlot.html">Sandip Gahlot</a> <!-- --> <li><p><a href="pub-support/BrianBush.html">Brian Bush</a> <!-- --> <li><p><a href="pub-support/ShawnStephens.html">Shawn Stephens</a> -<li><p><a href="pub-support/AaronKnauf.html">Aaron Knauf</a> -<li><p><a href="pub-support/DamienGlancy.html">Damien Glancy</a> +<li><p><a href="pub-support/AaronKnauf.html">Aaron Knauf</a> <!-- --> +<li><p><a href="pub-support/DamienGlancy.html">Damien Glancy</a> <!-- --> <li><p><a href="pub-support/RogerThomas.html">Roger Thomas</a> <!-- --> <li><p><a href="pub-support/SohailAhmed.html">Sohail Ahmed</a> <!-- --> <li><p><a href="pub-support/AndrewBaptist.html">Andrew Baptist</a> <!-- --> 1.25 +12 -28 jakarta-log4j/docs/manual.html Index: manual.html =================================================================== RCS file: /home/cvs/jakarta-log4j/docs/manual.html,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- manual.html 2001/07/30 20:32:09 1.24 +++ manual.html 2001/08/09 20:16:30 1.25 @@ -837,40 +837,24 @@ "log4j.properties" constitutes a malformed URL. <p>See <a - href="api/org/apache/log4j/helpers/Loader.html#getResource(java.lang.String, java.lang.Class)">Loader.getResource(java.lang.String, java.lang.Class)</a> + href="api/org/apache/log4j/helpers/Loader.html#getResource(java.lang.String)">Loader.getResource(java.lang.String)</a> for the list of searched locations. <p><li>If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL. + <p>The <a + href="api/org/apache/log4j/PropertyConfigurator.html">PropertyConfigurator</a> + will be used to parse the URL to configure log4j unless the URL ends + with the ".xml" extension, in which case the <a + href="api/org/apache/log4j/xml/DOMConfigurator.html">DOMConfigurator</a> + will be used. You can optionaly specify a custom configurator. The + value of the <b>log4j.configuratorClass</b> system property is taken + as the fully qualified class name of your custom configurator. The + custom configurator you specify <em>must</em> implement the <a + href="api/org/apache/log4j/spi/Configurator.html">Configurator</a> + interface. - <p>The URL format is important. Its <em>reference</em> part is - taken as the class name of the configurator. For example, if you - invoke your application using the command line - - <pre> java -Dlog4j.configuration=file:/temp/myconfig.xyz#com.myCompany.myConfigurator - </pre> - - then the log4j will be configured by a new instance of - <code>com.myCompany.myConfigurator</code> by interpreting the - file referenced by <code>file:/temp/myconfig.xyz</code>. The - configurator you specify <em>must</em> implement the <a - href="api/org/apache/log4j/spi/Configurator.html">Configurator</a> - interface. - - <p>After the feature was introduced, it was discovered that the - reference part was used by application servers for their own - used. Consequently, we will drop support for custom categories in - the reference part. A new propery called <b>log4j.configutationClass</b> - will be introduced instead. - - - <p>If the URL has no reference part, then the <a - href="api/org/apache/log4j/PropertyConfigurator.html">PropertyConfigurator</a> - will parse the URL. However, if the URL ends with a ".xml" - extension, then the <a - href="api/org/apache/log4j/xml/DOMConfigurator.html">DOMConfigurator</a> - will be used to parse the URL. </ol> <h2>Example Configurations</h2> 1.40 +28 -2 jakarta-log4j/src/java/org/apache/log4j/Category.java Index: Category.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/Category.java,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- Category.java 2001/08/07 12:13:55 1.39 +++ Category.java 2001/08/09 20:16:31 1.40 @@ -100,6 +100,26 @@ @since 1.0 */ static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration"; + /** + This string constant is set to <b>log4j.configuratorClass</b>. + + <p>It corresponds to name of a system property that, if set, + specifies the class name to use to automatically configure + log4j. See {@link OptionConverter#selectAndConfigure} for more + detailed information on the processing of this option. + + <p>Setting the <b>log4j.configuration</b> system property + overrides the default search for the file <b>log4j.properties</b>. + + <p>Note that all property keys are case sensitive. + + <p>See also the full description of <a + href="../../../../manual.html#defaultInit">default + intialization</a> procedure. + + @since 1.2 */ + static final public String CONFIGURATOR_CLASS_KEY="log4j.configuratorClass"; + /** Setting the system property <b>log4j.defaultInitOverride</b> to "true" or any other value than "false" will skip default @@ -130,13 +150,18 @@ String resource = OptionConverter.getSystemProperty( DEFAULT_CONFIGURATION_KEY, DEFAULT_CONFIGURATION_FILE); + + String configuratorClassName = OptionConverter.getSystemProperty( + CONFIGURATOR_CLASS_KEY, + null); + URL url = null; try { // so, resource is not a URL: // attempt to get the resource from the class path url = new URL(resource); } catch (MalformedURLException ex) { - url = Loader.getResource(resource, Category.class); + url = Loader.getResource(resource); } // If we have a non-null url, then delegate the rest of the @@ -144,7 +169,8 @@ // method. if(url != null) { LogLog.debug("Using URL ["+url+"] for automatic log4j configuration."); - OptionConverter.selectAndConfigure(url, defaultHierarchy); + OptionConverter.selectAndConfigure(url, configuratorClassName, + defaultHierarchy); } else { LogLog.debug("Could not find resource: ["+resource+"]."); } 1.25 +7 -8 jakarta-log4j/src/java/org/apache/log4j/FileAppender.java Index: FileAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/FileAppender.java,v retrieving revision 1.24 retrieving revision 1.25 diff -u -r1.24 -r1.25 --- FileAppender.java 2001/07/25 19:43:43 1.24 +++ FileAppender.java 2001/08/09 20:16:31 1.25 @@ -123,13 +123,13 @@ } /** - The <b>File</b> option takes a string value which should be - the name of the file to append to. Special values "System.out" or + The <b>File</b> property takes a string value which should be the + name of the file to append to. Special values "System.out" or "System.err" are interpreted as the standard out and standard error streams. <p><font color="#DD0044"><b>Note that the "System.out" or "System.err" - options are deprecated. Use {@link ConsoleAppender} + options are deprecated. Please use {@link ConsoleAppender} instead.</b></font> <p>If the option is set to "System.out" or "System.err" the @@ -138,8 +138,7 @@ and output will go there. <p>Note: Actual opening of the file is made when {@link - #activateOptions} is called, not when the options are set. - */ + #activateOptions} is called, not when the options are set. */ public void setFile(String file) { // Trim spaces from both ends. The users probably does not want // trailing spaces in file names. @@ -185,9 +184,9 @@ /** - If the value of {@link #FILE_OPTION} is not <code>null</code>, then {@link - #setFile} is called with the values of {@link #FILE_OPTION} and - {@link #APPEND_OPTION}. + If the value of <b>File</b> is not <code>null</code>, then {@link + #setFile} is called with the values of <b>File</b> and + <b>Append</b> properties. @since 0.8.1 */ public 1.24 +7 -1 jakarta-log4j/src/java/org/apache/log4j/Hierarchy.java Index: Hierarchy.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/Hierarchy.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- Hierarchy.java 2001/07/30 19:30:04 1.23 +++ Hierarchy.java 2001/08/09 20:16:31 1.24 @@ -195,6 +195,8 @@ This method is equivalent to calling {@link #disable} with the argument {@link Priority#FATAL}, the highest possible priority. + @deprecated Please use the {@link #enable} familiy of methods instead. + @since 0.8.5 */ public void disableAll() { @@ -207,6 +209,8 @@ category. Invoking this method is equivalent to calling {@link #disable} with the argument {@link Priority#DEBUG}. + @deprecated Please use the {@link #enable} familiy of methods instead. + @since 0.8.5 */ public void disableDebug() { @@ -222,6 +226,8 @@ <p>Invoking this method is equivalent to calling {@link #disable(Priority)} with the argument {@link Priority#INFO}. + @deprecated Please use the {@link #enable} familiy of methods instead. + @since 0.8.5 */ public void disableInfo() { @@ -393,7 +399,7 @@ } /** - @deprecated Use {@link isEnabled} instead. + @deprecated No replacement offered. */ public 1.13 +2 -2 jakarta-log4j/src/java/org/apache/log4j/PatternLayout.java Index: PatternLayout.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/PatternLayout.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- PatternLayout.java 2001/07/20 17:12:01 1.12 +++ PatternLayout.java 2001/08/09 20:16:31 1.13 @@ -441,8 +441,8 @@ } /** - Does not do anything as options become effective immediately. See - {@link #setOption} method. */ + Does not do anything as options become effective + */ public void activateOptions() { // nothing to do. 1.14 +36 -100 jakarta-log4j/src/java/org/apache/log4j/helpers/Loader.java Index: Loader.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/Loader.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- Loader.java 2001/08/06 21:16:22 1.13 +++ Loader.java 2001/08/09 20:16:31 1.14 @@ -36,15 +36,15 @@ } } - /** This method will search for <code>resource</code> in different places. The rearch order is as follows: <ol> - <p><li>Search for <code>resource</code> using the same class - loader that loaded <code>clazz</code>. + <p><li>Search for <code>resource</code> using the thread context + class loader under Java2 and using the class loader that loaded + this class (<code>Loader</code>) under JDK 1.1. <p><li>Try one last time with <code>ClassLoader.getSystemResource(resource)</code>, that is is @@ -54,78 +54,39 @@ </ol> */ - static + static public - URL getResource(String resource, Class clazz) { - + URL getResource(String resource) { + ClassLoader classLoader = null; URL url = null; - - // Is it under CLAZZ/resource somewhere in the classpath? CLAZZ - // stands for fully qualified name of "clazz" where dots have been - // changed to directory separators - ///LogLog.debug("Trying to find ["+resource+"] using clazz.getResource()."); - /// - ///try { - /// url = clazz.getResource(resource); - /// if(url != null) - /// return url; - ///} catch (Throwable t) { - /// LogLog.warn(TSTR,t); - ///} - /// - ///// attempt to get the resource under CLAZZ/resource from the - ///// system class path. The system class loader should not throw - ///// InvalidJarIndexExceptions - ///String fullyQualified = resolveName(resource, clazz); - ///LogLog.debug("Trying to find ["+fullyQualified+ - /// "] using ClassLoader.getSystemResource()."); - ///url = ClassLoader.getSystemResource(fullyQualified); - ///if(url != null) - /// return url; - - - // Let the class loader of clazz and parents (by the delagation - // property) seearch for resource - ClassLoader loader = clazz.getClassLoader(); - if(loader != null) { - try { - LogLog.debug("Trying to find ["+resource+"] using "+loader - +" class loader."); - url = loader.getResource(resource); - if(url != null) - return url; - } catch(Throwable t) { - LogLog.warn(TSTR, t); + try { + if(!java1) { + classLoader = Thread.currentThread().getContextClassLoader(); } + + if(classLoader == null) + classLoader = Loader.class.getClassLoader(); + + LogLog.debug("Trying to find ["+resource+"] using "+classLoader + +" class loader."); + url = classLoader.getResource(resource); + if(url != null) { + return url; + } + } catch(Throwable t) { + LogLog.warn(TSTR, t); } - - + // Attempt to get the resource from the class path. It may be the // case that clazz was loaded by the Extentsion class loader which // the parent of the system class loader. Hence the code below. - LogLog.debug("Trying to find ["+resource+"] using ClassLoader.getSystemResource()."); - url = ClassLoader.getSystemResource(resource); - return url; - } + LogLog.debug("Trying to find ["+resource+ + "] using ClassLoader.getSystemResource()."); + return ClassLoader.getSystemResource(resource); + } /** - Append the fully qualified name of a class before resource - (replace . with /). - */ - static - String resolveName(String resource, Class clazz) { - String fqcn = clazz.getName(); - int index = fqcn.lastIndexOf('.'); - if (index != -1) { - fqcn = fqcn.substring(0, index).replace('.', '/'); - resource = fqcn+"/"+resource; - } - return resource; - } - - - /** Are we running under JDK 1.x? */ @@ -147,40 +108,15 @@ if(java1) { return Class.forName(clazz); } else { - return Thread.currentThread().getContextClassLoader().loadClass(clazz); + try { + return Thread.currentThread().getContextClassLoader().loadClass(clazz); + } catch(Exception e) { + // we reached here because + // currentThread().getContextClassLoader() is null or because + // of a security exceptio, or because clazz could not be + // loaded, in any case we now try one more time + return Class.forName(clazz); + } } - } - - //public static Image getGIF_Image ( String path ) { - // Image img = null; - // try { - // URL url = ClassLoader.getSystemResource(path); - // System.out.println(url); - // img = (Image) (Toolkit.getDefaultToolkit()).getImage(url); - // } - // catch (Exception e) { - // System.out.println("Exception occured: " + e.getMessage() + - // " - " + e ); - // - // } - // return (img); - //} - // - //public static Image getGIF_Image ( URL url ) { - // Image img = null; - // try { - // System.out.println(url); - // img = (Image) (Toolkit.getDefaultToolkit()).getImage(url); - // } catch (Exception e) { - // System.out.println("Exception occured: " + e.getMessage() + - // " - " + e ); - // - // } - // return (img); - //} - // - //public static URL getHTML_Page ( String path ) { - // URL url = null; - // return (url = ClassLoader.getSystemResource(path)); - // } + } } 1.24 +1 -2 jakarta-log4j/src/java/org/apache/log4j/helpers/OptionConverter.java Index: OptionConverter.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/OptionConverter.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- OptionConverter.java 2001/08/06 20:21:01 1.23 +++ OptionConverter.java 2001/08/09 20:16:31 1.24 @@ -434,8 +434,7 @@ @since 1.0 */ static public - void selectAndConfigure(URL url, Hierarchy hierarchy) { - String clazz = url.getRef(); + void selectAndConfigure(URL url, String clazz, Hierarchy hierarchy) { Configurator configurator = null; 1.13 +0 -2 jakarta-log4j/src/java/org/apache/log4j/net/SyslogAppender.java Index: SyslogAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/net/SyslogAppender.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- SyslogAppender.java 2001/07/25 19:43:44 1.12 +++ SyslogAppender.java 2001/08/09 20:16:31 1.13 @@ -270,8 +270,6 @@ /** This method returns immediately as options are activated when they are set. - - @see #setOption */ public void activateOptions() { 1.4 +5 -7 jakarta-log4j/src/java/org/apache/log4j/test/propConfig Index: propConfig =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/test/propConfig,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- propConfig 2001/01/05 21:09:08 1.3 +++ propConfig 2001/08/09 20:16:31 1.4 @@ -16,7 +16,7 @@ touch $TEMP fi - java $1 org.apache.log4j.test.DefaultInit > $TEMP + java $* org.apache.log4j.test.DefaultInit > $TEMP check witness/propCfg.$TEST $TEMP; echo "OK." } @@ -29,9 +29,6 @@ function createProperties { echo "" > $LCF - #if [ -n "$1" ]; then - # lecho "log4j.configurator=$1" - #fi lecho "log4j.rootCategory=DEBUG, A1" lecho "log4j.appender.A1=org.apache.log4j.FileAppender" lecho "log4j.appender.A1.File=$TEMP" @@ -47,12 +44,13 @@ testPropConfig fi -rm $LCF -createProperties org.apache.log4j.test.SysoutConfigurator + +#org.apache.log4j.test.SysoutConfigurator + TEST=2 if [ $TEST -ge $start ]; then - testPropConfig -Dlog4j.configuration=file:///$LCF#org.apache.log4j.test.SysoutConfigurator + testPropConfig -Dlog4j.configuration=file:$LCF -Dlog4j.configuratorClass=org.apache.log4j.test.SysoutConfigurator fi rm $LCF 1.10 +8 -8 jakarta-log4j/src/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java Index: ExternallyRolledFileAppender.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/varia/ExternallyRolledFileAppender.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ExternallyRolledFileAppender.java 2001/07/26 11:16:49 1.9 +++ ExternallyRolledFileAppender.java 2001/08/09 20:16:31 1.10 @@ -19,10 +19,10 @@ /** This appender listens on a socket on the port specified by the - {@link #PORT_OPTION} for a "RollOver" message. When such a message - is received, the underlying log file is rolled over and an - acknowledgment message is sent back to the process initiating - the roll over. + <b>Port</b> property for a "RollOver" message. When such a message + is received, the underlying log file is rolled over and an + acknowledgment message is sent back to the process initiating the + roll over. <p>This method of triggering roll over has the advantage of being operating system independent, fast and reliable. @@ -62,9 +62,9 @@ } /** - The <b>Port</b> option is used for setting the port for - listening to external roll over messages. - */ + The <b>Port</b> [roperty is used for setting the port for + listening to external roll over messages. + */ public void setPort(int port) { this.port = port; @@ -80,7 +80,7 @@ /** Start listening on the port specified by a preceding call to - {@link #setOption}. */ + {@link #setPort}. */ public void activateOptions() { super.activateOptions(); --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]