741 |
10 Oct 06 |
olle |
1 |
/* |
1652 |
22 May 07 |
gregory |
$Id$ |
741 |
10 Oct 06 |
olle |
3 |
|
1916 |
31 Aug 07 |
jari |
Copyright (C) 2006 Olle Mansson |
1916 |
31 Aug 07 |
jari |
Copyright (C) 2007 Gregory Vincic |
741 |
10 Oct 06 |
olle |
6 |
|
1652 |
22 May 07 |
gregory |
This file is part of Proteios. |
1652 |
22 May 07 |
gregory |
Available at http://www.proteios.org/ |
741 |
10 Oct 06 |
olle |
9 |
|
1652 |
22 May 07 |
gregory |
Proteios is free software; you can redistribute it and/or modify it |
1652 |
22 May 07 |
gregory |
under the terms of the GNU General Public License as published by |
1652 |
22 May 07 |
gregory |
the Free Software Foundation; either version 2 of the License, or |
1652 |
22 May 07 |
gregory |
(at your option) any later version. |
741 |
10 Oct 06 |
olle |
14 |
|
1652 |
22 May 07 |
gregory |
Proteios is distributed in the hope that it will be useful, but |
1652 |
22 May 07 |
gregory |
WITHOUT ANY WARRANTY; without even the implied warranty of |
1652 |
22 May 07 |
gregory |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1652 |
22 May 07 |
gregory |
General Public License for more details. |
741 |
10 Oct 06 |
olle |
19 |
|
1652 |
22 May 07 |
gregory |
You should have received a copy of the GNU General Public License |
1652 |
22 May 07 |
gregory |
along with this program; if not, write to the Free Software |
1652 |
22 May 07 |
gregory |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
1652 |
22 May 07 |
gregory |
02111-1307, USA. |
1652 |
22 May 07 |
gregory |
24 |
*/ |
741 |
10 Oct 06 |
olle |
25 |
|
741 |
10 Oct 06 |
olle |
// Xerver Free Web Server |
741 |
10 Oct 06 |
olle |
// Copyright (C) 2002-2005 Omid Rouhani |
741 |
10 Oct 06 |
olle |
28 |
// |
741 |
10 Oct 06 |
olle |
29 |
// |
741 |
10 Oct 06 |
olle |
// This program is free software; you can redistribute it and/or |
741 |
10 Oct 06 |
olle |
// modify it under the terms of the GNU General Public License |
741 |
10 Oct 06 |
olle |
// as published by the Free Software Foundation; either version 2 |
741 |
10 Oct 06 |
olle |
// of the License, or (at your option) any later version. |
741 |
10 Oct 06 |
olle |
34 |
// |
741 |
10 Oct 06 |
olle |
// This program is distributed in the hope that it will be useful, |
741 |
10 Oct 06 |
olle |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
741 |
10 Oct 06 |
olle |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
741 |
10 Oct 06 |
olle |
// GNU General Public License for more details. |
741 |
10 Oct 06 |
olle |
39 |
// |
741 |
10 Oct 06 |
olle |
// You should have received a copy of the GNU General Public License |
741 |
10 Oct 06 |
olle |
// along with this program; if not, write to the Free Software |
741 |
10 Oct 06 |
olle |
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
741 |
10 Oct 06 |
olle |
43 |
// |
741 |
10 Oct 06 |
olle |
44 |
// |
741 |
10 Oct 06 |
olle |
45 |
// ############################################################# |
741 |
10 Oct 06 |
olle |
// ## YOU CAN CONTACT THE AUTHOR (OMID ROUHANI) AT: ## |
741 |
10 Oct 06 |
olle |
// ## HTTP://WWW.JAVASCRIPT.NU/XERVER/ ## |
741 |
10 Oct 06 |
olle |
48 |
// ## ## |
741 |
10 Oct 06 |
olle |
// ## IF YOUR SOFTWARE IS NOT RELEASED UNDER THE ## |
741 |
10 Oct 06 |
olle |
// ## GNU GENERAL PUBLIC LICENSE (GPL), ## |
741 |
10 Oct 06 |
olle |
// ## PLEASE DO NOT COPY ANYTHING FROM THIS SOURCE CODE!!! ## |
741 |
10 Oct 06 |
olle |
52 |
// ## ## |
741 |
10 Oct 06 |
olle |
// ## FOR FULL LICENSE, PLEASE READ "XERVER LICENSE". ## |
741 |
10 Oct 06 |
olle |
54 |
// ############################################################# |
741 |
10 Oct 06 |
olle |
55 |
|
1652 |
22 May 07 |
gregory |
56 |
package se.lu.thep.coreftpd.webserver; |
741 |
10 Oct 06 |
olle |
57 |
|
791 |
23 Oct 06 |
olle |
58 |
import se.lu.thep.coreftpd.common.DataInputStreamWithReadLine; |
791 |
23 Oct 06 |
olle |
59 |
import se.lu.thep.coreftpd.common.MyInteger; |
741 |
10 Oct 06 |
olle |
60 |
import java.io.BufferedInputStream; |
741 |
10 Oct 06 |
olle |
61 |
import java.io.BufferedOutputStream; |
741 |
10 Oct 06 |
olle |
62 |
import java.io.DataOutputStream; |
741 |
10 Oct 06 |
olle |
63 |
import java.io.File; |
741 |
10 Oct 06 |
olle |
64 |
import java.io.OutputStream; |
741 |
10 Oct 06 |
olle |
65 |
|
741 |
10 Oct 06 |
olle |
66 |
/** |
1652 |
22 May 07 |
gregory |
67 |
* |
1652 |
22 May 07 |
gregory |
* <B>How to use:</B> <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>(new RunScript(String command, OutputStream argFos, String [] |
1652 |
22 May 07 |
gregory |
* environmentVariablesString, DataInputStreamWithReadLine DISWR_POSTData, |
1652 |
22 May 07 |
gregory |
* String s_scriptLocation, NewConnection NC_theNewConnection)).start();</CODE> |
741 |
10 Oct 06 |
olle |
* <BR> |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
74 |
* |
1652 |
22 May 07 |
gregory |
* <B>More info:</B> <BR> |
1652 |
22 May 07 |
gregory |
* This class gets a command and runs it. STDOUT and STDERR from the script is |
1652 |
22 May 07 |
gregory |
* sent to an <CODE>argFos</CODE>. <BR> |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
79 |
* |
1652 |
22 May 07 |
gregory |
* <CODE>command</CODE> = a command (IMPORTANT: a command in java is NOT a |
1652 |
22 May 07 |
gregory |
* command you give in the prompt, but it's a runnable program. For example: |
1652 |
22 May 07 |
gregory |
* [Wrong: "script.pl"; Correct: "perl script.pl"] (it doesn't matter that you |
1652 |
22 May 07 |
gregory |
* in a prompt only have to write "script.pl")) <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>argFos</CODE> = the output will be written to this <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>environmentVariablesString</CODE> = an array of <CODE>String</CODE>s: |
1652 |
22 May 07 |
gregory |
* "envVar=envValue" <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>DISWR_POSTData</CODE> = this will be sent to standard input (if this |
1652 |
22 May 07 |
gregory |
* is <CODE>==null</CODE>, nothing will be sent to STDIN). <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>argScriptLocation</CODE> = Location of script as browser path |
1652 |
22 May 07 |
gregory |
* ("http://server.com/dir1/dir2/file.pl" ==> "/dir1/dir2/") <BR> |
1652 |
22 May 07 |
gregory |
* <CODE>NC_theNewConnection</CODE> = this shall be the <CODE>NewConnection</CODE> |
1652 |
22 May 07 |
gregory |
* that belongs to the specific request that started RunScript. We need this to |
1652 |
22 May 07 |
gregory |
* change the value off <CODE>s_errorStatus</CODE> to "500 Internal Server |
1652 |
22 May 07 |
gregory |
* Error" and to run <CODE>addThisHitToLog()</CODE>. |
1652 |
22 May 07 |
gregory |
95 |
* |
741 |
10 Oct 06 |
olle |
* <BR> |
1652 |
22 May 07 |
gregory |
97 |
* |
741 |
10 Oct 06 |
olle |
* @author <a href="http://www.JavaScript.nu/xerver/" TARGET="_top">Omid Rouhani</a> |
741 |
10 Oct 06 |
olle |
* @version 1.0 |
741 |
10 Oct 06 |
olle |
100 |
*/ |
741 |
10 Oct 06 |
olle |
101 |
|
1652 |
22 May 07 |
gregory |
102 |
final public class RunScript extends Thread { |
1652 |
22 May 07 |
gregory |
103 |
private final static boolean b_showErrors = false; |
741 |
10 Oct 06 |
olle |
104 |
|
1652 |
22 May 07 |
gregory |
105 |
private BufferedInputStream bis; // Get data from script from this |
1652 |
22 May 07 |
gregory |
// (STDOUT) |
741 |
10 Oct 06 |
olle |
107 |
|
1652 |
22 May 07 |
gregory |
108 |
private BufferedInputStream bes; // Get errors from script from this |
1652 |
22 May 07 |
gregory |
// (STDERR) |
741 |
10 Oct 06 |
olle |
110 |
|
1652 |
22 May 07 |
gregory |
111 |
private BufferedOutputStream bos; // Send data to script with this (for |
1652 |
22 May 07 |
gregory |
// example when POST-data has been sent) |
741 |
10 Oct 06 |
olle |
113 |
|
1652 |
22 May 07 |
gregory |
114 |
MyInteger whoShallRespond = new MyInteger(ReadInputStream.RESPOND_UNDEFINED); |
1652 |
22 May 07 |
gregory |
115 |
|
1652 |
22 May 07 |
gregory |
116 |
private int i_timeToKillScript = 60 * 60 * 1000; // One hour before we |
1652 |
22 May 07 |
gregory |
// kill process |
1652 |
22 May 07 |
gregory |
118 |
|
741 |
10 Oct 06 |
olle |
119 |
private Process proc; |
741 |
10 Oct 06 |
olle |
120 |
|
1652 |
22 May 07 |
gregory |
// private static int i_numberRunScriptsRunning=0; |
1652 |
22 May 07 |
gregory |
// private static int i_numberRunScriptsNotFinalized=0; |
741 |
10 Oct 06 |
olle |
123 |
|
1652 |
22 May 07 |
gregory |
124 |
public RunScript(String command, OutputStream argFos, |
1652 |
22 May 07 |
gregory |
125 |
String[] environmentVariablesString, |
1652 |
22 May 07 |
gregory |
126 |
DataInputStreamWithReadLine DISWR_POSTData, |
1652 |
22 May 07 |
gregory |
127 |
String s_scriptLocation, String s_documentToReturn, |
1652 |
22 May 07 |
gregory |
128 |
NewConnection NC_theNewConnection) { |
1652 |
22 May 07 |
gregory |
// i_numberRunScriptsRunning++; |
1652 |
22 May 07 |
gregory |
// i_numberRunScriptsNotFinalized++; |
741 |
10 Oct 06 |
olle |
131 |
|
741 |
10 Oct 06 |
olle |
132 |
try { |
741 |
10 Oct 06 |
olle |
133 |
Runtime run; |
1652 |
22 May 07 |
gregory |
134 |
DataOutputStream fos; // FileOutputStream |
741 |
10 Oct 06 |
olle |
135 |
run = Runtime.getRuntime(); |
1652 |
22 May 07 |
gregory |
136 |
proc = run.exec(command, environmentVariablesString, new File( |
1652 |
22 May 07 |
gregory |
137 |
s_documentToReturn).getParentFile()); // Make sure the |
1652 |
22 May 07 |
gregory |
// script is running |
1652 |
22 May 07 |
gregory |
// with PWD to the |
1652 |
22 May 07 |
gregory |
// correct directory |
1652 |
22 May 07 |
gregory |
141 |
fos = new DataOutputStream(argFos); |
741 |
10 Oct 06 |
olle |
142 |
|
1652 |
22 May 07 |
gregory |
143 |
bis = new BufferedInputStream(proc.getInputStream()); |
1652 |
22 May 07 |
gregory |
144 |
bes = new BufferedInputStream(proc.getErrorStream()); |
1652 |
22 May 07 |
gregory |
145 |
bos = new BufferedOutputStream(proc.getOutputStream()); |
741 |
10 Oct 06 |
olle |
146 |
|
741 |
10 Oct 06 |
olle |
147 |
ReadInputStreamSTDERR stdErrThread; |
1652 |
22 May 07 |
gregory |
148 |
(stdErrThread = new ReadInputStreamSTDERR(bes, fos, |
1652 |
22 May 07 |
gregory |
149 |
s_scriptLocation, NC_theNewConnection, whoShallRespond, |
1652 |
22 May 07 |
gregory |
150 |
this)).start(); // Don't write Location and Content-Type |
1652 |
22 May 07 |
gregory |
151 |
(new ReadInputStreamSTDOUT(bis, fos, s_scriptLocation, |
1652 |
22 May 07 |
gregory |
152 |
NC_theNewConnection, stdErrThread, whoShallRespond, this)) |
1652 |
22 May 07 |
gregory |
153 |
.start(); // Don't write Location and Content-Type |
741 |
10 Oct 06 |
olle |
154 |
|
1652 |
22 May 07 |
gregory |
155 |
if (DISWR_POSTData != null) { |
741 |
10 Oct 06 |
olle |
156 |
(new ReadInputStreamSTDIN(DISWR_POSTData, bos, this)).start(); |
741 |
10 Oct 06 |
olle |
157 |
} |
741 |
10 Oct 06 |
olle |
158 |
|
741 |
10 Oct 06 |
olle |
159 |
RunKiller rk_killer = new RunKiller(proc, fos, i_timeToKillScript); |
1652 |
22 May 07 |
gregory |
160 |
rk_killer.start(); // Kill process after 5*60 seconds |
741 |
10 Oct 06 |
olle |
161 |
|
741 |
10 Oct 06 |
olle |
162 |
proc.waitFor(); |
741 |
10 Oct 06 |
olle |
163 |
|
1652 |
22 May 07 |
gregory |
164 |
} catch (Exception e) { |
1652 |
22 May 07 |
gregory |
165 |
if (b_showErrors) |
1652 |
22 May 07 |
gregory |
166 |
System.out.println("An error has occured @ RunScript:\n" |
1652 |
22 May 07 |
gregory |
167 |
+ e.getMessage()); |
1652 |
22 May 07 |
gregory |
168 |
} |
741 |
10 Oct 06 |
olle |
169 |
|
1652 |
22 May 07 |
gregory |
// i_numberRunScriptsRunning--; |
741 |
10 Oct 06 |
olle |
171 |
|
1652 |
22 May 07 |
gregory |
// System.out.println("RunScript running: "+i_numberRunScriptsRunning); |
1652 |
22 May 07 |
gregory |
// System.out.println("RunScript running (finalized): |
1652 |
22 May 07 |
gregory |
// "+i_numberRunScriptsNotFinalized); |
741 |
10 Oct 06 |
olle |
175 |
} |
741 |
10 Oct 06 |
olle |
176 |
|
1652 |
22 May 07 |
gregory |
177 |
public void killProcess() { |
1652 |
22 May 07 |
gregory |
178 |
if (proc != null) { |
741 |
10 Oct 06 |
olle |
179 |
proc.destroy(); |
1652 |
22 May 07 |
gregory |
180 |
proc = null; |
741 |
10 Oct 06 |
olle |
181 |
} |
741 |
10 Oct 06 |
olle |
182 |
} |
741 |
10 Oct 06 |
olle |
183 |
|
1652 |
22 May 07 |
gregory |
// Testing... |
2386 |
14 Nov 07 |
gregory |
185 |
@Override |
1652 |
22 May 07 |
gregory |
186 |
protected void finalize() throws Throwable { |
1652 |
22 May 07 |
gregory |
// i_numberRunScriptsNotFinalized--; |
741 |
10 Oct 06 |
olle |
188 |
|
1652 |
22 May 07 |
gregory |
189 |
if (bos != null) { |
741 |
10 Oct 06 |
olle |
190 |
bos.flush(); |
741 |
10 Oct 06 |
olle |
191 |
bos.close(); |
1652 |
22 May 07 |
gregory |
192 |
bos = null; |
741 |
10 Oct 06 |
olle |
193 |
} |
1652 |
22 May 07 |
gregory |
194 |
if (bes != null) { |
741 |
10 Oct 06 |
olle |
195 |
bes.close(); |
1652 |
22 May 07 |
gregory |
196 |
bes = null; |
741 |
10 Oct 06 |
olle |
197 |
} |
1652 |
22 May 07 |
gregory |
198 |
if (bis != null) { |
741 |
10 Oct 06 |
olle |
199 |
bis.close(); |
1652 |
22 May 07 |
gregory |
200 |
bis = null; |
741 |
10 Oct 06 |
olle |
201 |
} |
1652 |
22 May 07 |
gregory |
202 |
if (proc != null) { |
741 |
10 Oct 06 |
olle |
203 |
proc.destroy(); |
1652 |
22 May 07 |
gregory |
204 |
proc = null; |
741 |
10 Oct 06 |
olle |
205 |
} |
741 |
10 Oct 06 |
olle |
206 |
} |
741 |
10 Oct 06 |
olle |
207 |
} |