diff --git a/Helpers/xinv.php b/Helpers/xinv.php new file mode 100644 index 0000000000..56c10b237f --- /dev/null +++ b/Helpers/xinv.php @@ -0,0 +1,427 @@ += 0 ORDER BY Firstname, LastName "; + $result = mysqli_query($sqllink, $query); + if (mysqli_num_rows($result) == 0) return false; + + $auuids = []; + while($vars = mysqli_fetch_assoc($result)) + { + $auuids[] = $vars['PrincipalID']; + } + return $auuids; + } +} + +function CheckDuplicateSystemFolders($rootid, $fix) +{ + global $sqllink; + global $verbose; + + $msgs = []; + + // Look for duplicate system folders (type >= 0) that point to the root. + // Change the rest to ordinary folders (type -1) and rename them to duplicate-{foldername} + $query = "SELECT * FROM " .INVENTORYFOLDERS ." WHERE type >= 0 AND parentFolderID='$rootid' ORDER BY type, folderName, version DESC"; + $result = mysqli_query($sqllink, $query); + + // The list is ordered by type, folder name, version (count of next level folders). + $currftype = ''; + $currfname = ''; + $numfolders = 0; + while ($vars = mysqli_fetch_assoc($result)) + { + $ftype = $vars['type']; + $fname = $vars['folderName']; + $fid = $vars['folderID']; + $fver = $vars['version']; + $fparent = $vars['parentFolderID']; + if ($currftype == '') $currftype = $ftype; + if ($currfname == '') $currfname = $fname; + + if ($currftype != $ftype || $currfname != $fname) + { + $currftype = $ftype; + $currfname = $fname; + $numfolders = 0; + } + + if ($currfname == $fname) + { + $numfolders++; + if ($numfolders > 1) + { + if ($fix) + { + $fname = mysqli_real_escape_string($sqllink, $fname); + $query = "UPDATE " .INVENTORYFOLDERS ." SET type=-1, folderName='Duplicate-$fname' WHERE folderID='$fid' "; + mysqli_query($sqllink, $query); + $msgs[] = "Duplicate ($numfolders) type $ftype folderID=$fid fixedname=Duplicate-$fname"; + } + else + { + $msgs[] = "Duplicate ($numfolders) type $ftype folderID=$fid parentID=$fparent subfolders=$fver name=$fname"; + } + } + else + { + if ($verbose) $msgs[] = "System folder type $ftype folderID=$fid parentID=$fparent subfolders=$fver name=$fname"; + } + } + } + + $msgs[] = ""; + return $msgs; +} + +function CheckInventory($auuid, $fix=false) +{ + global $sqllink; + global $verbose; + + // This performs basic integrity tests + // Returns [false, msgs...] if failures or [true, msgs...] if inventory is OK. + // + $msgs = []; + + // Verify uuid is listed in UserAccounts. Issue warning but continue. + $query = "SELECT FirstName, LastName, UserLevel FROM " .USERACCOUNTS ." WHERE PrincipalID='$auuid' "; + $result = mysqli_query($sqllink, $query); + if ($vars = mysqli_fetch_assoc($result)) + { + $msgs[] = "Checked UUID=$auuid Name={$vars['FirstName']} {$vars['LastName']} "; + } + else + { + $msgs[] = "Warning: UUID=$auuid does not exist in table " .USERACCOUNTS; + } + + // Find root folder(s) + $query = "SELECT * FROM " .INVENTORYFOLDERS ." WHERE agentID='$auuid' AND (type=8 OR type=9) ORDER BY type "; + $result = mysqli_query($sqllink, $query); + $vars = mysqli_fetch_assoc($result); + $num = mysqli_num_rows($result); + if ($num == 0) + { + if ($fix) + { + $rootid = mkuuid(); + $query = "INSERT INTO " .INVENTORYFOLDERS ." (folderName,type,version,folderID,agentID,parentFolderID) + VALUES('My Inventory', 8, 1, '$rootid', '$auuid','00000000-0000-0000-0000-000000000000')"; + mysqli_query($sqllink, $query); + + // Rerun select + $query = "SELECT * FROM " .INVENTORYFOLDERS ." WHERE agentID='$auuid' AND type=8 "; + $result = mysqli_query($sqllink, $query); + $vars = mysqli_fetch_assoc($result); + $num = mysqli_num_rows($result); + $msgs[] = "Warning: Missing root folder added. Consieder orphan check afterward: --chkorphan='uuid' "; + } + else + { + $msgs[] = "Warning: Root folder missing - needs adding root then orphan check required: --chkorphan='uuid' "; + return array_merge([false], $msgs); + } + } + + if ($num > 1) + { + $msgs[] = "Multiple ($num) roots found - manual inspection required"; + + return array_merge([false], $msgs); + } + + $rtype = $vars['type']; + $rootid = $vars['folderID']; + $rname = $vars['folderName']; + + // One root, could be type 9 (olde version of IAR). Fix it if found. + if ($rtype != 8) + { + if ($fix) + { + $query = "UPDATE " .INVENTORYFOLDERS ." SET type=8 WHERE agentID='$auuid' AND type=9"; + mysqli_query($sqllink, $query); + $msgs[] = "Warning: Old type 9 root found, converted to type=8"; + } + else + { + $msgs[] = "Warning: Old type 9 root found, needs conversion to type 8"; + } + } + if ($verbose) $msgs[] = "Root Folder type=$rtype folderID=$rootid name='$rname' "; + + // Cleanup parentFolder of root type 8/9 + $pfolder = $vars['parentFolderID']; + if ($pfolder != '00000000-0000-0000-0000-000000000000') + { + if ($fix) + { + $query = "UPDATE " .INVENTORYFOLDERS ." SET parentFolderID='00000000-0000-0000-0000-000000000000' WHERE agentID='$auuid' AND type=$rtype"; + mysqli_query($sqllink, $query); + $msgs[] = "Warning: type $rtype root parent folder ID was $pfolder, set to null key"; + } + else + { + $msgs[] = "Warning: type $rtype root parent folder ID was $pfolder, should be null key"; + } + } + + // Check the root folder. + $rc = CheckDuplicateSystemFolders($rootid, $fix); + $msgs = array_merge($msgs, $rc); + + // Check for the My Suitcase folder. + $query = "SELECT * FROM " .INVENTORYFOLDERS ." WHERE agentID='$auuid' AND type=100 "; + $result = mysqli_query($sqllink, $query); + $vars = mysqli_fetch_assoc($result); + $num = mysqli_num_rows($result); + if ($num == 0) + { + if ($fix) + { + $suitid = mkuuid(); + $query = "INSERT INTO " .INVENTORYFOLDERS ." (folderName,type,version,folderID,agentID,parentFolderID) + VALUES('My Suitcase', 100, 1, '$suitid', '$auuid','$rootid')"; + mysqli_query($sqllink, $query); + + // Rerun select + $query = "SELECT * FROM " .INVENTORYFOLDERS ." WHERE agentID='$auuid' AND type=100 "; + $result = mysqli_query($sqllink, $query); + $vars = mysqli_fetch_assoc($result); + $num = mysqli_num_rows($result); + $msgs[] = "Warning: Missing Suitcase folder added. Consieder orphan check afterward: --chkorphan='uuid' "; + } + else + { + $msgs[] = "My Suitcase folder is missing "; + } + } + + if ($num > 1) + { + if ($fix) + { + $msgs[] = "Multiple ($num) roots found - converting one to ordinary folder"; + } + else + { + $msgs[] = "Multiple ($num) roots found"; + } + } + + $rtype = $vars['type']; + $suitid = $vars['folderID']; + $rname = $vars['folderName']; + + if ($verbose) $msgs[] = "My Suitcase Folder type=$rtype folderID=$suitid name='$rname' "; + + // Fix parentFolder of My Suitcase type=100 + $pfolder = $vars['parentFolderID']; + if ($pfolder != $rootid) + { + if ($fix) + { + $query = "UPDATE " .INVENTORYFOLDERS ." SET parentFolderID='$rootid' WHERE agentID='$auuid' AND type=$rtype"; + mysqli_query($sqllink, $query); + $msgs[] = "Warning: type $rtype root parent folder ID was $pfolder, set to $rootid"; + } + else + { + $msgs[] = "Warning: type $rtype root parent folder ID was $pfolder, should be $rootid"; + } + } + + // Check the suitcase folder. + $rc = CheckDuplicateSystemFolders($suitid, $fix); + $msgs = array_merge($msgs, $rc); + + $msgs[] = "Scan Completed"; + if ($verbose) $msgs[] = ""; + return array_merge([true], $msgs); +} + +// =============================================================================================================== + $sqllink = null; + + $opts = getopt('v', ['chkinv::','fixinv:'] ); + + if (!OpenRobustDB()) + { + echo "Unable to open grid database"; + exit; + } + + $cmd = ''; + + if (isset($opts['v'])) $verbose = true; + else $verbose = false; + + /**/ if (isset($opts['chkinv'])) $cmd = 'chkinv'; + else if (isset($opts['fixinv'])) $cmd = 'fixinv'; + + if ($cmd == '') + { + echo 'missing parameters: php xinv.php {--chkinv="firstname lastname" | --fixinv="firstname lastname"}' ."\n"; + CloseDB(); + exit; + } + + // php xchkinv.php --chkinv="firstname lastname" or --chkinv="uuid" + if ($cmd == 'chkinv') + { + $auuids = false; + $aname = $opts['chkinv']; + // If avatar name is blank, get all active avatars + $auuids = GetAvatarUUID($aname); + if (!$auuids) + { + echo "Avatar $aname does not exist.\n"; + } + else + { + foreach($auuids AS $auuid) + { + //echo "$aname uuid=$auuid\n"; + $rc = CheckInventory($auuid, false); + + foreach ($rc as $msg) + { + if ($msg === false) echo "Errors\n"; + else if ($msg === true) echo "Success\n"; + else echo $msg ."\n"; + } + } + } + } + + // php xchkinv.php --fixinv="firstname lastname" or --fixinv="uuid" + else if ($cmd == 'fixinv') + { + $aname = $opts['fixinv']; + $auuid = GetAvatarUUID($aname); + if (!$auuid) + { + error_log("$aname does not exist."); + } + else + { + $auuid = $auuid[0]; + error_log("Avatar $aname uuid=$auuid"); + $rc = CheckInventory($auuid, true); + foreach ($rc as $msg) + { + if ($msg === false) echo "Errors\n"; + else if ($msg === true) echo "Success\n"; + else echo $msg ."\n"; + } + } + } + + CloseDB(); + exit; +?>