From: Marcin Haba Date: Thu, 12 Dec 2019 04:16:56 +0000 (+0100) Subject: baculum: Add to BVFS lsdirs, lsfiles and versions endpoints new output=raw/json parameter X-Git-Tag: Release-9.6.0~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbe280d2a78b908a9a3b5c69f6ad7bdbc1f20121;p=thirdparty%2Fbacula.git baculum: Add to BVFS lsdirs, lsfiles and versions endpoints new output=raw/json parameter --- diff --git a/gui/baculum/protected/API/Class/BLStat.php b/gui/baculum/protected/API/Class/BLStat.php new file mode 100644 index 000000000..5845ba581 --- /dev/null +++ b/gui/baculum/protected/API/Class/BLStat.php @@ -0,0 +1,108 @@ + + * @category Module + * @package Baculum API + */ +class BLStat extends APIModule { + + /** + * Decode Bacula base64 encoded LStat value. + * + * @param string $lstat encoded LStat string + * @return array decoded values from LStat string + */ + public function decode($lstat) { + $base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + $lstat = trim($lstat); + $lstat_fields = explode(' ', $lstat); + $lstat_len = count($lstat_fields); + if ($lstat_len < 16) { + // not known or empty lstat value + return; + } elseif ($lstat_len > 16) { + // cut off unknown fields + array_splice($lstat_fields, 16); + } + + list( + $dev, + $inode, + $mode, + $nlink, + $uid, + $gid, + $rdev, + $size, + $blocksize, + $blocks, + $atime, + $mtime, + $ctime, + $linkfi, + $flags, + $data + ) = $lstat_fields; + $encoded_values = array( + 'dev' => $dev, + 'inode' => $inode, + 'mode' => $mode, + 'nlink' => $nlink, + 'uid' => $uid, + 'gid' => $gid, + 'rdev' => $rdev, + 'size' => $size, + 'blocksize' => $blocksize, + 'blocks' => $blocks, + 'atime' => $atime, + 'mtime' => $mtime, + 'ctime' => $ctime, + 'linkfi' => $linkfi, + 'flags' => $flags, + 'data' => $data + ); + + $ret = array(); + foreach($encoded_values as $key => $val) { + $result = 0; + $is_minus = false; + $start = 0; + + if(substr($val, 0, 1) === '-') { + $is_minus = true; + $start++; + } + + for($i = $start; $i < strlen($val); $i++) { + $result = bcmul($result, bcpow(2,6)); + $result += strpos($base64, substr($val, $i , 1)); + } + $ret[$key] = ($is_minus === true) ? -$result : $result; + } + return $ret; + } +} +?> diff --git a/gui/baculum/protected/API/Class/BVFS.php b/gui/baculum/protected/API/Class/BVFS.php new file mode 100644 index 000000000..a3fb50564 --- /dev/null +++ b/gui/baculum/protected/API/Class/BVFS.php @@ -0,0 +1,110 @@ + + * @category Module + * @package Baculum API + */ +class BVFS extends APIModule { + + const DIR_PATTERN = '/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-z0-9\+\/\ ]+)\t(?P(.*\/|\.{2}))$/'; + const FILE_PATTERN = '/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-z0-9\+\-\/\ ]+)\t(?P[^\/]+)$/'; + const VERSION_PATTERN = '/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-Z0-9\+\/\ ]+)\t(?P.+)\t(?P.+)\t(?P\d+)$/'; + + public function parseFileDirList($list) { + $elements = array(); + $blstat = $this->getModule('blstat'); + for($i = 0; $i < count($list); $i++) { + if(preg_match(self::DIR_PATTERN, $list[$i], $match) == 1) { + if($match['name'] == '.') { + continue; + } + $elements[] = array( + 'pathid' => $match['pathid'], + 'filenameid' => $match['filenameid'], + 'fileid' => $match['fileid'], + 'jobid' => $match['jobid'], + 'lstat' => $blstat->decode($match['lstat']), + 'name' => $match['name'], + 'type' => 'dir' + ); + } elseif(preg_match(self::FILE_PATTERN, $list[$i], $match) == 1) { + if($match['name'] == '.') { + continue; + } + $elements[] = array( + 'pathid' => $match['pathid'], + 'filenameid' => $match['filenameid'], + 'fileid' => $match['fileid'], + 'jobid' => $match['jobid'], + 'lstat' => $blstat->decode($match['lstat']), + 'name' => $match['name'], + 'type' => 'file' + ); + } + } + usort($elements, 'sortFilesListByName'); + return $elements; + } + + public function parseFileVersions($list) { + $elements = array(); + for($i = 0; $i < count($list); $i++) { + if(preg_match(self::VERSION_PATTERN, $list[$i], $match) == 1) { + $elements[$match['fileid']] = array( + 'pathid' => $match['pathid'], + 'filenameid' => $match['filenameid'], + 'fileid' => $match['fileid'], + 'jobid' => $match['jobid'], + 'lstat' => $this->getModule('blstat')->decode($match['lstat']), + 'md5' => $match['md5'], + 'volname' => $match['volname'], + 'inchanger' => $match['inchanger'], + 'type' => 'file' + ); + } + } + return $elements; + } + +} + +/* + * Small sorting callback function to sort files and directories by name. + * Function keeps '.' and '..' names always in the beginning of array. + * Used to sort files and directories from Bvfs. + */ +function sortFilesListByName($a, $b) { + $firstLeft = substr($a['name'], 0, 1); + $firstRight = substr($b['name'], 0, 1); + if ($firstLeft == '.' && $firstRight != '.') { + return -1; + } else if ($firstRight == '.' && $firstLeft != '.') { + return 1; + } + return strcasecmp($a['name'], $b['name']); +} +?> diff --git a/gui/baculum/protected/API/Class/ConsoleOutputPage.php b/gui/baculum/protected/API/Class/ConsoleOutputPage.php index 2c8a8d39d..ad196c66c 100644 --- a/gui/baculum/protected/API/Class/ConsoleOutputPage.php +++ b/gui/baculum/protected/API/Class/ConsoleOutputPage.php @@ -38,12 +38,12 @@ abstract class ConsoleOutputPage extends BaculumAPIServer { /** * Get raw output from console. */ - abstract protected function getRawOutput($params = array()); + abstract protected function getRawOutput($params = []); /** * Get parsed JSON output from console. */ - abstract protected function getJSONOutput($params = array()); + abstract protected function getJSONOutput($params = []); /** * Validate output format. diff --git a/gui/baculum/protected/API/Pages/API/BVFSLsDirs.php b/gui/baculum/protected/API/Pages/API/BVFSLsDirs.php index 1a6f41841..28d44f160 100644 --- a/gui/baculum/protected/API/Pages/API/BVFSLsDirs.php +++ b/gui/baculum/protected/API/Pages/API/BVFSLsDirs.php @@ -19,6 +19,8 @@ * * Bacula(R) is a registered trademark of Kern Sibbald. */ + +Prado::using('Application.API.Class.ConsoleOutputPage'); /** * BVFS list directories. @@ -27,10 +29,7 @@ * @category API * @package Baculum API */ -class BVFSLsDirs extends BaculumAPIServer { - - private $jobids; - private $path; +class BVFSLsDirs extends ConsoleOutputPage { public function get() { $misc = $this->getModule('misc'); @@ -38,13 +37,7 @@ class BVFSLsDirs extends BaculumAPIServer { $offset = $this->Request->contains('offset') ? intval($this->Request['offset']) : 0; $jobids = $this->Request->contains('jobids') && $misc->isValidIdsList($this->Request['jobids']) ? $this->Request['jobids'] : null; $path = $this->Request->contains('path') && $misc->isValidPath($this->Request['path']) ? $this->Request['path'] : null; - if (is_null($jobids) && !is_null($this->jobids)) { - $jobids = $this->jobids; - } - - if (is_null($path) && !is_null($this->path)) { - $path = $this->path; - } + $out_format = $this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output']) ? $this->Request['output'] : parent::OUTPUT_FORMAT_RAW; if (is_null($jobids)) { $this->output = BVFSError::MSG_ERROR_INVALID_JOBID_LIST; @@ -58,17 +51,60 @@ class BVFSLsDirs extends BaculumAPIServer { return; } - $cmd = array('.bvfs_lsdirs', 'jobid="' . $jobids . '"', 'path="' . $path . '"'); + $params = [ + 'jobids' => $jobids, + 'path' => $path, + 'offset' => $offset, + 'limit' => $limit + ]; + $out = (object)['output' => [], 'exitcode' => 0]; + if ($out_format === parent::OUTPUT_FORMAT_RAW) { + $out = $this->getRawOutput($params); + } elseif($out_format === parent::OUTPUT_FORMAT_JSON) { + $out = $this->getJSONOutput($params); + } + + $this->output = $out->output; + $this->error = $out->exitcode; + } + + /** + * Get BVFS list directories output from console in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { + $cmd = [ + '.bvfs_lsdirs', + 'jobid="' . $params['jobids'] . '"', + 'path="' . $params['path'] . '"' + ]; - if ($offset > 0) { - array_push($cmd, 'offset="' . $offset . '"'); + if ($params['offset'] > 0) { + array_push($cmd, 'offset="' . $params['offset'] . '"'); } - if ($limit > 0) { - array_push($cmd, 'limit="' . $limit . '"'); + if ($params['limit'] > 0) { + array_push($cmd, 'limit="' . $params['limit'] . '"'); + } + return $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); + } + + /** + * Get BVFS list directories output in JSON format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getJSONOutput($params = []) { + $result = (object)['output' => [], 'exitcode' => 0]; + $raw = $this->getRawOutput($params); + if ($raw->exitcode === 0) { + $result->output = $this->getModule('bvfs')->parseFileDirList($raw->output); + } else { + $result = $raw; } - $result = $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); - $this->output = $result->output; - $this->error = $result->exitcode; + return $result; } } ?> diff --git a/gui/baculum/protected/API/Pages/API/BVFSLsFiles.php b/gui/baculum/protected/API/Pages/API/BVFSLsFiles.php index a226f400d..9f67c6d96 100644 --- a/gui/baculum/protected/API/Pages/API/BVFSLsFiles.php +++ b/gui/baculum/protected/API/Pages/API/BVFSLsFiles.php @@ -20,6 +20,8 @@ * Bacula(R) is a registered trademark of Kern Sibbald. */ +Prado::using('Application.API.Class.ConsoleOutputPage'); + /** * BVFS list files. * @@ -27,7 +29,7 @@ * @category API * @package Baculum API */ -class BVFSLsFiles extends BaculumAPIServer { +class BVFSLsFiles extends ConsoleOutputPage { private $jobids; private $path; @@ -38,13 +40,7 @@ class BVFSLsFiles extends BaculumAPIServer { $offset = $this->Request->contains('offset') ? intval($this->Request['offset']) : 0; $jobids = $this->Request->contains('jobids') && $misc->isValidIdsList($this->Request['jobids']) ? $this->Request['jobids'] : null; $path = $this->Request->contains('path') && $misc->isValidPath($this->Request['path']) ? $this->Request['path'] : null; - if (is_null($jobids) && !is_null($this->jobids)) { - $jobids = $this->jobids; - } - - if (is_null($path) && !is_null($this->path)) { - $path = $this->path; - } + $out_format = $this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output']) ? $this->Request['output'] : parent::OUTPUT_FORMAT_RAW; if (is_null($jobids)) { $this->output = BVFSError::MSG_ERROR_INVALID_JOBID_LIST; @@ -58,17 +54,60 @@ class BVFSLsFiles extends BaculumAPIServer { return; } - $cmd = array('.bvfs_lsfiles', 'jobid="' . $jobids . '"', 'path="' . $path . '"'); + $params = [ + 'jobids' => $jobids, + 'path' => $path, + 'offset' => $offset, + 'limit' => $limit + ]; + $out = (object)['output' => [], 'exitcode' => 0]; + if ($out_format === parent::OUTPUT_FORMAT_RAW) { + $out = $this->getRawOutput($params); + } elseif($out_format === parent::OUTPUT_FORMAT_JSON) { + $out = $this->getJSONOutput($params); + } - if ($offset > 0) { - array_push($cmd, 'offset="' . $offset . '"'); + $this->output = $out->output; + $this->error = $out->exitcode; + } + + /** + * Get BVFS list files output from console in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { + $cmd = [ + '.bvfs_lsfiles', + 'jobid="' . $params['jobids'] . '"', + 'path="' . $params['path'] . '"' + ]; + + if ($params['offset'] > 0) { + array_push($cmd, 'offset="' . $params['offset'] . '"'); + } + if ($params['limit'] > 0) { + array_push($cmd, 'limit="' . $params['limit'] . '"'); } - if ($limit > 0) { - array_push($cmd, 'limit="' . $limit . '"'); + return $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); + } + + /** + * Get BVFS list files output in JSON format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getJSONOutput($params = []) { + $result = (object)['output' => [], 'exitcode' => 0]; + $raw = $this->getRawOutput($params); + if ($raw->exitcode === 0) { + $result->output = $this->getModule('bvfs')->parseFileDirList($raw->output); + } else { + $result = $raw; } - $result = $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); - $this->output = $result->output; - $this->error = $result->exitcode; + return $result; } } ?> diff --git a/gui/baculum/protected/API/Pages/API/BVFSVersions.php b/gui/baculum/protected/API/Pages/API/BVFSVersions.php index 626909cc2..c513fe54d 100644 --- a/gui/baculum/protected/API/Pages/API/BVFSVersions.php +++ b/gui/baculum/protected/API/Pages/API/BVFSVersions.php @@ -20,6 +20,8 @@ * Bacula(R) is a registered trademark of Kern Sibbald. */ +Prado::using('Application.API.Class.ConsoleOutputPage'); + /** * BVFS versions. * @@ -27,13 +29,14 @@ * @category API * @package Baculum API */ -class BVFSVersions extends BaculumAPIServer { +class BVFSVersions extends ConsoleOutputPage { public function get() { $jobid = $this->Request->contains('jobid') ? intval($this->Request['jobid']) : 0; $pathid = $this->Request->contains('pathid') ? intval($this->Request['pathid']) : 0; $filenameid = $this->Request->contains('filenameid') ? intval($this->Request['filenameid']) : 0; $copies = $this->Request->contains('copies') ? intval($this->Request['copies']) : 0; + $out_format = $this->Request->contains('output') && $this->isOutputFormatValid($this->Request['output']) ? $this->Request['output'] : parent::OUTPUT_FORMAT_RAW; $client = null; if ($this->Request->contains('client') && $this->getModule('misc')->isValidName($this->Request['client'])) { $client = $this->Request['client']; @@ -44,20 +47,59 @@ class BVFSVersions extends BaculumAPIServer { $this->error = BVFSError::ERROR_INVALID_CLIENT; return; } + $params = [ + 'client' => $client, + 'jobid' => $jobid, + 'pathid' => $pathid, + 'filenameid' => $filenameid, + 'copies' => $copies + ]; + $out = (object)['output' => [], 'exitcode' => 0]; + if ($out_format === parent::OUTPUT_FORMAT_RAW) { + $out = $this->getRawOutput($params); + } elseif($out_format === parent::OUTPUT_FORMAT_JSON) { + $out = $this->getJSONOutput($params); + } + + $this->output = $out->output; + $this->error = $out->exitcode; + } + /** + * Get BVFS versions output from console in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { $cmd = array( '.bvfs_versions', - 'client="' . $client . '"', - 'jobid="' . $jobid . '"', - 'pathid="' . $pathid . '"', - 'fnid="' . $filenameid . '"' + 'client="' . $params['client'] . '"', + 'jobid="' . $params['jobid'] . '"', + 'pathid="' . $params['pathid'] . '"', + 'fnid="' . $params['filenameid'] . '"' ); - if ($copies == 1) { + if ($params['copies'] == 1) { $cmd[] = 'copies'; } - $result = $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); - $this->output = $result->output; - $this->error = $result->exitcode; + return $this->getModule('bconsole')->bconsoleCommand($this->director, $cmd); + } + + /** + * Get BVFS versions output in JSON format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getJSONOutput($params = []) { + $result = (object)['output' => [], 'exitcode' => 0]; + $raw = $this->getRawOutput($params); + if ($raw->exitcode === 0) { + $result->output = $this->getModule('bvfs')->parseFileVersions($raw->output); + } else { + $result = $raw; + } + return $result; } } ?> diff --git a/gui/baculum/protected/API/Pages/API/ClientShow.php b/gui/baculum/protected/API/Pages/API/ClientShow.php index c55fac6d4..99f463dfc 100644 --- a/gui/baculum/protected/API/Pages/API/ClientShow.php +++ b/gui/baculum/protected/API/Pages/API/ClientShow.php @@ -60,7 +60,13 @@ class ClientShow extends ConsoleOutputPage { } } - protected function getRawOutput($params = array()) { + /** + * Get show client output from console in raw format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getRawOutput($params = []) { $result = $this->getModule('bconsole')->bconsoleCommand( $this->director, array('show', 'client="' . $params['client'] . '"') @@ -68,7 +74,13 @@ class ClientShow extends ConsoleOutputPage { return $result; } - protected function getJSONOutput($params = array()) { + /** + * Get show client output in JSON format. + * + * @param array $params command parameters + * @return StdClass object with output and exitcode + */ + protected function getJSONOutput($params = []) { $result = (object)array('output' => array(), 'exitcode' => 0); $output = $this->getRawOutput($params); if ($output->exitcode === 0) { diff --git a/gui/baculum/protected/API/Pages/API/config.xml b/gui/baculum/protected/API/Pages/API/config.xml index 687a19d7d..766f2af5a 100644 --- a/gui/baculum/protected/API/Pages/API/config.xml +++ b/gui/baculum/protected/API/Pages/API/config.xml @@ -23,6 +23,8 @@ + + diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index 4fcbbcfd5..242eabfea 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -3518,6 +3518,9 @@ "schema": { "type": "string" } + }, + { + "$ref": "#/components/parameters/Output" } ] } @@ -3589,6 +3592,9 @@ "schema": { "type": "string" } + }, + { + "$ref": "#/components/parameters/Output" } ] } @@ -3670,6 +3676,9 @@ "type": "integer", "default": 0 } + }, + { + "$ref": "#/components/parameters/Output" } ] } diff --git a/gui/baculum/protected/Common/Class/Miscellaneous.php b/gui/baculum/protected/Common/Class/Miscellaneous.php index b9b09489c..530edcc63 100644 --- a/gui/baculum/protected/Common/Class/Miscellaneous.php +++ b/gui/baculum/protected/Common/Class/Miscellaneous.php @@ -266,6 +266,10 @@ class Miscellaneous extends TModule { return (preg_match('/^(all|deleted)$/', $type) === 1); } + public function isValidOutput($type) { + return (preg_match('/^(raw|json)$/', $type) === 1); + } + public function escapeCharsToConsole($path) { return preg_replace('/([$])/', '\\\${1}', $path); } @@ -274,134 +278,6 @@ class Miscellaneous extends TModule { return json_decode(json_encode($data), true); } - public function decodeBaculaLStat($lstat) { - $base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - $lstat = trim($lstat); - $lstat_fields = explode(' ', $lstat); - $lstat_len = count($lstat_fields); - if ($lstat_len < 16) { - // not known or empty lstat value - return; - } elseif ($lstat_len > 16) { - // cut off unknown fields - array_splice($lstat_fields, 16); - } - - list( - $dev, - $inode, - $mode, - $nlink, - $uid, - $gid, - $rdev, - $size, - $blocksize, - $blocks, - $atime, - $mtime, - $ctime, - $linkfi, - $flags, - $data - ) = $lstat_fields; - $encoded_values = array( - 'dev' => $dev, - 'inode' => $inode, - 'mode' => $mode, - 'nlink' => $nlink, - 'uid' => $uid, - 'gid' => $gid, - 'rdev' => $rdev, - 'size' => $size, - 'blocksize' => $blocksize, - 'blocks' => $blocks, - 'atime' => $atime, - 'mtime' => $mtime, - 'ctime' => $ctime, - 'linkfi' => $linkfi, - 'flags' => $flags, - 'data' => $data - ); - - $ret = array(); - foreach($encoded_values as $key => $val) { - $result = 0; - $is_minus = false; - $start = 0; - - if(substr($val, 0, 1) === '-') { - $is_minus = true; - $start++; - } - - for($i = $start; $i < strlen($val); $i++) { - $result = bcmul($result, bcpow(2,6)); - $result += strpos($base64, substr($val, $i , 1)); - } - $ret[$key] = ($is_minus === true) ? -$result : $result; - } - return $ret; - } - - public function parseBvfsList($list) { - $elements = array(); - for($i = 0; $i < count($list); $i++) { - if(preg_match('/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-z0-9\+\/\ ]+)\t(?P.*)\/$/', $list[$i], $match) == 1 || preg_match('/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-z0-9\+\/\ ]+)\t(?P\.{2})$/', $list[$i], $match) == 1) { - if($match['name'] == '.') { - continue; - } elseif($match['name'] != '..') { - $match['name'] .= '/'; - } - $elements[] = array( - 'pathid' => $match['pathid'], - 'filenameid' => $match['filenameid'], - 'fileid' => $match['fileid'], - 'jobid' => $match['jobid'], - 'lstat' => $this->decodeBaculaLStat($match['lstat']), - 'name' => $match['name'], - 'type' => 'dir' - ); - } elseif(preg_match('/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-z0-9\+\-\/\ ]+)\t(?P[^\/]+)$/', $list[$i], $match) == 1) { - if($match['name'] == '.') { - continue; - } - $elements[] = array( - 'pathid' => $match['pathid'], - 'filenameid' => $match['filenameid'], - 'fileid' => $match['fileid'], - 'jobid' => $match['jobid'], - 'lstat' => $this->decodeBaculaLStat($match['lstat']), - 'name' => $match['name'], - 'type' => 'file' - ); - } - } - usort($elements, 'sortFilesListByName'); - return $elements; - } - - public function parseFileVersions($filename, $list) { - $elements = array(); - for($i = 0; $i < count($list); $i++) { - if(preg_match('/^(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P\d+)\t(?P[a-zA-Z0-9\+\/\ ]+)\t(?P.+)\t(?P.+)\t(?P\d+)$/', $list[$i], $match) == 1) { - $elements[$match['fileid']] = array( - 'name' => $filename, - 'pathid' => $match['pathid'], - 'filenameid' => $match['filenameid'], - 'fileid' => $match['fileid'], - 'jobid' => $match['jobid'], - 'lstat' => $this->decodeBaculaLStat($match['lstat']), - 'md5' => $match['md5'], - 'volname' => $match['volname'], - 'inchanger' => $match['inchanger'], - 'type' => 'file' - ); - } - } - return $elements; - } - public function findJobIdStartedJob($output) { $jobid = null; $output = array_reverse($output); // jobid is ussually at the end of output @@ -484,20 +360,4 @@ class Miscellaneous extends TModule { return sprintf('$apr1$%s$%s', $salt, $tmp); } } - -/* - * Small sorting callback function to sort files and directories by name. - * Function keeps '.' and '..' names always in the beginning of array. - * Used to sort files and directories from Bvfs. - */ -function sortFilesListByName($a, $b) { - $firstLeft = substr($a['name'], 0, 1); - $firstRight = substr($b['name'], 0, 1); - if ($firstLeft == '.' && $firstRight != '.') { - return -1; - } else if ($firstRight == '.' && $firstLeft != '.') { - return 1; - } - return strcasecmp($a['name'], $b['name']); -} ?> diff --git a/gui/baculum/protected/Web/Pages/RestoreWizard.php b/gui/baculum/protected/Web/Pages/RestoreWizard.php index 63b8d5c43..1da3eba8f 100644 --- a/gui/baculum/protected/Web/Pages/RestoreWizard.php +++ b/gui/baculum/protected/Web/Pages/RestoreWizard.php @@ -395,18 +395,18 @@ class RestoreWizard extends BaculumWebPage // generating Bvfs may take a moment $this->generateBvfsCache($jobids); - // get directories list - $query = sprintf( - '?jobids=%s&path=%s', - rawurlencode($jobids), - rawurlencode(implode($_SESSION['restore_path'])) - ); + // get directory and file list + $query = '?' . http_build_query(array( + 'jobids' => $jobids, + 'path' => implode($_SESSION['restore_path']), + 'output' => 'json' + )); $bvfs_dirs = $this->getModule('api')->get( array('bvfs', 'lsdirs', $query) ); $dirs = array(); if ($bvfs_dirs->error === 0) { - $dirs = $this->getModule('misc')->parseBvfsList($bvfs_dirs->output); + $dirs = json_decode(json_encode($bvfs_dirs->output), true); } // get files list @@ -415,7 +415,7 @@ class RestoreWizard extends BaculumWebPage ); $files = array(); if ($bvfs_files->error === 0) { - $files = $this->getModule('misc')->parseBvfsList($bvfs_files->output); + $files = json_decode(json_encode($bvfs_files->output), true); } $elements = array_merge($dirs, $files); @@ -615,14 +615,28 @@ class RestoreWizard extends BaculumWebPage 'client' => $clientname, 'jobid' => $jobid, 'pathid' => $pathid, - 'filenameid' => $filenameid + 'filenameid' => $filenameid, + 'output' => 'json' ]; if ($this->EnableCopyJobRestore->Checked) { $params['copies'] = 1; } + + /** + * Helper for adding filename to versions list. + * + * @param array $el version list element + * @return return version list element + */ + $add_version_filename_func = function ($el) use ($filename) { + $el['name'] = $filename; + return $el; + }; + $query = '?' . http_build_query($params); $versions = $this->getModule('api')->get(array('bvfs', 'versions', $query))->output; - $file_versions = $this->getModule('misc')->parseFileVersions($filename, $versions); + $versions = json_decode(json_encode($versions), true); + $file_versions = array_map($add_version_filename_func, $versions); $file_versions = array_map(array('RestoreWizard', 'addUniqid'), $file_versions); $this->setFileVersions($file_versions); $this->VersionsDataGrid->dataSource = $file_versions;