/** * Writes the tail portion of the file to the {@link OutputStream}. * * @param start The byte offset in the input file where the write operation starts. * @return if the file is still being written, this method writes the file until the last newline * character and returns the offset to start the next write operation. */ public long writeLogTo(long start, OutputStream out) throws IOException { CountingOutputStream os = new CountingOutputStream(out); Session f = source.open(); f.skip(start); if (completed) { // write everything till EOF byte[] buf = new byte[1024]; int sz; while ((sz = f.read(buf)) >= 0) os.write(buf, 0, sz); } else { ByteBuf buf = new ByteBuf(null, f); HeadMark head = new HeadMark(buf); TailMark tail = new TailMark(buf); buf = null; int readLines = 0; while (tail.moveToNextLine(f) && readLines++ < MAX_LINES_READ) { head.moveTo(tail, os); } head.finish(os); } f.close(); os.flush(); return os.getCount() + start; }
private int receive( Transaction[] txs, Session session, StatsManager statsManager, int lastTxIdx) { boolean isSessionReadable = true; int firstFailedIndex = Integer.MAX_VALUE; for (int j = 0; j <= lastTxIdx && isSessionReadable; j++) { switch (txs[j].getState()) { case PROCESSED: continue; case FATAL_ERROR: firstFailedIndex = Math.min(j, firstFailedIndex); continue; default: } Response response = txs[j].getResponse(); try { session.read(response); txs[j].setState(TransactionState.PROCESSED); statsManager.recordResponseTime( txs[j].getCommand().getCommandType(), txs[j].getResponseTime()); } catch (ParsingException pe) { txs[j].setState(TransactionState.FATAL_ERROR); if (pe.getCause() instanceof SAXException) { SAXException saxe = (SAXException) pe.getCause(); userLogger.warning(saxe.getMessage()); txs[j].setCause(pe.getCause()); } else { userLogger.warning(pe.getMessage()); txs[j].setCause(pe); } // We can't trust that the message boundaries will be correct // following a parsing error, so the session must be closed in // order to prevent incorrect interpretation of further service // elements received via this session. session.close(); firstFailedIndex = Math.min(j, firstFailedIndex); isSessionReadable = false; } catch (IOException ioe) { userLogger.warning(ioe.getMessage()); txs[j].setState(TransactionState.RETRY); txs[j].setCause(ioe); firstFailedIndex = Math.min(j, firstFailedIndex); isSessionReadable = false; } } return Math.min(firstFailedIndex, txs.length); }
public ByteBuf(ByteBuf previous, Session f, int size) throws IOException { this.buf = new byte[size]; if (previous != null) { assert previous.next == null; previous.next = this; } while (!this.isFull()) { int chunk = f.read(buf, size, buf.length - size); if (chunk == -1) return; size += chunk; } }
/** * Writes the section of the file {@link OutputStream}. * * @param start The byte offset in the input file where the write operation starts. * @return if the file is still being written, this method writes the file until the last newline * character and returns the offset to start the next write operation. */ public long writeLogTo(long start, int size, OutputStream out) throws IOException { if (size <= 0) { return 0; } CountingOutputStream os = new CountingOutputStream(out); Session f = source.open(); f.skip(start); long end = start + size; byte[] buf = new byte[size]; int sz; if ((sz = f.read(buf)) >= 0) { os.write(buf, 0, sz); } /* if(completed) { } else { ByteBuf buf = new ByteBuf(null,f, size); HeadMark head = new HeadMark(buf); TailMark tail = new TailMark(buf); int readLines = 0; while(tail.moveToNextLine(f) && readLines++ < MAX_LINES_READ) { head.moveTo(tail, os); if (buf.isFull() || os.getCount() >= end) { break; } } head.finish(os); } */ f.close(); os.flush(); return os.getCount() + start; }
/** * Try to process a single transaction. Up to {@code MAX_ACCEPTABLE_FAIL_COUNT} attempts will be * made to process the transaction in cases where I/O errors or non-protocol server errors occur * during processing. Use of the underlying session is protected against concurrent use by other * threads by using the getSession/releaseSession features of this SessionManager's {@link * com.ausregistry.jtoolkit2.session.SessionPool}. This method guarantees that the session used * will be returned to the pool before the method returns. * * @throws FatalSessionException No session could be acquired to process the transaction. Check * the exception message and log records for details. * @throws IOException Every attempt to execute the transaction command failed due to an * IOException. This is the last such IOException. * @throws ParsingException Parsing of the response failed. Check the exception message for the * cause. * @throws CommandFailedException The acceptable limit on the number of failed commands due to * server error was exceeded in trying to process the command. This probably indicates a * server limitation related to the command being processed. * @throws IllegalStateException The SessionManager had been shutdown or not started up prior to * invoking this method. */ @Override public void execute(Transaction tx) throws FatalSessionException, IOException, ParsingException, CommandFailedException, IllegalStateException { debugLogger.finest("enter"); if (state == SMState.STOPPED) { throw new IllegalStateException(); } Command cmd = tx.getCommand(); Response response = tx.getResponse(); int failCount = 0; boolean isExecuted = false; Session session = null; // if only processing one transaction, get a new session for each // attempt in case the session fails mid-transaction. while (!isExecuted && state != SMState.STOPPED) { try { session = sessionPool.getSession(cmd.getCommandType()); StatsManager statsManager = session.getStatsManager(); statsManager.incCommandCounter(cmd.getCommandType()); tx.start(); session.write(cmd); isExecuted = true; session.read(response); tx.setState(TransactionState.PROCESSED); statsManager.recordResponseTime(cmd.getCommandType(), tx.getResponseTime()); Result[] results = response.getResults(); assert results != null; if (results != null) { for (Result result : results) { assert result != null; statsManager.incResultCounter(result.getResultCode()); int code = result.getResultCode(); switch (code) { case ResultCode.CMD_FAILED: throw new CommandFailedException(); case ResultCode.CMD_FAILED_CLOSING: default: throw new CommandFailedException(); } } } } catch (CommandFailedException cfe) { userLogger.warning(cfe.getMessage()); if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) { failCount++; } else { throw cfe; } } catch (IOException ioe) { userLogger.warning(ioe.getMessage()); userLogger.warning("net.socket.closed"); session.close(); if (state != SMState.STOPPED && failCount < MAX_ACCEPTABLE_FAIL_COUNT) { failCount++; } else { throw ioe; } } catch (InterruptedException ie) { // if interrupted by shutdown, then started will be false // Note: this still enters the finally block continue; } catch (SessionConfigurationException sce) { throw new FatalSessionException(sce); } catch (SessionOpenException soe) { throw new FatalSessionException(soe); } finally { sessionPool.releaseSession(session); } } if (!isExecuted && state == SMState.STOPPED) { throw new IllegalStateException(); } debugLogger.finest("exit"); }
@Override public boolean start(Session session) throws Exception { super.start(session); if (userinfo != null && !(userinfo instanceof UIKeyboardInteractive)) { return false; } String dest = username + "@" + session.host; if (session.port != 22) { dest += (":" + session.port); } byte[] password = session.password; boolean cancel = false; byte[] _username = null; _username = Util.str2byte(username); while (true) { // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name (ISO-10646 UTF-8, as defined in [RFC-2279]) // string service name (US-ASCII) "ssh-userauth" ? "ssh-connection" // string "keyboard-interactive" (US-ASCII) // string language tag (as defined in [RFC-3066]) // string submethods (ISO-10646 UTF-8) packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); buf.putString("ssh-connection".getBytes()); // buf.putString("ssh-userauth".getBytes()); buf.putString("keyboard-interactive".getBytes()); buf.putString("".getBytes()); buf.putString("".getBytes()); session.write(packet); boolean firsttime = true; loop: while (true) { buf = session.read(buf); int command = buf.getCommand() & 0xff; if (command == SSH_MSG_USERAUTH_SUCCESS) { return true; } if (command == SSH_MSG_USERAUTH_BANNER) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] _message = buf.getString(); byte[] lang = buf.getString(); String message = null; try { message = new String(_message, "UTF-8"); } catch (java.io.UnsupportedEncodingException e) { message = new String(_message); } if (userinfo != null) { userinfo.showMessage(message); } continue loop; } if (command == SSH_MSG_USERAUTH_FAILURE) { buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo = buf.getString(); int partial_success = buf.getByte(); // System.err.println(new String(foo)+ // " partial_success:"+(partial_success!=0)); if (partial_success != 0) { throw new JSchPartialAuthException(new String(foo)); } if (firsttime) { return false; // throw new JSchException("USERAUTH KI is not supported"); // cancel=true; // ?? } break; } if (command == SSH_MSG_USERAUTH_INFO_REQUEST) { firsttime = false; buf.getInt(); buf.getByte(); buf.getByte(); String name = new String(buf.getString()); String instruction = new String(buf.getString()); String languate_tag = new String(buf.getString()); int num = buf.getInt(); String[] prompt = new String[num]; boolean[] echo = new boolean[num]; for (int i = 0; i < num; i++) { prompt[i] = new String(buf.getString()); echo[i] = (buf.getByte() != 0); } byte[][] response = null; if (num > 0 || (name.length() > 0 || instruction.length() > 0)) { if (userinfo != null) { UIKeyboardInteractive kbi = (UIKeyboardInteractive) userinfo; String[] _response = kbi.promptKeyboardInteractive(dest, name, instruction, prompt, echo); if (_response != null) { response = new byte[_response.length][]; for (int i = 0; i < _response.length; i++) { response[i] = Util.str2byte(_response[i]); } } } else if (password != null && prompt.length == 1 && !echo[0] && prompt[0].toLowerCase().startsWith("password:"******"response.length="+response.length); // else // System.err.println("response is null"); packet.reset(); buf.putByte((byte) SSH_MSG_USERAUTH_INFO_RESPONSE); if (num > 0 && (response == null || // cancel num != response.length)) { if (response == null) { // working around the bug in OpenSSH ;-< buf.putInt(num); for (int i = 0; i < num; i++) { buf.putString("".getBytes()); } } else { buf.putInt(0); } if (response == null) cancel = true; } else { buf.putInt(num); for (int i = 0; i < num; i++) { // System.err.println("response: |"+new String(response[i])+"| <- replace here with // **** if you need"); buf.putString(response[i]); } } session.write(packet); /* * if(cancel) break; */ continue loop; } // throw new JSchException("USERAUTH fail ("+command+")"); return false; } if (cancel) { throw new JSchAuthCancelException("keyboard-interactive"); // break; } } // return false; }