2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FIo_FileImpl.cpp
20 * @brief This is the implementation file for %_FileImpl class.
27 #include <sys/types.h>
28 #include <sys/mount.h>
32 #include <unique_ptr.h>
34 #include <FBaseSysLog.h>
35 #include <FAppPkgPackageInfo.h>
36 #include <FIoDirectory.h>
39 #include <FSysEnvironment.h>
41 #include <FBase_StringConverter.h>
42 #include <FApp_AppInfo.h>
43 #include <FAppPkg_PackageInfoImpl.h>
44 #include <FSys_EnvironmentImpl.h>
46 #include "FIo_FileImpl.h"
47 #include "FIo_NormalFile.h"
48 #include "FIo_DirectoryImpl.h"
49 #include "FIo_SecureFile.h"
50 #include "FIo_SecureIoUtil.h"
51 #include "FIo_IFileCore.h"
52 #include "FIo_FileUtil.h"
55 using namespace Tizen::Base;
56 using namespace Tizen::App;
57 using namespace Tizen::System;
59 namespace Tizen { namespace Io
62 static const int _MAX_PATH_LENGTH = 128;
63 static const int _APP_UID = 5000;
64 static const size_t _MAX_FILE_OPENMODE_LENGTH = 3;
65 static const char _INTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/internal";
66 static const char _EXTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/external";
70 char path[_MAX_PATH_LENGTH];
72 bool appPrivilege; // false: root privilege
77 char srcPath[_MAX_PATH_LENGTH];
78 char destPath[_MAX_PATH_LENGTH];
83 char destPath[_MAX_PATH_LENGTH];
86 _FileImpl::_FileImpl(void)
95 _FileImpl::~_FileImpl(void)
100 _FileImpl::_FileImpl(const _FileImpl& fileImpl)
107 SysAssertf(false, "_FileImpl class does not support copy constructor.\n");
111 _FileImpl::operator =(const _FileImpl& fileImpl)
113 SysAssertf(false, "_FileImpl class does not support '=' operator.\n");
115 if (&fileImpl == this)
124 _FileImpl::VerifyFileOpenMode(const char* pOpenMode)
126 if (pOpenMode == null)
128 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode is null.");
132 if (strlen(pOpenMode) > _MAX_FILE_OPENMODE_LENGTH)
134 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
138 switch (pOpenMode[0])
152 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
156 switch (pOpenMode[1])
161 if (pOpenMode[2] == '\0' || pOpenMode[2] == 'b')
169 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
173 if (pOpenMode[2] == '\0')
177 else if (pOpenMode[2] == '+')
185 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
189 SysLog(NID_IO, "[E_INVALID_ARG] The specified openMode (%s) is invalid.", pOpenMode);
197 _FileImpl::Construct(const String& filePath, const String& openMode, bool createParentDirsToo, const ByteBuffer* pSecretKey)
199 SysAssertf(__pCore == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
200 result r = E_SUCCESS;
202 if (openMode.Contains(L'r') == true)
204 SysTryReturnResult(NID_IO, !createParentDirsToo, E_INVALID_ARG,
205 "The specified createParentDirsToo cannot be used without file creation mode.");
208 if (createParentDirsToo == true)
213 r = filePath.LastIndexOf(L'/', filePath.GetLength() - 1, position);
214 SysTryReturnResult(NID_IO, r != E_OBJ_NOT_FOUND, E_INVALID_ARG, "The specified filePath is invalid.");
215 SysTryReturnResult(NID_IO, !(position == 0), E_INVALID_ARG, "The specified filePath is invalid.");
217 r = filePath.SubString(0, position, dirPath);
218 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Failed to extract dir path.", GetErrorMessage(r));
220 r = Directory::Create(dirPath, true);
223 if (r == E_FILE_ALREADY_EXIST)
229 SysPropagate(NID_IO, r);
235 unique_ptr<char[]> pOpenMode(_StringConverter::CopyToCharArrayN(openMode));
236 SysTryReturnResult(NID_IO, pOpenMode != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
238 return Construct(filePath, pOpenMode.get(), pSecretKey);
242 _FileImpl::Construct(const String& filePath, const char* pOpenMode, const ByteBuffer* pSecretKey)
244 SysAssertf(__pCore == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
245 result r = E_SUCCESS;
247 bool isValidOpenMode = VerifyFileOpenMode(pOpenMode);
248 SysTryReturnResult(NID_IO, isValidOpenMode == true, E_INVALID_ARG, "The specified openMode is invalid. (%s)", pOpenMode);
250 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
251 E_INVALID_ARG, " [%ls] is not compatible.", filePath.GetPointer());
253 if (!__truncate && IsFileExist(filePath))
255 r = _SecureIoUtil::CheckSecureFileHeader(filePath, pSecretKey);
256 if (r == E_END_OF_FILE)
258 r = E_IO; //for security error
260 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] Propagated.", GetErrorMessage(r));
263 if (pSecretKey == null)
265 unique_ptr<_NormalFile> pNormalFile(new (std::nothrow) _NormalFile());
266 SysTryReturnResult(NID_IO, pNormalFile, E_OUT_OF_MEMORY, "The memory is insufficient.");
268 r = pNormalFile->Construct(filePath, pOpenMode);
269 SysTryReturn(NID_IO, !IsFailed(r), r , r, "[%s] Propagated.", GetErrorMessage(r));
270 __pCore = pNormalFile.release();
274 unique_ptr<_SecureFile> pSecureFile(new (std::nothrow) _SecureFile(__read, __write, __truncate, __append));
275 SysTryReturnResult(NID_IO, pSecureFile, E_OUT_OF_MEMORY, "The memory is insufficient.");
277 r = pSecureFile->Construct(filePath, pOpenMode, pSecretKey);
278 SysTryReturn(NID_IO, !IsFailed(r), r , r, "[%s] Propagated.", GetErrorMessage(r));
279 __pCore = pSecureFile.release();
286 _FileImpl::ReadN(char** buffer, int& length)
288 result r = E_SUCCESS;
291 _NormalFile* pNormalFile = dynamic_cast< _NormalFile* > (__pCore);
292 if (pNormalFile != null)
294 r = pNormalFile->ReadN(buffer, length);
299 r = E_INVALID_OPERATION;
306 _FileImpl::Read(ByteBuffer& buffer)
308 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
309 SysTryReturnResult(NID_IO, __read == true, E_ILLEGAL_ACCESS, "File is not opened for reading.");
310 return __pCore->Read(buffer);
314 _FileImpl::Read(void* buffer, int length)
316 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
317 SysTryReturn(NID_IO, __read == true, 0, E_ILLEGAL_ACCESS, "[E_ILLEGAL_ACCESS] File is not opened for reading.");
318 return __pCore->Read(buffer, length);
322 _FileImpl::Read(String& buffer)
324 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
325 SysTryReturnResult(NID_IO, __read == true, E_ILLEGAL_ACCESS, "File is not opened for reading.");
326 return __pCore->Read(buffer);
330 _FileImpl::Write(const ByteBuffer& buffer)
332 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
333 SysTryReturnResult(NID_IO, __write == true, E_ILLEGAL_ACCESS, "File is not opened for writing.");
334 return __pCore->Write(buffer);
338 _FileImpl::Write(const void* buffer, int length)
340 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
341 SysTryReturnResult(NID_IO, __write == true, E_ILLEGAL_ACCESS, "File is not opened for writing.");
342 return __pCore->Write(buffer, length);
346 _FileImpl::Write(const String& buffer)
348 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
349 SysTryReturnResult(NID_IO, __write == true, E_ILLEGAL_ACCESS, "File is not opened for writing.");
350 return __pCore->Write(buffer);
354 _FileImpl::Flush(void)
356 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
357 return __pCore->Flush();
361 _FileImpl::Tell(void) const
363 SysTryReturnResult(NID_IO, __pCore != null, -1, "File is not constructed! Construct destined file first! ");
364 return __pCore->Tell();
368 _FileImpl::Seek(FileSeekPosition position, long offset)
370 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
371 return __pCore->Seek(position, offset);
375 _FileImpl::Truncate(int length)
377 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
378 SysTryReturnResult(NID_IO, __write == true, E_ILLEGAL_ACCESS, "File is not opened for writing.");
379 return __pCore->Truncate(length);
383 _FileImpl::GetName(void) const
385 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
386 return __pCore->GetName();
390 _FileImpl::GetFilePointer(void) const
392 SysAssertf(__pCore != null, "Not yet constructed. Construct() should be called before use.\n");
393 return __pCore->GetFilePointer();
397 _FileImpl::Remove(const String& filePath)
399 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
400 E_INVALID_ARG, " [%ls] is not compatible.", filePath.GetPointer());
401 return _FileUtil::Remove(filePath);
405 _FileImpl::Move(const String& oldFilePath, const String& newFilePath)
407 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(oldFilePath, _AppInfo::IsOspCompat()) == true,
408 E_INVALID_ARG, " [%ls] is not compatible.", oldFilePath.GetPointer());
410 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(newFilePath, _AppInfo::IsOspCompat()) == true,
411 E_INVALID_ARG, " [%ls] is not compatible.", newFilePath.GetPointer());
412 return _FileUtil::Move(oldFilePath, newFilePath);
416 _FileImpl::Copy(const String& srcFilePath, const String& destFilePath, bool failIfExist)
418 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(srcFilePath, _AppInfo::IsOspCompat()) == true,
419 E_INVALID_ARG, " [%ls] is not compatible.", srcFilePath.GetPointer());
421 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(destFilePath, _AppInfo::IsOspCompat()) == true,
422 E_INVALID_ARG, " [%ls] is not compatible.", destFilePath.GetPointer());
423 return _FileUtil::Copy(srcFilePath, destFilePath, failIfExist);
427 _FileImpl::GetAttributes(const String& filePath, FileAttributes& attribute)
429 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
430 E_INVALID_ARG, " [%ls] is not compatible.", filePath.GetPointer());
431 return _FileUtil::GetAttributes(filePath, attribute);
435 _FileImpl::GetFileName(const String& filePath)
438 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true, fileName, E_INVALID_ARG,
439 "[E_INVALID_ARG] The length of the specified filePath (%ls) is zero or exceeds system limitations.",
440 filePath.GetPointer());
442 return _FileUtil::GetFileName(filePath);
446 _FileImpl::GetFileExtension(const String& filePath)
449 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true, extName, E_INVALID_ARG,
450 "[E_INVALID_ARG] The length of the specified filePath (%ls) is zero or exceeds system limitations.",
451 filePath.GetPointer());
453 return _FileUtil::GetFileExtension(filePath);
457 _FileImpl::IsFileExist(const String& filePath)
459 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
460 false, E_INVALID_ARG, "[E_INVALID_ARG] The specified filePath (%ls) is invalid.", filePath.GetPointer());
462 return _FileUtil::IsFileExist(filePath);
466 _FileImpl::ConvertToSecureFile(const String& plainFilePath, const String& secureFilePath,
467 const ByteBuffer& key)
469 return _FileUtil::ConvertToSecureFile(plainFilePath, secureFilePath, &key);
473 _FileImpl::IsAppPath(const String& filePath)
475 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
476 false, E_INVALID_ARG, "[E_INVALID_ARG] The specified filePath (%ls) is invalid.", filePath.GetPointer());
478 return _FileUtil::IsAppPath(filePath);
482 _FileImpl::IsMediaPath(const String& filePath)
484 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
485 false, E_INVALID_ARG, "[E_INVALID_ARG] The specified filePath (%ls) is invalid.", filePath.GetPointer());
487 return _FileUtil::IsMediaPath(filePath);
491 _FileImpl::IsSystemPath(const String& filePath)
493 SysTryReturn(NID_IO, VerifyFilePathCompatibility(filePath, _AppInfo::IsOspCompat()) == true,
494 false, E_INVALID_ARG, "[E_INVALID_ARG] The specified filePath (%ls) is invalid.", filePath.GetPointer());
496 return _FileUtil::IsSystemPath(filePath);
500 _FileImpl::VerifyFilePath(const String& filePath, _FilePathType pathType)
502 return _FileUtil::VerifyFilePath(filePath, pathType);
506 _FileImpl::CleanDirectories(const String& appRootPath, const String& pkgId)
508 char removeCmd[PATH_MAX] = {0, };
511 String ospSharePkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
512 ospSharePkgIdPath.Append(L"share/");
513 ospSharePkgIdPath.Append(pkgId);
515 String ospShare2PkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
516 ospShare2PkgIdPath.Append(L"share2/");
517 ospShare2PkgIdPath.Append(pkgId);
520 r = Directory::Remove(ospSharePkgIdPath, true);
521 SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
522 GetErrorMessage(r), ospSharePkgIdPath.GetPointer());
524 r = Directory::Remove(ospShare2PkgIdPath, true);
525 SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
526 GetErrorMessage(r), ospShare2PkgIdPath.GetPointer());
528 sprintf(removeCmd, "rm -rf %ls", ospSharePkgIdPath.GetPointer());
529 ret = system(removeCmd);
530 SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
531 ospSharePkgIdPath.GetPointer());
533 memset(removeCmd, 0, PATH_MAX);
535 sprintf(removeCmd, "rm -rf %ls", ospShare2PkgIdPath.GetPointer());
536 ret = system(removeCmd);
537 SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
538 ospShare2PkgIdPath.GetPointer());
544 // This method is called by package installer backend.
546 _FileImpl::PrepareDataCaging(const String& appRootPath, const String& pkgId)
550 bool internalInstalled = true;
551 result r = E_SUCCESS;
553 SysLog(NID_IO, "[data_caging] PrepareDataCaging() was called by installer backend, appRootPath: %ls, packageId: %ls",
554 appRootPath.GetPointer(), pkgId.GetPointer());
556 if (CleanDirectories(appRootPath, pkgId) == false)
558 SysLog(NID_IO, "CleanDirectories() failed.");
562 pCwd = get_current_dir_name();
563 SysTryCatch(NID_IO, pCwd != null, r = E_SYSTEM, E_SYSTEM,
564 "[E_SYSTEM] get_current_dir_name() was failed, errno: %d (%s).", errno, strerror(errno));
566 // Check whether package is installed on internal storage or not
567 r = appRootPath.IndexOf("/opt/storage/sdcard", 0, index);
570 internalInstalled = false;
574 internalInstalled = true;
579 if (internalInstalled == true)
581 unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
582 SysTryCatch(NID_IO, pAppRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
584 SysTryCatch(NID_IO, chdir(pAppRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
585 "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppRootPath.get());
587 SysTryCatch(NID_IO, CreateOspInternalDirectories(pkgId) == true, r = E_SYSTEM, E_SYSTEM,
588 "[E_SYSTEM] fail to create OSP Internal directories");
592 String appExRootPath(appRootPath);
596 appExRootPath.Append(pkgId);
597 unique_ptr<char[]> pAppExRootPath(_StringConverter::CopyToCharArrayN(appExRootPath));
598 SysTryCatch(NID_IO, pAppExRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
600 ret = mkdir(pAppExRootPath.get(), 0705);
601 if (ret == -1 && errno != 17) // EEXIST
603 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
604 strerror(errno), pAppExRootPath.get(), 0705);
608 SysTryCatch(NID_IO, chdir(pAppExRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
609 "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppExRootPath.get());
610 SysTryCatch(NID_IO, CreateOspExternalDirectories(pkgId) == true, r = E_SYSTEM, E_SYSTEM,
611 "[E_SYSTEM] fail to create OSP External directories");
614 SysTryCatch(NID_IO, CreateSlpDirectories() == true, r = E_SYSTEM, E_SYSTEM,
615 "[E_SYSTEM] fail to create SLP directories");
616 SysTryCatch(NID_IO, CreateSymbolicLink() == true, r = E_SYSTEM, E_SYSTEM,
617 "[E_SYSTEM] Fail to create symbolic link.");
618 SysTryCatch(NID_IO, chdir(pCwd) == 0, r = E_SYSTEM, E_SYSTEM,
619 "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pCwd);
622 SysLog(NID_IO, "[data_caging] PrepareDataCaging() succeeded.");
635 SysLog(NID_IO, "[data_caging] PrepareDataCaging() failed.");
643 _FileImpl::FinalizeDataCaging(const String& appRootPath) // for 2.0 app
645 static const struct _PathInfo mountPath[] =
656 //{ "./lost+found" },
660 { "./opt/var/kdb/db" },
661 { "./opt/storage/sdcard" },
667 { "./sys/kernel/debug" },
684 { "./Storagecard/Media" },
687 { "./HomeExt/Share" },
688 { "./HomeExt/Share2" },
692 unique_ptr< char[] > pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
693 SysTryReturn(NID_IO, pAppRootPath != null, false, E_OUT_OF_MEMORY,
694 "[E_OUT_OF_MEMORY] The memory is insufficient.");
696 SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
697 "[E_SYSTEM] chdir() failed (%d, %s), path: %ls", errno, strerror(errno), appRootPath.GetPointer());
699 for (int i = 0; i < sizeof(mountPath) / sizeof(struct _PathInfo); ++i)
701 int ret = umount2(mountPath[i].destPath, MNT_DETACH);
702 SysTryLog(NID_IO, ret == 0, "umount2() errno: %d (%s)", errno, strerror(errno));
703 SysTryReturn(NID_IO, ret == 0 || errno == EINVAL || errno == ENOENT, false, E_SYSTEM,
704 "[E_SYSTEM] umount2() failed (%d, %s), path: %s", errno, strerror(errno), mountPath[i].destPath);
707 char* pkgId = strrchr(pAppRootPath.get(), '/');
708 char mountFlag[_MAX_PATH_LENGTH] = { 0, };
709 sprintf(mountFlag, "%s/%s", _INTERNAL_MOUNT_FLAG, ++pkgId);
710 int res = unlink(mountFlag);
711 if (res == -1 && errno != ENOENT)
713 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
714 mountFlag, errno, strerror(errno));
718 memset(mountFlag, 0, _MAX_PATH_LENGTH);
719 sprintf(mountFlag, "%s/%s", _EXTERNAL_MOUNT_FLAG, pkgId);
720 res = unlink(mountFlag);
721 if (res == -1 && errno != ENOENT)
723 SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
724 mountFlag, errno, strerror(errno));
728 SysLog(NID_IO, "[data_caging] FinalizeDataCaging() succeeded, appRootPath: %ls", appRootPath.GetPointer());
733 _FileImpl::GetAvailableUid(void)
739 _FileImpl::CreateOspApplicationDirectories(const String& appRootPath, const String& pkgId) // for 2.1 app
741 struct _OspDir appSubDir[] =
743 { "./shared\0", 0755, false },
744 //{ "./shared/data\0", 0755, true },
745 { "./shared/res\0", 0755, false },
746 { "./shared/trusted\0", 0755, true },
747 //{ "./cache\0", 0700, true }
752 result r = E_SUCCESS;
754 SysTryReturn(NID_IO, CleanDirectories(appRootPath, pkgId) == true, false, E_SYSTEM,
755 "[E_SYSTEM] Failed to clean directories for 2.0 application compatibility.");
757 unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
758 SysTryReturn(NID_IO, pAppRootPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
760 SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
761 "[E_SYSTEM] chdir() failed (%d, %s), path: %s", errno, strerror(errno), pAppRootPath.get());
763 uid = GetAvailableUid();
767 for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); ++i)
769 ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
770 if (ret == -1 && errno != 17) // EEXIST
772 SysLog(NID_IO, "[E_SYSTEM] mkdir() failed (%d, %s), path: %s, mode: 0%o",
773 errno, strerror(errno), appSubDir[i].path, appSubDir[i].mode);
777 if (appSubDir[i].appPrivilege)
779 ret = chown(appSubDir[i].path, uid, uid);
780 SysTryCatch(NID_IO, ret == 0, , E_SYSTEM,
781 "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: %d",
782 errno, strerror(errno), appSubDir[i].path, uid);
786 if (access("./shared/data", F_OK) == 0)
788 SysTryCatch(NID_IO, system("chown -R 5000:5000 ./shared/data") != -1, , E_SYSTEM,
789 "[E_SYSTEM] chown() failed");
791 // XXX: Temp code for supporting old share directory.
792 else if (access("./share", F_OK) == 0)
794 SysTryCatch(NID_IO, system("rm -rf ./shared/data") != -1, , E_SYSTEM,
795 "[E_SYSTEM] Failed to remove ./shared/data directory");
797 SysTryCatch(NID_IO, rename("./share", "./shared/data") == 0, , E_SYSTEM,
798 "[E_SYSTEM] Failed to rename share directory (%d, %s)", errno, strerror(errno));
800 SysTryCatch(NID_IO, system("chown -R 5000:5000 ./shared/data") != -1, , E_SYSTEM,
801 "[E_SYSTEM] chown() failed");
803 SysTryCatch(NID_IO, chmod("./shared/data", 0755) == 0, , E_SYSTEM, "[E_SYSTEM] chmod() failed");
809 SysLog(NID_IO, "_FileImpl::CreateOspApplicationDirectories() succeeded.");
819 _FileImpl::CreateOspInternalDirectories(const String& pkgId) // for 2.0 app
824 struct _OspDir appSubDir[] =
826 // { "./data", 0700, true }, // It is created by installer.
827 { "./shared", 0755, false },
828 { "./data/Share", 0000, true }, // mount from /opt/usr/share/.osp-compat/share/{pkgId}
829 { "./data/Share2", 0000, true }, // mount from /opt/usr/share/.osp-compat/share2/{pkgId}
830 { "./Share", 0000, false }, // mount from /opt/usr/share/.osp-compat/share
831 { "./Share2", 0000, false }, // mount from /opt/usr/share/.osp-compat/share2
832 // { "./Clipboard", 0000, false },
833 // { "./NPKI", 0000, false },
834 // { "./System", 0000, false },
835 // { "./Tmp", 0000, false },
836 { "./Media", 0000, false }, // mount from /opt/usr/media
837 { "./Storagecard", 0705, false },
838 { "./Storagecard/Media", 0000, false }, // mount from /opt/storage/sdcard
841 struct _OspDir mediaDir[] =
843 { "/opt/usr/media/Images", 0777, false },
844 { "/opt/usr/media/Sounds", 0777, false },
845 { "/opt/usr/media/Videos", 0777, false },
846 //{ "/opt/usr/media/Themes", 0777, false },
847 { "/opt/usr/media/Others", 0777, false }
850 String ospCompatSharedPath = _EnvironmentImpl::GetOspCompatSharedPath();
851 String ospShareAppIdPath(L"share/");
852 String ospShare2AppIdPath(L"share2/");
853 result r = E_SUCCESS;
855 r = ospShareAppIdPath.Insert(ospCompatSharedPath, 0);
856 SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
857 "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
859 r = ospShare2AppIdPath.Insert(ospCompatSharedPath, 0);
860 SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
861 "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
863 uid = GetAvailableUid();
865 for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
867 ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
868 if (ret == -1 && errno != 17) // EEXIST
870 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
871 strerror(errno), appSubDir[i].path, appSubDir[i].mode);
874 if (appSubDir[i].appPrivilege)
876 ret = chown(appSubDir[i].path, uid, uid);
879 SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
880 strerror(errno), appSubDir[i].path, uid);
886 ospShareAppIdPath.Append(pkgId);
887 unique_ptr<char[]> pOspShareAppIdPath(_StringConverter::CopyToCharArrayN(ospShareAppIdPath));
888 SysTryReturn(NID_IO, pOspShareAppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
889 ret = mkdir(pOspShareAppIdPath.get(), 0705);
890 if (ret == -1 && errno != 17) // EEXIST
892 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
893 strerror(errno), pOspShareAppIdPath.get(), 0705);
896 ret = chown(pOspShareAppIdPath.get(), uid, uid);
899 SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
900 strerror(errno), pOspShareAppIdPath.get(), uid);
904 ospShare2AppIdPath.Append(pkgId);
905 unique_ptr<char[]> pOspShare2AppIdPath(_StringConverter::CopyToCharArrayN(ospShare2AppIdPath));
906 SysTryReturn(NID_IO, pOspShare2AppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
907 ret = mkdir(pOspShare2AppIdPath.get(), 0705); // TODO: change to 0770
908 if (ret == -1 && errno != 17) // EEXIST
910 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
911 strerror(errno), pOspShare2AppIdPath.get(), 0705);
914 ret = chown(pOspShare2AppIdPath.get(), uid, uid);
917 SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
918 strerror(errno), pOspShare2AppIdPath.get(), uid);
923 for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); ++i)
925 ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
926 if (ret == -1 && errno != 17) // EEXIST
928 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
929 strerror(errno), mediaDir[i].path, mediaDir[i].mode);
932 ret = chown(mediaDir[i].path, 5000, 5000);
933 SysTryReturn(NID_IO, ret == 0, false, E_SYSTEM,
934 "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: 5000, gid: 5000",
935 errno, strerror(errno), mediaDir[i].path);
939 // XXX: shared directory is not supported for 2.0 applications
941 if (access("./shared/data", F_OK) == 0)
943 char copyCmd[256] = { 0, };
944 sprintf(copyCmd, "cp -rf ./shared/data/* /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
945 ret = system(copyCmd);
946 SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to copy command (%s)", copyCmd);
948 SysTryReturn(NID_IO, system("rm -rf ./shared/data") != -1, false, E_SYSTEM,
949 "[E_SYSTEM] rmdir() failed, path: ./shared/data");
951 char chownCmd[256] = { 0, };
952 sprintf(chownCmd, "chown -R 5000:5000 /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
953 SysTryReturn(NID_IO, system(chownCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] chown() failed");
955 char symlinkCmd[256] = { 0, };
956 sprintf(symlinkCmd, "ln -s %s ./shared/data", pOspShareAppIdPath.get());
957 SysTryReturn(NID_IO, system(symlinkCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] symlink() failed");
960 char symlinkCmd[256] = { 0, };
961 sprintf(symlinkCmd, "ln -s %s ./shared/data", pOspShareAppIdPath.get());
962 SysTryReturn(NID_IO, system(symlinkCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] symlink() failed");
967 // TODO: Need to test this method.
969 _FileImpl::CreateOspExternalDirectories(const String& pkgId)
974 struct _OspDir appSubDir[] = { // virtual path
975 // { "./data", 0700, true },
976 { "./System", 0000, false }, // mount from /opt/apps/com.samsung.osp/system
977 { "./Storagecard", 0705, false },
978 { "./Storagecard/Media", 0000, false } // mount from /opt/storage/sdcard
981 struct _OspDir mediaDir[] = { // physical path
982 { "/opt/usr/media/Images", 0777, false },
983 { "/opt/usr/media/Sounds", 0777, false },
984 { "/opt/usr/media/Videos", 0777, false },
985 //{ "/opt/usr/media/Themes", 0777, false },
986 { "/opt/usr/media/Others", 0777, false }
990 for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
992 ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
993 if (ret == -1 && errno != 17) // EEXIST
995 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
996 strerror(errno), appSubDir[i].path, appSubDir[i].mode);
999 if (appSubDir[i].appPrivilege)
1001 ret = chown(appSubDir[i].path, uid, uid);
1004 SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
1005 strerror(errno), appSubDir[i].path, uid);
1012 for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); i++)
1014 ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
1015 if (ret == -1 && errno != 17) // EEXIST
1017 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
1018 strerror(errno), mediaDir[i].path, mediaDir[i].mode);
1028 _FileImpl::CreateSlpDirectories(void)
1032 struct _OspDir slpDir[] = { // virtual path
1033 //{ "./bin", 0000, false }, // mount from /bin
1034 //{ "./boot", 0000, false },
1035 //{ "./cache", 0000, false },
1036 { "./csa", 0000, false },
1037 { "./dev", 0000, false },
1038 { "./etc", 0000, false },
1039 { "./lib", 0000, false },
1040 //{ "./lost+found", 0000, false },
1041 { "./media", 0000, false },
1042 { "./mnt", 0000, false },
1043 { "./opt", 0000, false },
1044 //{ "./packaging", 0000, false },
1045 { "./proc", 0000, false },
1046 { "./sbin", 0000, false },
1047 { "./srv", 0000, false },
1048 { "./sys", 0000, false },
1049 { "./tmp", 0000, false },
1050 { "./usr", 0000, false },
1051 { "./var", 0000, false }
1054 for (i = 0; i < sizeof(slpDir) / sizeof(struct _OspDir); i++)
1056 ret = mkdir(slpDir[i].path, slpDir[i].mode);
1057 if (ret == -1 && errno != 17) // EEXIST
1059 SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
1060 strerror(errno), slpDir[i].path, slpDir[i].mode);
1069 _FileImpl::CreateSymbolicLink(void)
1071 struct _LinkDir linkDirList[] = {
1072 { "/opt/home", "./home" },
1073 { "/opt/home/root", "./root" },
1074 { "/mnt/mmc", "./sdcard" }
1077 for (unsigned int i = 0; i < sizeof(linkDirList) / sizeof(struct _LinkDir); ++i)
1079 int ret = symlink(linkDirList[i].srcPath, linkDirList[i].destPath);
1080 if (ret == -1 && errno != 17) // EEXIST
1082 SysLog(NID_IO, "Failed to create symbolic link, errno: %d (%s), src path: %s, dest path: %s",
1083 strerror(errno), linkDirList[i].srcPath, linkDirList[i].destPath);
1092 _FileImpl::VerifyFilePathCompatibility(const String& filePath, bool ospCompat)
1094 if (ospCompat == true)
1096 if (filePath[0] != L'/')
1101 int length = filePath.GetLength();
1110 _FileImpl::GetInstance(File& file)
1112 return file.__pFileImpl;
1116 _FileImpl::GetInstance(const File& file)
1118 return file.__pFileImpl;
1122 _FileImpl::ConvertVirtualToPhysicalPath(const String& virtualPath, String& physicalPath) // for 2.0 app
1124 SysTryReturnResult(NID_IO, VerifyFilePathCompatibility(virtualPath, _AppInfo::IsOspCompat()) == true,
1125 E_INVALID_ARG, "[E_INVALID_ARG] %ls is not compatible.", virtualPath.GetPointer());
1127 const wchar_t* virtualPathPrefix[] =
1134 L"/Share/AppControl",
1141 L"/Storagecard/Media",
1142 //L"/Storagecard/NPKI",
1144 result r = E_SUCCESS;
1145 int count = sizeof(virtualPathPrefix)/sizeof(wchar_t*);
1148 for (i = 0; i < count; i++)
1150 SysLog(NID_IO, "[V2P] i: %d, path: %ls", i, virtualPathPrefix[i]);
1151 if (virtualPath.StartsWith(virtualPathPrefix[i], 0) == true)
1156 SysTryReturnResult(NID_IO, i != count, E_INVALID_ARG, "The path (%ls) is not matched.",
1157 virtualPath.GetPointer());
1159 int prefixLen = String(virtualPathPrefix[i]).GetLength();
1160 if (virtualPath.GetLength() > prefixLen)
1164 r = virtualPath.GetCharAt(prefixLen, ch);
1165 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] The path (%ls) is not matched.",
1166 GetErrorMessage(r), virtualPath.GetPointer());
1170 physicalPath.Clear();
1171 SysLog(NID_IO, "[E_INVALID_ARG] The path (%ls) is not matched.",
1172 virtualPath.GetPointer());
1174 return E_INVALID_ARG;
1179 virtualPath.SubString(wcslen(virtualPathPrefix[i]), subPath);
1181 Tizen::App::App* pApp = Tizen::App::App::GetInstance();
1182 SysTryReturnResult(NID_IO, pApp != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1183 String homePath = pApp->GetAppRootPath();
1184 String ospCompatSharedPath = _EnvironmentImpl::GetOspCompatSharedPath();
1189 physicalPath = homePath + L"data/Share2";
1192 physicalPath = homePath + L"data/Share";
1195 physicalPath = homePath + L"data";
1198 physicalPath = homePath + L"res";
1201 physicalPath = ospCompatSharedPath + L"share2";
1204 physicalPath = ospCompatSharedPath + L"share/AppControl";
1207 physicalPath = ospCompatSharedPath + L"share";
1210 physicalPath = Tizen::System::Environment::GetMediaPath();
1213 physicalPath = Tizen::System::Environment::GetExternalStoragePath() + L"Media";
1216 SysLog(NID_IO, "[E_INVALID_ARG] The path (%ls) is not matched.",
1217 virtualPath.GetPointer());
1218 return E_INVALID_ARG;
1221 if (subPath.IsEmpty() == false)
1223 physicalPath.Append(subPath);
1230 _FileImpl::ConvertPhysicalToVirtualPath(const String& physicalPath, String& virtualPath) // for 2.0 app
1232 result r = E_SUCCESS;
1233 const wchar_t* homeSubDir[] = {
1239 const wchar_t* ospHomeSubDir[] = {
1241 L"/share/AppControl",
1245 int homeSubDirCount = sizeof(homeSubDir)/sizeof(wchar_t*);
1246 int ospHomeSubDirCount = sizeof(ospHomeSubDir)/sizeof(wchar_t*);
1250 SysLog(NID_IO, "[P2V] physicalPath: %ls", physicalPath.GetPointer());
1252 Tizen::App::App* pApp = Tizen::App::App::GetInstance();
1253 SysTryReturnResult(NID_IO, pApp != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
1254 String homePath = pApp->GetAppRootPath();
1255 homePath.SetLength(homePath.GetLength() - 1);
1257 String ospCompatSharedPath = _EnvironmentImpl::GetOspCompatSharedPath();
1258 ospCompatSharedPath.SetLength(ospCompatSharedPath.GetLength() - 1);
1260 String mediaPath = Tizen::System::Environment::GetMediaPath();
1261 mediaPath.SetLength(mediaPath.GetLength() - 1);
1263 String externalPath = Tizen::System::Environment::GetExternalStoragePath();
1264 externalPath.SetLength(externalPath.GetLength() - 1);
1266 if (physicalPath.StartsWith(homePath, 0) == true)
1268 physicalPath.SubString(homePath.GetLength(), subPath);
1270 for (i = 0; i < homeSubDirCount; i++)
1272 SysLog(NID_IO, "[P2V] i: %d, path: %ls", i, homeSubDir[i]);
1273 if (subPath.StartsWith(homeSubDir[i], 0) == true)
1278 SysTryReturnResult(NID_IO, i != homeSubDirCount, E_INVALID_ARG, "The path (%ls) is not matched.",
1279 physicalPath.GetPointer());
1281 baseDirLen = homePath.GetLength() + String(homeSubDir[i]).GetLength();
1286 virtualPath = L"/Home/Share2";
1289 virtualPath = L"/Home/Share";
1292 virtualPath = L"/Home";
1295 virtualPath = L"/Res";
1302 else if (physicalPath.StartsWith(ospCompatSharedPath, 0) == true)
1304 physicalPath.SubString(ospCompatSharedPath.GetLength(), subPath);
1306 for (i = 0; i < ospHomeSubDirCount; i++)
1308 SysLog(NID_IO, "[P2V] i: %d, path: %ls", i, ospHomeSubDir[i]);
1309 if (subPath.StartsWith(ospHomeSubDir[i], 0) == true)
1314 SysTryReturnResult(NID_IO, i != ospHomeSubDirCount, E_INVALID_ARG, "The path (%ls) is not matched.",
1315 physicalPath.GetPointer());
1317 baseDirLen = ospCompatSharedPath.GetLength() + String(ospHomeSubDir[i]).GetLength();
1322 virtualPath = L"/Share2";
1325 virtualPath = L"/Share/AppControl";
1328 virtualPath = L"/Share";
1334 else if (physicalPath.StartsWith(mediaPath, 0) == true)
1336 SysLog(NID_IO, "[P2V] media");
1337 virtualPath = L"/Media";
1338 baseDirLen = mediaPath.GetLength();
1340 else if (physicalPath.StartsWith(externalPath, 0) == true)
1342 SysLog(NID_IO, "[P2V] external media");
1343 virtualPath = L"/Storagecard/Media";
1344 baseDirLen = externalPath.GetLength();
1348 SysLog(NID_IO, "[E_INVALID_ARG] The path (%ls) is not matched.",
1349 physicalPath.GetPointer());
1351 return E_INVALID_ARG;
1354 if (physicalPath.GetLength() > baseDirLen)
1358 r = physicalPath.GetCharAt(baseDirLen, ch);
1359 SysTryReturn(NID_IO, !IsFailed(r), r, r, "[%s] The path (%ls) is not matched.",
1360 GetErrorMessage(r), physicalPath.GetPointer());
1364 virtualPath.Clear();
1365 SysLog(NID_IO, "[E_INVALID_ARG] The path (%ls) is not matched.",
1366 physicalPath.GetPointer());
1368 return E_INVALID_ARG;
1373 physicalPath.SubString(baseDirLen, subPath);
1375 if (subPath.IsEmpty() == false)
1377 virtualPath.Append(subPath);