%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/vendor/glpi-project/inventory_format/lib/php/ |
Current File : //var/www/projetos/suporte.iigd.com.br/vendor/glpi-project/inventory_format/lib/php/FilesToJSON.php |
<?php /** * --------------------------------------------------------------------- * GLPI - Gestionnaire Libre de Parc Informatique * Copyright (C) 2015-2018 Teclib' and contributors. * * http://glpi-project.org * * based on GLPI - Gestionnaire Libre de Parc Informatique * Copyright (C) 2003-2014 by the INDEPNET Development Team. * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * GLPI 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. * * GLPI 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 GLPI. If not, see <http://www.gnu.org/licenses/>. * --------------------------------------------------------------------- * * PHP version 7 * * @category Inventory * @package Glpi * @author Johan Cwiklinski <jcwiklinski@teclib.com> * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version * @link https://glpi-project.org */ namespace Glpi\Inventory; use RuntimeException; /** * Converts old FusionInventory XML format to new JSON schema * for automatic inventory. * * @category Inventory * @package Glpi * @author Johan Cwiklinski <jcwiklinski@teclib.com> * @copyright 2018-2023 GLPI Team and Contributors * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version * @link https://glpi-project.org */ final class FilesToJSON { public const TYPE_PCI = 'pciid'; public const TYPE_USB = 'usbid'; public const TYPE_OUI = 'ouis'; public const TYPE_IFTYPE = 'iftype'; private const SOURCES_URLS = [ self::TYPE_PCI => 'https://pci-ids.ucw.cz/v2.2/pci.ids', self::TYPE_USB => 'http://www.linux-usb.org/usb.ids', self::TYPE_OUI => 'https://standards-oui.ieee.org/oui/oui.txt', self::TYPE_IFTYPE => 'https://www.iana.org/assignments/smi-numbers/smi-numbers-5.csv', ]; /** * @var string */ private string $path = __DIR__ . '/../../data'; /** * Get JSON file path * * @param string $type Type (either 'pci', 'usb' or 'oui') * * @return string */ public function getJsonFilePath(string $type): string { return $this->path . '/' . $type . '.json'; } /** * Download new sources * * @throws RuntimeException * @return void */ public function refreshSources() { foreach (self::SOURCES_URLS as $type => $uri) { $path = $this->getSourceFilePath($type); $contents = $this->callCurl($uri); if (file_put_contents($path, $contents) !== strlen($contents)) { throw new RuntimeException(sprintf('Unable to write content in %s.', $path)); } } } /** * Runs all conversions * * @throws RuntimeException * @return void */ public function run(): void { $this->convertPciFile(); $this->convertUsbFile(); $this->convertOUIFile(); $this->convertIftypeFile(); } /** * Return source file name for given type. * * @param string $type * @return string */ private function getSourceFilename(string $type): string { $basename = null; switch ($type) { case self::TYPE_PCI: $basename = 'pci.ids'; break; case self::TYPE_USB: $basename = 'usb.ids'; break; case self::TYPE_OUI: $basename = 'oui.txt'; break; case self::TYPE_IFTYPE: $basename = 'iftype.csv'; break; default: throw new RuntimeException('Unknown type ' . $type); } return $basename; } /** * Get source file path * * @param string $type File type * * @return string */ private function getSourceFilePath(string $type): string { return $this->path . '/' . $this->getSourceFilename($type); } /** * Get file for type * * @param string $type Type * @throws RuntimeException * @return resource */ private function getSourceFile(string $type) { $path = $this->getSourceFilePath($type); if (!file_exists($path)) { // Fallback to default source file $path = __DIR__ . '/../../source_files/' . $this->getSourceFilename($type); if (!file_exists($path)) { throw new RuntimeException(sprintf('Source file %s not found.', $this->getSourceFilename($type))); } } $file = fopen($path, 'r'); if ($file === false) { throw new RuntimeException(sprintf('Unable to open source file %s.', $path)); } return $file; } /** * Convert PCI file from IDS to JSON * * @throws RuntimeException * @return void */ private function convertPciFile(): void { $pciFile = $this->getSourceFile(self::TYPE_PCI); $pci_ids = []; $vendorId = null; while ($buffer = fgets($pciFile)) { $stack = []; if (preg_match("/^(\w+)\s*(.+)/i", $buffer, $stack)) { $vendorId = $stack[1]; $pci_ids[$vendorId] = $stack[2]; } $stack = []; if (preg_match("/^\t(\w+)\s*(.+)/i", $buffer, $stack)) { $deviceId = $stack[1]; $pci_ids[$vendorId . '::' . $deviceId] = $stack[2]; } } if (!feof($pciFile)) { // Ensure source file reading reach end of file. throw new RuntimeException('Error while reading PCI source file.'); } $this->writeJsonFile(self::TYPE_PCI, $pci_ids); } /** * Convert USB file from IDS to JSON * * @throws RuntimeException * @return void */ private function convertUsbFile(): void { $usbFile = $this->getSourceFile(self::TYPE_USB); $usb_ids = []; $vendorId = null; while ($buffer = fgets($usbFile)) { $stack = []; if (preg_match("/^(\w+)\s*(.+)/i", $buffer, $stack)) { $vendorId = $stack[1]; $usb_ids[$vendorId] = $stack[2]; } $stack = []; if (preg_match("/^\t(\w+)\s*(.+)/i", $buffer, $stack)) { $deviceId = $stack[1]; $usb_ids[$vendorId . '::' . $deviceId] = $stack[2]; } } if (!feof($usbFile)) { // Ensure source file reading reach end of file. throw new RuntimeException('Error while reading USB source file.'); } $this->writeJsonFile(self::TYPE_USB, $usb_ids); } /** * Convert OUI file from TXT to JSON * * @throws RuntimeException * @return void */ private function convertOUIFile(): void { $ouiFile = $this->getSourceFile(self::TYPE_OUI); $ouis = []; while ($buffer = fgets($ouiFile)) { $stack = []; if (preg_match("/^(\S+)\s*\(hex\)\t{2}(.+)/i", $buffer, $stack)) { $mac = strtr($stack[1], '-', ':'); $ouis[$mac] = trim($stack[2]); } } if (!feof($ouiFile)) { // Ensure source file reading reach end of file. throw new RuntimeException('Error while reading OUI source file.'); } $this->writeJsonFile(self::TYPE_OUI, $ouis); } /** * Convert iftype file from CSV to JSON * * @throws RuntimeException * @return void */ private function convertIftypeFile(): void { $iftypeFile = $this->getSourceFile(self::TYPE_IFTYPE); $iftypes = []; while ($line = fgetcsv($iftypeFile)) { $iftypes[] = [ 'decimal' => $line[0], 'name' => $line[1], 'description' => $line[2] ?? '', 'references' => $line[3] ?? '' ]; } if (!feof($iftypeFile)) { // Ensure source file reading reach end of file. throw new RuntimeException('Error while reading IFtype source file.'); } $this->writeJsonFile(self::TYPE_IFTYPE, $iftypes); } /** * Write converted source into corresponding file. * * @param string $type * @param array<string|int, mixed> $data * @throws RuntimeException * @return void */ private function writeJsonFile(string $type, array $data): void { $path = $this->getJsonFilePath($type); $contents = json_encode($data, JSON_PRETTY_PRINT); if ($contents === false) { throw new RuntimeException(sprintf('Error while encoding "%s" data to JSON.', $type)); } if (file_put_contents($path, $contents) !== strlen($contents)) { throw new RuntimeException(sprintf('Unable to write "%s" JSON into "%s".', $type, $path)); } } /** * Executes a curl call * * @param string $url URL to retrieve * @throws RuntimeException * @return string */ private function callCurl(string $url): string { $ch = curl_init($url); if ($ch === false) { throw new RuntimeException( sprintf( 'Unable to initialize curl for %s', $url ) ); } $opts = [ CURLOPT_URL => $url, CURLOPT_USERAGENT => "GLPI/Inventory format 1.0", CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, ]; curl_setopt_array($ch, $opts); $content = curl_exec($ch); $curl_error = curl_error($ch) ?: null; $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $msgerr = null; if ($curl_error !== null) { $msgerr = $curl_error; } elseif ($status_code !== 200) { $msgerr = sprintf( 'HTTP code %s received from %s', $status_code, $url ); } elseif (empty($content)) { $msgerr = sprintf( 'No data available on %s', $url ); } if ($msgerr !== null) { throw new RuntimeException($msgerr); } //force cast to made phpstan happy, but return is always string here return (string)$content; } }