123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //===--- Distro.cpp - Linux distribution detection support ------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "clang/Driver/Distro.h"
- #include "clang/Basic/LLVM.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/Support/ErrorOr.h"
- #include "llvm/Support/MemoryBuffer.h"
- using namespace clang::driver;
- using namespace clang;
- static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
- VFS.getBufferForFile("/etc/lsb-release");
- if (File) {
- StringRef Data = File.get()->getBuffer();
- SmallVector<StringRef, 16> Lines;
- Data.split(Lines, "\n");
- Distro::DistroType Version = Distro::UnknownDistro;
- for (StringRef Line : Lines)
- if (Version == Distro::UnknownDistro && Line.startswith("DISTRIB_CODENAME="))
- Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(17))
- .Case("hardy", Distro::UbuntuHardy)
- .Case("intrepid", Distro::UbuntuIntrepid)
- .Case("jaunty", Distro::UbuntuJaunty)
- .Case("karmic", Distro::UbuntuKarmic)
- .Case("lucid", Distro::UbuntuLucid)
- .Case("maverick", Distro::UbuntuMaverick)
- .Case("natty", Distro::UbuntuNatty)
- .Case("oneiric", Distro::UbuntuOneiric)
- .Case("precise", Distro::UbuntuPrecise)
- .Case("quantal", Distro::UbuntuQuantal)
- .Case("raring", Distro::UbuntuRaring)
- .Case("saucy", Distro::UbuntuSaucy)
- .Case("trusty", Distro::UbuntuTrusty)
- .Case("utopic", Distro::UbuntuUtopic)
- .Case("vivid", Distro::UbuntuVivid)
- .Case("wily", Distro::UbuntuWily)
- .Case("xenial", Distro::UbuntuXenial)
- .Case("yakkety", Distro::UbuntuYakkety)
- .Case("zesty", Distro::UbuntuZesty)
- .Case("artful", Distro::UbuntuArtful)
- .Case("bionic", Distro::UbuntuBionic)
- .Case("cosmic", Distro::UbuntuCosmic)
- .Case("disco", Distro::UbuntuDisco)
- .Case("eoan", Distro::UbuntuEoan)
- .Default(Distro::UnknownDistro);
- if (Version != Distro::UnknownDistro)
- return Version;
- }
- File = VFS.getBufferForFile("/etc/redhat-release");
- if (File) {
- StringRef Data = File.get()->getBuffer();
- if (Data.startswith("Fedora release"))
- return Distro::Fedora;
- if (Data.startswith("Red Hat Enterprise Linux") ||
- Data.startswith("CentOS") ||
- Data.startswith("Scientific Linux")) {
- if (Data.find("release 7") != StringRef::npos)
- return Distro::RHEL7;
- else if (Data.find("release 6") != StringRef::npos)
- return Distro::RHEL6;
- else if (Data.find("release 5") != StringRef::npos)
- return Distro::RHEL5;
- }
- return Distro::UnknownDistro;
- }
- File = VFS.getBufferForFile("/etc/debian_version");
- if (File) {
- StringRef Data = File.get()->getBuffer();
- // Contents: < major.minor > or < codename/sid >
- int MajorVersion;
- if (!Data.split('.').first.getAsInteger(10, MajorVersion)) {
- switch (MajorVersion) {
- case 5:
- return Distro::DebianLenny;
- case 6:
- return Distro::DebianSqueeze;
- case 7:
- return Distro::DebianWheezy;
- case 8:
- return Distro::DebianJessie;
- case 9:
- return Distro::DebianStretch;
- case 10:
- return Distro::DebianBuster;
- case 11:
- return Distro::DebianBullseye;
- default:
- return Distro::UnknownDistro;
- }
- }
- return llvm::StringSwitch<Distro::DistroType>(Data.split("\n").first)
- .Case("squeeze/sid", Distro::DebianSqueeze)
- .Case("wheezy/sid", Distro::DebianWheezy)
- .Case("jessie/sid", Distro::DebianJessie)
- .Case("stretch/sid", Distro::DebianStretch)
- .Case("buster/sid", Distro::DebianBuster)
- .Case("bullseye/sid", Distro::DebianBullseye)
- .Default(Distro::UnknownDistro);
- }
- File = VFS.getBufferForFile("/etc/SuSE-release");
- if (File) {
- StringRef Data = File.get()->getBuffer();
- SmallVector<StringRef, 8> Lines;
- Data.split(Lines, "\n");
- for (const StringRef& Line : Lines) {
- if (!Line.trim().startswith("VERSION"))
- continue;
- std::pair<StringRef, StringRef> SplitLine = Line.split('=');
- // Old versions have split VERSION and PATCHLEVEL
- // Newer versions use VERSION = x.y
- std::pair<StringRef, StringRef> SplitVer = SplitLine.second.trim().split('.');
- int Version;
- // OpenSUSE/SLES 10 and older are not supported and not compatible
- // with our rules, so just treat them as Distro::UnknownDistro.
- if (!SplitVer.first.getAsInteger(10, Version) && Version > 10)
- return Distro::OpenSUSE;
- return Distro::UnknownDistro;
- }
- return Distro::UnknownDistro;
- }
- if (VFS.exists("/etc/exherbo-release"))
- return Distro::Exherbo;
- if (VFS.exists("/etc/alpine-release"))
- return Distro::AlpineLinux;
- if (VFS.exists("/etc/arch-release"))
- return Distro::ArchLinux;
- if (VFS.exists("/etc/gentoo-release"))
- return Distro::Gentoo;
- return Distro::UnknownDistro;
- }
- Distro::Distro(llvm::vfs::FileSystem &VFS) : DistroVal(DetectDistro(VFS)) {}
|