1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.setup.InstallerHelper; 25 26 import org.openoffice.setup.InstallData; 27 import org.openoffice.setup.SetupData.PackageDescription; 28 import org.openoffice.setup.Util.Converter; 29 import org.openoffice.setup.Util.ExecuteProcess; 30 import org.openoffice.setup.Util.LogManager; 31 import org.openoffice.setup.Util.SystemManager; 32 import java.io.File; 33 import java.util.Enumeration; 34 import java.util.HashMap; 35 import java.util.Vector;public class LinuxHelper { 36 LinuxHelper()37 public LinuxHelper() { 38 super(); 39 } 40 getPackageNamesContent(PackageDescription packageData, Vector packageNames)41 private void getPackageNamesContent(PackageDescription packageData, Vector packageNames) { 42 if (( packageData.getPackageName() != null ) && ( ! packageData.getPackageName().equals(""))) { 43 packageNames.add(packageData.getPackageName() + "=" + packageData.getFullPackageName()); 44 } 45 46 for (Enumeration e = packageData.children(); e.hasMoreElements(); ) { 47 PackageDescription child = (PackageDescription) e.nextElement(); 48 getPackageNamesContent(child, packageNames); 49 } 50 } 51 getPackageNameFromRpm(PackageDescription packageData, InstallData installData)52 private String getPackageNameFromRpm(PackageDescription packageData, InstallData installData) { 53 String fullPackageName = null; 54 String packagePath = installData.getPackagePath(); 55 56 if (( packageData.getPkgSubdir() != null ) && ( ! packageData.getPkgSubdir().equals("") )) { 57 File completePackageFile = new File(packagePath, packageData.getPkgSubdir()); 58 packagePath = completePackageFile.getPath(); 59 } 60 61 String rpmFileName = packageData.getPackageName(); 62 File rpmFile = new File(packagePath, rpmFileName); 63 64 if ( rpmFile.exists() ) { 65 String rpmCommand = "rpm -qp " + rpmFile.getPath(); 66 String[] rpmCommandArray = new String[3]; 67 rpmCommandArray[0] = "rpm"; 68 rpmCommandArray[1] = "-qp"; 69 rpmCommandArray[2] = rpmFile.getPath(); 70 71 Vector returnVector = new Vector(); 72 Vector returnErrorVector = new Vector(); 73 int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector); 74 String returnString = (String) returnVector.get(0); 75 76 String log = rpmCommand + "<br><b>Returns: " + returnString + "</b><br>"; 77 LogManager.addCommandsLogfileComment(log); 78 79 fullPackageName = returnString; 80 81 } else { 82 System.err.println("Error: Could not find file " + rpmFile.getPath()); 83 } 84 85 return fullPackageName; 86 } 87 checkPackageExistence(PackageDescription packageData, InstallData installData)88 private boolean checkPackageExistence(PackageDescription packageData, InstallData installData) { 89 boolean fileExists = false; 90 91 String packagePath = installData.getPackagePath(); 92 93 if (( packageData.getPkgSubdir() != null ) && ( ! packageData.getPkgSubdir().equals("") )) { 94 File completePackageFile = new File(packagePath, packageData.getPkgSubdir()); 95 packagePath = completePackageFile.getPath(); 96 } 97 98 String rpmFileName = packageData.getPackageName(); 99 100 File rpmFile = new File(packagePath, rpmFileName); 101 if ( rpmFile.exists() ) { 102 fileExists = true; 103 } 104 105 return fileExists; 106 } 107 analyzeVersionString(String versionString)108 private HashMap analyzeVersionString(String versionString) { 109 110 boolean errorOccured = false; 111 112 Integer micro = null; 113 Integer minor = null; 114 Integer major = null; 115 Integer release = null; 116 117 String microString = null; 118 String minorString = null; 119 String majorString = null; 120 String releaseString = null; 121 122 int pos = versionString.lastIndexOf("_"); // this is a jre RPM (1.5.0_06) 123 124 if ( pos > -1 ) { 125 try { 126 releaseString = versionString.substring(pos+1, versionString.length()); 127 versionString = versionString.substring(0, pos); 128 } catch (IndexOutOfBoundsException ex) { 129 System.err.println("Error: Could not get substring from " + versionString); 130 errorOccured = true; 131 } 132 try { 133 int releaseInt = Integer.parseInt(releaseString); 134 release = new Integer(releaseInt); 135 } catch (NumberFormatException ex) { 136 System.err.println("Error: Could not convert " + releaseString + " to integer"); 137 errorOccured = true; 138 } 139 } 140 141 // Problem: Some rpms have "2.3" instead of "2.3.0" 142 String compareString = versionString; 143 pos = compareString.lastIndexOf("."); // returns "-1", if not found 144 if ( pos > -1 ) { 145 String substring = compareString.substring(0, pos); 146 pos = substring.lastIndexOf("."); // returns "-1", if not found 147 if ( pos == -1 ) { 148 versionString = versionString + ".0"; 149 // System.err.println("Warning: Changing from " + compareString + " to " + versionString); 150 } 151 } else { 152 versionString = versionString + ".0.0"; 153 } 154 155 // the standard analyzing mechanism 156 pos = versionString.lastIndexOf("."); // returns "-1", if not found 157 158 if ( pos > -1 ) 159 { 160 try { 161 microString = versionString.substring(pos+1, versionString.length()); 162 versionString = versionString.substring(0, pos); 163 } catch (IndexOutOfBoundsException ex) { 164 System.err.println("Error: Could not get substring from " + versionString); 165 errorOccured = true; 166 } 167 168 pos = versionString.lastIndexOf("."); 169 if ( pos > -1 ) { 170 try { 171 minorString = versionString.substring(pos+1, versionString.length()); 172 majorString = versionString.substring(0, pos); 173 } catch (IndexOutOfBoundsException ex) { 174 System.err.println("Error: Could not get substring from " + versionString); 175 errorOccured = true; 176 } 177 try { 178 int microInt = Integer.parseInt(microString); 179 int minorInt = Integer.parseInt(minorString); 180 int majorInt = Integer.parseInt(majorString); 181 micro = new Integer(microInt); 182 minor = new Integer(minorInt); 183 major = new Integer(majorInt); 184 } catch (NumberFormatException ex) { 185 System.err.println("Error: Could not convert " + microString + "," + 186 minorString + " or " + majorString + " to integer"); 187 errorOccured = true; 188 } 189 } 190 } 191 192 // if ( microString == null ) { microString = ""; } 193 // if ( majorString == null ) { majorString = ""; } 194 // if ( releaseString == null ) { releaseString = ""; } 195 // if ( minorString == null ) { minorString = ""; } 196 // System.err.println("Major " + majorString + " Minor: " + minorString + " Micro: " + microString + " Release: " + releaseString); 197 198 if ( errorOccured ) { 199 micro = null; 200 minor = null; 201 major = null; 202 release = null; 203 } 204 205 HashMap hashRpm = new HashMap(); 206 207 hashRpm.put("micro", micro); 208 hashRpm.put("minor", minor); 209 hashRpm.put("major", major); 210 hashRpm.put("release", release); 211 212 // If one of this values is "null", procedure "compareTwoRpms" always delivers false. 213 // This means, that the installed package is not older. 214 215 // System.err.println("Analyzed: " + "micro: " + hashRpm.get("micro").toString() + " minor: " + hashRpm.get("minor").toString() + " major: " + hashRpm.get("major").toString()); 216 217 return hashRpm; 218 } 219 analyzeReleaseString(HashMap hashRpm, String releaseString)220 private HashMap analyzeReleaseString(HashMap hashRpm, String releaseString) { 221 int release; 222 223 try { 224 release = Integer.parseInt(releaseString); 225 Integer releaseObj = new Integer(release); 226 hashRpm.put("release", releaseObj); 227 } 228 catch (NumberFormatException ex) { 229 // JRE often contain a string like "FCS" 230 // System.err.println("Error: Could not convert " + releaseString + " to integer"); 231 hashRpm.put("release", null); 232 } 233 234 return hashRpm; 235 } 236 getInstalledMinor(String version)237 public int getInstalledMinor(String version) { 238 239 int minor = 0; 240 int pos = version.indexOf("."); 241 if ( pos > -1 ) { 242 String reduced = version.substring(pos + 1, version.length()); 243 244 pos = reduced.indexOf("."); 245 if ( pos > -1 ) { 246 reduced = reduced.substring(0, pos); 247 minor = Integer.parseInt(reduced); 248 } 249 } 250 251 return minor; 252 } 253 compareTwoRpms(HashMap hash1, HashMap hash2)254 private boolean compareTwoRpms(HashMap hash1, HashMap hash2) { 255 boolean hash1IsOlder = false; 256 257 if (( hash1.get("major") != null ) && ( hash2.get("major") != null )) { 258 if ( ((Integer)hash1.get("major")).intValue() < ((Integer)hash2.get("major")).intValue() ) { 259 hash1IsOlder = true; 260 } else { 261 if (( hash1.get("minor") != null ) && ( hash2.get("minor") != null )) { 262 if ( ((Integer)hash1.get("minor")).intValue() < ((Integer)hash2.get("minor")).intValue() ) { 263 hash1IsOlder = true; 264 } else { 265 if (( hash1.get("micro") != null ) && ( hash2.get("micro") != null )) { 266 if ( ((Integer)hash1.get("micro")).intValue() < ((Integer)hash2.get("micro")).intValue() ) { 267 hash1IsOlder = true; 268 } else { 269 if (( hash1.get("release") != null ) && ( hash2.get("release") != null )) { 270 if ( ((Integer)hash1.get("release")).intValue() < ((Integer)hash2.get("release")).intValue() ) { 271 hash1IsOlder = true; 272 } 273 } 274 } 275 } 276 } 277 } 278 } 279 } 280 281 return hash1IsOlder; 282 } 283 compareVersionAndRelease(String versionString, String releaseString, PackageDescription packageData, boolean checkIfInstalledIsOlder)284 public boolean compareVersionAndRelease(String versionString, String releaseString, PackageDescription packageData, boolean checkIfInstalledIsOlder) { 285 // version and release are gotten from the rpm database. packageData contains 286 // the information about the rpm, that shall be installed. It has to be installed, 287 // if the installed product defined by version and release is older. 288 // version is something like "2.0.3", release something like "164". 289 // An exception is the jre package, where version is "1.5.0_06" and release "fcs". 290 291 HashMap installedRpm = analyzeVersionString(versionString); 292 if ( installedRpm.get("release") == null ) { 293 installedRpm = analyzeReleaseString(installedRpm, releaseString); 294 } 295 296 // System.err.println("Package: " + packageData.getPackageName()); 297 // String outputString = "Installed RPM: "; 298 // if ( installedRpm.get("major") != null ) { outputString = outputString + " major: " + installedRpm.get("major").toString(); } 299 // else { outputString = outputString + " major is null"; } 300 // if ( installedRpm.get("minor") != null ) { outputString = outputString + " minor: " + installedRpm.get("minor").toString(); } 301 // else { outputString = outputString + " minor is null"; } 302 // if ( installedRpm.get("micro") != null ) { outputString = outputString + " micro: " + installedRpm.get("micro").toString(); } 303 // else { outputString = outputString + " micro is null"; } 304 // if ( installedRpm.get("release") != null ) { outputString = outputString + " release: " + installedRpm.get("release").toString(); } 305 // else { outputString = outputString + " release is null"; } 306 // System.err.println(outputString); 307 308 HashMap notInstalledRpm = analyzeVersionString(packageData.getPkgVersion()); 309 if ( notInstalledRpm.get("release") == null ) { 310 notInstalledRpm = analyzeReleaseString(notInstalledRpm, packageData.getPkgRelease()); 311 } 312 313 // outputString = "Not installed RPM: "; 314 // if ( notInstalledRpm.get("major") != null ) { outputString = outputString + " major: " + notInstalledRpm.get("major").toString(); } 315 // else { outputString = outputString + " major is null"; } 316 // if ( notInstalledRpm.get("minor") != null ) { outputString = outputString + " minor: " + notInstalledRpm.get("minor").toString(); } 317 // else { outputString = outputString + " minor is null"; } 318 // if ( notInstalledRpm.get("micro") != null ) { outputString = outputString + " micro: " + notInstalledRpm.get("micro").toString(); } 319 // else { outputString = outputString + " micro is null"; } 320 // if ( notInstalledRpm.get("release") != null ) { outputString = outputString + " release: " + notInstalledRpm.get("release").toString(); } 321 // else { outputString = outputString + " release is null"; } 322 // System.err.println(outputString); 323 324 boolean firstIsOlder = false; 325 326 if ( checkIfInstalledIsOlder ) { 327 firstIsOlder = compareTwoRpms(installedRpm, notInstalledRpm); 328 // System.err.println("Result: Installed RPM is older: " + firstIsOlder); 329 } else { 330 firstIsOlder = compareTwoRpms(notInstalledRpm, installedRpm); 331 // System.err.println("Result: Not installed RPM is older: " + firstIsOlder); 332 } 333 334 return firstIsOlder; 335 } 336 getLinuxPackageNamesFromRpmquery(PackageDescription packageData, InstallData installData)337 public void getLinuxPackageNamesFromRpmquery(PackageDescription packageData, InstallData installData) { 338 339 if ((packageData.getPackageName() != null) && ( ! packageData.getPackageName().equals(""))) { 340 341 boolean rpmExists = checkPackageExistence(packageData, installData); 342 343 if ( rpmExists ) { 344 // Full package name not defined in xpd file 345 if (( packageData.getFullPackageName() == null ) || ( packageData.getFullPackageName().equals(""))) { 346 // Now it is possible to query the rpm database for the packageName, if it is not defined in xpd file! 347 String fullPackageName = getPackageNameFromRpm(packageData, installData); 348 if ( fullPackageName != null ) { 349 packageData.setFullPackageName(fullPackageName); 350 } else { 351 System.err.println("Error: Linux package name not defined in xpd file and could not be determined: " 352 + packageData.getPackageName()); 353 } 354 } 355 packageData.setPkgExists(true); 356 357 } else { 358 packageData.setPkgExists(false); 359 } 360 361 } 362 363 for (Enumeration e = packageData.children(); e.hasMoreElements(); ) { 364 PackageDescription child = (PackageDescription) e.nextElement(); 365 getLinuxPackageNamesFromRpmquery(child, installData); 366 } 367 } 368 getLinuxDatabasePath(InstallData data)369 public String getLinuxDatabasePath(InstallData data) { 370 String databasePath = null; 371 String installDir = data.getInstallDir(); 372 String databaseDir = installDir; 373 // String databaseDir = SystemManager.getParentDirectory(installDir); 374 String linuxDatabaseName = ".RPM_OFFICE_DATABASE"; 375 File databaseFile = new File(databaseDir, linuxDatabaseName); 376 databasePath = databaseFile.getPath(); 377 return databasePath; 378 } 379 investigateDebian(InstallData data)380 public void investigateDebian(InstallData data) { 381 382 // First check: Is this a Debian system? 383 384 String dpkgFile = "/usr/bin/dpkg"; 385 386 if ( new File(dpkgFile).exists() ) { 387 388 data.setIsDebianSystem(true); 389 390 // Second check: If this is a Debian system, is "--force-debian" required? Older 391 // versions do not support "--force-debian". 392 393 // String rpmQuery = "rpm --help; 394 String[] rpmQueryArray = new String[2]; 395 rpmQueryArray[0] = "rpm"; 396 rpmQueryArray[1] = "--help"; 397 398 Vector returnVector = new Vector(); 399 Vector returnErrorVector = new Vector(); 400 int returnValue = ExecuteProcess.executeProcessReturnVector(rpmQueryArray, returnVector, returnErrorVector); 401 402 // Checking if the return vector contains the string "force-debian" 403 404 for (int i = 0; i < returnVector.size(); i++) { 405 String line = (String) returnVector.get(i); 406 if ( line.indexOf("force-debian") > -1 ) { 407 data.setUseForceDebian(true); 408 } 409 } 410 } 411 } 412 getLinuxFileInfo(PackageDescription packageData)413 public void getLinuxFileInfo(PackageDescription packageData) { 414 // analyzing a string like "openoffice-core01-2.0.3-159" as "name-version-release" 415 InstallData data = InstallData.getInstance(); 416 if ( packageData.pkgExists() ) { 417 if (( packageData.getFullPackageName() != null ) && ( ! packageData.getFullPackageName().equals(""))) { 418 String longName = packageData.getFullPackageName(); 419 420 int pos = longName.lastIndexOf("-"); 421 if (data.isInstallationMode()) { 422 // not saving at uninstallation, because it can be updated without GUI installer 423 packageData.setPkgRelease(longName.substring(pos+1, longName.length())); 424 } 425 longName = longName.substring(0, pos); 426 427 pos = longName.lastIndexOf("-"); 428 if (data.isInstallationMode()) { 429 // not saving at uninstallation, because it can be updated without GUI installer 430 packageData.setPkgVersion(longName.substring(pos+1, longName.length())); 431 } 432 packageData.setPkgRealName(longName.substring(0, pos)); 433 } 434 } 435 436 for (Enumeration e = packageData.children(); e.hasMoreElements(); ) { 437 PackageDescription child = (PackageDescription) e.nextElement(); 438 getLinuxFileInfo(child); 439 } 440 441 } 442 setFullPackageNameAtUninstall(PackageDescription packageData, HashMap packageNames)443 public void setFullPackageNameAtUninstall(PackageDescription packageData, HashMap packageNames) { 444 445 if (( packageData.getPackageName() != null ) && ( ! packageData.getPackageName().equals(""))) { 446 if (( packageData.getFullPackageName() == null ) || ( packageData.getFullPackageName().equals(""))) { 447 String packageName = packageData.getPackageName(); 448 // Does this always exist? Should not be required! 449 // But is there another way to get the packageNames, without this file? 450 // During installation the packageNames can be determined by querying the rpm file 451 // -> this is not possible during uninstallation 452 String fullPackageName = (String) packageNames.get(packageName); 453 packageData.setFullPackageName(fullPackageName); 454 } 455 } 456 457 for (Enumeration e = packageData.children(); e.hasMoreElements(); ) { 458 PackageDescription child = (PackageDescription) e.nextElement(); 459 setFullPackageNameAtUninstall(child, packageNames); 460 } 461 } 462 getRelocationString(PackageDescription packageData, String packageName)463 public String getRelocationString(PackageDescription packageData, String packageName) { 464 String relocationString = null; 465 466 if ( packageData.isRelocatable() ) { 467 // String rpmQuery = "rpm -qp --qf %{PREFIXES}" + " " + packageName; 468 String[] rpmQueryArray = new String[5]; 469 rpmQueryArray[0] = "rpm"; 470 rpmQueryArray[1] = "-qp"; 471 rpmQueryArray[2] = "--qf"; 472 rpmQueryArray[3] = "%{PREFIXES}"; 473 rpmQueryArray[4] = packageName; 474 475 Vector returnVector = new Vector(); 476 Vector returnErrorVector = new Vector(); 477 int returnValue = ExecuteProcess.executeProcessReturnVector(rpmQueryArray, returnVector, returnErrorVector); 478 relocationString = (String) returnVector.get(0); 479 } 480 481 return relocationString; 482 } 483 createPackageNameFileAtPostinstall(InstallData data, PackageDescription packageData)484 public void createPackageNameFileAtPostinstall(InstallData data, PackageDescription packageData) { 485 486 // The file "packageNames" must not be an own database! It must be possible to install 487 // and deinstall RPMs without this GUI installer. Therefore the file packageNames is 488 // not always up to date. Nevertheless it makes the deinstallation faster, because of 489 // all packages, whose "real" package name is not defined in xpd files (for example 490 // "openoffice-core01-2.0.3-159.rpm" hat the "real" name "openoffice-core01" that is 491 // used for deinstallation) this can be read in this file. Otherwise it would be 492 // necessary to determine the "real" name with a database question. 493 // The version and release that are also stored in file "packageNames" must not be 494 // used for deinstallation because they are probably not up to date. 495 496 File destDir = new File(data.getInstallDefaultDir(), data.getProductDir()); 497 File uninstallDir = new File(destDir, data.getUninstallDirName()); 498 String fileName = "packageNames"; 499 File packageNamesFile = new File(uninstallDir, fileName); 500 Vector packageNames = new Vector(); 501 getPackageNamesContent(packageData, packageNames); 502 SystemManager.saveCharFileVector(packageNamesFile.getPath(), packageNames); 503 } 504 readPackageNamesFile()505 public HashMap readPackageNamesFile() { 506 // package names are stored in file "packageNames" in data.getInfoRoot() directory 507 String fileName = "packageNames"; 508 InstallData data = InstallData.getInstance(); 509 File dir = data.getInfoRoot(); 510 File file = new File(dir, fileName); 511 Vector fileContent = SystemManager.readCharFileVector(file.getPath()); 512 HashMap map = Converter.convertVectorToHashmap(fileContent); 513 return map; 514 } 515 saveModulesLogFile(InstallData data)516 public void saveModulesLogFile(InstallData data) { 517 if ( data.logModuleStates() ) { 518 Vector logContent = LogManager.getModulesLogFile(); 519 File destDir = new File(data.getInstallDefaultDir(), data.getProductDir()); 520 File uninstallDir = new File(destDir, data.getUninstallDirName()); 521 File modulesLogFile = new File(uninstallDir, "moduleSettingsLog.txt"); 522 SystemManager.saveCharFileVector(modulesLogFile.getPath(), logContent); 523 } 524 } 525 fixInstallationDirectory(String installDir)526 public String fixInstallationDirectory(String installDir) { 527 // inject a second slash to the last path segment to avoid rpm 3 concatenation bug 528 int lastSlashPos = installDir.lastIndexOf('/'); 529 String sub1 = installDir.substring(0,lastSlashPos); 530 String sub2 = installDir.substring(lastSlashPos); 531 String fixedInstallDir = sub1 + "/" + sub2; 532 // fixedInstallDir.replaceAll(" ", "%20"); 533 return fixedInstallDir; 534 } 535 536 } 537