blob: 48331b0fb0d774ba8ce14531bf19c17fed2cae6e [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package org.openoffice.setup.InstallerHelper;
import org.openoffice.setup.InstallData;
import org.openoffice.setup.SetupData.PackageDescription;
import org.openoffice.setup.Util.Converter;
import org.openoffice.setup.Util.ExecuteProcess;
import org.openoffice.setup.Util.LogManager;
import org.openoffice.setup.Util.SystemManager;
import java.io.File;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Vector;public class LinuxHelper {
public LinuxHelper() {
super();
}
private void getPackageNamesContent(PackageDescription packageData, Vector packageNames) {
if (( packageData.getPackageName() != null ) && ( ! packageData.getPackageName().equals(""))) {
packageNames.add(packageData.getPackageName() + "=" + packageData.getFullPackageName());
}
for (Enumeration e = packageData.children(); e.hasMoreElements(); ) {
PackageDescription child = (PackageDescription) e.nextElement();
getPackageNamesContent(child, packageNames);
}
}
private String getPackageNameFromRpm(PackageDescription packageData, InstallData installData) {
String fullPackageName = null;
String packagePath = installData.getPackagePath();
if (( packageData.getPkgSubdir() != null ) && ( ! packageData.getPkgSubdir().equals("") )) {
File completePackageFile = new File(packagePath, packageData.getPkgSubdir());
packagePath = completePackageFile.getPath();
}
String rpmFileName = packageData.getPackageName();
File rpmFile = new File(packagePath, rpmFileName);
if ( rpmFile.exists() ) {
String rpmCommand = "rpm -qp " + rpmFile.getPath();
String[] rpmCommandArray = new String[3];
rpmCommandArray[0] = "rpm";
rpmCommandArray[1] = "-qp";
rpmCommandArray[2] = rpmFile.getPath();
Vector returnVector = new Vector();
Vector returnErrorVector = new Vector();
int returnValue = ExecuteProcess.executeProcessReturnVector(rpmCommandArray, returnVector, returnErrorVector);
String returnString = (String) returnVector.get(0);
String log = rpmCommand + "<br><b>Returns: " + returnString + "</b><br>";
LogManager.addCommandsLogfileComment(log);
fullPackageName = returnString;
} else {
System.err.println("Error: Could not find file " + rpmFile.getPath());
}
return fullPackageName;
}
private boolean checkPackageExistence(PackageDescription packageData, InstallData installData) {
boolean fileExists = false;
String packagePath = installData.getPackagePath();
if (( packageData.getPkgSubdir() != null ) && ( ! packageData.getPkgSubdir().equals("") )) {
File completePackageFile = new File(packagePath, packageData.getPkgSubdir());
packagePath = completePackageFile.getPath();
}
String rpmFileName = packageData.getPackageName();
File rpmFile = new File(packagePath, rpmFileName);
if ( rpmFile.exists() ) {
fileExists = true;
}
return fileExists;
}
private HashMap analyzeVersionString(String versionString) {
boolean errorOccured = false;
Integer micro = null;
Integer minor = null;
Integer major = null;
Integer release = null;
String microString = null;
String minorString = null;
String majorString = null;
String releaseString = null;
int pos = versionString.lastIndexOf("_"); // this is a jre RPM (1.5.0_06)
if ( pos > -1 ) {
try {
releaseString = versionString.substring(pos+1, versionString.length());
versionString = versionString.substring(0, pos);
} catch (IndexOutOfBoundsException ex) {
System.err.println("Error: Could not get substring from " + versionString);
errorOccured = true;
}
try {
int releaseInt = Integer.parseInt(releaseString);
release = new Integer(releaseInt);
} catch (NumberFormatException ex) {
System.err.println("Error: Could not convert " + releaseString + " to integer");
errorOccured = true;
}
}
// Problem: Some rpms have "2.3" instead of "2.3.0"
String compareString = versionString;
pos = compareString.lastIndexOf("."); // returns "-1", if not found
if ( pos > -1 ) {
String substring = compareString.substring(0, pos);
pos = substring.lastIndexOf("."); // returns "-1", if not found
if ( pos == -1 ) {
versionString = versionString + ".0";
// System.err.println("Warning: Changing from " + compareString + " to " + versionString);
}
} else {
versionString = versionString + ".0.0";
}
// the standard analyzing mechanism
pos = versionString.lastIndexOf("."); // returns "-1", if not found
if ( pos > -1 )
{
try {
microString = versionString.substring(pos+1, versionString.length());
versionString = versionString.substring(0, pos);
} catch (IndexOutOfBoundsException ex) {
System.err.println("Error: Could not get substring from " + versionString);
errorOccured = true;
}
pos = versionString.lastIndexOf(".");
if ( pos > -1 ) {
try {
minorString = versionString.substring(pos+1, versionString.length());
majorString = versionString.substring(0, pos);
} catch (IndexOutOfBoundsException ex) {
System.err.println("Error: Could not get substring from " + versionString);
errorOccured = true;
}
try {
int microInt = Integer.parseInt(microString);
int minorInt = Integer.parseInt(minorString);
int majorInt = Integer.parseInt(majorString);
micro = new Integer(microInt);
minor = new Integer(minorInt);
major = new Integer(majorInt);
} catch (NumberFormatException ex) {
System.err.println("Error: Could not convert " + microString + "," +
minorString + " or " + majorString + " to integer");
errorOccured = true;
}
}
}
// if ( microString == null ) { microString = ""; }
// if ( majorString == null ) { majorString = ""; }
// if ( releaseString == null ) { releaseString = ""; }
// if ( minorString == null ) { minorString = ""; }
// System.err.println("Major " + majorString + " Minor: " + minorString + " Micro: " + microString + " Release: " + releaseString);
if ( errorOccured ) {
micro = null;
minor = null;
major = null;
release = null;
}
HashMap hashRpm = new HashMap();
hashRpm.put("micro", micro);
hashRpm.put("minor", minor);
hashRpm.put("major", major);
hashRpm.put("release", release);
// If one of this values is "null", procedure "compareTwoRpms" always delivers false.
// This means, that the installed package is not older.
// System.err.println("Analyzed: " + "micro: " + hashRpm.get("micro").toString() + " minor: " + hashRpm.get("minor").toString() + " major: " + hashRpm.get("major").toString());
return hashRpm;
}
private HashMap analyzeReleaseString(HashMap hashRpm, String releaseString) {
int release;
try {
release = Integer.parseInt(releaseString);
Integer releaseObj = new Integer(release);
hashRpm.put("release", releaseObj);
}
catch (NumberFormatException ex) {
// JRE often contain a string like "FCS"
// System.err.println("Error: Could not convert " + releaseString + " to integer");
hashRpm.put("release", null);
}
return hashRpm;
}
public int getInstalledMinor(String version) {
int minor = 0;
int pos = version.indexOf(".");
if ( pos > -1 ) {
String reduced = version.substring(pos + 1, version.length());
pos = reduced.indexOf(".");
if ( pos > -1 ) {
reduced = reduced.substring(0, pos);
minor = Integer.parseInt(reduced);
}
}
return minor;
}
private boolean compareTwoRpms(HashMap hash1, HashMap hash2) {
boolean hash1IsOlder = false;
if (( hash1.get("major") != null ) && ( hash2.get("major") != null )) {
if ( ((Integer)hash1.get("major")).intValue() < ((Integer)hash2.get("major")).intValue() ) {
hash1IsOlder = true;
} else {
if (( hash1.get("minor") != null ) && ( hash2.get("minor") != null )) {
if ( ((Integer)hash1.get("minor")).intValue() < ((Integer)hash2.get("minor")).intValue() ) {
hash1IsOlder = true;
} else {
if (( hash1.get("micro") != null ) && ( hash2.get("micro") != null )) {
if ( ((Integer)hash1.get("micro")).intValue() < ((Integer)hash2.get("micro")).intValue() ) {
hash1IsOlder = true;
} else {
if (( hash1.get("release") != null ) && ( hash2.get("release") != null )) {
if ( ((Integer)hash1.get("release")).intValue() < ((Integer)hash2.get("release")).intValue() ) {
hash1IsOlder = true;
}
}
}
}
}
}
}
}
return hash1IsOlder;
}
public boolean compareVersionAndRelease(String versionString, String releaseString, PackageDescription packageData, boolean checkIfInstalledIsOlder) {
// version and release are gotten from the rpm database. packageData contains
// the information about the rpm, that shall be installed. It has to be installed,
// if the installed product defined by version and release is older.
// version is something like "2.0.3", release something like "164".
// An exception is the jre package, where version is "1.5.0_06" and release "fcs".
HashMap installedRpm = analyzeVersionString(versionString);
if ( installedRpm.get("release") == null ) {
installedRpm = analyzeReleaseString(installedRpm, releaseString);
}
// System.err.println("Package: " + packageData.getPackageName());
// String outputString = "Installed RPM: ";
// if ( installedRpm.get("major") != null ) { outputString = outputString + " major: " + installedRpm.get("major").toString(); }
// else { outputString = outputString + " major is null"; }
// if ( installedRpm.get("minor") != null ) { outputString = outputString + " minor: " + installedRpm.get("minor").toString(); }
// else { outputString = outputString + " minor is null"; }
// if ( installedRpm.get("micro") != null ) { outputString = outputString + " micro: " + installedRpm.get("micro").toString(); }
// else { outputString = outputString + " micro is null"; }
// if ( installedRpm.get("release") != null ) { outputString = outputString + " release: " + installedRpm.get("release").toString(); }
// else { outputString = outputString + " release is null"; }
// System.err.println(outputString);
HashMap notInstalledRpm = analyzeVersionString(packageData.getPkgVersion());
if ( notInstalledRpm.get("release") == null ) {
notInstalledRpm = analyzeReleaseString(notInstalledRpm, packageData.getPkgRelease());
}
// outputString = "Not installed RPM: ";
// if ( notInstalledRpm.get("major") != null ) { outputString = outputString + " major: " + notInstalledRpm.get("major").toString(); }
// else { outputString = outputString + " major is null"; }
// if ( notInstalledRpm.get("minor") != null ) { outputString = outputString + " minor: " + notInstalledRpm.get("minor").toString(); }
// else { outputString = outputString + " minor is null"; }
// if ( notInstalledRpm.get("micro") != null ) { outputString = outputString + " micro: " + notInstalledRpm.get("micro").toString(); }
// else { outputString = outputString + " micro is null"; }
// if ( notInstalledRpm.get("release") != null ) { outputString = outputString + " release: " + notInstalledRpm.get("release").toString(); }
// else { outputString = outputString + " release is null"; }
// System.err.println(outputString);
boolean firstIsOlder = false;
if ( checkIfInstalledIsOlder ) {
firstIsOlder = compareTwoRpms(installedRpm, notInstalledRpm);
// System.err.println("Result: Installed RPM is older: " + firstIsOlder);
} else {
firstIsOlder = compareTwoRpms(notInstalledRpm, installedRpm);
// System.err.println("Result: Not installed RPM is older: " + firstIsOlder);
}
return firstIsOlder;
}
public void getLinuxPackageNamesFromRpmquery(PackageDescription packageData, InstallData installData) {
if ((packageData.getPackageName() != null) && ( ! packageData.getPackageName().equals(""))) {
boolean rpmExists = checkPackageExistence(packageData, installData);
if ( rpmExists ) {
// Full package name not defined in xpd file
if (( packageData.getFullPackageName() == null ) || ( packageData.getFullPackageName().equals(""))) {
// Now it is possible to query the rpm database for the packageName, if it is not defined in xpd file!
String fullPackageName = getPackageNameFromRpm(packageData, installData);
if ( fullPackageName != null ) {
packageData.setFullPackageName(fullPackageName);
} else {
System.err.println("Error: Linux package name not defined in xpd file and could not be determined: "
+ packageData.getPackageName());
}
}
packageData.setPkgExists(true);
} else {
packageData.setPkgExists(false);
}
}
for (Enumeration e = packageData.children(); e.hasMoreElements(); ) {
PackageDescription child = (PackageDescription) e.nextElement();
getLinuxPackageNamesFromRpmquery(child, installData);
}
}
public String getLinuxDatabasePath(InstallData data) {
String databasePath = null;
String installDir = data.getInstallDir();
String databaseDir = installDir;
// String databaseDir = SystemManager.getParentDirectory(installDir);
String linuxDatabaseName = ".RPM_OFFICE_DATABASE";
File databaseFile = new File(databaseDir, linuxDatabaseName);
databasePath = databaseFile.getPath();
return databasePath;
}
public void investigateDebian(InstallData data) {
// First check: Is this a Debian system?
String dpkgFile = "/usr/bin/dpkg";
if ( new File(dpkgFile).exists() ) {
data.setIsDebianSystem(true);
// Second check: If this is a Debian system, is "--force-debian" required? Older
// versions do not support "--force-debian".
// String rpmQuery = "rpm --help;
String[] rpmQueryArray = new String[2];
rpmQueryArray[0] = "rpm";
rpmQueryArray[1] = "--help";
Vector returnVector = new Vector();
Vector returnErrorVector = new Vector();
int returnValue = ExecuteProcess.executeProcessReturnVector(rpmQueryArray, returnVector, returnErrorVector);
// Checking if the return vector contains the string "force-debian"
for (int i = 0; i < returnVector.size(); i++) {
String line = (String) returnVector.get(i);
if ( line.indexOf("force-debian") > -1 ) {
data.setUseForceDebian(true);
}
}
}
}
public void getLinuxFileInfo(PackageDescription packageData) {
// analyzing a string like "openoffice-core01-2.0.3-159" as "name-version-release"
InstallData data = InstallData.getInstance();
if ( packageData.pkgExists() ) {
if (( packageData.getFullPackageName() != null ) && ( ! packageData.getFullPackageName().equals(""))) {
String longName = packageData.getFullPackageName();
int pos = longName.lastIndexOf("-");
if (data.isInstallationMode()) {
// not saving at uninstallation, because it can be updated without GUI installer
packageData.setPkgRelease(longName.substring(pos+1, longName.length()));
}
longName = longName.substring(0, pos);
pos = longName.lastIndexOf("-");
if (data.isInstallationMode()) {
// not saving at uninstallation, because it can be updated without GUI installer
packageData.setPkgVersion(longName.substring(pos+1, longName.length()));
}
packageData.setPkgRealName(longName.substring(0, pos));
}
}
for (Enumeration e = packageData.children(); e.hasMoreElements(); ) {
PackageDescription child = (PackageDescription) e.nextElement();
getLinuxFileInfo(child);
}
}
public void setFullPackageNameAtUninstall(PackageDescription packageData, HashMap packageNames) {
if (( packageData.getPackageName() != null ) && ( ! packageData.getPackageName().equals(""))) {
if (( packageData.getFullPackageName() == null ) || ( packageData.getFullPackageName().equals(""))) {
String packageName = packageData.getPackageName();
// Does this always exist? Should not be required!
// But is there another way to get the packageNames, without this file?
// During installation the packageNames can be determined by querying the rpm file
// -> this is not possible during uninstallation
String fullPackageName = (String) packageNames.get(packageName);
packageData.setFullPackageName(fullPackageName);
}
}
for (Enumeration e = packageData.children(); e.hasMoreElements(); ) {
PackageDescription child = (PackageDescription) e.nextElement();
setFullPackageNameAtUninstall(child, packageNames);
}
}
public String getRelocationString(PackageDescription packageData, String packageName) {
String relocationString = null;
if ( packageData.isRelocatable() ) {
// String rpmQuery = "rpm -qp --qf %{PREFIXES}" + " " + packageName;
String[] rpmQueryArray = new String[5];
rpmQueryArray[0] = "rpm";
rpmQueryArray[1] = "-qp";
rpmQueryArray[2] = "--qf";
rpmQueryArray[3] = "%{PREFIXES}";
rpmQueryArray[4] = packageName;
Vector returnVector = new Vector();
Vector returnErrorVector = new Vector();
int returnValue = ExecuteProcess.executeProcessReturnVector(rpmQueryArray, returnVector, returnErrorVector);
relocationString = (String) returnVector.get(0);
}
return relocationString;
}
public void createPackageNameFileAtPostinstall(InstallData data, PackageDescription packageData) {
// The file "packageNames" must not be an own database! It must be possible to install
// and deinstall RPMs without this GUI installer. Therefore the file packageNames is
// not always up to date. Nevertheless it makes the deinstallation faster, because of
// all packages, whose "real" package name is not defined in xpd files (for example
// "openoffice-core01-2.0.3-159.rpm" hat the "real" name "openoffice-core01" that is
// used for deinstallation) this can be read in this file. Otherwise it would be
// neccessary to determine the "real" name with a database question.
// The version and release that are also stored in file "packageNames" must not be
// used for deinstallation because they are probably not up to date.
File destDir = new File(data.getInstallDefaultDir(), data.getProductDir());
File uninstallDir = new File(destDir, data.getUninstallDirName());
String fileName = "packageNames";
File packageNamesFile = new File(uninstallDir, fileName);
Vector packageNames = new Vector();
getPackageNamesContent(packageData, packageNames);
SystemManager.saveCharFileVector(packageNamesFile.getPath(), packageNames);
}
public HashMap readPackageNamesFile() {
// package names are stored in file "packageNames" in data.getInfoRoot() directory
String fileName = "packageNames";
InstallData data = InstallData.getInstance();
File dir = data.getInfoRoot();
File file = new File(dir, fileName);
Vector fileContent = SystemManager.readCharFileVector(file.getPath());
HashMap map = Converter.convertVectorToHashmap(fileContent);
return map;
}
public void saveModulesLogFile(InstallData data) {
if ( data.logModuleStates() ) {
Vector logContent = LogManager.getModulesLogFile();
File destDir = new File(data.getInstallDefaultDir(), data.getProductDir());
File uninstallDir = new File(destDir, data.getUninstallDirName());
File modulesLogFile = new File(uninstallDir, "moduleSettingsLog.txt");
SystemManager.saveCharFileVector(modulesLogFile.getPath(), logContent);
}
}
public String fixInstallationDirectory(String installDir) {
// inject a second slash to the last path segment to avoid rpm 3 concatenation bug
int lastSlashPos = installDir.lastIndexOf('/');
String sub1 = installDir.substring(0,lastSlashPos);
String sub2 = installDir.substring(lastSlashPos);
String fixedInstallDir = sub1 + "/" + sub2;
// fixedInstallDir.replaceAll(" ", "%20");
return fixedInstallDir;
}
}