diff -r c07047c47ce9 autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java --- a/autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java Tue Mar 10 18:21:48 2009 +0300 +++ b/autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java Wed Mar 11 13:26:40 2009 +0300 @@ -42,6 +42,7 @@ package org.netbeans.updater; import java.io.*; +import java.lang.reflect.Method; import java.util.*; import java.util.jar.*; @@ -354,6 +355,8 @@ try { jarFile = new JarFile (nbm); Enumeration entries = jarFile.entries(); + List list = new ArrayList (jarFile.size()); + List executableList = new ArrayList (); while( entries.hasMoreElements() ) { JarEntry entry = (JarEntry) entries.nextElement(); checkStop(); @@ -375,14 +378,14 @@ File bckFile = new File( getBackupDirectory (cluster), entry.getName() ); bckFile.getParentFile ().mkdirs (); // System.out.println("Backing up" ); // NOI18N - copyStreams( new FileInputStream( destFile ), new FileOutputStream( bckFile ), -1 ); + copyStreams( new FileInputStream( destFile ), bckFile, -1, list, executableList ); if (!destFile.delete() && isWindows()) { trickyDeleteOnWindows(destFile); } } else { destFile.getParentFile ().mkdirs (); } - bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); + bytesRead = copyStreams( jarFile.getInputStream( entry ), destFile, bytesRead, list, executableList ); UpdaterFrame.setProgressValue( bytesRead ); } } else if ( entry.getName().startsWith( UPDATE_MAIN_DIR )&& @@ -392,10 +395,11 @@ entry.getName().substring(UPDATE_MAIN_DIR.length() + 1) ); destFile.getParentFile ().mkdirs (); hasMainClass = true; - bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); + bytesRead = copyStreams( jarFile.getInputStream( entry ), destFile, bytesRead, list, executableList ); UpdaterFrame.setProgressValue( bytesRead ); } } + fixPermissions(list,executableList); if ( hasMainClass ) { MainConfig mconfig = new MainConfig (getMainDirString (cluster) + UpdateTracking.FILE_SEPARATOR + JVM_PARAMS_FILE, cluster); if (mconfig.isValid()) { @@ -532,6 +536,108 @@ private String getMainDirString (File activeCluster) { return getMainDirectory (activeCluster).getPath (); } + + + private void fixPermissions(List list, List executableList) { + if (!isWindows() && !list.isEmpty()) { + List commands = new ArrayList(); + commands.add("/usr/bin/file"); + commands.addAll(list); + + String filesInfo = readCommandOutput(commands); + List fileExecutables = new ArrayList(); + for (String s : filesInfo.split("(?:\r\n|\n|\r)")) {//split by lines + int colonIndex = s.indexOf(":"); + if (colonIndex != -1) { + String filePath = s.substring(0, colonIndex).trim(); + String fileType = s.substring(colonIndex + 1); + if (fileType.contains("executable") || + fileType.contains("dynamic lib") || + fileType.contains("shared object") || + fileType.contains("shared library")) { + fileExecutables.add(filePath); + //System.out.println("Executable [/usr/bin/file]: " + filePath); + } + } + } + List allExecutables = new ArrayList (); + allExecutables.addAll(fileExecutables); + for(String s : executableList) { + if(!allExecutables.contains(s)) { + //System.out.println("Executable [ interpreter ]: " + s); + allExecutables.add(s); + } + } + chmod(allExecutables); + } + } + + private void chmod(List executables) { + if(executables.isEmpty()) { + return ; + } + if(System.getProperty("java.version").startsWith("1.5")) { + // Find chmod + File chmod = new File("/bin/chmod"); // NOI18N + if (!chmod.isFile()) { + chmod = new File("/usr/bin/chmod"); // NOI18N + } + if (chmod.isFile()) { + List commands = new ArrayList(executables.size() + 2); + commands.add(chmod.getAbsolutePath()); + commands.add("a+x"); // NOI18N + commands.addAll(executables); + try { + System.out.println("Executing command : " + commands); + new ProcessBuilder(commands).start().waitFor(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + // Determine if java.io.File.setExecutable method is supported + try { + Method setExecutableMethod = File.class.getMethod("setExecutable", new Class[] {Boolean.class, Boolean.class}); + for(String s : executables) { + setExecutableMethod.invoke(new File(s), true, false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private String readCommandOutput(List command) { + ProcessBuilder builder = new ProcessBuilder(command); + boolean doRun = true; + StringBuilder sb = new StringBuilder(); + byte[] bytes = new byte[8192]; + int c = 0; + + try { + Process process = builder.start(); + while (doRun) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + } + try { + process.exitValue(); + doRun = false; + } catch (IllegalThreadStateException e) { + ; // do nothing - the process is still running + } + InputStream is = process.getInputStream(); + while ((c = is.read(bytes)) != -1) { + sb.append(new String(bytes, 0, c)); + } + } + return sb.toString(); + } catch (IOException e) { + e.printStackTrace(); + return new String(); + } + } /** Quotes string correctly, eg. removes all quotes from the string and adds * just one at the start and @@ -564,8 +670,10 @@ * @param progressVal The current progress bar value. If this is * negative, we don't want to update the progress bar. */ - private long copyStreams( InputStream src, OutputStream dest, - long progressVal ) throws java.io.IOException { + private long copyStreams( InputStream src, File destFile, + long progressVal, List list, List executableList ) throws java.io.IOException { + OutputStream dest = new FileOutputStream(destFile); + list.add(destFile.getAbsolutePath()); BufferedInputStream bsrc = new BufferedInputStream( src ); BufferedOutputStream bdest = new BufferedOutputStream( dest ); @@ -574,10 +682,32 @@ int c; byte [] bytes = new byte [8192]; - + boolean read = false; try { while( ( c = bsrc.read(bytes) ) != -1 ) { bdest.write(bytes, 0, c); + if (!read) { + read = true; + if (c >= 4) { // length of ELF header and min length of "#!/X" string + if (bytes[0] == '\177' && + bytes[1] == 'E' && + bytes[2] == 'L' && + bytes[3] == 'F') { + executableList.add(destFile.getAbsolutePath()); + } else if (bytes[0] == '#' && bytes[1] == '!') { + String s = new String(bytes, 0, c); + String[] array = s.split("(?:\r\n|\n|\r)"); + + if (array.length > 0) { + //read the first line only + //allow lines like "#! /bin/sh" + if (array[0].replaceAll("#!(\\s)+/", "#!/").startsWith("#!/")) { + executableList.add(destFile.getAbsolutePath()); + } + } + } + } + } count+=c; if ( count > 8500 ) { if (progressVal >= 0) {