All Packages This Package Class Hierarchy Class Search Index
java.lang.Object | +----app.authkit.envoy.Envoy
Summary |
public class Envoy extends java.lang.Object { // Fields 11 public static final String PROTOCOL_BEGIN_OUTPUT; public static final String PROTOCOL_BEGIN_TASK; public static final String PROTOCOL_DELIM; public static final String PROTOCOL_END_OUTPUT; public static final String PROTOCOL_END_TASK; public static final String PROTOCOL_NEWLINE; public static final String PROTOCOL_STOP; public static final String TASKS_BETWEEN; public static final String TASKS_BETWEEN_PROP; protected int myTaskNumber; protected int myTaskStatus; // Constructors 1 public Envoy(); // Methods 20 public static void main(String[]); protected Authorization buildAuth(); public void explain(Throwable); public int finish(); protected Authorization getAuthorization(); protected void groupTaskArgs(Enumeration, Vector, String); protected Authorization newAuth(); public void perform(String[]); public void prepare(); protected void prepareTaskIO(); protected void protocolBegins(); protected void protocolEnds(); protected InputStream protocolIn(); protected PrintStream protocolOut(); protected void taskBegins(int, String); protected void taskBeginsOutput(int, Task); protected void taskEnds(int, Task, int); protected void taskEndsOutput(int, Task); protected void taskFails(int, Task, int); protected int taskPerform(int, Vector); }
Envoy performs Tasks in a presumably privileged process, reporting on their success.
The Envoy.main() method is the typical entry-point of a privileged process, executed via Authorization.execPrivileged(). As a result, its stdin and stdout (System.in and System.out) are presumed to be connected to a pipe going back to the parent process. The pipe's streams may be coupled together, so closing one may close both. This constrains how the Envoy can communicate results back to its parent. The Envoy is expected to return Task outcomes and data on its stdout, including its own termination status, since the privileged Process in the parent may not provide waitFor() or exitValue().
An Envoy's stderr stream is typically inherited from the parent process, and usually writes to the system console (or its log-file) in a double-clicked app. It writes to stderr when invoked at the command-line or in other-than-double-clicked launches. It may or may not be used by the Envoy protocol. By default, it is not.
The simplest communication protocol for an Envoy is to only return its own "exit status" on stdout, and to discard all output produced by Tasks or external commands. The provided protocol can do more than that, but it's still very simple, if not simple-minded.
As each Task is undertaken, the Envoy sends a task-begin message. As each Task is completed, the Envoy sends a task-end message containing that Task's completion-code. Between task-begin and task-end, an output-producing Task's output data is produced. The output data is bracketed by text-begin and text-end messages.
When all Tasks are complete, the Envoy sends a stop message containing the Envoy's status code, i.e. its exit-code. An EOF on the Envoy stream before a stop message appears is an indication of failure.
The default Envoy behavior is to stop performing Tasks as soon as one of them fails. That is, as soon as a Task returns a non-zero completion code or throws an uncaught exception. The appropriate text-end, task-end, and stop messages are sent when a Task fails.
All task and stop messages are in plain ASCII text, one byte per char. Each message consists of an LF-terminated line, regardless of the host platform's local line-ending convention. Each message contains multiple parameters separated by :'s.
Subclasses of Envoy can use a different protocol, such as one based on XML. The messages are sent by specific methods, which can be overridden. If you use a different protocol, be sure to change the relevant Tool methods, too.
See Also: Task, Tool, Authorization
Fields |
· TASKS_BETWEEN | Summary | Top |
public static final String TASKS_BETWEEN
The default marker between task-groups in the args received by main() and perform().
· TASKS_BETWEEN_PROP | Summary | Top |
public static final String TASKS_BETWEEN_PROP
The property name of an override for TASKS_BETWEEN.
· myTaskNumber | Summary | Top |
protected int myTaskNumber
Task-number in perform() etc.
· myTaskStatus | Summary | Top |
protected int myTaskStatus
Completion status of most recently performed Task: 0 = success, !0 = failure-code.
· PROTOCOL_DELIM | Summary | Top |
public static final String PROTOCOL_DELIM
· PROTOCOL_NEWLINE | Summary | Top |
public static final String PROTOCOL_NEWLINE
· PROTOCOL_BEGIN_TASK | Summary | Top |
public static final String PROTOCOL_BEGIN_TASK
· PROTOCOL_BEGIN_OUTPUT | Summary | Top |
public static final String PROTOCOL_BEGIN_OUTPUT
· PROTOCOL_END_OUTPUT | Summary | Top |
public static final String PROTOCOL_END_OUTPUT
· PROTOCOL_END_TASK | Summary | Top |
public static final String PROTOCOL_END_TASK
· PROTOCOL_STOP | Summary | Top |
public static final String PROTOCOL_STOP
Constructors |
· Envoy | Summary | Top |
public Envoy()
Creates, but does not prepare() it.
Methods |
· main | Summary | Top |
public static void main(String[] args)
Static entry point, when run as an application. It just creates an Envoy instance and lets it do everything.
Normally, this method calls System.exit() with the value returned from finish(). If the Envoy throws an exception, this method calls System.exit(1), after printing a stack-trace to stderr and flushing both output streams.
· explain | Summary | Top |
public void explain(Throwable failure)
Emit stack trace on stderr, flushing protocolOut() first.
· prepare | Summary | Top |
public void prepare()
Prepare this Envoy for subsequent use.
This method should prepare the System I/O streams for use with Tasks, and arrange to "do protocol" on the default streams, which are presumed to be pipes to a parent process.
· perform | Summary | Top |
public void perform(String[] args)
Work through the args and the Tasks, communicating results to parent using Envoy protocol over presumed pipe. The protocol is performed by taskBegins(), taskEnds(), etc., which are called from taskPerform().
· finish | Summary | Top |
public int finish()
Finish doing protocol and anything else. Return exit-code that will be passed to System.exit().
By default, does not release() or detach() the Authorization. Therefore, the default action occurs on process termination, which is equivalent to release().
· groupTaskArgs | Summary | Top |
protected void groupTaskArgs(Enumeration argsEnum, Vector taskArgs, String between)
Pull one Task-name and a group of args from the given Enumeration, placing the String representation of each into the Vector. Upon return, the Vector may be empty.
Task-groups are separated by the 'between' String. The Vector will not contain either a leading or trailing 'between' String.
· taskPerform | Summary | Top |
protected int taskPerform(int taskNum, Vector taskGroup)
Perform a Task and return its status code: 0 for success, non-zero for all others. This method is responsible for all protocol messages regarding the task and its status.
This method calls taskBegins() before it runs the Task, followed by taskEnds() or taskFails() afterwards. It also calls taskBeginsOutput() and taskEndsOutput() as appropriate.
· getAuthorization | Summary | Top |
protected Authorization getAuthorization()
Return an Authorization, or null if before prepare()'d.
· buildAuth | Summary | Top |
protected Authorization buildAuth()
Called from prepare(), build an Authorization for possible subsequent use. If unsuccessful, throw an UnauthorizedException.
The returned Authorization should be attached to a session, if that's appropriate for what the Envoy is doing. Since an Envoy typically operates with an effective uid of 'root', and is typically a child process via execPrivileged(), the typical attachment is done with attachPrivileged(). This implementation does that.
This implementation calls newAuth() to make the concrete Authorization, then calls attachPrivileged() to attach it. Therefore, an Envoy by default will only run in a child process via execPrivileged(). This is a reasonable precaution to help prevent accidents, such as running Envoy.main() from a normal shell command-line.
· newAuth | Summary | Top |
protected Authorization newAuth()
The returned Authorization is unattached to any underlying session. The available concrete imps are hard-wired here, for security reasons.
If the "os.name" property is "Mac OS X", then a MacOSXAuthorization is returned. All other situations, including failure to instantiate a MacOSXAuthorization, return a DenyAllAuthorization.
The concrete classes are referenced by name, using Class.forName(). This avoids invoking an imp's static initializers unless it's actually chosen.
· protocolIn | Summary | Top |
protected InputStream protocolIn()
Return the stdin InputStream piped from controlling parent process, or null if before prepare()'d.
· protocolOut | Summary | Top |
protected PrintStream protocolOut()
Return the stdout PrintStream piped to controlling parent process, or null if before prepare()'d.
· protocolBegins | Summary | Top |
protected void protocolBegins()
Set up the streams that will be used to "do protocol" in taskBegins(), tasksEnds(), and taskFails(), and which will be shut down in an orderly fashion by finish().
If any initial text should be emitted on the protocol streams, do it here. This ensures it will occur before the first task begins.
· prepareTaskIO | Summary | Top |
protected void prepareTaskIO()
Called from prepare(), replace the System I/O streams with ones appropriate for a Task's use. This process's default streams, which are piped to another process, have already been harnessed to "do protocol" by protocolBegins().
· protocolEnds | Summary | Top |
protected void protocolEnds()
Called from finish(), send any Envoy-termination messages, and then shut down the I/O streams used to "do protocol". "Shut down" doesn't necessarily mean the streams are closed. It may just mean the streams are flushed, as here.
· taskBegins | Summary | Top |
protected void taskBegins(int taskNum, String taskName)
Send a BEGIN_TASK protocol message.
· taskBeginsOutput | Summary | Top |
protected void taskBeginsOutput(int taskNum, Task task)
Send a BEGIN_OUTPUT protocol message, then redirect System.out to a stream ready for the Task to produce its output on. If the Task does not write anything to System.out, then its results will be empty. This is acceptable as far as the protocol is concerned.
· taskEndsOutput | Summary | Top |
protected void taskEndsOutput(int taskNum, Task task)
Shut down the System.out used by the Task, sending any protocol messages to mark the end of Task output.
· taskEnds | Summary | Top |
protected void taskEnds(int taskNum, Task task, int status)
Send an END_TASK message.
The Task should not be null.
· taskFails | Summary | Top |
protected void taskFails(int taskNum, Task task, int status)
Send an END_TASK message.
The Task may be null, so qualify before using it.
All Packages This Package Class Hierarchy Class Search IndexFreshly brewed Java API Documentation automatically generated with polardoc Version 1.0.7