本文整理汇总了PHP中OC_FileProxy::enabled方法的典型用法代码示例。如果您正苦于以下问题:PHP OC_FileProxy::enabled方法的具体用法?PHP OC_FileProxy::enabled怎么用?PHP OC_FileProxy::enabled使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类OC_FileProxy
的用法示例。
在下文中一共展示了OC_FileProxy::enabled方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: stream_open
public function stream_open($path, $mode, $options, &$opened_path)
{
if (!self::$rootView) {
self::$rootView = new OC_FilesystemView('');
}
$path = str_replace('crypt://', '', $path);
if (dirname($path) == 'streams' and isset(self::$sourceStreams[basename($path)])) {
$this->source = self::$sourceStreams[basename($path)]['stream'];
$this->path = self::$sourceStreams[basename($path)]['path'];
$this->size = self::$sourceStreams[basename($path)]['size'];
} else {
$this->path = $path;
if ($mode == 'w' or $mode == 'w+' or $mode == 'wb' or $mode == 'wb+') {
$this->size = 0;
} else {
$this->size = self::$rootView->filesize($path, $mode);
}
OC_FileProxy::$enabled = false;
//disable fileproxies so we can open the source file
$this->source = self::$rootView->fopen($path, $mode);
OC_FileProxy::$enabled = true;
if (!is_resource($this->source)) {
OCP\Util::writeLog('files_encryption', 'failed to open ' . $path, OCP\Util::ERROR);
}
}
if (is_resource($this->source)) {
$this->meta = stream_get_meta_data($this->source);
}
return is_resource($this->source);
}
示例2: __construct
/**
* if session is started, check if ownCloud key pair is set up, if not create it
* @param \OC\Files\View $view
*
* @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
*/
public function __construct($view)
{
$this->view = $view;
if (!$this->view->is_dir('files_encryption')) {
$this->view->mkdir('files_encryption');
}
$appConfig = \OC::$server->getAppConfig();
$publicShareKeyId = Helper::getPublicShareKeyId();
if ($publicShareKeyId === false) {
$publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
$appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
}
if (!Keymanager::publicShareKeyExists($view)) {
$keypair = Crypt::createKeypair();
// Save public key
Keymanager::setPublicKey($keypair['publicKey'], $publicShareKeyId);
// Encrypt private key empty passphrase
$cipher = Helper::getCipher();
$encryptedKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], '', $cipher);
if ($encryptedKey) {
Keymanager::setPrivateSystemKey($encryptedKey, $publicShareKeyId);
} else {
\OCP\Util::writeLog('files_encryption', 'Could not create public share keys', \OCP\Util::ERROR);
}
}
if (Helper::isPublicAccess() && !self::getPublicSharePrivateKey()) {
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$encryptedKey = Keymanager::getPrivateSystemKey($publicShareKeyId);
$privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
self::setPublicSharePrivateKey($privateKey);
\OC_FileProxy::$enabled = $proxyStatus;
}
}
示例3: getDocumentHash
protected function getDocumentHash($view, $path)
{
$this->validate($view, $path);
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$hash = sha1($view->file_get_contents($path));
\OC_FileProxy::$enabled = $proxyStatus;
return $hash;
}
示例4: testSimple
public function testSimple()
{
$file = OC::$SERVERROOT . '/3rdparty/MDB2.php';
$original = file_get_contents($file);
OC_Filesystem::file_put_contents('/file', $original);
OC_FileProxy::$enabled = false;
$stored = OC_Filesystem::file_get_contents('/file');
OC_FileProxy::$enabled = true;
$fromFile = OC_Filesystem::file_get_contents('/file');
$this->assertNotEqual($original, $stored);
$this->assertEqual($original, $fromFile);
}
示例5: createkey
public static function createkey($username, $passcode)
{
// generate a random key
$key = mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999);
// encrypt the key with the passcode of the user
$enckey = OC_Crypt::encrypt($key, $passcode);
// Write the file
$proxyEnabled = OC_FileProxy::$enabled;
OC_FileProxy::$enabled = false;
$view = new OC_FilesystemView('/' . $username);
$view->file_put_contents('/encryption.key', $enckey);
OC_FileProxy::$enabled = $proxyEnabled;
}
示例6: setKey
/**
* write key to disk
*
*
* @param string $path path to key directory
* @param string $name key name
* @param string $key key
* @param \OC\Files\View $view
* @return bool
*/
private static function setKey($path, $name, $key, $view)
{
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
self::keySetPreparation($view, $path);
$pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
$result = $view->file_put_contents($pathToKey, $key);
\OC_FileProxy::$enabled = $proxyStatus;
if (is_int($result) && $result > 0) {
self::$key_cache[$pathToKey] = $key;
return true;
}
return false;
}
示例7: set
public function set($key, $value, $ttl = 0)
{
$storage = $this->getStorage();
$result = false;
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if ($storage and $storage->file_put_contents($key, $value)) {
if ($ttl === 0) {
$ttl = 86400;
// 60*60*24
}
$result = $storage->touch($key, time() + $ttl);
}
\OC_FileProxy::$enabled = $proxyStatus;
return $result;
}
示例8: __construct
/**
* if session is started, check if ownCloud key pair is set up, if not create it
* @param \OC\Files\View $view
*
* @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
*/
public function __construct($view)
{
$this->view = $view;
if (!$this->view->is_dir('owncloud_private_key')) {
$this->view->mkdir('owncloud_private_key');
}
$appConfig = \OC::$server->getAppConfig();
$publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId');
if ($publicShareKeyId === null) {
$publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
$appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
}
if (!$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")) {
$keypair = Crypt::createKeypair();
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// Save public key
if (!$view->is_dir('/public-keys')) {
$view->mkdir('/public-keys');
}
$this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']);
// Encrypt private key empty passphrase
$cipher = \OCA\Encryption\Helper::getCipher();
$encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], '', $cipher);
if ($encryptedKey) {
Keymanager::setPrivateSystemKey($encryptedKey, $publicShareKeyId . '.private.key');
} else {
\OCP\Util::writeLog('files_encryption', 'Could not create public share keys', \OCP\Util::ERROR);
}
\OC_FileProxy::$enabled = $proxyStatus;
}
if (\OCA\Encryption\Helper::isPublicAccess()) {
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key');
$privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
$this->setPublicSharePrivateKey($privateKey);
$this->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL);
\OC_FileProxy::$enabled = $proxyStatus;
}
}
示例9: stream_open
public function stream_open($path, $mode, $options, &$opened_path)
{
$path = str_replace('crypt://', '', $path);
if (dirname($path) == 'streams' and isset(self::$sourceStreams[basename($path)])) {
$this->source = self::$sourceStreams[basename($path)]['stream'];
$this->path = self::$sourceStreams[basename($path)]['path'];
} else {
$this->path = $path;
OCP\Util::writeLog('files_encryption', 'open encrypted ' . $path . ' in ' . $mode, OCP\Util::DEBUG);
OC_FileProxy::$enabled = false;
//disable fileproxies so we can open the source file
$this->source = OC_FileSystem::fopen($path, $mode);
OC_FileProxy::$enabled = true;
if (!is_resource($this->source)) {
OCP\Util::writeLog('files_encryption', 'failed to open ' . $path, OCP\Util::ERROR);
}
}
if (is_resource($this->source)) {
$this->meta = stream_get_meta_data($this->source);
}
return is_resource($this->source);
}
示例10: __construct
/**
* @brief if session is started, check if ownCloud key pair is set up, if not create it
* @param \OC_FilesystemView $view
*
* @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
*/
public function __construct($view)
{
$this->view = $view;
if (!$this->view->is_dir('owncloud_private_key')) {
$this->view->mkdir('owncloud_private_key');
}
$publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
if ($publicShareKeyId === null) {
$publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
\OC_Appconfig::setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
}
if (!$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")) {
$keypair = Crypt::createKeypair();
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// Save public key
if (!$view->is_dir('/public-keys')) {
$view->mkdir('/public-keys');
}
$this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']);
// Encrypt private key empty passphrase
$encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], '');
// Save private key
$this->view->file_put_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key', $encryptedPrivateKey);
\OC_FileProxy::$enabled = $proxyStatus;
}
if (\OCA\Encryption\Helper::isPublicAccess()) {
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key');
$privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
$this->setPublicSharePrivateKey($privateKey);
\OC_FileProxy::$enabled = $proxyStatus;
}
}
示例11: testStreamDecryptLongFileContentWithoutHeader
/**
* @medium
* Test that data that is written by the crypto stream wrapper with AES 128
* @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
* @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
* reassembly of its data
*/
public function testStreamDecryptLongFileContentWithoutHeader()
{
// Generate a a random filename
$filename = 'tmp-' . $this->getUniqueID() . '.test';
\OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
\OCP\Config::deleteSystemValue('cipher');
// Test that data was successfully written
$this->assertTrue(is_int($cryptedFile));
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// Get file contents without using any wrapper to get it's actual contents on disk
$retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
// Check that the file was encrypted before being written to disk
$this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
// remove the header to check if we can also decrypt old files without a header,
// this files should fall back to AES-128
$cryptedWithoutHeader = substr($retreivedCryptedFile, Encryption\Crypt::BLOCKSIZE);
$this->view->file_put_contents($this->userId . '/files/' . $filename, $cryptedWithoutHeader);
// Re-enable proxy - our work is done
\OC_FileProxy::$enabled = $proxyStatus;
$decrypted = file_get_contents('crypt:///' . $this->userId . '/files/' . $filename);
$this->assertEquals($this->dataLong . $this->dataLong, $decrypted);
// Teardown
$this->view->unlink($this->userId . '/files/' . $filename);
Encryption\Keymanager::deleteFileKey($this->view, $filename);
}
示例12: testSetFileKey
/**
* @medium
*/
function testSetFileKey()
{
$key = $this->randomKey;
$file = 'unittest-' . $this->getUniqueID() . '.txt';
$util = new Encryption\Util($this->view, $this->userId);
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$this->view->file_put_contents($this->userId . '/files/' . $file, $this->dataShort);
Encryption\Keymanager::setFileKey($this->view, $util, $file, $key);
$this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/keyfiles/' . $file . '.key'));
// cleanup
$this->view->unlink('/' . $this->userId . '/files/' . $file);
// change encryption proxy to previous state
\OC_FileProxy::$enabled = $proxyStatus;
}
示例13: restoreEncryptionKeys
/**
* restore encryption keys from trash bin
*
* @param \OC\Files\View $view
* @param string $file complete path to file
* @param string $filename name of file
* @param string $uniqueFilename new file name to restore the file without overwriting existing files
* @param string $location location of file
* @param int $timestamp deleteion time
*
*/
private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp)
{
// Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!)
if (\OCP\App::isEnabled('files_encryption')) {
$user = \OCP\User::getUser();
$rootView = new \OC\Files\View('/');
$target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename);
list($owner, $ownerPath) = self::getUidAndFilename($target);
$util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user);
if ($util->isSystemWideMountPoint($ownerPath)) {
$baseDir = '/files_encryption/';
} else {
$baseDir = $owner . '/files_encryption/';
}
$path_parts = pathinfo($file);
$source_location = $path_parts['dirname'];
if ($view->is_dir('/files_trashbin/keyfiles/' . $file)) {
if ($source_location != '.') {
$keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename);
$sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename);
} else {
$keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $filename);
$sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $filename);
}
} else {
$keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename . '.key');
}
if ($timestamp) {
$keyfile .= '.d' . $timestamp;
}
// disable proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if ($rootView->file_exists($keyfile)) {
// handle directory
if ($rootView->is_dir($keyfile)) {
// handle keyfiles
$rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath);
// handle share-keys
if ($timestamp) {
$sharekey .= '.d' . $timestamp;
}
$rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath);
} else {
// handle keyfiles
$rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key');
// handle share-keys
$ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey');
if ($timestamp) {
$ownerShareKey .= '.d' . $timestamp;
}
// move only owners key
$rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey');
// try to re-share if file is shared
$filesystemView = new \OC\Files\View('/');
$session = new \OCA\Encryption\Session($filesystemView);
$util = new \OCA\Encryption\Util($filesystemView, $user);
// fix the file size
$absolutePath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files/' . $ownerPath);
$util->fixFileSize($absolutePath);
// get current sharing state
$sharingEnabled = \OCP\Share::isEnabled();
// get users sharing this file
$usersSharing = $util->getSharingUsersArray($sharingEnabled, $target);
// Attempt to set shareKey
$util->setSharedFileKeyfiles($session, $usersSharing, $target);
}
}
// enable proxy
\OC_FileProxy::$enabled = $proxyStatus;
}
}
示例14: postFileSize
/**
* @param string $path
* @param int $size
* @return int|bool
*/
public function postFileSize($path, $size, $fileInfo = null)
{
$view = new \OC\Files\View('/');
$userId = Helper::getUser($path);
$util = new Util($view, $userId);
// if encryption is no longer enabled or if the files aren't migrated yet
// we return the default file size
if (!\OCP\App::isEnabled('files_encryption') || $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) {
return $size;
}
// if path is a folder do nothing
if ($view->is_dir($path)) {
$proxyState = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$fileInfo = $view->getFileInfo($path);
\OC_FileProxy::$enabled = $proxyState;
if (isset($fileInfo['unencrypted_size']) && $fileInfo['unencrypted_size'] > 0) {
return $fileInfo['unencrypted_size'];
}
return $size;
}
// get relative path
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
// if path is empty we cannot resolve anything
if (empty($relativePath)) {
return $size;
}
// get file info from database/cache if not .part file
if (empty($fileInfo) && !Helper::isPartialFilePath($path)) {
$proxyState = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$fileInfo = $view->getFileInfo($path);
\OC_FileProxy::$enabled = $proxyState;
}
// if file is encrypted return real file size
if (isset($fileInfo['encrypted']) && $fileInfo['encrypted'] === true) {
// try to fix unencrypted file size if it doesn't look plausible
if ((int) $fileInfo['size'] > 0 && (int) $fileInfo['unencrypted_size'] === 0) {
$fixSize = $util->getFileSize($path);
$fileInfo['unencrypted_size'] = $fixSize;
// put file info if not .part file
if (!Helper::isPartialFilePath($relativePath)) {
$view->putFileInfo($path, array('unencrypted_size' => $fixSize));
}
}
$size = $fileInfo['unencrypted_size'];
} else {
$fileInfoUpdates = array();
$fixSize = $util->getFileSize($path);
if ($fixSize > 0) {
$size = $fixSize;
$fileInfoUpdates['encrypted'] = true;
$fileInfoUpdates['unencrypted_size'] = $size;
// put file info if not .part file
if (!Helper::isPartialFilePath($relativePath)) {
$view->putFileInfo($path, $fileInfoUpdates);
}
}
}
return $size;
}
示例15: start
/**
* @NoAdminRequired
*/
public function start()
{
$request = $this->request;
$response = new JSONResponse();
$params = $this->request->urlParams;
$app = new App($this->api->getUserId());
$addressBook = $app->getAddressBook($params['backend'], $params['addressBookId']);
if (!$addressBook->hasPermission(\OCP\PERMISSION_CREATE)) {
$response->setStatus('403');
$response->bailOut(App::$l10n->t('You do not have permissions to import into this address book.'));
return $response;
}
$filename = isset($request->post['filename']) ? $request->post['filename'] : null;
$progresskey = isset($request->post['progresskey']) ? $request->post['progresskey'] : null;
if (is_null($filename)) {
$response->bailOut(App::$l10n->t('File name missing from request.'));
return $response;
}
if (is_null($progresskey)) {
$response->bailOut(App::$l10n->t('Progress key missing from request.'));
return $response;
}
$filename = strtr($filename, array('/' => '', "\\" => ''));
if (\OC\Files\Filesystem::isFileBlacklisted($filename)) {
$response->bailOut(App::$l10n->t('Attempt to access blacklisted file:') . $filename);
return $response;
}
$view = \OCP\Files::getStorage('contacts');
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$file = $view->file_get_contents('/imports/' . $filename);
\OC_FileProxy::$enabled = $proxyStatus;
$writeProgress = function ($pct) use($progresskey) {
\OC_Cache::set($progresskey, $pct, 300);
};
$cleanup = function () use($view, $filename, $progresskey) {
if (!$view->unlink('/imports/' . $filename)) {
$response->debug('Unable to unlink /imports/' . $filename);
}
\OC_Cache::remove($progresskey);
};
$writeProgress('20');
$nl = "\n";
$file = str_replace(array("\r", "\n\n"), array("\n", "\n"), $file);
$lines = explode($nl, $file);
$inelement = false;
$parts = array();
$card = array();
foreach ($lines as $line) {
if (strtoupper(trim($line)) == 'BEGIN:VCARD') {
$inelement = true;
} elseif (strtoupper(trim($line)) == 'END:VCARD') {
$card[] = $line;
$parts[] = implode($nl, $card);
$card = array();
$inelement = false;
}
if ($inelement === true && trim($line) != '') {
$card[] = $line;
}
}
if (count($parts) === 0) {
$response->bailOut(App::$l10n->t('No contacts found in: ') . $filename);
$cleanup();
return $response;
}
//import the contacts
$imported = 0;
$failed = 0;
$partially = 0;
$processed = 0;
// TODO: Add a new group: "Imported at {date}"
foreach ($parts as $part) {
try {
$vcard = VObject\Reader::read($part);
} catch (VObject\ParseException $e) {
try {
$vcard = VObject\Reader::read($part, VObject\Reader::OPTION_IGNORE_INVALID_LINES);
$partially += 1;
$response->debug('Import: Retrying reading card. Error parsing VCard: ' . $e->getMessage());
} catch (\Exception $e) {
$failed += 1;
$response->debug('Import: skipping card. Error parsing VCard: ' . $e->getMessage());
continue;
// Ditch cards that can't be parsed by Sabre.
}
}
try {
$vcard->validate(MyVCard::REPAIR | MyVCard::UPGRADE);
} catch (\Exception $e) {
\OCP\Util::writeLog('contacts', __METHOD__ . ' ' . 'Error validating vcard: ' . $e->getMessage(), \OCP\Util::ERROR);
$failed += 1;
}
/**
* TODO
* - Check if a contact with identical UID exists.
* - If so, fetch that contact and call $contact->mergeFromVCard($vcard);
//.........这里部分代码省略.........