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 import sun.security.action.GetPropertyAction; 31 32 class MimeLauncher extends Thread { 33 java.net.URLConnection uc; 34 MimeEntry m; 35 String genericTempFileTemplate; 36 InputStream is; 37 String execPath; 38 39 MimeLauncher (MimeEntry M, java.net.URLConnection uc, 40 InputStream is, String tempFileTemplate, String threadName) throws ApplicationLaunchException { 41 super(null, null, threadName, 0, false); 42 m = M; 43 this.uc = uc; 44 this.is = is; 45 genericTempFileTemplate = tempFileTemplate; 46 47 /* get the application to launch */ 48 String launchString = m.getLaunchString(); 49 50 /* get a valid path to launch application - sets 51 the execPath instance variable with the correct path. 52 */ 53 if (!findExecutablePath(launchString)) { 54 /* strip off parameters i.e %s */ 55 String appName; 56 int index = launchString.indexOf(' '); 57 if (index != -1) { 58 appName = launchString.substring(0, index); 59 } 60 else { 61 appName = launchString; 62 } 63 throw new ApplicationLaunchException(appName); 64 } 65 } 66 67 protected String getTempFileName(URL url, String template) { 68 String tempFilename = template; 69 70 // Replace all but last occurrance of "%s" with timestamp to insure 71 // uniqueness. There's a subtle behavior here: if there is anything 72 // _after_ the last "%s" we need to append it so that unusual launch 73 // strings that have the datafile in the middle can still be used. 74 int wildcard = tempFilename.lastIndexOf("%s"); 75 String prefix = tempFilename.substring(0, wildcard); 76 77 String suffix = ""; 78 if (wildcard < tempFilename.length() - 2) { 79 suffix = tempFilename.substring(wildcard + 2); 80 } 81 82 long timestamp = System.currentTimeMillis()/1000; 83 int argIndex = 0; 84 while ((argIndex = prefix.indexOf("%s")) >= 0) { 85 prefix = prefix.substring(0, argIndex) 86 + timestamp 87 + prefix.substring(argIndex + 2); 88 } 89 90 // Add a file name and file-extension if known 91 String filename = url.getFile(); 92 93 String extension = ""; 94 int dot = filename.lastIndexOf('.'); 95 96 // BugId 4084826: Temp MIME file names not always valid. 97 // Fix: don't allow slashes in the file name or extension. 98 if (dot >= 0 && dot > filename.lastIndexOf('/')) { 99 extension = filename.substring(dot); 100 } 101 102 filename = "HJ" + url.hashCode(); 103 104 tempFilename = prefix + filename + timestamp + extension + suffix; 105 106 return tempFilename; 107 } 108 109 public void run() { 110 try { 111 String ofn = m.getTempFileTemplate(); 112 if (ofn == null) { 113 ofn = genericTempFileTemplate; 114 } 115 116 ofn = getTempFileName(uc.getURL(), ofn); 117 try { 118 OutputStream os = new FileOutputStream(ofn); 119 byte buf[] = new byte[2048]; 120 int i = 0; 121 try { 122 while ((i = is.read(buf)) >= 0) { 123 os.write(buf, 0, i); 124 } 125 } catch(IOException e) { 126 //System.err.println("Exception in write loop " + i); 127 //e.printStackTrace(); 128 } finally { 129 os.close(); 130 is.close(); 131 } 132 } catch(IOException e) { 133 //System.err.println("Exception in input or output stream"); 134 //e.printStackTrace(); 135 } 136 137 int inx = 0; 138 String c = execPath; 139 while ((inx = c.indexOf("%t")) >= 0) { 140 c = c.substring(0, inx) + uc.getContentType() 141 + c.substring(inx + 2); 142 } 143 144 boolean substituted = false; 145 while ((inx = c.indexOf("%s")) >= 0) { 146 c = c.substring(0, inx) + ofn + c.substring(inx + 2); 147 substituted = true; 148 } 149 if (!substituted) 150 c = c + " <" + ofn; 151 152 // System.out.println("Execing " +c); 153 154 Runtime.getRuntime().exec(c); 155 } catch(IOException e) { 156 } 157 } 158 159 /* This method determines the path for the launcher application 160 and sets the execPath instance variable. It uses the exec.path 161 property to obtain a list of paths that is in turn used to 162 location the application. If a valid path is not found, it 163 returns false else true. */ 164 private boolean findExecutablePath(String str) { 165 if (str == null || str.isEmpty()) { 166 return false; 167 } 168 169 String command; 170 int index = str.indexOf(' '); 171 if (index != -1) { 172 command = str.substring(0, index); 173 } 174 else { 175 command = str; 176 } 177 178 File f = new File(command); 179 if (f.isFile()) { 180 // Already executable as it is 181 execPath = str; 182 return true; 183 } 184 185 String execPathList; 186 execPathList = GetPropertyAction.privilegedGetProperty("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 }