Skip to content
Snippets Groups Projects
get_distro.cpp 4.69 KiB
/* Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
 * Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
 *
 * This file is part of simmc-agent
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 * USA.
 */

#include "agent/linux/get_distro.h"

int open_file(std::string name, std::ifstream& fstream) {
        fstream.open(name);
        if (fstream.is_open())
            return 1;
        else
            return 0;
}

std::string get_distro() {
    /* currently recorded distros are
       * Ubuntu
       * Debian
       * Linux Comunicações
       * Linux Educacional
       all of which should have the lsb-release file, but I added a couple more
       common distros just in case */

    std::ifstream release_file;
    std::string line;

    // lsb compliant
    if (open_file("/etc/lsb-release", release_file)) {
        const std::string key = "DISTRIB_DESCRIPTION=";
        std::size_t found;

        while (getline(release_file, line)) {
            found = line.find(key);
            if (found != std::string::npos) {
                return (line.substr(found+key.length()+1,
                                   // remove key and quotes at the beginning
                                   line.length()-(found+key.length()+1)-1));
                                   // remove quotes at the end
            }
        }

        throw std::string("Release file empty or incomplete.");

    // openSuSE
    } else if (open_file("/etc/os-release", release_file)) {
        const std::string name_key = "NAME=";
        const std::string version_key = "VERSION=";

        std::string name;
        std::string version;

        std::size_t found_name;
        std::size_t found_version;

        while (getline(release_file, line)) {
            found_name = line.find(name_key);
            found_version = line.find(version_key);
            if (found_name < line.length()) {
                name = line.substr(found_name+name_key.length()+1,
                              // remove key and quotes at the beginning
                              line.length()-(found_name+name_key.length()+1)-1);
                              // remove quotes at the end
            }

            if (found_version < line.length()) {
                version = line.substr(found_version+version_key.length()+1,
                                // remove key and quotes at the beginning
                                line.length()-
                                (found_version+version_key.length()+1)-1);
                                // remove quotes at the end
            }

            if (name.length() && version.length()) {
                return name + version;
            }
        }

        if (name.length())
            return name;

        throw std::string("Release file empty or incomplete.");

    } else if (open_file("/etc/novell-release", release_file)) {
        getline(release_file, line);

        if (line.length())
            return line;

        throw std::string("Release file empty.");

    } else if (open_file("/etc/sles-release", release_file)) {
        getline(release_file, line);

        if (line.length())
            return line;

        throw std::string("Release file empty.");

    // fedora
    } else if (open_file("/etc/redhat-release", release_file)) {
        getline(release_file, line);

        if (line.length())
            return line;

        throw std::string("Release file empty.");

    // debian -- leave this at the end, otherwise debian-based distros
    //           will find the debian_version file instead of the actual
    //           distro name
    } else if (open_file("/etc/debian-release", release_file)) {
        getline(release_file, line);

        if (line.length())
            return line;

        throw std::string("Release file empty.");

    } else if (open_file("/etc/debian-version", release_file)) {
        getline(release_file, line);

        if (line.length())
            return line;

        throw std::string("Release file empty.");
    }

    throw std::string("No release file found.");
}