Author: bodewig
Date: Mon May 8 21:26:36 2006
New Revision: 405300
URL: http://svn.apache.org/viewcvs?rev=405300&view=rev
Log:
Make <scp> support the sftp protocol. PR 39373
Added:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
(with props)
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
(with props)
Modified:
ant/core/trunk/WHATSNEW
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
Modified: ant/core/trunk/WHATSNEW
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/WHATSNEW?rev=405300&r1=405299&r2=405300&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Mon May 8 21:26:36 2006
@@ -410,6 +410,8 @@
* Handling of ' ', '#' in CLASSPATH and '#' in -lib (cannot use ' '
in -lib on UNIX at the moment). Bugzilla Report 39295.
+* <scp> now optionally supports the sftp protocol. Bugzilla Report 39373.
+
Changes from Ant 1.6.4 to Ant 1.6.5
===================================
Modified:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java?rev=405300&r1=405299&r2=405300&view=diff
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
(original)
+++
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
Mon May 8 21:26:36 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 The Apache Software Foundation
+ * Copyright 2003-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,10 @@
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
+import com.jcraft.jsch.SftpProgressMonitor;
import java.io.IOException;
import java.io.OutputStream;
@@ -75,6 +79,17 @@
}
/**
+ * Open an ssh sftp channel.
+ * @return the channel
+ * @throws JSchException on error
+ */
+ protected ChannelSftp openSftpChannel() throws JSchException {
+ ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
+
+ return channel;
+ }
+
+ /**
* Send an ack.
* @param out the output stream to use
* @throws IOException on error
@@ -213,4 +228,39 @@
return percent;
}
+ private ProgressMonitor monitor = null;
+
+ protected SftpProgressMonitor getProgressMonitor(){
+ if (monitor == null) {
+ monitor = new ProgressMonitor();
+ }
+ return monitor;
+ }
+
+ private class ProgressMonitor implements SftpProgressMonitor {
+ private long initFileSize = 0;
+ private long totalLength = 0;
+ private int percentTransmitted = 0;
+
+ public void init(int op, String src, String dest, long max) {
+ initFileSize = max;
+ totalLength = 0;
+ percentTransmitted = 0;
+ }
+
+ public boolean count(long len) {
+ totalLength += len;
+ percentTransmitted = trackProgress(initFileSize,
+ totalLength,
+ percentTransmitted);
+ return true;
+ }
+
+ public void end() {
+ }
+
+ public long getTotalLength() {
+ return totalLength;
+ }
+ }
}
Modified:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java?rev=405300&r1=405299&r2=405300&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
Mon May 8 21:26:36 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 The Apache Software Foundation
+ * Copyright 2003-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@
private String toUri;
private List fileSets = null;
private boolean isFromRemote, isToRemote;
+ private boolean isSftp = false;
/**
* Sets the file to be transferred. This can either be a remote
@@ -142,6 +143,15 @@
}
/**
+ * Setting this to true to use sftp protocol.
+ *
+ * @param yesOrNo if true sftp protocol will be used.
+ */
+ public void setSftp(boolean yesOrNo) {
+ isSftp = yesOrNo;
+ }
+
+ /**
* Adds a FileSet tranfer to remote host. NOTE: Either
* addFileSet() or setFile() are required. But, not both.
*
@@ -213,10 +223,18 @@
Session session = null;
try {
session = openSession();
- ScpFromMessage message =
- new ScpFromMessage(getVerbose(), session, file,
- getProject().resolveFile(toPath),
- fromSshUri.endsWith("*"));
+ ScpFromMessage message = null;
+ if (!isSftp){
+ message =
+ new ScpFromMessage(getVerbose(), session, file,
+ getProject().resolveFile(toPath),
+ fromSshUri.endsWith("*"));
+ } else{
+ message =
+ new ScpFromMessageBySftp(getVerbose(), session, file,
+ getProject().resolveFile(toPath),
+ fromSshUri.endsWith("*"));
+ }
log("Receiving file: " + file);
message.setLogListener(this);
message.execute();
@@ -243,8 +261,14 @@
}
if (!list.isEmpty()) {
session = openSession();
- ScpToMessage message = new ScpToMessage(getVerbose(), session,
- list, file);
+ ScpToMessage message = null;
+ if (!isSftp){
+ message = new ScpToMessage(getVerbose(), session,
+ list, file);
+ } else{
+ message = new ScpToMessageBySftp(getVerbose(), session,
+ list, file);
+ }
message.setLogListener(this);
message.execute();
}
@@ -262,9 +286,17 @@
Session session = null;
try {
session = openSession();
- ScpToMessage message =
- new ScpToMessage(getVerbose(), session,
- getProject().resolveFile(fromPath), file);
+ ScpToMessage message = null;
+ if (!isSftp){
+ message =
+ new ScpToMessage(getVerbose(), session,
+ getProject().resolveFile(fromPath), file);
+ } else{
+ message =
+ new ScpToMessageBySftp(getVerbose(), session,
+ getProject().resolveFile(fromPath),
+ file);
+ }
message.setLogListener(this);
message.execute();
} finally {
Modified:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java?rev=405300&r1=405299&r2=405300&view=diff
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
(original)
+++
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
Mon May 8 21:26:36 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 The Apache Software Foundation
+ * Copyright 2003-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,24 @@
private String remoteFile;
private File localFile;
private boolean isRecursive = false;
+
+ /**
+ * Constructor for ScpFromMessage
+ * @param session the ssh session to use
+ */
+ public ScpFromMessage(Session session) {
+ super(session);
+ }
+
+ /**
+ * Constructor for ScpFromMessage
+ * @param verbose if true do verbose logging
+ * @param session the ssh session to use
+ * @since Ant 1.6.2
+ */
+ public ScpFromMessage(boolean verbose, Session session) {
+ super(verbose, session);
+ }
/**
* Constructor for ScpFromMessage.
Added:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java?rev=405300&view=auto
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
(added)
+++
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
Mon May 8 21:26:36 2006
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.io.ByteArrayOutputStream;
+
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.SftpException;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpProgressMonitor;
+
+/**
+ * A helper object representing an scp download.
+ */
+public class ScpFromMessageBySftp extends ScpFromMessage {
+
+ private String remoteFile;
+ private File localFile;
+ private boolean isRecursive = false;
+ private boolean verbose = false;
+
+ /**
+ * Constructor for ScpFromMessageBySftp.
+ * @param verbose if true log extra information
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion
+ * @since Ant 1.7
+ */
+ public ScpFromMessageBySftp(boolean verbose,
+ Session session,
+ String aRemoteFile,
+ File aLocalFile,
+ boolean recursive) {
+ super(verbose, session);
+ this.verbose = verbose;
+ this.remoteFile = aRemoteFile;
+ this.localFile = aLocalFile;
+ this.isRecursive = recursive;
+ }
+
+ /**
+ * Constructor for ScpFromMessageBySftp.
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion
+ */
+ public ScpFromMessageBySftp(Session session,
+ String aRemoteFile,
+ File aLocalFile,
+ boolean recursive) {
+ this(false, session, aRemoteFile, aLocalFile, recursive);
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ public void execute() throws IOException, JSchException {
+ ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+ try {
+ SftpATTRS attrs = channel.stat(remoteFile);
+ if (attrs.isDir() && !remoteFile.endsWith("/")) {
+ remoteFile=remoteFile+"/";
+ }
+ } catch(SftpException ee) {
+ }
+ getDir(channel, remoteFile, localFile);
+ } catch(SftpException e) {
+ throw new JSchException(e.toString());
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ log("done\n");
+ }
+
+ private void getDir(ChannelSftp channel,
+ String remoteFile,
+ File localFile) throws IOException, SftpException {
+ String pwd=remoteFile;
+ if (remoteFile.lastIndexOf('/')!=-1) {
+ if (remoteFile.length()>1) {
+ pwd=remoteFile.substring(0, remoteFile.lastIndexOf('/'));
+ }
+ }
+ channel.cd(pwd);
+ if (!localFile.exists()) {
+ localFile.mkdirs();
+ }
+ java.util.Vector files = channel.ls(remoteFile);
+ for(int i = 0; i < files.size(); i++){
+ ChannelSftp.LsEntry le = (ChannelSftp.LsEntry) files.elementAt(i);
+ String name = le.getFilename();
+ if (le.getAttrs().isDir()) {
+ if (name.equals(".") || name.equals("..")) {
+ continue;
+ }
+ getDir(channel,
+ channel.pwd() + "/" + name + "/",
+ new File(localFile, le.getFilename()));
+ } else{
+ getFile(channel, le, localFile);
+ }
+ }
+ channel.cd("..");
+ }
+
+ private void getFile(ChannelSftp channel,
+ ChannelSftp.LsEntry le,
+ File localFile) throws IOException, SftpException {
+ String remoteFile = le.getFilename();
+ if (!localFile.exists()) {
+ String path = localFile.getAbsolutePath();
+ int i = 0;
+ if ((i = path.lastIndexOf(File.pathSeparator)) != -1) {
+ if (path.length()>File.pathSeparator.length()) {
+ new File(path.substring(0, i)).mkdirs();
+ }
+ }
+ }
+
+ if (localFile.isDirectory()) {
+ localFile=new File(localFile, remoteFile);
+ }
+
+ long startTime = System.currentTimeMillis();
+ long totalLength = le.getAttrs().getSize();
+
+ SftpProgressMonitor monitor = null;
+ boolean trackProgress = getVerbose() && totalLength > 102400;
+ if (trackProgress){
+ monitor = getProgressMonitor();
+ }
+ try{
+ log("Receiving: " + remoteFile + " : " + le.getAttrs().getSize());
+ channel.get(remoteFile, localFile.getAbsolutePath(), monitor);
+ } finally{
+ long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, (int)totalLength);
+ }
+ }
+}
Propchange:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java?rev=405300&r1=405299&r2=405300&view=diff
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
(original)
+++
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
Mon May 8 21:26:36 2006
@@ -40,6 +40,24 @@
private List directoryList;
/**
+ * Constructor for ScpToMessage
+ * @param session the ssh session to use
+ */
+ public ScpToMessage(Session session) {
+ super(session);
+ }
+
+ /**
+ * Constructor for ScpToMessage
+ * @param verbose if true do verbose logging
+ * @param session the ssh session to use
+ * @since Ant 1.7
+ */
+ public ScpToMessage(boolean verbose, Session session) {
+ super(verbose, session);
+ }
+
+ /**
* Constructor for a local file to remote.
* @param verbose if true do verbose logging
* @param session the scp session to use
Added:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
URL:
http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java?rev=405300&view=auto
==============================================================================
---
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
(added)
+++
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
Mon May 8 21:26:36 2006
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.SftpException;
+import com.jcraft.jsch.SftpProgressMonitor;
+import com.jcraft.jsch.SftpATTRS;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Iterator;
+
+public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ {
+
+ private File localFile;
+ private String remotePath;
+ private List directoryList;
+
+ /**
+ * Constructor for a local file to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ * @since Ant 1.7
+ */
+ public ScpToMessageBySftp(boolean verbose,
+ Session session,
+ File aLocalFile,
+ String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.localFile = aLocalFile;
+ }
+
+ /**
+ * Constructor for a local directories to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ * @since Ant 1.7
+ */
+ public ScpToMessageBySftp(boolean verbose,
+ Session session,
+ List aDirectoryList,
+ String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.directoryList = aDirectoryList;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aRemotePath the remote path
+ * @since Ant 1.6.2
+ */
+ private ScpToMessageBySftp(boolean verbose,
+ Session session,
+ String aRemotePath) {
+ super(verbose, session);
+ this.remotePath = aRemotePath;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessageBySftp(Session session,
+ File aLocalFile,
+ String aRemotePath) {
+ this(false, session, aLocalFile, aRemotePath);
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessageBySftp(Session session,
+ List aDirectoryList,
+ String aRemotePath) {
+ this(false, session, aDirectoryList, aRemotePath);
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ public void execute() throws IOException, JSchException {
+ if (directoryList != null) {
+ doMultipleTransfer();
+ }
+ if (localFile != null) {
+ doSingleTransfer();
+ }
+ log("done.\n");
+ }
+
+ private void doSingleTransfer() throws IOException, JSchException {
+ ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+ try{
+ sendFileToRemote(channel, localFile, remotePath);
+ }
+ catch(SftpException e){
+ throw new JSchException(e.toString());
+ }
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void doMultipleTransfer() throws IOException, JSchException {
+ ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+
+ try{
+ channel.cd(remotePath);
+ for (Iterator i = directoryList.iterator(); i.hasNext();) {
+ Directory current = (Directory) i.next();
+ sendDirectory(channel, current);
+ }
+ }
+ catch(SftpException e){
+ throw new JSchException(e.toString());
+ }
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void sendDirectory(ChannelSftp channel,
+ Directory current)
+ throws IOException, SftpException {
+ for (Iterator fileIt = current.filesIterator(); fileIt.hasNext();) {
+ sendFileToRemote(channel, (File) fileIt.next(), null);
+ }
+ for (Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) {
+ Directory dir = (Directory) dirIt.next();
+ sendDirectoryToRemote(channel, dir);
+ }
+ }
+
+ private void sendDirectoryToRemote(ChannelSftp channel,
+ Directory directory)
+ throws IOException, SftpException {
+ String dir=directory.getDirectory().getName();
+ try{
+ channel.stat(dir);
+ }
+ catch(SftpException e){
+ // dir does not exist.
+ if (e.id==ChannelSftp.SSH_FX_NO_SUCH_FILE) {
+ channel.mkdir(dir);
+ }
+ }
+ channel.cd(dir);
+ sendDirectory(channel, directory);
+ channel.cd("..");
+ }
+
+ private void sendFileToRemote(ChannelSftp channel,
+ File localFile,
+ String remotePath)
+ throws IOException, SftpException {
+ long filesize = localFile.length();
+
+ if (remotePath==null) {
+ remotePath=localFile.getName();
+ }
+
+ long startTime = System.currentTimeMillis();
+ long totalLength = filesize;
+
+ // only track progress for files larger than 100kb in verbose mode
+ boolean trackProgress = getVerbose() && filesize > 102400;
+
+ SftpProgressMonitor monitor = null;
+ if (trackProgress){
+ monitor = getProgressMonitor();
+ }
+
+ try{
+ if (this.getVerbose()) {
+ log("Sending: " + localFile.getName() + " : " + filesize);
+ }
+ channel.put(localFile.getAbsolutePath(), remotePath, monitor);
+ }
+ finally {
+ if (this.getVerbose()) {
+ long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, (int) totalLength);
+ }
+ }
+ }
+
+ public File getLocalFile() {
+ return localFile;
+ }
+
+ public String getRemotePath() {
+ return remotePath;
+ }
+}
Propchange:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]