1 /* 2 * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.net.www; 27 import java.net.URL; 28 import java.io.*; 29 import java.util.StringTokenizer; 30 31 class MimeLauncher extends Thread { 32 java.net.URLConnection uc; 33 MimeEntry m; 34 String genericTempFileTemplate; 35 InputStream is; 36 String execPath; 37 MimeLauncher(MimeEntry M, java.net.URLConnection uc, InputStream is, String tempFileTemplate, String threadName)38 MimeLauncher (MimeEntry M, java.net.URLConnection uc, 39 InputStream is, String tempFileTemplate, String threadName) throws ApplicationLaunchException { 40 super(threadName); 41 m = M; 42 this.uc = uc; 43 this.is = is; 44 genericTempFileTemplate = tempFileTemplate; 45 46 /* get the application to launch */ 47 String launchString = m.getLaunchString(); 48 49 /* get a valid path to launch application - sets 50 the execPath instance variable with the correct path. 51 */ 52 if (!findExecutablePath(launchString)) { 53 /* strip off parameters i.e %s */ 54 String appName; 55 int index = launchString.indexOf(' '); 56 if (index != -1) { 57 appName = launchString.substring(0, index); 58 } 59 else { 60 appName = launchString; 61 } 62 throw new ApplicationLaunchException(appName); 63 } 64 } 65 getTempFileName(URL url, String template)66 protected String getTempFileName(URL url, String template) { 67 String tempFilename = template; 68 69 // Replace all but last occurrance of "%s" with timestamp to insure 70 // uniqueness. There's a subtle behavior here: if there is anything 71 // _after_ the last "%s" we need to append it so that unusual launch 72 // strings that have the datafile in the middle can still be used. 73 int wildcard = tempFilename.lastIndexOf("%s"); 74 String prefix = tempFilename.substring(0, wildcard); 75 76 String suffix = ""; 77 if (wildcard < tempFilename.length() - 2) { 78 suffix = tempFilename.substring(wildcard + 2); 79 } 80 81 long timestamp = System.currentTimeMillis()/1000; 82 int argIndex = 0; 83 while ((argIndex = prefix.indexOf("%s")) >= 0) { 84 prefix = prefix.substring(0, argIndex) 85 + timestamp 86 + prefix.substring(argIndex + 2); 87 } 88 89 // Add a file name and file-extension if known 90 String filename = url.getFile(); 91 92 String extension = ""; 93 int dot = filename.lastIndexOf('.'); 94 95 // BugId 4084826: Temp MIME file names not always valid. 96 // Fix: don't allow slashes in the file name or extension. 97 if (dot >= 0 && dot > filename.lastIndexOf('/')) { 98 extension = filename.substring(dot); 99 } 100 101 filename = "HJ" + url.hashCode(); 102 103 tempFilename = prefix + filename + timestamp + extension + suffix; 104 105 return tempFilename; 106 } 107 run()108 public void run() { 109 try { 110 String ofn = m.getTempFileTemplate(); 111 if (ofn == null) { 112 ofn = genericTempFileTemplate; 113 } 114 115 ofn = getTempFileName(uc.getURL(), ofn); 116 try { 117 OutputStream os = new FileOutputStream(ofn); 118 byte buf[] = new byte[2048]; 119 int i = 0; 120 try { 121 while ((i = is.read(buf)) >= 0) { 122 os.write(buf, 0, i); 123 } 124 } catch(IOException e) { 125 //System.err.println("Exception in write loop " + i); 126 //e.printStackTrace(); 127 } finally { 128 os.close(); 129 is.close(); 130 } 131 } catch(IOException e) { 132 //System.err.println("Exception in input or output stream"); 133 //e.printStackTrace(); 134 } 135 136 int inx = 0; 137 String c = execPath; 138 while ((inx = c.indexOf("%t")) >= 0) { 139 c = c.substring(0, inx) + uc.getContentType() 140 + c.substring(inx + 2); 141 } 142 143 boolean substituted = false; 144 while ((inx = c.indexOf("%s")) >= 0) { 145 c = c.substring(0, inx) + ofn + c.substring(inx + 2); 146 substituted = true; 147 } 148 if (!substituted) 149 c = c + " <" + ofn; 150 151 // System.out.println("Execing " +c); 152 153 Runtime.getRuntime().exec(c); 154 } catch(IOException e) { 155 } 156 } 157 158 /* This method determines the path for the launcher application 159 and sets the execPath instance variable. It uses the exec.path 160 property to obtain a list of paths that is in turn used to 161 location the application. If a valid path is not found, it 162 returns false else true. */ findExecutablePath(String str)163 private boolean findExecutablePath(String str) { 164 if (str == null || str.length() == 0) { 165 return false; 166 } 167 168 String command; 169 int index = str.indexOf(' '); 170 if (index != -1) { 171 command = str.substring(0, index); 172 } 173 else { 174 command = str; 175 } 176 177 File f = new File(command); 178 if (f.isFile()) { 179 // Already executable as it is 180 execPath = str; 181 return true; 182 } 183 184 String execPathList; 185 execPathList = java.security.AccessController.doPrivileged( 186 new sun.security.action.GetPropertyAction("exec.path")); 187 if (execPathList == null) { 188 // exec.path property not set 189 return false; 190 } 191 192 StringTokenizer iter = new StringTokenizer(execPathList, "|"); 193 while (iter.hasMoreElements()) { 194 String prefix = (String)iter.nextElement(); 195 String fullCmd = prefix + File.separator + command; 196 f = new File(fullCmd); 197 if (f.isFile()) { 198 execPath = prefix + File.separator + str; 199 return true; 200 } 201 } 202 203 return false; // application not found in exec.path 204 } 205 } 206