1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs.optional.ssh;
  18. import com.jcraft.jsch.Channel;
  19. import com.jcraft.jsch.ChannelExec;
  20. import com.jcraft.jsch.JSchException;
  21. import com.jcraft.jsch.Session;
  22. import java.io.IOException;
  23. import java.io.OutputStream;
  24. import java.io.InputStream;
  25. import java.text.NumberFormat;
  26. import org.apache.tools.ant.BuildException;
  27. public abstract class AbstractSshMessage {
  28. private Session session;
  29. private boolean verbose;
  30. private LogListener listener = new LogListener() {
  31. public void log(String message) {
  32. // do nothing;
  33. }
  34. };
  35. public AbstractSshMessage(Session session) {
  36. this(false, session);
  37. }
  38. /**
  39. * @since Ant 1.6.2
  40. */
  41. public AbstractSshMessage(boolean verbose, Session session) {
  42. this.verbose = verbose;
  43. this.session = session;
  44. }
  45. protected Channel openExecChannel(String command) throws JSchException {
  46. ChannelExec channel = (ChannelExec) session.openChannel("exec");
  47. channel.setCommand(command);
  48. return channel;
  49. }
  50. protected void sendAck(OutputStream out) throws IOException {
  51. byte[] buf = new byte[1];
  52. buf[0] = 0;
  53. out.write(buf);
  54. out.flush();
  55. }
  56. /**
  57. * Reads the response, throws a BuildException if the response
  58. * indicates an error.
  59. */
  60. protected void waitForAck(InputStream in)
  61. throws IOException, BuildException {
  62. int b = in.read();
  63. // b may be 0 for success,
  64. // 1 for error,
  65. // 2 for fatal error,
  66. if (b == -1) {
  67. // didn't receive any response
  68. throw new BuildException("No response from server");
  69. } else if (b != 0) {
  70. StringBuffer sb = new StringBuffer();
  71. int c = in.read();
  72. while (c > 0 && c != '\n') {
  73. sb.append((char) c);
  74. c = in.read();
  75. }
  76. if (b == 1) {
  77. throw new BuildException("server indicated an error: "
  78. + sb.toString());
  79. } else if (b == 2) {
  80. throw new BuildException("server indicated a fatal error: "
  81. + sb.toString());
  82. } else {
  83. throw new BuildException("unknown response, code " + b
  84. + " message: " + sb.toString());
  85. }
  86. }
  87. }
  88. public abstract void execute() throws IOException, JSchException;
  89. public void setLogListener(LogListener aListener) {
  90. listener = aListener;
  91. }
  92. protected void log(String message) {
  93. listener.log(message);
  94. }
  95. protected void logStats(long timeStarted,
  96. long timeEnded,
  97. int totalLength) {
  98. double duration = (timeEnded - timeStarted) / 1000.0;
  99. NumberFormat format = NumberFormat.getNumberInstance();
  100. format.setMaximumFractionDigits(2);
  101. format.setMinimumFractionDigits(1);
  102. listener.log("File transfer time: " + format.format(duration)
  103. + " Average Rate: " + format.format(totalLength / duration)
  104. + " B/s");
  105. }
  106. /**
  107. * @since Ant 1.6.2
  108. */
  109. protected final boolean getVerbose() {
  110. return verbose;
  111. }
  112. /*
  113. * Track progress every 10% if 100kb < filesize < 1mb. For larger
  114. * files track progress for every percent transmitted.
  115. */
  116. protected final int trackProgress(int filesize, int totalLength,
  117. int percentTransmitted) {
  118. int percent = (int) Math.round(Math.floor((totalLength /
  119. (double)filesize) * 100));
  120. if (percent > percentTransmitted) {
  121. if (filesize < 1048576) {
  122. if (percent % 10 == 0) {
  123. if (percent == 100) {
  124. System.out.println(" 100%");
  125. } else {
  126. System.out.print("*");
  127. }
  128. }
  129. } else {
  130. if (percent == 50) {
  131. System.out.println(" 50%");
  132. } else if (percent == 100) {
  133. System.out.println(" 100%");
  134. } else {
  135. System.out.print(".");
  136. }
  137. }
  138. }
  139. return percent;
  140. }
  141. }