// ExecCommand.java
// $Id: ExecCommand.java,v 1.4 2000/08/16 21:37:47 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.jigsaw.ssi.commands ;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.Dictionary;
import java.util.Vector;
import org.w3c.www.http.HTTP ;
import org.w3c.util.ArrayDictionary;
import org.w3c.jigsaw.http.Reply;
import org.w3c.jigsaw.http.Request;
import org.w3c.jigsaw.ssi.DelayedInputStream;
import org.w3c.jigsaw.ssi.SSIFrame;
/**
* Implementation of the SSI <code>exec</code> command.
* It inserts the output from a CGI script or a shell command in the
* document. Note that in the Jigsaw architecture CGI scripts are just
* another resource class, so that no distinction is made between
* executing a CGI script or including a file.
* Relies on variables set by DefaultCommandRegistry.
* @author Antonio Ramirez <anto@mit.edu>
*/
public class ExecCommand extends BasicCommand {
private final static String NAME = "exec" ;
public Reply execute(SSIFrame ssiframe,
Request request,
ArrayDictionary parameters,
Dictionary variables)
{
String cmd = (String) parameters.get("cmd") ;
if(cmd != null) return executeCmd(ssiframe,
request,
parameters,
variables,
cmd) ;
// "cgi" would be handled here (just like an include...)
Reply reply = ssiframe.createDefaultReply(request,HTTP.OK) ;
reply.setContent("[unimplemented: use include]") ;
handleSimpleIMS(request,reply) ;
return reply ;
}
/**
* return true if reply can be cached.
* @return a boolean.
*/
public boolean acceptCaching() {
return true;
}
private Reply executeCmd(SSIFrame ssiframe,
Request request,
ArrayDictionary parameters,
Dictionary variables,
String cmd)
{
// Deny command if secure flag was set
if(((Boolean)variables.get("secure")).booleanValue()) {
Reply reply = ssiframe
.createCommandReply(request,HTTP.OK) ;
reply.setContent("[exec cmd not allowed: secure SSI]") ;
return reply ;
}
ArrayDictionary ssiVars = (ArrayDictionary)
variables.get("ssiVars") ;
if(ssiVars==null) {
Reply reply = ssiframe
.createCommandReply(request,HTTP.OK) ;
reply.setContent("[exec: can't find environment]") ;
handleSimpleIMS(request,reply) ;
return reply ;
}
String[] env = new String[ssiVars.size()] ;
for(int i=0,j=0;
i<ssiVars.capacity() && ssiVars.keyAt(i)!=null;
i++)
env[j++] =
(ssiVars.keyAt(i).toString())
+ "="
+ (ssiVars.elementAt(i).toString()) ;
Reply reply = new Reply(request.getClient()) ;
reply.setStream(new DelayedProcessStream(cmd,env)) ;
return reply ;
}
private final void addEnv(Vector env,String var,String val)
{
if(var!=null && val!=null)
env.addElement(var+'='+val) ;
}
public String getName()
{
return NAME;
}
public String getValue(Dictionary variables, String variable,
Request request) {
return "null";
}
}
class DelayedProcessStream extends DelayedInputStream {
private String cmd = null ;
private String[] env = null ;
DelayedProcessStream(String cmd, String[] env)
{
this.cmd = cmd ;
this.env = env ;
}
protected final void init()
{
Process proc = null ;
try {
proc = Runtime.getRuntime().exec(cmd,env) ;
} catch(IOException ex) {
proc = null ;
}
if(proc == null)
in = new StringBufferInputStream
("[exec: cannot start process: \""+cmd+"\"]") ;
else
in = proc.getInputStream() ;
}
}