Files
Yuba/Yuba.php

850 lines
25 KiB
PHP
Raw Normal View History

2017-05-03 00:39:48 -07:00
#!/usr/bin/php
<?php
2017-05-25 15:38:19 -07:00
date_default_timezone_set("America/Los_Angeles");
2017-06-16 00:14:32 -07:00
$time_start = microtime(true);
2017-05-25 15:38:19 -07:00
2017-05-03 00:39:48 -07:00
// Yuba
2017-05-25 15:38:19 -07:00
// //
2017-05-20 20:03:50 -07:00
//////////////////////////////////////////
2017-06-18 03:17:42 -07:00
$version = "0.4.7.2";
2017-05-25 15:38:19 -07:00
2017-06-16 00:14:32 -07:00
// Treat these directories as files
$wopt_bundles = array( "app",
"bundle",
"sparsebundle",
"photoslibrary",
"aplibrary",
"apvault",
"abbu",
"calendar",
"framework",
"plugin",
"kext",
"rtfd"
);
foreach ($wopt_bundles as $bundle) {
$wopt_nodescend[] = "*.".$bundle;
}
2017-05-25 15:38:19 -07:00
// Ignore matching files and directories
2017-06-16 00:14:32 -07:00
$wopt_ignore = array( ".DS_Store",
".DocumentRevisions-V100",
".Spotlight-V100",
".TemporaryItems",
".apdisk",
".com.apple.timemachine.donotpresent",
".fseventsd",
".metadata-never-index",
".neofinder.abemeda.volinfo.xml"
);
2017-05-25 15:38:19 -07:00
if (in_array("-hash", $argv)) { $wopt_hash = 1; } else { $wopt_hash = 0; }
$wopt_thumb_size = "256";
$wopt_thumb_factor = $wopt_thumb_size/128;
// Location of binaries used to collect metadata
$bin_gfi = "/Applications/Xcode.app/Contents/Developer/usr/bin/GetFileInfo";
$bin_mediainfo = "/opt/local/bin/mediainfo";
$bin_exiftool = "/opt/local/bin/exiftool";
// Functions
function stringPrint($string) {
2017-06-16 00:14:32 -07:00
echo $string.@str_repeat(" ", (10-strlen($string)));
2017-05-25 15:38:19 -07:00
}
function getWoptString() {
global $wopt_nodescend, $wopt_ignore, $wopt_hash, $wopt_mediainfo, $wopt_exiftool, $wopt_thumb_size, $wopt_thumb_factor, $wopt_tmpdir, $wopt_paranoid;
return array( array("nodescend", $wopt_nodescend),
array("ignore", $wopt_ignore),
array("hash", $wopt_hash),
array("mediainfo", $wopt_mediainfo),
array("exiftool", $wopt_exiftool),
array("thumb_size", $wopt_thumb_size),
array("thumb_factor", $wopt_thumb_factor),
array("wopt_paranoid", $wopt_paranoid)
);
}
class plistParser extends XMLReader {
public function parseString($string) { $this->XML($string); return $this->process(); }
private function process() {
$this->read();
if($this->nodeType !== XMLReader::DOC_TYPE || $this->name !== "plist") { throw new Exception(sprintf("Error parsing plist. nodeType: %d -- Name: %s", $this->nodeType, $this->name), 2); }
if(!$this->next("plist") || $this->nodeType !== XMLReader::ELEMENT || $this->name !== "plist") { throw new Exception(sprintf("Error parsing plist. nodeType: %d -- Name: %s", $this->nodeType, $this->name), 3); }
$plist = array(); while($this->read()) { if($this->nodeType == XMLReader::ELEMENT) { $plist[] = $this->parse_node(); } }
if(count($plist) == 1 && $plist[0]) { return $plist[0]; } else { return $plist; }
}
private function parse_node() {
if($this->nodeType !== XMLReader::ELEMENT) return;
switch($this->name) {
case 'data': return base64_decode($this->getNodeText()); break;
case 'real': return floatval($this->getNodeText()); break;
case 'string': return $this->getNodeText(); break;
case 'integer': return intval($this->getNodeText()); break;
case 'date': return $this->getNodeText(); break;
case 'true': return true; break;
case 'false': return false; break;
case 'array': return $this->parse_array(); break;
case 'dict': return $this->parse_dict(); break;
default: throw new Exception(sprintf("Not a valid plist. %s is not a valid type", $this->name), 4);
}
}
private function parse_dict() {
$array = array(); $this->nextOfType(XMLReader::ELEMENT);
do { if($this->nodeType !== XMLReader::ELEMENT || $this->name !== "key") { if(!$this->next("key")) { return $array; } } $key = $this->getNodeText(); $this->nextOfType(XMLReader::ELEMENT); $array[$key] = $this->parse_node(); $this->nextOfType(XMLReader::ELEMENT, XMLReader::END_ELEMENT); }
while($this->nodeType && !$this->isNodeOfTypeName(XMLReader::END_ELEMENT, "dict")); return $array;
}
private function parse_array() {
$array = array(); $this->nextOfType(XMLReader::ELEMENT);
do { $array[] = $this->parse_node(); $this->nextOfType(XMLReader::ELEMENT, XMLReader::END_ELEMENT); }
while($this->nodeType && !$this->isNodeOfTypeName(XMLReader::END_ELEMENT, "array")); return $array;
}
private function getNodeText() { $string = $this->readString(); $this->nextOfType(XMLReader::END_ELEMENT); return $string; }
private function nextOfType() { $types = func_get_args(); $this->read(); while($this->nodeType && !(in_array($this->nodeType, $types))) { $this->read(); } }
private function isNodeOfTypeName($type, $name) { return $this->nodeType === $type && $this->name === $name; }
}
function parseMediaInfo ($xml) {
$xml = simplexml_load_string($xml);
$data = array();
$data['version'] = (string) $xml['version'];
foreach ($xml->File->track as $track) {
$trackType = strtolower($track['type']);
$trackId = isset($track['streamid']) ? $track['streamid'] : 1;
$trackId = (string)$trackId;
$trackData = [];
foreach ($track as $rawKey => $rawVal) {
$key = strtolower($rawKey);
$val = (string)$rawVal;
if ($key == 'stream_identifier') { continue; }
if (!array_key_exists($key, $trackData)) {
$trackData[$key] = array($val);
} elseif (!in_array($val, $trackData[$key])) {
$trackData[$key][] = $val;
}
}
if ($trackType == 'general') {
$data['file']['general'] = $trackData;
} else {
$data['file'][$trackType][$trackId] = $trackData;
}
}
return $data;
}
function bashcolor($str,$fgcolor="white",$bgcolor=null) {
static $fgcolors = array('black' => '0;30', 'dark gray' => '1;30', 'blue' => '0;34', 'light blue' => '1;34', 'green' => '0;32', 'light green' => '1;32', 'cyan' => '0;36', 'light cyan' => '1;36', 'red' => '0;31', 'light red' => '1;31', 'purple' => '0;35', 'light purple' => '1;35', 'brown' => '0;33', 'yellow' => '1;33', 'light gray' => '0;37', 'white' => '1;37', 'underline' => '4');
static $bgcolors = array('black' => '40', 'red' => '41', 'green' => '42', 'yellow' => '43', 'blue' => '44', 'magenta' => '45', 'cyan' => '46', 'light gray' => '47');
$out="";
if (!isset($fgcolors[$fgcolor])) { $fgcolor='white'; }
if (!isset($bgcolors[$bgcolor])) { $bgcolor=null; }
if ($fgcolor) { $out .= "\033[{$fgcolors[$fgcolor]}m"; }
if ($bgcolor) { $out .= "\033[{$bgcolors[$bgcolor]}m"; }
$out .= $str."\033[0m";
return $out;
}
2017-05-22 23:37:36 -07:00
// Path arguments
$zpath = realpath($argv[1]);
if (!is_dir($zpath)) { echo "Usage: walk <path> <dbfile>"; die; }
if (isset($argv[2]) && is_dir($argv[2])) {
$dbprefix = realpath($argv[2]);
} else {
$dbprefix = ".";
}
2017-05-03 00:39:48 -07:00
2017-06-18 03:17:42 -07:00
if (is_writable($zpath)) { $wopt_paranoid = 1; } else { $wopt_paranoid = 0; }
2017-05-20 20:03:50 -07:00
// File checks
$stamp = date("Y-m-d_H-i-s", time());
2017-05-25 15:38:19 -07:00
$wopt_tmpdir = "/tmp/WalkWalk_".$stamp."/";
if (!is_dir($wopt_tmpdir)) { mkdir($wopt_tmpdir); }
2017-05-20 20:03:50 -07:00
$base = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath));
2017-06-16 00:14:32 -07:00
if (!$base) { $base = "root"; }
2017-05-20 20:03:50 -07:00
$dbfile = $dbprefix."/".$stamp."_".$base.".sqlite3";
if (file_exists($dbfile)) { echo "File \"".$dbfile."\" already exists!"; die; }
// Banner
2017-05-03 00:39:48 -07:00
echo "Yuba ".$version."\n";
echo "-----------------------------------------------\n";
2017-05-20 20:03:50 -07:00
$banner = $zpath." -> ".$dbfile;
2017-05-03 00:39:48 -07:00
echo $banner."\n";
echo str_repeat("-", strlen($banner))."\n";
2017-05-20 20:03:50 -07:00
2017-05-22 23:37:36 -07:00
// Disk info
2017-05-20 20:03:50 -07:00
$host = gethostname();
2017-05-22 23:37:36 -07:00
$disks = shell_exec("diskutil list 2>&1");
if (substr($zpath, 0, 9) != "/Volumes/") {
$zbase = "/";
} else {
$zparts = explode("/", $zpath);
$zbase = "/Volumes/".$zparts[2];
}
$diskutil = shell_exec("diskutil info ".$zbase." 2>&1");
$getstats = array( "Volume Name",
"Protocol",
"Volume UUID",
"Device Location",
"Volume Total Space",
"Volume Available Space",
"Level Type"
);
foreach ($getstats as $stat) {
preg_match("/(".$stat.":)(.*)(\n)/",$diskutil,$matches);
if (isset($matches[2])) {
if (substr($stat, -5, 5) == "Space") {
$pieces = explode(" ", trim($matches[2]));
$summary = $pieces[0]." ".$pieces[1];
$stats[$stat] = $summary;
} else {
$stats[$stat] = trim($matches[2]);
}
}
}
$dstats = serialize($stats);
if ($zpath == "/") {
$type = "Startup disk";
} elseif (strtolower($zpath) == strtolower("/Volumes/".$stats["Volume Name"])) {
if ($stats["Protocol"] == "Disk Image") {
$type = "Disk image";
} else {
$type = "External disk";
}
} else {
$type = "Folder";
}
$profile = shell_exec("system_profiler SPHardwareDataType SPStorageDataType SPThunderboltDataType SPUSBDataType 2>&1");
2017-06-16 00:14:32 -07:00
$qlmanage = shell_exec("qlmanage -m 2>&1");
$sysvers = shell_exec("sw_vers 2>&1");
2017-05-22 23:37:36 -07:00
// Database
2017-05-20 20:03:50 -07:00
2017-06-16 00:14:32 -07:00
// use mysql?
//$dbo = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $pass);
2017-05-20 20:03:50 -07:00
$dbo = new PDO("sqlite:".$dbfile);
$dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2017-06-18 03:17:42 -07:00
$dbo->query("PRAGMA page_size = 4096");
$dbo->query("PRAGMA cache_size = 10000");
$dbo->query("PRAGMA locking_mode = EXCLUSIVE");
$dbo->query("PRAGMA synchronous = NORMAL");
$dbo->query("PRAGMA journal_mode = WAL");
2017-06-16 00:14:32 -07:00
2017-05-25 15:38:19 -07:00
$dbo->exec("CREATE TABLE files (
2017-05-20 20:03:50 -07:00
id INTEGER PRIMARY KEY,
parent INTEGER,
2017-05-25 15:38:19 -07:00
Pathname TEXT,
Path TEXT,
Filename TEXT,
Extension TEXT,
Type TEXT,
2017-06-16 00:14:32 -07:00
items INTEGER,
2017-06-18 03:17:42 -07:00
newest INTEGER,
2017-05-25 15:38:19 -07:00
stat TEXT,
LinkTarget TEXT,
RealPath TEXT,
Inode INTEGER,
Size INTEGER,
Perms INTEGER,
Owner TEXT,
ATime INTEGER,
MTime INTEGER,
CTime INTEGER,
gfi_type TEXT,
gfi_attr TEXT,
gfi_created TEXT,
2017-05-20 20:03:50 -07:00
hash TEXT,
2017-05-25 15:38:19 -07:00
tinfo TEXT
)");
$dbo->exec("CREATE TABLE mdls (
id INTEGER PRIMARY KEY,
hasmeta INTEGER,
DateAdded TEXT,
ContentType TEXT,
Creator TEXT,
Kind TEXT,
UserTags TEXT,
FSInvisible INTEGER,
PixelWidth INTEGER,
PixelHeight INTEGER,
spotlight TEXT
)");
$dbo->exec("CREATE TABLE metadata (
id INTEGER PRIMARY KEY,
duration TEXT,
2017-05-20 20:03:50 -07:00
mediainfo TEXT,
2017-05-25 15:38:19 -07:00
exiftool TEXT
)");
2017-05-22 23:37:36 -07:00
2017-05-25 15:38:19 -07:00
$dbo->exec("CREATE TABLE thumbs (
2017-05-22 23:37:36 -07:00
id INTEGER PRIMARY KEY,
2017-05-25 15:38:19 -07:00
thumb BLOB
)");
2017-05-20 20:03:50 -07:00
2017-06-16 00:14:32 -07:00
$dbo->exec("CREATE TABLE _walkwalk (
2017-05-20 20:03:50 -07:00
version TEXT,
2017-05-25 15:38:19 -07:00
opts TEXT,
2017-05-20 20:03:50 -07:00
host TEXT,
2017-05-22 23:37:36 -07:00
zpath TEXT,
type TEXT,
2017-05-25 15:38:19 -07:00
nodescended INTEGER,
ignored INTEGER,
2017-05-22 23:37:36 -07:00
stats TEXT,
2017-06-16 00:14:32 -07:00
qlmanage TEXT,
sysvers TEXT,
2017-05-22 23:37:36 -07:00
diskutil TEXT,
disks TEXT,
2017-05-25 15:38:19 -07:00
profile TEXT,
status TEXT
)");
2017-05-20 20:03:50 -07:00
2017-06-16 00:14:32 -07:00
$stmt = $dbo->prepare("INSERT INTO _walkwalk VALUES (:version, :opts, :host, :zpath, :type, :nodescended, :ignored, :stats, :qlmanage, :sysvers, :diskutil, :disks, :profile, :status)");
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":version",$version." (".posix_getuid().")");
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":opts",serialize(getWoptString()));
2017-05-20 20:03:50 -07:00
$stmt->BindValue(":host",$host);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":zpath",$zpath);
$stmt->BindValue(":type",$type);
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":nodescended",null);
$stmt->BindValue(":ignored",null);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":stats",$dstats);
2017-06-16 00:14:32 -07:00
$stmt->BindValue(":qlmanage",$qlmanage);
$stmt->BindValue(":sysvers",$sysvers);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":diskutil",$diskutil);
2017-05-20 20:03:50 -07:00
$stmt->BindValue(":disks",$disks);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":profile",$profile);
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":status","aborted");
2017-05-20 20:03:50 -07:00
$stmt->execute();
// Iterate
2017-05-03 00:39:48 -07:00
2017-05-25 15:38:19 -07:00
$nodescended = 0;
$ignored = 0;
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
2017-06-16 00:14:32 -07:00
// start in parent dir to include self
dirname($zpath),
2017-05-25 15:38:19 -07:00
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($wopt_ignore, $wopt_nodescend) {
2017-06-16 00:14:32 -07:00
global $nodescended, $ignored, $zpath;
2017-05-25 15:38:19 -07:00
$clean = true;
2017-06-16 00:14:32 -07:00
// ensure we don't traverse zpath siblings
if ($zpath != "/" && (substr($current->getRealpath(), 0, strlen($zpath)+1) != $zpath."/") && ($current->getRealpath() != $zpath)) {
$clean = false;
}
// filenames to ignore
2017-05-25 15:38:19 -07:00
if (is_array($wopt_ignore)) {
foreach ($wopt_ignore as $wildcard) {
if (fnmatch($wildcard, $current->getFilename())) {
$clean = false;
$ignored++;
echo "\nSkipping: ".$current->getRealpath()."\n\n";
}
}
}
2017-06-16 00:14:32 -07:00
// directories to ignore
2017-05-25 15:38:19 -07:00
if (is_array($wopt_nodescend)) {
foreach ($wopt_nodescend as $wildcard) {
if (fnmatch($wildcard, $current->getPath())) {
$clean = false;
$nodescended++;
echo "\nNodescending: ".$current->getRealpath()."\n\n";
}
}
}
return $clean;
}
),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
// Debug input array
/*
foreach ($files as $splFileInfo) {
echo "====================================================================================\n";
print_r($splFileInfo);
echo "====================================================================================\n";
echo "getRealPath = ".$splFileInfo->getRealPath()."\n";
echo "getPathname = ".$splFileInfo->getPathname()."\n";
echo "isLink = ".$splFileInfo->isLink()."\n";
if ($splFileInfo->isLink()) {
echo "getLinkTarget = ".$splFileInfo->getLinkTarget()."\n";
} else {
echo "getLinkTarget = N/A\n";
}
echo "getType = ".$splFileInfo->getType()." (".filetype($splFileInfo->getPathname()).")\n";
echo "isDir = ".$splFileInfo->isDir()."\n";
echo "isFile = ".$splFileInfo->isFile()."\n";
echo "-----------------------------------------------------------------------\n";
echo "getPath = ".$splFileInfo->getPath()."\n";
echo "getFilename = ".$splFileInfo->getFilename()."\n";
echo "getBasename = ".$splFileInfo->getBasename()." (".basename($splFileInfo->getPathname()).")\n";
echo "getExtension = ".$splFileInfo->getExtension()."\n";
echo "-----------------------------------------------------------------------\n";
if (!$splFileInfo->isLink()) {
echo "getATime = ".$splFileInfo->getAtime()." (".fileatime($splFileInfo->getPathname()).")\n";
echo "getMTime = ".$splFileInfo->getMtime()." (".filemtime($splFileInfo->getPathname()).")\n";
echo "getCTime = ".$splFileInfo->getCtime()." (".filectime($splFileInfo->getPathname()).")\n";
echo "getInode = ".$splFileInfo->getInode()." (".fileinode($splFileInfo->getPathname()).")\n";
echo "getPerms = ".$splFileInfo->getPerms()." (".fileperms($splFileInfo->getPathname()).")\n";
echo "getGroup = ".$splFileInfo->getGroup()." (".filegroup($splFileInfo->getPathname()).")\n";
echo "getOwner = ".$splFileInfo->getOwner()." (".fileowner($splFileInfo->getPathname()).")\n";
echo "getSize = ".$splFileInfo->getSize()." (".filesize($splFileInfo->getPathname()).")\n";
}
}
die;
*/
2017-05-22 23:37:36 -07:00
// Check perms
if (posix_getuid()) {
2017-06-16 00:14:32 -07:00
echo bashcolor("You are not root. Checking file readability: ", "red");
2017-05-22 23:37:36 -07:00
2017-06-18 03:17:42 -07:00
echo "\n";
2017-05-22 23:37:36 -07:00
$oops = 0;
2017-05-25 15:38:19 -07:00
foreach ($files as $splFileInfo) {
2017-05-22 23:37:36 -07:00
$path = $splFileInfo->getRealPath();
if (!is_readable($path)) {
$oops = 1;
echo "x";
} else {
echo ".";
}
}
echo "\n\n";
if ($oops) {
echo "Some files could not be read. Continue? (Y/n)";
$line = trim(fgets(fopen("php://stdin","r")));
$line = $line ?: "y";
if($line != "y"){
echo "Exiting!\n"; die;
}
}
2017-06-16 00:14:32 -07:00
} else {
echo bashcolor("Running as root. Some QuickLook plugins may not be available.", "red");
2017-06-18 03:17:42 -07:00
echo "\n";
2017-05-22 23:37:36 -07:00
}
2017-06-18 03:17:42 -07:00
$fixatimes = 0;
if ($wopt_paranoid) {
echo bashcolor("\nFilesystem is writable. You can choose:\n(c) Preserve ctimes (default)\n(a) Preserve atimes\n", "purple");
$line = trim(fgets(fopen("php://stdin","r"))) ?: "c";
if ($line == "a") { $fixatimes = 1; }
}
2017-05-25 15:38:19 -07:00
// Filetypes for special handling
2017-05-22 23:37:36 -07:00
$m_files = array( "mkv",
"ogg",
"avi",
"wav",
"mpeg",
"mpg",
"vob",
"mp4",
"m2v",
"mp3",
"asf",
"wma",
"wmv",
"qt",
"mov",
"rm",
"ifo",
"ac3",
"dts",
"aac",
"ape",
"flac",
"aiff",
"m2ts" );
$e_files = array( "ai",
"aiff",
"ape",
"asf",
"avi",
"bmp",
"divx",
"dng",
"doc",
"docx",
"eps",
"epub",
"exe",
"exif",
"fla",
"flac",
"flv",
"gif",
"icc",
"iso",
"jpg",
"jpeg",
"m2ts",
"m4a",
"m4b",
"m4v",
"mkv",
"mobi",
"azw",
"azw3",
"mov",
"qt",
"mp3",
"mp4",
"mpeg",
"mpg",
"m2v",
"nef",
"numbers",
"ogg",
"pages",
"pdf",
"pict",
"png",
"ppm",
"ppt",
"psd",
"psb",
"qif",
"raw",
"rtf",
"sr2",
"srf",
"svg",
"swf",
"tiff",
"tif",
"torrent",
"vcf",
"vob",
"wav",
"webm",
"wma",
"wmv",
"xls",
"xlsx",
"xmp",
"zip" );
2017-06-16 00:14:32 -07:00
foreach ($e_files as $ext) { $e_files[] = strtoupper($ext); }
foreach ($m_files as $ext) { $m_files[] = strtoupper($ext); }
2017-05-25 15:38:19 -07:00
// Inserts
foreach ($files as $splFileInfo) {
$type = $splFileInfo->getType();
2017-06-16 00:14:32 -07:00
if ($type == "dir") {
foreach ($wopt_bundles as $bundle) {
$check = ".".$bundle;
if (substr($splFileInfo->getFilename(), -(strlen($check)), strlen($check)) == $check) { $type = "bundle"; }
}
}
2017-05-25 15:38:19 -07:00
if ($type != "link") { $atime = $splFileInfo->getATime(); }
$pathname = $splFileInfo->getPathname();
$path = $splFileInfo->getPath();
$filename = $splFileInfo->getFilename();
$extension = $splFileInfo->getExtension();
$shellpath = escapeshellarg($pathname);
2017-06-18 03:17:42 -07:00
echo bashcolor("\n".$pathname."\n","blue");
2017-06-16 00:14:32 -07:00
2017-05-25 15:38:19 -07:00
if (!$type) { echo "\nBREAK: can't determine type of ".$pathname; die; }
if ($type != "link") {
2017-06-18 03:17:42 -07:00
$stat = chop(@shell_exec("stat -x ".$shellpath." 2>&1"));
2017-05-20 20:03:50 -07:00
} else {
2017-05-25 15:38:19 -07:00
$stat = null;
2017-05-20 20:03:50 -07:00
}
2017-06-16 00:14:32 -07:00
2017-06-18 03:17:42 -07:00
if ($type != "link" && $wopt_paranoid) {
$pre_access = null;
$pre_modify = null;
$pre_change = null;
foreach (explode("\n", $stat) as $line) {
$check = substr($line, 0, 6);
if ($check == "Access") { $pre_access = $line; }
if ($check == "Modify") { $pre_modify = $line; }
if ($check == "Change") { $pre_change = $line; }
}
2017-05-25 15:38:19 -07:00
}
// Determine ID of parent dir by querying database
$parent = $dbo->query("SELECT id FROM files WHERE (Pathname='".str_replace("'", "''", $path)."')")->fetch()['id'];
stringPrint("parent");
// Gather file attributes
2017-06-18 03:17:42 -07:00
$stmt = $dbo->prepare("INSERT INTO files VALUES (:id, :parent, :Pathname, :Path, :Filename, :Extension, :Type, :items, :newest, :stat, :LinkTarget, :RealPath, :Inode, :Size, :Perms, :Owner, :ATime, :MTime, :CTime, :gfi_type, :gfi_attr, :gfi_created, :hash, :tinfo)");
2017-05-25 15:38:19 -07:00
if ($type == "dir") {
2017-06-18 03:17:42 -07:00
$size = trim(shell_exec("du -ks ".$shellpath." | cut -f1"))*1024;
2017-06-16 00:14:32 -07:00
} elseif ($type == "file" || $type == "bundle") {
2017-05-25 15:38:19 -07:00
$size = $splFileInfo->getSize();
2017-05-03 00:39:48 -07:00
} else {
2017-05-25 15:38:19 -07:00
$size = null;
2017-05-03 00:39:48 -07:00
}
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":Size",@$size);
stringPrint(floor($size/1024)."k");
if ($parent) {
$stmt->BindValue(":parent",$parent);
} else {
$stmt->BindValue(":parent",0);
}
2017-06-18 03:17:42 -07:00
stringPrint("items");
if ($type == "dir" || $type == "bundle" ) {
$items = chop(@shell_exec("find ".$shellpath." \( ! -regex '.*/\..*' \) | wc -l 2>&1"))-1;
} else {
$items = null;
}
2017-06-16 00:14:32 -07:00
$stmt->BindValue(":items",@$items);
2017-06-18 03:17:42 -07:00
stringPrint("newest");
if ($type == "dir") {
$newest = filemtime(chop(shell_exec("find ".$shellpath." -type f -not -path '*/\.*' -print0 | xargs -0 stat -f \"%m %N\" | sort -rn | head -1 | cut -f2- -d\" \"")));
} else {
$newest = null;
}
$stmt->BindValue(":newest",@$newest);
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":stat",@$stat);
$stmt->BindValue(":Pathname",$pathname);
$stmt->BindValue(":Path",$path);
$stmt->BindValue(":Filename",$filename);
$stmt->BindValue(":Extension",$extension);
$stmt->BindValue(":Type",$type);
if ($type == "link") {
$stmt->BindValue(":LinkTarget",$splFileInfo->getLinkTarget());
$stmt->BindValue(":RealPath",$splFileInfo->getRealPath());
} else {
$stmt->BindValue(":Inode",$splFileInfo->getInode());
$stmt->BindValue(":Perms",$splFileInfo->getPerms());
$stmt->BindValue(":Owner",$splFileInfo->getOwner().":".$splFileInfo->getGroup());
$stmt->BindValue(":ATime",$atime);
$stmt->BindValue(":CTime",$splFileInfo->getCTime());
$stmt->BindValue(":MTime",$splFileInfo->getMTime());
}
2017-06-18 03:17:42 -07:00
2017-05-25 15:38:19 -07:00
stringPrint("attr");
$gfiparts = explode("\n", chop(shell_exec($bin_gfi." -P ".$shellpath." 2>&1")));
if (is_array($gfiparts)) {
foreach ($gfiparts as $line) {
list($label, $value) = explode(": ", $line);
$gfi[$label] = isset($value) ? trim($value,"\"") : null;
2017-05-20 20:03:50 -07:00
}
2017-05-03 00:39:48 -07:00
}
2017-05-25 15:38:19 -07:00
$writegfitype = @$gfi['type'].":".@$gfi['creator'];
if ($writegfitype == "\\0\\0\\0\\0:\\0\\0\\0\\0" || $writegfitype == ":") { $writegfitype = null; }
$stmt->BindValue("gfi_type",$writegfitype);
$stmt->BindValue("gfi_attr",@$gfi['attributes']);
$stmt->BindValue("gfi_created",strtotime($gfi['created']));
stringPrint("gfi");
if ($wopt_hash && $type != "link") {
$stmt->BindValue(":hash",md5_file($pathname));
StringPrint("hash");
} else {
$stmt->BindValue(":hash",null);
StringPrint("(x)hash");
}
$thumb = $wopt_tmpdir.$filename.".png";
2017-06-16 00:14:32 -07:00
/*
// insane workaround for insane apple bug
if (@pathinfo($pathname)['extension'] == "mp3" | "MP3" | "m4a" | "M4A" | "m4b" | "M4B" ) {
$zprefix = "sudo qlmanage";
} else {
$zprefix = "qlmanage";
}
*/
2017-06-18 03:17:42 -07:00
$zprefix = "sudo qlmanage"; // prevent hang
2017-06-16 00:14:32 -07:00
@exec($zprefix." -t -f ".$wopt_thumb_factor." -o ".$wopt_tmpdir." ".$shellpath." 2>&1");
2017-05-25 15:38:19 -07:00
stringPrint("thumb");
if ($size && !file_exists($thumb) && (in_array($extension, $m_files) || in_array($extension, $e_files))) {
@exec("ffmpegthumbnailer -i ".$shellpath." -o \"".$thumb."\" -s ".$wopt_thumb_size." -c png 2>&1");
stringPrint("fthumb");
} else {
stringPrint("(x)fthumb");
2017-05-22 23:37:36 -07:00
}
if (file_exists($thumb) && filesize($thumb)) {
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":tinfo",serialize(getimagesize($thumb)));
2017-05-03 00:39:48 -07:00
}
2017-06-18 03:17:42 -07:00
2017-05-25 15:38:19 -07:00
$stmt->execute();
stringPrint("->files");
// Gather spotlight metadata
$stmt = $dbo->prepare("INSERT INTO mdls VALUES (:id, :hasmeta, :DateAdded, :ContentType, :Creator, :Kind, :UserTags, :FSInvisible, :PixelWidth, :PixelHeight, :spotlight)");
$mdls = shell_exec("mdls -plist - ".$shellpath." 2>&1");
stringPrint("mdls");
if ($mdls != $pathname.": could not find ".$pathname.".\n") {
$stmt->BindValue(":hasmeta",1);
$parser = new plistParser();
$spotlight = $parser->parseString($mdls);
2017-06-16 00:14:32 -07:00
$stmt->BindValue(":DateAdded",@strtotime($spotlight['kMDItemDateAdded']));
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":ContentType",@$spotlight['kMDItemContentType']);
$stmt->BindValue(":Creator",@$spotlight['kMDItemCreator']);
$stmt->BindValue(":Kind",@$spotlight['kMDItemKind']);
if (isset($spotlight['kMDItemUserTags'])) {
$stmt->BindValue(":UserTags",serialize($spotlight['kMDItemUserTags']));
}
$stmt->BindValue(":FSInvisible",@$spotlight['kMDItemFSInvisible']);
$stmt->BindValue(":PixelWidth",@$spotlight['kMDItemPixelWidth']);
$stmt->BindValue(":PixelHeight",@$spotlight['kMDItemPixelHeight']);
$stmt->BindValue(":spotlight",serialize($spotlight));
} else {
$stmt->BindValue(":hasmeta",0);
}
$stmt->execute();
stringPrint("->mdls");
// Gather external metadata
$stmt = $dbo->prepare("INSERT INTO metadata VALUES (:id, :duration, :mediainfo, :exiftool)");
if ($type != "dir" && in_array($extension, $m_files)) {
2017-06-18 03:17:42 -07:00
$minfo = parseMediaInfo(shell_exec($bin_mediainfo." --Output=OLDXML ".$shellpath." 2>&1"));
2017-05-25 15:38:19 -07:00
if ($minfo['file']['general']['duration'][0]) {
$stmt->BindValue(":duration",$minfo['file']['general']['duration'][0]);
} else {
$stmt->BindValue(":duration",null);
}
$stmt->BindValue(":mediainfo",serialize($minfo));
stringPrint("minfo");
} else {
$stmt->BindValue(":duration",null);
$stmt->BindValue(":mediainfo",null);
stringPrint("(x)info");
}
if ($type != "dir" && $type != "link" && in_array($extension, $e_files)) {
$stmt->BindValue(":exiftool",serialize(eval("return ".`$bin_exiftool -php $shellpath`)));
stringPrint("etool");
} else {
$stmt->BindValue(":exiftool",null);
stringPrint("(x)etool");
2017-05-22 23:37:36 -07:00
}
$stmt->execute();
2017-05-25 15:38:19 -07:00
stringPrint("->meta");
// Gather thumbnail
2017-06-18 03:17:42 -07:00
2017-05-25 15:38:19 -07:00
$stmt = $dbo->prepare("INSERT INTO thumbs VALUES (:id, :thumb)");
if (file_exists($thumb) && filesize($thumb)) {
$stmt->BindValue(":thumb",file_get_contents($thumb));
} else {
$stmt->BindValue(":thumb",null);
}
2017-05-20 20:03:50 -07:00
$stmt->execute();
2017-05-25 15:38:19 -07:00
stringPrint("->thumb");
// Set fileatime back to original value
2017-06-18 03:17:42 -07:00
if ($type != "link" && is_writable($pathname) && $fixatimes) {
@exec("touch -at `date -r ".$atime." +%Y%m%d%H%M.%S` ".$shellpath." 2>&1");
stringPrint("touch");
}
2017-05-25 15:38:19 -07:00
2017-05-22 23:37:36 -07:00
echo "\n";
2017-05-20 20:03:50 -07:00
2017-05-25 15:38:19 -07:00
// Double check stat for file against pre-run value
2017-06-18 03:17:42 -07:00
if ($type != "link" && $wopt_paranoid) {
2017-05-25 15:38:19 -07:00
$restat = chop(@shell_exec("stat -x ".$shellpath." 2>&1"));
2017-06-18 03:17:42 -07:00
$post_access = null;
$post_modify = null;
$post_change = null;
foreach (explode("\n", $restat) as $line) {
$check = substr($line, 0, 6);
if ($check == "Access") { $post_access = $line; }
if ($check == "Modify") { $post_modify = $line; }
if ($check == "Change") { $post_change = $line; }
}
$message = array();
if ($pre_access != $post_access) {
$message[] = "ATIME CHANGED";
}
if ($pre_modify != $post_modify) {
$message[] = "MTIME CHANGED";
}
if ($pre_change != $post_change) {
$message[] = "CTIME CHANGED";
}
if (count($message)) { echo bashcolor(str_repeat(" ",99).implode(" ~ ", $message), "purple"); }
2017-05-25 15:38:19 -07:00
}
2017-05-20 20:03:50 -07:00
}
2017-06-18 03:17:42 -07:00
echo "\n\n\n";
2017-05-25 15:38:19 -07:00
// Footer
$seconds = floor($time = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]);
$fbanner = "Finished in ".$seconds." seconds";
2017-05-20 20:03:50 -07:00
echo str_repeat("-", strlen($fbanner))."\n".$fbanner."\n";
2017-05-25 15:38:19 -07:00
echo "Files ignored: ".$ignored." / Files nodescended: ".$nodescended."\n";
// Write app summary values
$dbo->exec("UPDATE _walkwalk SET nodescended=".$nodescended.", ignored=".$ignored.", status='completed_in_".$seconds."'");
2017-05-03 00:39:48 -07:00
?>