/*******************************************************************************
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.usage.googleanalytics.eclipse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.Platform;
/**
* @author André Dietisheim, Alexey Kazakov
*/
public class LinuxSystem {
public static final LinuxSystem INSTANCE = new LinuxSystem();
/**
* @see <a href="http://linuxmafia.com/faq/Admin/release-files.html"> an
* extensive list of release file locations</a>
*
* @see <a
* href="http://superuser.com/questions/11008/how-do-i-find-out-what-version-of-linux-im-running">
* release-file strings</a>
*/
public final LinuxDistro ARCH = new LinuxDistro("Arch", "/etc/arch-release");
public final LinuxDistro CENTOS = new ReleaseFileContentCheckedDistro("CentOS", "/etc/redhat-release");
public final LinuxDistro CENTOS_ALTERNATIVE = new LinuxDistro("CentOS", "/etc/centos-release");
public final LinuxDistro DEBIAN = new LinuxDistro("Debian", "/etc/debian_version");
public final LinuxDistro DEBIAN_ALTERNATIVE = new LinuxDistro("Debian", "/etc/debian_release");
public final LinuxDistro FEDORA = new LinuxDistro("Fedora", "/etc/fedora-release");
public final LinuxDistro GENTOO = new LinuxDistro("Gentoo", "/etc/gentoo-release");
public final LinuxDistro YELLOWDOG = new LinuxDistro("YellowDog", "/etc/yellowdog-release");
public final LinuxDistro KNOPPIX = new LinuxDistro("Knoppix", "knoppix_version");
public final LinuxDistro MAGEIA = new LinuxDistro("Mageia", "/etc/mageia-release");
public final LinuxDistro MANDRAKE = new LinuxDistro("Mandrake", "/etc/mandrake-release");
public final LinuxDistro MANDRIVA = new LinuxDistro("Mandriva", "/etc/mandriva-release");
public final LinuxDistro MANDRIVA_ALTERNATIVE = new ReleaseFileContentCheckedDistro("Mandriva", "/etc/version");
public final LinuxDistro MINT = new ReleaseFileContentCheckedDistro("LinuxMint", "/etc/lsb-release");
public final LinuxDistro PLD = new LinuxDistro("PLD", "/etc/pld-release");
public final LinuxDistro REDHAT = new ReleaseFileContentCheckedDistro("Red Hat", "/etc/redhat-release");
public final LinuxDistro SLACKWARE = new LinuxDistro("Slackware", "/etc/slackware-version");
public final LinuxDistro SLACKWARE_ALTERNATIVE = new LinuxDistro("Slackware", "/etc/slackware-release");
public final LinuxDistro SUSE = new LinuxDistro("SUSE", "/etc/SuSE-release");
public final LinuxDistro OPEN_SUSE = new ReleaseFileContentCheckedDistro("openSUSE", "/etc/os-release");
public final LinuxDistro SUSE_ALTERNATIVE = new ReleaseFileContentCheckedDistro("SUSE", "/etc/os-release");
public final LinuxDistro UBUNTU = new ReleaseFileContentCheckedDistro("Ubuntu", "/etc/lsb-release");
public final LinuxDistro PUPPY = new LinuxDistro("Puppy", "/etc/puppyversion");
public final LinuxDistro DEFAULT_OS_RELEASE_FILE_BASED_DISTRO = new OsReleaseFileDistro();
public final LinuxDistro LIB_OS_RELEASE_FILE_BASED_DISTRO_ALTERNATIVE = new OsReleaseFileDistro("/usr/lib/os-release");
private final LinuxDistro[] ALL = new LinuxDistro[] {
CENTOS,
CENTOS_ALTERNATIVE,
MINT,
UBUNTU,
DEBIAN,
FEDORA,
GENTOO,
KNOPPIX,
MANDRAKE,
MANDRIVA,
PLD,
REDHAT,
SLACKWARE,
SLACKWARE_ALTERNATIVE,
SUSE,
OPEN_SUSE,
SUSE_ALTERNATIVE,
YELLOWDOG,
ARCH,
DEBIAN_ALTERNATIVE,
DEFAULT_OS_RELEASE_FILE_BASED_DISTRO,
LIB_OS_RELEASE_FILE_BASED_DISTRO_ALTERNATIVE
};
private LinuxDistro detectedDistro;
private String nameAndVersion;
boolean firstTimeDistroDetection = true;
boolean firstTimeNameDetection = true;
public LinuxDistro getDistro() {
if(firstTimeDistroDetection && detectedDistro==null) {
firstTimeDistroDetection = false;
if(isLinux()) {
for (LinuxDistro distro : ALL) {
if (distro.isDetected()) {
detectedDistro = distro;
break;
}
}
}
}
return detectedDistro;
}
protected boolean isLinux() {
return Platform.getOS().toLowerCase().indexOf("linux")>-1;
}
public String getDistroNameAndVersion() {
if(firstTimeNameDetection && nameAndVersion==null) {
firstTimeNameDetection = false;
LinuxDistro distro = getDistro();
if(isLinux()) {
nameAndVersion = (distro != null)?distro.getNameAndVersion():"Unknown";
}
}
return nameAndVersion;
}
protected boolean exists(String releaseFilePath) {
return releaseFilePath != null
&& releaseFilePath.length() > 0
&& new File(releaseFilePath).exists();
}
protected String getDistroFileContent(String filePath) throws IOException {
int charachtersToRead = 1024;
StringBuilder builder = new StringBuilder(charachtersToRead);
BufferedReader reader = new BufferedReader(new FileReader(filePath));
char[] buf = new char[charachtersToRead];
int charRead = 0;
while ((charRead = reader.read(buf)) != -1 && builder.length() < charachtersToRead) {
String readData = String.valueOf(buf, 0, charRead);
builder.append(readData);
}
reader.close();
return builder.toString();
}
public class LinuxDistro {
/**
* The pattern to match the contents of the release-file -
* /etc/fedora-release etc. Attention: Ubuntu has multi-line release
* file
*/
private final Pattern VERSION_REGEX = Pattern.compile("([0-9.]+)");
protected final String releaseFilePath;
protected String name;
protected LinuxDistro(String name, String releaseFilePath) {
this.name = name;
this.releaseFilePath = releaseFilePath;
}
protected boolean isDetected() {
return exists(getReleaseFilePath());
}
public String getName() {
return name;
}
public String getVersion() {
String distroString = getReleaseFileContent();
Matcher matcher = VERSION_REGEX.matcher(distroString);
if (matcher.find()) {
return matcher.group(1);
}
return "";
}
public String getNameAndVersion() {
return new StringBuilder().append(getName()).append(" ").append(getVersion()).toString().trim();
}
public String getReleaseFilePath() {
return releaseFilePath;
}
protected String getReleaseFileContent() {
try {
String distroString = getDistroFileContent(getReleaseFilePath());
if(distroString!=null) {
return distroString;
}
} catch (IOException e) {
// Ignore
}
return "";
}
@Override
public String toString() {
return getName();
}
}
/**
* A distribution definition that checks for presence of the given distro
* name in the given release file.
*/
public class ReleaseFileContentCheckedDistro extends LinuxDistro {
public ReleaseFileContentCheckedDistro(String name, String releaseFilePath) {
super(name, releaseFilePath);
}
@Override
protected boolean isDetected() {
boolean fileExists = exists(getReleaseFilePath());
if (fileExists) {
String content = getReleaseFileContent();
return content.toLowerCase().indexOf(getName().toLowerCase()) >= 0;
}
return false;
}
}
/**
* A distribution definition based on "/etc/os-release" file.
* The name is read from the "NAME=" property.
* See http://www.freedesktop.org/software/systemd/man/os-release.html
*/
public class OsReleaseFileDistro extends LinuxDistro {
protected OsReleaseFileDistro() {
this("/etc/os-release");
}
protected OsReleaseFileDistro(String releaseFilePath) {
super("Unknown", releaseFilePath);
}
@Override
public String getName() {
if(!isDetected()) {
return super.getName();
}
String content = getReleaseFileContent();
Properties p = new Properties();
try {
p.load(new StringReader(content));
String stName = p.getProperty("NAME");
if(stName==null) {
stName = p.getProperty("ID");
}
if(stName!=null) {
if(stName.startsWith("\"") && stName.endsWith("\"") && stName.length()>3) {
stName = stName.substring(1, stName.length()-1);
}
name = stName;
}
} catch (IOException e) {
// Ignore
}
return name;
}
}
}