ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ken Wood <kw...@i2.com>
Subject Re: [patch] rough Telnet Remote Command Task
Date Thu, 26 Oct 2000 12:14:12 GMT
Forgive my ignorance, but wouldn't an "rsh" task be better suited
to what you are trying to do with the "telnet" task???

Stuart Roebuck wrote:

> I've just put together a task for issuing single remote commands on a telnet host.  Despite
it's rough edges it's very useful to me, so it may be useful to someone else.  Please feel
free to incorporate it in Ant or use it as you see fit.  It relies on NetComponents.
>
> The task is called "Telnet"
>
> I've built it in as a standard Task.
>
> Here's an example of its attributes:
>         <telnet host="telnet.host.com" user="anonymous" password="my@email.address"
>                 prompt="% " command="touch ihavebeenhere" />
>
> It relies heavily on the user entering the correct prompt.
>
> There are various problems with the Task:
> - It waits endlessly for responses, so if something goes wrong it will just wait forever
- I haven't got round to including a timeout.
> - It assumes that the command prompt will not be issued as part of any other output between
entering the password and giving the prompt.  Hence you want to enter as long a portion of
the prompt as possible.
> - It doesn't detect to see whether the command completed successfully - though it does
at least display the response.
> - It relies on a remote shell which understands ";" as a command delimiter and "echo"
as a command line echo command.
>
> ... and probably lots of other things.
>
> On the positive side, it gives a fair amount of helpful feedback.
>
> Stuart.
>
> Here's the patch to defaults.properties if you want to enter it as a default task:
>
> Index: src/main/org/apache/tools/ant/taskdefs/defaults.properties
> ===================================================================
> RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
> retrieving revision 1.47
> diff -u -r1.47 defaults.properties
> --- src/main/org/apache/tools/ant/taskdefs/defaults.properties  2000/10/25 11:59:47 
   1.47
> +++ src/main/org/apache/tools/ant/taskdefs/defaults.properties  2000/10/25 23:12:09
> @@ -42,6 +42,7 @@
>  fail=org.apache.tools.ant.taskdefs.Exit
>  war=org.apache.tools.ant.taskdefs.War
>  uptodate=org.apache.tools.ant.taskdefs.UpToDate
> +telnet=org.apache.tools.ant.taskdefs.Telnet
>
>  # optional tasks
>  script=org.apache.tools.ant.taskdefs.optional.Script
>
> Here's the listing of the new task which should be filed as "src/main/org/apache/tools/ant/taskdefs/Telnet.java".
 Sorry this isn't a patch because I could see how to create a patch for something that isn't
already in the repository.  If anyone can tell me how I would be obliged.
>
> /*
>  * The Apache Software License, Version 1.1
>  *
>  * Copyright (c) 1999 The Apache Software Foundation.  All rights
>  * reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
>  * modification, are permitted provided that the following conditions
>  * are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
>  *    notice, this list of conditions and the following disclaimer.
>  *
>  * 2. Redistributions in binary form must reproduce the above copyright
>  *    notice, this list of conditions and the following disclaimer in
>  *    the documentation and/or other materials provided with the
>  *    distribution.
>  *
>  * 3. The end-user documentation included with the redistribution, if
>  *    any, must include the following acknowlegement:
>  *       "This product includes software developed by the
>  *        Apache Software Foundation (http://www.apache.org/)."
>  *    Alternately, this acknowlegement may appear in the software itself,
>  *    if and wherever such third-party acknowlegements normally appear.
>  *
>  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
>  *    Foundation" must not be used to endorse or promote products derived
>  *    from this software without prior written permission. For written
>  *    permission, please contact apache@apache.org.
>  *
>  * 5. Products derived from this software may not be called "Apache"
>  *    nor may "Apache" appear in their names without prior written
>  *    permission of the Apache Group.
>  *
>  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
>  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>  * SUCH DAMAGE.
>  * ====================================================================
>  *
>  * This software consists of voluntary contributions made by many
>  * individuals on behalf of the Apache Software Foundation.  For more
>  * information on the Apache Software Foundation, please see
>  * <http://www.apache.org/>.
>  */
>
> package org.apache.tools.ant.taskdefs;
>
> import com.oroinc.io.*;
> import com.oroinc.net.telnet.*;
> import java.io.*;
> import java.net.*;
> import java.util.*;
> import org.apache.tools.ant.*;
> import org.apache.tools.ant.types.*;
>
> /**
>  * <p>Task to allow remote commands to be issue on a telnet host.</p>
>  *
>  * <p>Example of task use:</p>
>  * <code>&lt;telnet host="telnet.host.com" user="anonymous" password="my@email.address"
prompt="% " command="touch ihavebeenhere" /&gt;</code>
>  *
>  * @author Stuart Roebuck <a href="mailto:sr@adolos.com">sr@adolos.com</a>
>  */
> public class Telnet extends Task {
>     private String user = "anonymous";
>     private String password;
>     private String host;
>     private String command;
>     private String prompt;
>
>     /** Creates new Telnet Task */
>     public Telnet() {
>     }
>
>     /**
>      * Sets the user or username used to login to the telnet server.
>      *
>      * @param user the telnet login username.
>      */
>     public void setUser(String user) {
>         this.user = user;
>     }
>
>     /**
>      * Sets the password used to login to the telnet server.
>      *
>      * @param password the telnet login password.
>      */
>     public void setPassword(String password) {
>         this.password = password;
>     }
>
>     /**
>      * Sets the hostname of the telnet server.
>      *
>      * @param host the telnet server hostname.
>      */
>     public void setHost(String host) {
>         this.host = host;
>     }
>
>     /**
>      * Sets the shell command to be issued on the remote host.
>      *
>      * @param command shell command to issue on remote host.
>      */
>     public void setCommand(String command) {
>         this.command = command;
>     }
>
>     /**
>      * Sets the command prompt expected from the remote host. This defaults to "->";
>      *
>      * @param prompt command prompt.
>      */
>     public void setPrompt(String prompt) {
>         this.prompt = prompt;
>     }
>
>     /**
>      * Executes this telnet task.
>      *
>      * throws org.apache.tools.ant.BuildException if there is an error during task
>      *        execution.
>      */
>     public void execute() {
>
>         if (this.host == null) {
>             throw new BuildException("Attribute \"host\" is required. This should be
the hostname of the telnet server.");
>         }
>         if (this.password == null) {
>             throw new BuildException("Attribute \"password\" is required. This should
be your password on the remote server or your email address if it is an anonymous login.");
>         }
>         if (this.command == null) {
>             throw new BuildException("Attribute \"command\" is required. This is the
command you want to issue on the remote server.");
>         }
>         if (this.prompt == null) {
>             throw new BuildException("Attribute \"prompt\" is required. This is the command
prompt issue by the remote server. Please be sure to enter this correctly, entering as many
characters of the prompt as you can, as this makes the task wok more reliably.");
>         }
>
>         TelnetClient telnet = new TelnetClient();
>         try {
>             log("Connecting to telnet host '" + this.host + "'");
>             telnet.connect(this.host, 23);
>         } catch (IOException e) {
>             throw new BuildException("Failed to connect to remote host - be sure that
your hostname is correct!");
>         }
>
>         try {
>             BufferedInputStream in = new BufferedInputStream(telnet.getInputStream());
>             Writer out = new OutputStreamWriter(telnet.getOutputStream());
>             BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
>
>             // FIXME - Currently the code outputs the username and password straight
away without waiting for a response for the server.  However, many servers require the responses
to be issues only after the prompts have been given. So we need to enter code to deal with
that here!
>             out.write("\r\n\r\n");
>             out.flush();
>             waitForResponse(in, "login:");
>             log("Entering username");
>             out.write(this.user + "\r\n");
>             out.flush();
>             waitForResponse(in, "assword:"); // NO 'p' as it could be upper or lower
case.
>             log("Entering password");
>             out.write(this.password + "\r\n");
>             out.flush();
>             waitForResponse(in, this.prompt); // Wait for command prompt
>             log("Issuing command '" + this.command + "'");
>             // XXX - In the longterm it would be better to embed the command inside this
task so that you could issue multiple commands on the telnet server.
>             String fullCommand = this.command + "; echo '[COMPLETED]'";
>             out.write(fullCommand +"\r\n");
>             out.flush();
>             String response = waitForResponse(in, "[COMPLETED]"); // Make sure the command
has been received.
>             log("Response: " + response.substring(0, response.length() - "[COMPLETED]".length()));
>             // XXX - There is no code here to detect whether the command was successfully
issues, and to provide feedback to the users. An improved version of this code should provide
feedback and check that the command has worked, perhaps by wrapping it in a standard csh conditional
statement which checks for success and then returns an output that can be detected by this
task and translated into a success or failure.
>             log("Exiting from Telnet session");
>             out.write("exit\r\n");
>             out.flush();
>             log("Disconnected");
>
>             telnet.disconnect();
>         } catch(IOException e) {
>             // XXX - Nice idea, but it won't get here when I'd like it to!
>             throw new BuildException("Failed to login and issue your command - make sure
your username and password are correct!");
>         }
>     }
>
>     private String waitForResponse(InputStream in, String response) throws BuildException,
IOException {
>         StringBuffer buf = new StringBuffer();
>         boolean match = false;
>         int c;
>         while (! match) {
>             c = in.read();
>             if (c == -1) {
>                 throw new BuildException("Telnet host has cancelled connection before
awaited response '" + response + "'");
>             }
>             buf.append((char)c);
>             if (c == buf.charAt(buf.length()-1)) {
>                 // Most recently received character is the same as the last character
of the response to be matched. Check to see whether the complete response matches.
>                 String buffer = buf.toString();
>                 if (buffer.lastIndexOf(response) != -1) match = true;
>             }
>         }
>         return buf.toString();
>     }
>
> }
>
> -------------------------------------------------------------------------
> Stuart Roebuck, BSc, MBA        Tel.: 0131 228 4853 / Fax.: 0870 054 8322
> Managing Director                       Alpha Numeric Pager: 07654 588898
> ADOLOS                                             http://www.adolos.com/


Mime
View raw message