client/ftpd/src/se/lu/thep/coreftpd/webserver/ReadInputStreamSTDOUT.java

Code
Comments
Other
Rev Date Author Line
741 10 Oct 06 olle 1 /*
1652 22 May 07 gregory 2  $Id$
741 10 Oct 06 olle 3
1916 31 Aug 07 jari 4  Copyright (C) 2006 Olle Mansson
1916 31 Aug 07 jari 5  Copyright (C) 2007 Gregory Vincic
741 10 Oct 06 olle 6
1652 22 May 07 gregory 7  This file is part of Proteios.
1652 22 May 07 gregory 8  Available at http://www.proteios.org/
741 10 Oct 06 olle 9
1652 22 May 07 gregory 10  Proteios is free software; you can redistribute it and/or modify it
1652 22 May 07 gregory 11  under the terms of the GNU General Public License as published by
1652 22 May 07 gregory 12  the Free Software Foundation; either version 2 of the License, or
1652 22 May 07 gregory 13  (at your option) any later version.
741 10 Oct 06 olle 14
1652 22 May 07 gregory 15  Proteios is distributed in the hope that it will be useful, but
1652 22 May 07 gregory 16  WITHOUT ANY WARRANTY; without even the implied warranty of
1652 22 May 07 gregory 17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1652 22 May 07 gregory 18  General Public License for more details.
741 10 Oct 06 olle 19
1652 22 May 07 gregory 20  You should have received a copy of the GNU General Public License
1652 22 May 07 gregory 21  along with this program; if not, write to the Free Software
1652 22 May 07 gregory 22  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1652 22 May 07 gregory 23  02111-1307, USA.
1652 22 May 07 gregory 24  */
741 10 Oct 06 olle 25
741 10 Oct 06 olle 26 //  Xerver Free Web Server
741 10 Oct 06 olle 27 //  Copyright (C) 2002-2005 Omid Rouhani
741 10 Oct 06 olle 28 //
741 10 Oct 06 olle 29 //
741 10 Oct 06 olle 30 //  This program is free software; you can redistribute it and/or
741 10 Oct 06 olle 31 //  modify it under the terms of the GNU General Public License
741 10 Oct 06 olle 32 //  as published by the Free Software Foundation; either version 2
741 10 Oct 06 olle 33 //  of the License, or (at your option) any later version.
741 10 Oct 06 olle 34 //
741 10 Oct 06 olle 35 //  This program is distributed in the hope that it will be useful,
741 10 Oct 06 olle 36 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
741 10 Oct 06 olle 37 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
741 10 Oct 06 olle 38 //  GNU General Public License for more details.
741 10 Oct 06 olle 39 //
741 10 Oct 06 olle 40 //  You should have received a copy of the GNU General Public License
741 10 Oct 06 olle 41 //  along with this program; if not, write to the Free Software
741 10 Oct 06 olle 42 //  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 46 //  ##  YOU CAN CONTACT THE AUTHOR (OMID ROUHANI) AT:          ##
741 10 Oct 06 olle 47 //  ##  HTTP://WWW.JAVASCRIPT.NU/XERVER/                       ##
741 10 Oct 06 olle 48 //  ##                                                         ##
741 10 Oct 06 olle 49 //  ##  IF YOUR SOFTWARE IS NOT RELEASED UNDER THE             ##
741 10 Oct 06 olle 50 //  ##  GNU GENERAL PUBLIC LICENSE (GPL),                      ##
741 10 Oct 06 olle 51 //  ##  PLEASE DO NOT COPY ANYTHING FROM THIS SOURCE CODE!!!   ##
741 10 Oct 06 olle 52 //  ##                                                         ##
741 10 Oct 06 olle 53 //  ##  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.MyInteger;
741 10 Oct 06 olle 59 import java.io.BufferedInputStream;
741 10 Oct 06 olle 60 import java.io.DataInputStream;
741 10 Oct 06 olle 61 import java.io.DataOutputStream;
741 10 Oct 06 olle 62 import java.io.InputStream;
741 10 Oct 06 olle 63 import java.io.OutputStream;
741 10 Oct 06 olle 64 import java.text.DateFormat;
741 10 Oct 06 olle 65 import java.util.Date;
741 10 Oct 06 olle 66
741 10 Oct 06 olle 67 /**
1652 22 May 07 gregory 68  * 
1652 22 May 07 gregory 69  * <B>About this class:</B> <BR>
1652 22 May 07 gregory 70  * This class reads the STDOUT from a script and sends it to the browser. <BR>
741 10 Oct 06 olle 71  * <BR>
1652 22 May 07 gregory 72  * 
1652 22 May 07 gregory 73  * <B>How to use:</B> <BR>
1652 22 May 07 gregory 74  * <CODE>(new ReadInputStreamSTDOUT(InputStream argIs, OutputStream argOs,
1652 22 May 07 gregory 75  * String argScriptLocation, NewConnection argTheNewConnection,
1652 22 May 07 gregory 76  * ReadInputStreamSTDERR argStdErrThread)).start();</CODE> <BR>
741 10 Oct 06 olle 77  * <BR>
1652 22 May 07 gregory 78  * 
1652 22 May 07 gregory 79  * <B>More info:</B> <BR>
1652 22 May 07 gregory 80  * <CODE>argIs</CODE> = STDERR from a script. <BR>
741 10 Oct 06 olle 81  * <CODE>argOs</CODE> = Everything written to this will be sent to browser.
741 10 Oct 06 olle 82  * <BR>
1652 22 May 07 gregory 83  * <CODE>argScriptLocation</CODE> = Location of script as browser path
1652 22 May 07 gregory 84  * ("http://server.com/dir1/dir2/file.pl" ==> "/dir1/dir2/") <BR>
1652 22 May 07 gregory 85  * <CODE>argTheNewConnection</CODE> = this shall be the <CODE>NewConnection</CODE>
1652 22 May 07 gregory 86  * that belongs to the specific request that started RunScript. We need this to
1652 22 May 07 gregory 87  * change the value off <CODE>s_errorStatus</CODE> to "500 Internal Server
1652 22 May 07 gregory 88  * Error" and to run <CODE>addThisHitToLog()</CODE>. <BR>
1652 22 May 07 gregory 89  * <CODE>argStdErrThread</CODE> = this is the <CODE>ReadInputStreamSTDERR</CODE>
1652 22 May 07 gregory 90  * thread which looks for error output in STDERR. If (and only if) there is
1652 22 May 07 gregory 91  * STDERR from the script, <CODE>stdErrThread.b_hasSentData==true</CODE>.
1652 22 May 07 gregory 92  * Otherwise <CODE>stdErrThread.b_hasSentData==false</CODE>. We use this
1652 22 May 07 gregory 93  * information to make sure that <CODE>ReadInputStreamSTDOUT</CODE> doesn't
1652 22 May 07 gregory 94  * close <CODE>argOs</CODE> while <CODE>ReadInputStreamSTDERR</CODE> is
1652 22 May 07 gregory 95  * writing information to it. <CODE>ReadInputStreamSTDERR</CODE> will close
1652 22 May 07 gregory 96  * <CODE>argOs</CODE> when all STDERR has been sent to browser. <BR>
741 10 Oct 06 olle 97  * <BR>
1652 22 May 07 gregory 98  * 
1652 22 May 07 gregory 99  * <B>IMPORTANT:</B> <CODE>argOs</CODE> is closed ("<CODE>argOs.close()</CODE>")
1652 22 May 07 gregory 100  * by <CODE>ReadInputStreamSTDOUT</CODE> if (and only if) <CODE>ReadInputStreamSTDERR</CODE>
1652 22 May 07 gregory 101  * doesn't write to <CODE>argOs</CODE>.
1652 22 May 07 gregory 102  * 
741 10 Oct 06 olle 103  * @author <a href="http://www.JavaScript.nu/xerver/" TARGET="_top">Omid Rouhani</a>
741 10 Oct 06 olle 104  * @version 1.0
741 10 Oct 06 olle 105  */
741 10 Oct 06 olle 106
1652 22 May 07 gregory 107 final public class ReadInputStreamSTDOUT extends ReadInputStream {
741 10 Oct 06 olle 108   private DataOutputStream os;
1652 22 May 07 gregory 109
1652 22 May 07 gregory 110   private final DateFormat df_dateFormat = DateFormat.getDateTimeInstance(
1652 22 May 07 gregory 111       DateFormat.LONG, DateFormat.LONG);
1652 22 May 07 gregory 112
741 10 Oct 06 olle 113   private String s_scriptLocation;
1652 22 May 07 gregory 114
741 10 Oct 06 olle 115   private NewConnection NC_theNewConnection;
1652 22 May 07 gregory 116
741 10 Oct 06 olle 117   private ReadInputStreamSTDERR stdErrThread;
1652 22 May 07 gregory 118
741 10 Oct 06 olle 119   private MyInteger whoShallRespond;
1652 22 May 07 gregory 120
741 10 Oct 06 olle 121   RunScript rs_theRunScript;
741 10 Oct 06 olle 122
1652 22 May 07 gregory 123   public ReadInputStreamSTDOUT() // now we can Extend ReadInputStream without
1652 22 May 07 gregory 124                   // problem
741 10 Oct 06 olle 125   {
741 10 Oct 06 olle 126   }
741 10 Oct 06 olle 127
1652 22 May 07 gregory 128   public ReadInputStreamSTDOUT(InputStream argIs, OutputStream argOs,
1652 22 May 07 gregory 129       String argScriptLocation, NewConnection argTheNewConnection,
1652 22 May 07 gregory 130       ReadInputStreamSTDERR argStdErrThread,
1652 22 May 07 gregory 131       MyInteger argWhoShallRespond, RunScript argTheRunScript) {
1652 22 May 07 gregory 132     whoShallRespond = argWhoShallRespond;
1652 22 May 07 gregory 133     currentMode = INPUT_MODE;
1652 22 May 07 gregory 134     is = argIs;
1652 22 May 07 gregory 135     os = (DataOutputStream) argOs;
1652 22 May 07 gregory 136     s_scriptLocation = argScriptLocation;
1652 22 May 07 gregory 137     NC_theNewConnection = argTheNewConnection;
1652 22 May 07 gregory 138     stdErrThread = argStdErrThread;
1652 22 May 07 gregory 139     rs_theRunScript = argTheRunScript;
741 10 Oct 06 olle 140   }
741 10 Oct 06 olle 141
2386 14 Nov 07 gregory 142   @Override
1652 22 May 07 gregory 143   public void sendDataInputMode() {
1652 22 May 07 gregory 144     try {
1652 22 May 07 gregory 145       is = new BufferedInputStream(new DataInputStream(is));
741 10 Oct 06 olle 146
1652 22 May 07 gregory 147       int n;
1652 22 May 07 gregory 148       boolean b_hasSentHeader = false;
1652 22 May 07 gregory 149       boolean b_hasReadHeader = false;
1652 22 May 07 gregory 150       byte[] buffer = new byte[8192];
741 10 Oct 06 olle 151
1652 22 May 07 gregory 152       /*******************************************************************
1652 22 May 07 gregory 153        * ALGORITHM TO READ STDOUT FROM A SCRIPT AND GET HEADERS IT SENDS
1652 22 May 07 gregory 154        * ********* What we are doing now is to read one large buffer (call
1652 22 May 07 gregory 155        * it BUFFER) from the script output and then make a copy of this to
1652 22 May 07 gregory 156        * a String (lets call it "STR"). Our algoritm: 1) Read BUFFER.
1652 22 May 07 gregory 157        * Create STR from BUFFER. 2) Remove all \r and \n from the
1652 22 May 07 gregory 158        * *beginning* of STR. 3) If no more \r's and no \n's are left in
1652 22 May 07 gregory 159        * STR we are done! Send the BUFFER to browser and now send all
1652 22 May 07 gregory 160        * other outputs from script to browser. 4) Create int FST, which
1652 22 May 07 gregory 161        * contain the index of the first \r OR \n in STR. Choose \r OR \n
1652 22 May 07 gregory 162        * so FST becomes as small as possible, but not -1. 5) Create a new
1652 22 May 07 gregory 163        * string ONELINE. It contains everything from index 0 to FST in
1652 22 May 07 gregory 164        * STR. Make STR shorter with ONELINE.length.
1652 22 May 07 gregory 165        * (oldSTR=ONELINE+newSTR) 6) Go into the IF's and see if ONELINE
1652 22 May 07 gregory 166        * starts with for example "Location:" or "content-type:". If it
1652 22 May 07 gregory 167        * does, take actions and send BUFFER and other outputs. If not, go
1652 22 May 07 gregory 168        * back to step 2.
1652 22 May 07 gregory 169        ******************************************************************/
741 10 Oct 06 olle 170
1652 22 May 07 gregory 171       // Note, when I run Perl-scripts one my Win XP all \n-outputs are
1652 22 May 07 gregory 172       // converted to \r\n, which means that print "Content-type:
1652 22 May 07 gregory 173       // text/html\r\n\r\n"; will be sent as "Content-type:
1652 22 May 07 gregory 174       // text/html\r\r\n\r\r\n" by perl.exe. This is nothing we care
1652 22 May 07 gregory 175       // about, but it might be good to know...
1652 22 May 07 gregory 176       String s_thisLine = null;
1652 22 May 07 gregory 177       boolean b_waitForData = true; // We use this to be able to check
1652 22 May 07 gregory 178                       // for data in the InputStream
1652 22 May 07 gregory 179                       // twice. If we don't find anything
1652 22 May 07 gregory 180                       // the first time we check, we check
1652 22 May 07 gregory 181                       // another time a few milliseconds
1652 22 May 07 gregory 182                       // later
1652 22 May 07 gregory 183       while (b_waitForData) {
1652 22 May 07 gregory 184         b_waitForData = false;
1652 22 May 07 gregory 185         while ((n = is.read(buffer)) != -1) {
1652 22 May 07 gregory 186           b_waitForData = true;
1652 22 May 07 gregory 187           String s_firstPartOfData = new String(buffer, 0, n); // s_firstPartOfData
1652 22 May 07 gregory 188                                       // might
1652 22 May 07 gregory 189                                       // conatin
1652 22 May 07 gregory 190                                       // data
1652 22 May 07 gregory 191                                       // since
1652 22 May 07 gregory 192                                       // last
1652 22 May 07 gregory 193                                       // loop,
1652 22 May 07 gregory 194                                       // add
1652 22 May 07 gregory 195                                       // the
1652 22 May 07 gregory 196                                       // new
1652 22 May 07 gregory 197                                       // string
1652 22 May 07 gregory 198                                       // to
1652 22 May 07 gregory 199                                       // this.
1652 22 May 07 gregory 200           while (!b_hasReadHeader) {
1652 22 May 07 gregory 201             while (s_firstPartOfData.startsWith("\n")
1652 22 May 07 gregory 202                 || s_firstPartOfData.startsWith("\r"))
1652 22 May 07 gregory 203               s_firstPartOfData = s_firstPartOfData.substring(1); // Lines
1652 22 May 07 gregory 204                                         // staring
1652 22 May 07 gregory 205                                         // with
1652 22 May 07 gregory 206                                         // a \r
1652 22 May 07 gregory 207                                         // or
1652 22 May 07 gregory 208                                         // \n
1652 22 May 07 gregory 209                                         // shall
1652 22 May 07 gregory 210                                         // be
1652 22 May 07 gregory 211                                         // removed,
1652 22 May 07 gregory 212                                         // we
1652 22 May 07 gregory 213                                         // don't
1652 22 May 07 gregory 214                                         // care
1652 22 May 07 gregory 215                                         // for
1652 22 May 07 gregory 216                                         // \r
1652 22 May 07 gregory 217                                         // and
1652 22 May 07 gregory 218                                         // \n
741 10 Oct 06 olle 219
1652 22 May 07 gregory 220             int distForR = s_firstPartOfData.indexOf("\r"), distForN = s_firstPartOfData
1652 22 May 07 gregory 221                 .indexOf("\n");
1652 22 May 07 gregory 222             int minDistForNandR;
741 10 Oct 06 olle 223
1652 22 May 07 gregory 224             if (distForN + distForR == -2) // both are -1 ==> no \r
1652 22 May 07 gregory 225                             // or \n exists ==> we
1652 22 May 07 gregory 226                             // are done locking for
1652 22 May 07 gregory 227                             // headers...
741 10 Oct 06 olle 228             {
1652 22 May 07 gregory 229               b_hasReadHeader = true;
1652 22 May 07 gregory 230             } else // Atleast one of distForN or distForR is != -1
741 10 Oct 06 olle 231             {
1652 22 May 07 gregory 232               // set minDistForNandR to the lowest value of
1652 22 May 07 gregory 233               // distForN and distForR, but don't set it to -1
1652 22 May 07 gregory 234               if (distForR > distForN)
1652 22 May 07 gregory 235                 if (distForN != -1)
1652 22 May 07 gregory 236                   minDistForNandR = distForN;
741 10 Oct 06 olle 237                 else
1652 22 May 07 gregory 238                   minDistForNandR = distForR;
1652 22 May 07 gregory 239               else if (distForR != -1)
1652 22 May 07 gregory 240                 minDistForNandR = distForR;
741 10 Oct 06 olle 241               else
1652 22 May 07 gregory 242                 minDistForNandR = distForN;
741 10 Oct 06 olle 243
1652 22 May 07 gregory 244               s_thisLine = s_firstPartOfData.substring(0,
1652 22 May 07 gregory 245                   minDistForNandR);
1652 22 May 07 gregory 246               s_firstPartOfData = s_firstPartOfData
1652 22 May 07 gregory 247                   .substring(minDistForNandR + 1);
1652 22 May 07 gregory 248               s_thisLine = s_thisLine.toLowerCase();
1652 22 May 07 gregory 249               if (s_thisLine.startsWith("content-type:")) {
1652 22 May 07 gregory 250                 // We don't take any special actions now, except
1652 22 May 07 gregory 251                 // that we stop searching for "Location:"
1652 22 May 07 gregory 252                 b_hasReadHeader = true;
1652 22 May 07 gregory 253               } else if (s_thisLine.startsWith("location:")) {
1652 22 May 07 gregory 254                 // We change error code
1652 22 May 07 gregory 255                 NC_theNewConnection.s_errorStatus = "302 Found";
1652 22 May 07 gregory 256                 b_hasReadHeader = true;
741 10 Oct 06 olle 257               }
741 10 Oct 06 olle 258             }
741 10 Oct 06 olle 259           }
741 10 Oct 06 olle 260
1652 22 May 07 gregory 261           if (!b_hasSentHeader) {
1652 22 May 07 gregory 262             b_hasSentHeader = true;
741 10 Oct 06 olle 263             sendHeaderInfo();
741 10 Oct 06 olle 264           }
741 10 Oct 06 olle 265
1652 22 May 07 gregory 266           if (whoShallRespond.getValue() != RESPOND_STDERR) {
1652 22 May 07 gregory 267             NewConnection.totalNumberOfBytesDownloaded += n;
1652 22 May 07 gregory 268             os.write(buffer, 0, n);
1652 22 May 07 gregory 269           } else {
1652 22 May 07 gregory 270             break; // If STDERR is being sent right now, then we
1652 22 May 07 gregory 271                 // stop here and don't send STDOUT
741 10 Oct 06 olle 272           }
1652 22 May 07 gregory 273           sleep(25); // Don't remove: without this it might happen
1652 22 May 07 gregory 274                 // that we don't read the complete output (or
1652 22 May 07 gregory 275                 // any output) from the process.
741 10 Oct 06 olle 276         }
741 10 Oct 06 olle 277
1652 22 May 07 gregory 278         yield();
1652 22 May 07 gregory 279         sleep(75); // Don't remove: without this it might happen that
1652 22 May 07 gregory 280               // we don't read the complete output (or any output)
1652 22 May 07 gregory 281               // from the process.
741 10 Oct 06 olle 282       }
741 10 Oct 06 olle 283
741 10 Oct 06 olle 284       yield();
741 10 Oct 06 olle 285       sleep(150);
741 10 Oct 06 olle 286
1652 22 May 07 gregory 287       if (whoShallRespond.getValue() == RESPOND_STDOUT) // Only add to
1652 22 May 07 gregory 288                                 // log if we are
1652 22 May 07 gregory 289                                 // sending
1652 22 May 07 gregory 290                                 // STDOUT,
1652 22 May 07 gregory 291                                 // otherwise
1652 22 May 07 gregory 292                                 // ReadInputStreamSTDERR
1652 22 May 07 gregory 293                                 // will add to
1652 22 May 07 gregory 294                                 // log...
1652 22 May 07 gregory 295       {
1652 22 May 07 gregory 296         NC_theNewConnection.addThisHitToLog(); // Log this visitor
1652 22 May 07 gregory 297       }
741 10 Oct 06 olle 298
1652 22 May 07 gregory 299       if (!stdErrThread.b_hasSentData) // If ReadInputStreamSTDERR has
1652 22 May 07 gregory 300                         // found output in the STDERR,
1652 22 May 07 gregory 301                         // then we shall not close the
1652 22 May 07 gregory 302                         // stream, as
1652 22 May 07 gregory 303                         // ReadInputStreamSTDERR is
1652 22 May 07 gregory 304                         // writing to it.
1652 22 May 07 gregory 305       {
1652 22 May 07 gregory 306         yield();
1652 22 May 07 gregory 307         sleep(125); // Be safe, don't close before all data has been
1652 22 May 07 gregory 308               // sent
741 10 Oct 06 olle 309
1652 22 May 07 gregory 310         os.flush();
1652 22 May 07 gregory 311         os.close();
1652 22 May 07 gregory 312       }
741 10 Oct 06 olle 313
1652 22 May 07 gregory 314     } catch (Exception e) {
1652 22 May 07 gregory 315       exceptionOccured(e);
1652 22 May 07 gregory 316       if (b_showErrors)
1652 22 May 07 gregory 317         System.out
1652 22 May 07 gregory 318             .println("An error has occured @ sendDataInputMode:\n"
1652 22 May 07 gregory 319                 + e.getMessage());
1652 22 May 07 gregory 320     }
741 10 Oct 06 olle 321   }
741 10 Oct 06 olle 322
1652 22 May 07 gregory 323   private void sendHeaderInfo() {
741 10 Oct 06 olle 324     try {
1652 22 May 07 gregory 325       if (whoShallRespond.getValue() != RESPOND_STDERR) {
1652 22 May 07 gregory 326         whoShallRespond.setValue(RESPOND_STDOUT); // This will make
1652 22 May 07 gregory 327                               // sure so no STDERR
1652 22 May 07 gregory 328                               // is sent to the
1652 22 May 07 gregory 329                               // browser (a
1652 22 May 07 gregory 330                               // reference of
1652 22 May 07 gregory 331                               // "B_hasGotAResponse"
1652 22 May 07 gregory 332                               // is also at
1652 22 May 07 gregory 333                               // ReadInputStreamSTDERR,
1652 22 May 07 gregory 334                               // which will
1652 22 May 07 gregory 335                               // "block" it from
1652 22 May 07 gregory 336                               // sending data now)
1652 22 May 07 gregory 337         os.writeBytes(""
1652 22 May 07 gregory 338             + "HTTP/1.1 "
1652 22 May 07 gregory 339             + NC_theNewConnection.s_errorStatus
1652 22 May 07 gregory 340             + "\r\n"
1652 22 May 07 gregory 341             + "Date: "
1652 22 May 07 gregory 342             + df_dateFormat.format(new Date())
1652 22 May 07 gregory 343             + "\r\n"
1652 22 May 07 gregory 344             + "Server: "
1652 22 May 07 gregory 345             + XerverKernel.getXerverName()
1652 22 May 07 gregory 346             + "\r\n"
1652 22 May 07 gregory 347             + "Connection: close\r\n"
1652 22 May 07 gregory 348             + ((NC_theNewConnection.s_errorStatus
1652 22 May 07 gregory 349                 .equals("302 Found")) ? ("") : ("Location: "
1652 22 May 07 gregory 350                 + s_scriptLocation + "\r\n")) // If the script
1652 22 May 07 gregory 351                                 // has an
1652 22 May 07 gregory 352                                 // Location-line
1652 22 May 07 gregory 353                                 // as output,
1652 22 May 07 gregory 354                                 // don't send
1652 22 May 07 gregory 355                                 // our own
1652 22 May 07 gregory 356                                 // Location-line
1652 22 May 07 gregory 357         );
741 10 Oct 06 olle 358       }
1652 22 May 07 gregory 359     } catch (Exception e) {
1652 22 May 07 gregory 360       exceptionOccured(e);
1652 22 May 07 gregory 361       if (b_showErrors)
1652 22 May 07 gregory 362         System.out.println("An error has occured @ sendHeaderInfo\n"
1652 22 May 07 gregory 363             + e);
1652 22 May 07 gregory 364     }
741 10 Oct 06 olle 365   }
741 10 Oct 06 olle 366
1652 22 May 07 gregory 367   private void exceptionOccured(Exception e) {
741 10 Oct 06 olle 368     rs_theRunScript.killProcess();
741 10 Oct 06 olle 369   }
741 10 Oct 06 olle 370 }