#!/usr/bin/php -q Array)$/","$1..$2$3",$row); $row = preg_replace("/^(\s*\[(name|nameOrig|comment|flashGUID|regGUID|regTo|readList|writeList)\] => \S).*(\S)$/","$1..$3",$row); } } return implode("\n", $rows); case 2: $name = basename($text,'.cfg'); $len = strlen($name); if ($len>2) { $dash = str_repeat('-',$len-2); $name = preg_replace("/^(\S).*(\S)/","$1$dash$2",$name); $i = 1; while (file_exists(dirname($text)."/$name.cfg")) {$name = substr($name,0,$len)." ($i)"; $i++;} } return dirname($text)."/$name.cfg"; } } if ($cli) { // script is called from CLI echo "Starting diagnostics collection... "; exec("mkdir -p /boot/logs"); $var = @parse_ini_file("/var/local/emhttp/var.ini"); $server = isset($var['NAME']) ? str_replace(' ','_',strtolower($var['NAME'])) : 'tower'; $date = date('Ymd-Hi'); $diag = "$server-diagnostics-$date"; $zip = "/boot/logs/$diag.zip"; } else { // script is called from GUI $diag = basename($zip, '.zip'); $split = explode('-', $diag); $date = "{$split[2]}-{$split[3]}"; } // create folder structure exec("mkdir -p /$diag/system /$diag/config /$diag/logs /$diag/shares /$diag/smart /$diag/qemu"); // copy ini variables foreach (glob("/var/local/emhttp/*.ini") as $file) { $ini = basename($file,".ini"); // skip users file in anonymized mode if ($all || $ini != "users") file_put_contents("/$diag/system/vars.txt",preg_replace(["/\n/","/^Array/"],["\r\n",$ini],anonymize(print_r(parse_ini_file($file,true),true),1)),FILE_APPEND); } // individual commands execution (suppress errors) exec("lsscsi -vgl 2>/dev/null|todos >/$diag/system/lsscsi.txt"); exec("lspci -knn 2>/dev/null|todos >/$diag/system/lspci.txt"); exec("free -mt 2>/dev/null|todos >/$diag/system/memory.txt"); exec("ps -ef 2>/dev/null|todos >/$diag/system/ps.txt"); exec("lsof -Pni 2>/dev/null|todos >/$diag/system/lsof.txt"); exec("lsmod 2>/dev/null|todos >/$diag/system/lsmod.txt"); exec("ifconfig -s 2>/dev/null|grep -Po '^(eth|bond)[0-9]+'", $ports); // create ethernet information information (suppress errors) foreach ($ports as $port) { exec("ethtool $port 2>/dev/null|todos >>/$diag/system/ethtool.txt"); file_put_contents("/$diag/system/ethtool.txt", "\r\n", FILE_APPEND); exec("ethtool -i $port 2>/dev/null|todos >>/$diag/system/ethtool.txt"); file_put_contents("/$diag/system/ethtool.txt", "--------------------------------\r\n", FILE_APPEND); } exec("ifconfig 2>/dev/null|todos >/$diag/system/ifconfig.txt"); // create system information (suppress errors) exec("find /sys/kernel/iommu_groups/ -type l 2>/dev/null|todos >/$diag/system/iommu_groups.txt"); exec("todos /$diag/system/cmdline.txt"); // copy configuration files (suppress errors) exec("cp /boot/config/*.{cfg,conf,dat} /boot/config/go /$diag/config 2>/dev/null"); // anonymize configuration files if (!$all) exec("sed -ri 's/^((disk|flash)(Read|Write)List.*=\")[^\"]+/\\1.../' /$diag/config/*.cfg 2>/dev/null"); // copy share information (anonymize if applicable) $files = glob("/boot/config/shares/*.cfg"); foreach ($files as $file) { $dest = anonymize("/$diag/shares/".basename($file),2); @copy($file, $dest); if (!$all) exec("sed -ri 's/^(share(Comment|ReadList|WriteList)=\")[^\"]+/\\1.../' '$dest' 2>/dev/null"); } // create default user shares information $ini = "/var/local/emhttp/shares.ini"; $shares = file_exists($ini) ? parse_ini_file($ini, true) : []; foreach ($shares as $share) { $name = $share['name']; if (!in_array("/boot/config/shares/$name.cfg",$files)) file_put_contents(anonymize("/$diag/shares/$name.cfg",2),"# This share has default settings.\r\n"); } // copy syslog information (anonymize if applicable) foreach (glob("/var/log/syslog*") as $file) { $dest = "/$diag/logs/".basename($file).".txt"; exec("todos <$file >$dest"); if (!$all) { unset($titles,$rows); exec("grep -Po 'logger: moving \"\K[^\"]+' $dest 2>/dev/null|sort|uniq", $titles); exec("sed -ri 's|\b\S+@\S+\.\S+\b|xxx@removed.com|;s|\b(username\|password)([=:])\S+\b|\\1\\2xxx|;s|(GUID: \S)\S+(\S) |\\1..\\2 |;s|(moving \"\S\|\"/mnt/user/\S).*(\S)\"|\\1..\\2\"|' $dest"); foreach ($titles as $mover) { $title = "/{$mover[0]}..".substr($mover,-1)."/..."; exec("sed -ri 's|(logger: [.>cr].*)[ /]$mover/.*$|\\1 file: $title|' $dest 2>/dev/null"); } exec("grep -n ' cache_dirs: -' $dest 2>/dev/null|cut -d: -f1", $rows); for ($i = 0; $i < count($rows); $i += 2) for ($row = $rows[$i]+1; $row < $rows[$i+1]; $row++) exec("sed -ri '$row s|(cache_dirs: \S).*(\S)|\\1..\\2|' $dest 2>/dev/null"); } } // copy docker information (if existing) $docker = "/var/log/docker.log"; if (file_exists($docker)) exec("todos <$docker >/$diag/logs/docker.log"); $libvirtd = "/var/log/libvirt/libvirtd.log"; if (file_exists($libvirtd)) exec("todos <$libvirtd >/$diag/logs/libvirtd.log"); $qemu = glob("/var/log/libvirt/qemu/*.log*"); if ($qemu) foreach ($qemu as $file) exec("todos <".escapeshellarg($file)." >/$diag/qemu/".escapeshellarg(basename($file))); else file_put_contents("/$diag/qemu/no qemu log files",""); // create SMART reports (suppress errors) exec("ls -l /dev/disk/by-id/[au]* 2>/dev/null|awk '$0!~/-part/{split($11,a,\"/\");print a[3],substr($9,21)}'", $devices); foreach ($devices as $device) { $disk = explode(' ',$device); exec("smartctl -a /dev/${disk[0]} 2>/dev/null|todos >/$diag/smart/${disk[1]}-$date.txt"); } // create resulting zip file and remove temp folder exec("zip -qmr $zip /$diag"); if ($cli) echo "done.\nZIP file '$zip' created.\n"; ?>