package jeffaschenk.commons.frameworks.cnxidx.shell; import jeffaschenk.commons.frameworks.cnxidx.utility.ldap.idxElapsedTime; import java.util.*; import java.util.regex.*; import java.io.*; import java.net.InetAddress; /** * Frontend class to provide a IRR Shell Environement to run all commands * requests and facilities via a single Shell. * * @author jeff.schenk * @version 4.4 $Revision * Developed 2005 */ public class Shell { // ************************************** // Generic Globals. public String HOSTNAME = null; public String RUNDIR = null; public String LDAPPORT = null; public String DAPPORT = null; public String RUNASDIR = null; public String RUNASUSERNAME = null; public String HOMEDIR = null; public String ICOSDIR = null; // ************************************** // Last External Command Output public LinkedList<String> lastExternalCMDOutput = new LinkedList<>(); public LinkedList<String> lastExternalCMDError = new LinkedList<>(); // ************************************** // Indicators public boolean BatchMode = true; public boolean VERBOSE = true; public boolean DEBUG = false; public boolean UNIX = true; public boolean WINDOWS = false; // ************************************** // BackEnd Information public String BackEndName = ""; // ************************************** // Prompt Information. public static final String DEFAULT_PROMPT = "irrShell> "; public String Prompt = DEFAULT_PROMPT; // ************************************** // Common Return Codes. public static int SHELL_RETURN_CODE_SUCCESSFUL = 0; public static int SHELL_RETURN_CODE_EXIT = 99; // ************************************** // OS Specific Literals. public static final String WIN_RUNDLL32 = "rundll32 SHELL32.DLL,ShellExec_RunDLL"; public static final String WIN_RUNCMD = "cmd.exe /C"; // ************************************** // Global Literals. public static final String UNKNOWN = "UNKNOWN"; public static final String NONE = "NONE"; // ************************************** // String Formatting Utility Object public StringFormat SF = new StringFormat(); /** * Initial Constructor. */ public Shell() { this(true); } // End of Constructor /** * Constructor for Specifying Mode. */ public Shell(boolean _mode) { BatchMode = _mode; determineOS(); // ************************* // Obtain Hostname. HOSTNAME = getHostName(); // ************************* // Obtain Environment // Globals. RUNDIR = System.getProperty("user.dsae.directory.dir", ""); RUNASDIR = System.getProperty("user.dsae.runas.home.dir", ""); RUNASUSERNAME = System.getProperty("user.dsae.runas.username", ""); HOMEDIR = System.getProperty("user.home", ""); ICOSDIR = System.getProperty("user.icos.dir", ""); } // End of Constructor /** * Set Prompt for this Shell. * * @param _prompt Prompt String. */ public void setPrompt(String _prompt) { Prompt = _prompt; } // End of setPrompt Method. /** * Set BackEnd for this Shell. * * @param _BackEndName BackEnd Name String. */ public void setBackEnd(String _BackEndName) { BackEndName = _BackEndName; } // End of setBackEnd Method. /** * Command Line Interactive Mode Shell. */ public int CMDprocess(String[] _cmdargs) throws InterruptedException, IOException { // *************************** // Convert Array to LinkedList LinkedList<String> _cmdargsLL = new LinkedList<>(); for (int i = 0; i < _cmdargs.length; i++) { _cmdargsLL.addLast(_cmdargs[i]); } // ******************** // Return return (CMDprocess(_cmdargsLL)); } // End of CMDprocess Method. /** * Command Line Interactive Mode Shell. */ public int CMDprocess(LinkedList<String> _cmdargs) throws InterruptedException, IOException { // ******************** // Do we have any // Command at All? if (_cmdargs.size() < 1) { return (0); } // ******************** // Check for Command String COMMAND = (String) _cmdargs.get(0); // *************************** // Check for an Exit Command. if ((COMMAND.equalsIgnoreCase("exit")) || (COMMAND.equalsIgnoreCase("end")) || (COMMAND.equalsIgnoreCase("quit"))) { return (SHELL_RETURN_CODE_EXIT); } // *************************** // If we fell through then we // have an invalid command. displayMsg("Specified Command '" + COMMAND + "', is Invalid."); displayMsg("Please use 'help' for Commands and Usage."); // ******************** // Return return (0); } // End of CMDprocess Method. /** * Command Line Interactive Mode Shell. */ public int CMDInteractiveShell() { BatchMode = false; // *************************** // Gain Access to Our // System Input. Reader r = new BufferedReader(new InputStreamReader(System.in)); StreamTokenizer st = new StreamTokenizer(r); // *************************** // Customize our Tokenizer. st.resetSyntax(); st.wordChars('0', '9'); // Make digit chars Word Characters. st.wordChars('a', 'z'); // Word Characters. st.wordChars('A', 'Z'); // Word Characters. st.wordChars('!', '!'); // ! as a Word Character. st.wordChars('(', '/'); // ( ) * + , - . / as Word Characters. st.wordChars('$', '&'); // $ % & as Word Characters. st.wordChars(':', '@'); // : ; < = > ? @ as Word Characters. st.wordChars('[', '`'); // [ \ ] ^ _ ` as Word Characters. st.wordChars('{', '~'); // { | } ~ as Word Characters. st.quoteChar('"'); // Double Quote. st.quoteChar('\047'); // Single Quote. st.eolIsSignificant(true); // End Of Line is Significant. st.slashStarComments(false); // Slash Star Comments Ignored. st.slashSlashComments(false); // C-C++ Slash Comments Ignored. st.commentChar('#'); // Pound Sign, Single Line Comment. st.whitespaceChars(0, ' '); // ************************** // Show Initial Prompt displayMsg("Framework Interactive Shell Session Started."); displayPrompt(); int cmdrc = 0; LinkedList<String> CMDLINE = new LinkedList<>(); boolean ILOOP = true; try { while (ILOOP) { switch (st.nextToken()) { case StreamTokenizer.TT_NUMBER: Double num = new Double(st.nval); CMDLINE.addLast(num.toString()); break; case StreamTokenizer.TT_WORD: CMDLINE.addLast(st.sval); break; case StreamTokenizer.TT_EOL: // ********************** // Process the Request try { cmdrc = CMDprocess(CMDLINE); } catch (Exception cx) { displayErrorMsg(cx.getMessage()); displayErrorMsg(cx.toString()); cx.printStackTrace(); } // End of Exception // ********************** // Check for Exit... if (cmdrc == SHELL_RETURN_CODE_EXIT) { ILOOP = false; break; } // End of Exit If. // *********************** // Ready for Next Command. CMDLINE.clear(); displayPrompt(); break; case StreamTokenizer.TT_EOF: ILOOP = false; break; default: if ((st.sval != null) && (!st.sval.equalsIgnoreCase(""))) { CMDLINE.addLast("\042" + st.sval + "\042"); } break; } // End of Switch } // End of While Loop. } catch (IOException ioe) { // won't happen too often from the keyboard } // End Of Exception. // ***************************** // Return from Interactive Shell displayMsg("Framework Interactive Shell Session Complete."); return (0); } // End of CMDInteractiveShell. /** * Command Line Prompt to obtain a Yes|No, True|False Indication. */ public boolean CMDPrompt() { // *********************** // Initialize. // *************************** // Gain Access to Our // System Input. BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); // ************************ // Loop to Obtain Data. String response = null; while (response == null) { try { response = r.readLine(); } catch (IOException ioe) { // Ignore Exception. } // End of Exception Processing. } // End of While Loop Obtaining Data from StdInput. // ************************* // Now Check the Response. if ((response.trim().equalsIgnoreCase("yes")) || (response.trim().equalsIgnoreCase("y")) || (response.trim().equalsIgnoreCase("true")) || (response.trim().equalsIgnoreCase("t"))) { return true; } // ***************************** // Falling Through we have a // False Condition. return false; } // End of CMDPrompt. /** * Command Line Prompt to obtain a String. */ public String CMDPromptForString() { // *********************** // Initialize. // *************************** // Gain Access to Our // System Input. BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); // ************************ // Loop to Obtain Data. String response = null; while (response == null) { try { response = r.readLine(); } catch (IOException ioe) { // Ignore Exception. } // End of Exception Processing. } // End of While Loop Obtaining Data from StdInput. // ***************************** // Return the String Data. return response.trim(); } // End of CMDPromptForString Method.. /** * Set indicators for OS we are running on. */ public void determineOS() { String os = System.getProperty("os.name").toLowerCase(); if (os.startsWith("windows")) { UNIX = false; WINDOWS = true; } // End of If. else { UNIX = true; WINDOWS = false; } // End of Else. } // End of determineOS Method. /** * getHostName Helper Method for Methods. */ public static String getHostName() { try { return InetAddress.getLocalHost().getHostName(); } catch (java.net.UnknownHostException uhe) { return ("localhost"); } // End of Exception. } // End of getHostName Method. /** * Display Prompt in common format. */ public void displayPrompt() { System.out.print(Prompt); } // End of displayPrompt Method. /** * Display Messages in common format. */ public void displayMsg(String _message) { if (_message == null) { return; } if (!VERBOSE) { return; } // ************************** // Display Message. //if (!BatchMode) { System.out.print(Prompt); } System.out.println(_message); } // End of displayMsg Method. /** * Display Error Messages in common format. */ public void displayErrorMsg(String _message) { if (_message == null) { return; } // ************************** // Display Message. //if (!BatchMode) { System.out.print(Prompt); } System.out.println("** " + _message); } // End of displayMsg Method. /** * Perform an External Command Function, wait until completed while obtaining the results. * * @param _ExecName Command To be Executed. * @param _ExecArgs Arguments for the Command, Space Seperated. * @return int Return code from External Command. */ public int performExternalCommand(String _ExecName, String _ExecArgs) throws InterruptedException, IOException { return (performExternalCommand(_ExecName, _ExecArgs, true, true)); } // End of performExternalCommand Method. /** * Perform an External Command Function, wait until completed while obtaining the results. * * @param _ExecName Command To be Executed. * @param _ExecArgs Arguments for the Command, Space Seperated. * @param _obtainoutput Indicator whether or not to obtain output from Command completion. * @param _wait Indicator whether or not to wait for Command completion. * @return int Return code from External Command. */ public int performExternalCommand(final String _ExecName, final String _ExecArgs, final boolean _obtainoutput, final boolean _wait) throws InterruptedException, IOException { // **************************************** // Note The Start Time. idxElapsedTime elt = new idxElapsedTime(); // ************************************* // Initialize the results. lastExternalCMDOutput.clear(); lastExternalCMDError.clear(); int lastExternalRC = 0; // ************************************ // Perform the External Command. try { String zExecName = _ExecName; if (WINDOWS) { zExecName = WIN_RUNCMD + " " + _ExecName; } Process p = Runtime.getRuntime().exec(zExecName + " " + _ExecArgs); BufferedReader se = new BufferedReader (new InputStreamReader(p.getErrorStream())); BufferedReader so = new BufferedReader (new InputStreamReader(p.getInputStream())); // ****************************** // Wait for Completion. if (_wait) { if (_obtainoutput) { // ************************** // Obtain the Output. String buf; while ((buf = so.readLine()) != null) { lastExternalCMDOutput.addLast(buf); } // ************************** // Obtain the Error Messages. while ((buf = se.readLine()) != null) { lastExternalCMDError.addLast(buf); } } // End of obtain output If. // ************************** // Wait for Completion. lastExternalRC = p.waitFor(); } // End of Wait } catch (IOException ioe) { // ************************************** // If we receive an Error Code = 2, // then we have a file not found, or a // command not found condition. displayMsg("*** IOE:" + ioe.getMessage()); throw (ioe); } // End of Trap of IOException // **************************************** // Note The End Time. elt.setEnd(); // ************************** // Return return (lastExternalRC); } ///:~ End of performExternalCommand Method. /** * Find in List a String and Return List of Responses from the Stack. */ public LinkedList<String> findInList(LinkedList _LL, String _pattern) { LinkedList<String> resultsList = new LinkedList<>(); // ********************* // Compile Our Pattern. Pattern pattern = null; Matcher pm = null; try { pattern = Pattern.compile(_pattern); } catch (PatternSyntaxException pse) { displayErrorMsg("Error Using RegEx Pattern in findinList Method, " + pse.getMessage()); return (resultsList); } // End of Exception. // ********************** // Scan our Link List // for the Expression. // for (int i = 0; i < _LL.size(); i++) { if (pm == null) { pm = pattern.matcher((String) _LL.get(i)); } else { pm.reset((String) _LL.get(i)); } if (pm.find()) { resultsList.addLast((String) _LL.get(i)); } // End of find if. } // End of For Loop. // ******************* // Return. return (resultsList); } // End of findInList Method. /** * Find in List a String and Return List of Responses from the Stack. */ public LinkedList getFromList(LinkedList<String> _LL, int[] _tokens, int _max) { LinkedList<String> resultsList = new LinkedList<>(); // ********************** // Scan our Link List // for the Expression. // for (int i = 0; i < _LL.size(); i++) { if (i >= _max) { break; } int b = 0; String nstr = ""; StringTokenizer st = new StringTokenizer((String) _LL.get(i)); while (st.hasMoreTokens()) { String NT = st.nextToken(); b++; for (int j = 0; j < _tokens.length; j++) { if (b == _tokens[j]) { if (nstr.equalsIgnoreCase("")) { nstr = NT; } else { nstr = nstr + " " + NT; } break; } // End of Token Hit. } // End of For Loop. } // End of Tokenizer While. // **************************************** // Stuff the new String into the new List. resultsList.addLast(nstr); } // End of Outer For Loop. // ******************* // Return. return (resultsList); } // End of getFromList Method. /** * Show a Directory Listing using a Pattern, with no sizes. */ public int showDirListing(String _dirname, String _pattern) { return (showDirListing(_dirname, _pattern, false)); } // End of showDirListing Method. /** * Show a Directory Listing using a Pattern. */ public int showDirListing(String _dirname, String _pattern, boolean _showsize) { // ********************* // Compile Our Pattern. Pattern pattern = null; Matcher pm = null; try { pattern = Pattern.compile(_pattern); } catch (PatternSyntaxException pse) { displayErrorMsg("Error Using RegEx Pattern in showDirList Method, " + pse.getMessage()); return (0); } // End of Exception. // ****************************** // Obtain the Directory Listing. int count = 0; File ld = new File(_dirname); if (!ld.isDirectory()) { return (0); } String contents[] = ld.list(); for (int i = 0; i < contents.length; i++) { if (pm == null) { pm = pattern.matcher((String) contents[i]); } else { pm.reset((String) contents[i]); } // ******************************** // Display the Filtered Contents if (pm.find()) { count++; File DGD = new File(_dirname + File.separator + contents[i]); String type = "-"; if (DGD.isDirectory()) { type = "d"; } if (_showsize) { Long bytesize = new Long(DGD.length()); displayMsg(type + " " + SF.JRight(bytesize.toString(), 10) + " " + getTimeStamp(DGD.lastModified()) + " " + DGD.getAbsolutePath()); } else { displayMsg(type + " " + getTimeStamp(DGD.lastModified()) + " " + DGD.getAbsolutePath()); } // End of If Else. } // End of find if. } // End of For Loop. // ******************* // Return. return (count); } // End of showDirListing Method. /** * getFTS will obtain a timestamp suitable for printing * in a Log file. * * @return String the value containing the timestamp in the for of * <B>YYYY-MM-DY.HH:MM:SS</B> * All timestamps generated will be relative to GMT+0 if LOCALTIME * is set to false. */ public String getTimeStamp(long _ms) { int year; int month; int day; int hour; int minute; int second; String myTimeStamp = ""; Calendar rightNow = Calendar.getInstance(); if (_ms > 0) { rightNow.setTimeInMillis(_ms); } // *************************** // Formulate the Time Stamp. year = rightNow.get(Calendar.YEAR); myTimeStamp = String.valueOf(year); myTimeStamp = myTimeStamp.concat("-"); month = rightNow.get(Calendar.MONTH) + 1; if (month <= 9) { myTimeStamp = myTimeStamp.concat("0"); } myTimeStamp = myTimeStamp.concat(String.valueOf(month)); myTimeStamp = myTimeStamp.concat("-"); day = rightNow.get(Calendar.DAY_OF_MONTH); if (day <= 9) { myTimeStamp = myTimeStamp.concat("0"); } myTimeStamp = myTimeStamp.concat(String.valueOf(day)); myTimeStamp = myTimeStamp.concat("."); hour = rightNow.get(Calendar.HOUR_OF_DAY); if (hour <= 9) { myTimeStamp = myTimeStamp.concat("0"); } myTimeStamp = myTimeStamp.concat(String.valueOf(hour)); myTimeStamp = myTimeStamp.concat(":"); minute = rightNow.get(Calendar.MINUTE); if (minute <= 9) { myTimeStamp = myTimeStamp.concat("0"); } myTimeStamp = myTimeStamp.concat(String.valueOf(minute)); myTimeStamp = myTimeStamp.concat(":"); second = rightNow.get(Calendar.SECOND); if (second <= 9) { myTimeStamp = myTimeStamp.concat("0"); } myTimeStamp = myTimeStamp.concat(String.valueOf(second)); return (myTimeStamp); } // End of getTimeStamp Method. /** * Display STDOUT from Command. */ public void displayLastSTDOUT() { for (int i = 0; i < lastExternalCMDOutput.size(); i++) { displayMsg((String) lastExternalCMDOutput.get(i)); } } // End of displayLastSTDOUT Method. /** * Display Error from Command. */ public void displayLastSTDERR() { for (int i = 0; i < lastExternalCMDError.size(); i++) { displayErrorMsg((String) lastExternalCMDError.get(i)); } } // End of displayLastSTDERR Method. /** * Obtain a Return Code Value from the STDOUT Stream. */ public int obtainReturnCodeFromLastSTDOUT() { int rc = -1; for (int i = 0; i < lastExternalCMDOutput.size(); i++) { String rcstr = (String) lastExternalCMDOutput.get(i); try { rc = Integer.parseInt(rcstr); } catch (NumberFormatException nfe) { rc = -1; // Ignore it. } // End of Exception Processing } // End of For Loop. // **************************** // Return a Numeric Value. return rc; } // End of obtainReturnCodeFromLastSTDOUT Method. /* * Write Logs to a Real LOG File. */ public void saveLogs(final String LogFileName) { // *************************************** // Open up our Log File for Writing.... // Always Append. try { BufferedWriter LOGOUT = new BufferedWriter( new FileWriter(LogFileName, true)); // *************************************** // Loop to write out Standard Output. for (int i = 0; i < lastExternalCMDOutput.size(); i++) { LOGOUT.write((String) lastExternalCMDOutput.get(i)); LOGOUT.newLine(); } // End of For Loop. // *************************************** // Loop to write out Error Output. for (int i = 0; i < lastExternalCMDError.size(); i++) { LOGOUT.write((String) lastExternalCMDError.get(i)); LOGOUT.newLine(); } // End of For Loop. // *************************************** // Now Close up the Log File. LOGOUT.flush(); LOGOUT.close(); } catch (IOException ioe) { displayErrorMsg("IOException encountered when Saving Log File:[" + ioe + "]"); ioe.printStackTrace(); } // End of Exception Processing. } // End of saveLogs Method. /** * backupFile from source file to new destination file. * Wraps the copyFile Method. */ public void backupFile(String filename, String srcdir, String destdir) throws IOException { // *********************************** // Copy a File from one location to // another for Backup. try { long bc = this.copyFile(new File(srcdir + File.separator + filename), new File(destdir + File.separator + filename)); if (bc > 0) { displayMsg("Backup of " + filename + ", Successful, File Size:[" + bc + "] Bytes"); } else { displayMsg("Backup of " + filename + ", Not Successful!"); } } catch (FileNotFoundException fnotfound) { //displayMsg("Backup of "+filename+", not performed, since source file does not exist."); } // End of Exception. } // End of backupFile. /** * restoreFile from a backup source file to new destination file. * Wraps the copyFile Method. */ public void restoreFile(String filename, String srcdir, String destdir) throws IOException { // *********************************** // Copy a File from one location to // another for Restoration. try { long bc = this.copyFile(new File(srcdir + File.separator + filename), new File(destdir + File.separator + filename)); if (bc > 0) { displayMsg("Restore of " + filename + ", Successful, File Size:[" + bc + "] Bytes"); } else { displayMsg("restore of " + filename + ", Not Successful!"); } } catch (FileNotFoundException fnotfound) { //displayMsg("Restore of "+filename+", not performed, since backup file does not exist."); } // End of Exception. } // End of copyFile. /** * copyFile from source file to new destination file. */ public long copyFile(File src, File dst) throws IOException { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dst); // ****************************** // Transfer bytes from in to out byte[] buf = new byte[1024]; int len = 0; long bytecount = 0; while ((len = in.read(buf)) > 0) { bytecount = bytecount + len; out.write(buf, 0, len); } // End of While Loop for Copy. // **************************** // Close off the Files. in.close(); out.close(); // **************************** // Return the byte count. return (bytecount); } // End of copyFile Shell Method. /** * showFile Contents. */ public void showFile(File src) throws IOException { InputStream in = new FileInputStream(src); // ****************************** // Transfer bytes from in to out StringBuffer sb = new StringBuffer(); byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) > 0) { for (int ib = 0; ib < len; ib++) { sb.append((char) buf[ib]); } } // End of While Loop for Copy. // **************************** // Close off the File. in.close(); // **************************** // Now Dump the Contents. displayMsg(sb.toString()); // **************************** // Return. return; } // End of showFile Shell Method. // ****************************************************** // MAIN // ****************************************************** /** * main to provide command line capability. */ public static void main(String[] args) { // ********************** // Check the Command Line // Argument for a "-i" or // /i option to specify // interactive mode. if ((args.length == 1) && ((args[0].equalsIgnoreCase("-i")) || (args[0].equalsIgnoreCase("--interactive")) || (args[0].equalsIgnoreCase("/i")))) { Shell shell = new Shell(false); System.exit(shell.CMDInteractiveShell()); } // End of Interactive Shell Check. // ********************* // Establish new // Batch Shell to process // Single Command. // Shell shell = new Shell(); try { // ********************* // Process Command System.exit(shell.CMDprocess(args)); } catch (Exception x) { System.err.println(x); } // End of Exception. } // End of Main. } ///~ End of Shell Class