{
static const int _MAX_PATH_LENGTH = 128;
+static const int _APP_UID = 5000;
static const size_t _MAX_FILE_OPENMODE_LENGTH = 3;
static const char _INTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/internal";
static const char _EXTERNAL_MOUNT_FLAG[] = "/tmp/osp-compat/mount/external";
struct _PathInfo
{
- char pathName[_MAX_PATH_LENGTH];
+ char destPath[_MAX_PATH_LENGTH];
};
_FileImpl::_FileImpl(void)
}
bool
+_FileImpl::CleanDirectories(const String& appRootPath, const String& pkgId)
+{
+ char removeCmd[PATH_MAX] = {0, };
+ int ret = 0;
+
+ String ospSharePkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
+ ospSharePkgIdPath.Append(L"share/");
+ ospSharePkgIdPath.Append(pkgId);
+
+ String ospShare2PkgIdPath = _EnvironmentImpl::GetOspCompatSharedPath();
+ ospShare2PkgIdPath.Append(L"share2/");
+ ospShare2PkgIdPath.Append(pkgId);
+
+#if 0
+ r = Directory::Remove(ospSharePkgIdPath, true);
+ SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
+ GetErrorMessage(r), ospSharePkgIdPath.GetPointer());
+
+ r = Directory::Remove(ospShare2PkgIdPath, true);
+ SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM, "[%s] Failed to remove directory (%ls)",
+ GetErrorMessage(r), ospShare2PkgIdPath.GetPointer());
+#else
+ sprintf(removeCmd, "rm -rf %ls", ospSharePkgIdPath.GetPointer());
+ ret = system(removeCmd);
+ SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
+ ospSharePkgIdPath.GetPointer());
+
+ memset(removeCmd, 0, PATH_MAX);
+
+ sprintf(removeCmd, "rm -rf %ls", ospShare2PkgIdPath.GetPointer());
+ ret = system(removeCmd);
+ SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to remove directory (%ls)",
+ ospShare2PkgIdPath.GetPointer());
+#endif
+
+ return true;
+}
+
+// This method is called by package installer backend.
+bool
+_FileImpl::PrepareDataCaging(const String& appRootPath, const String& pkgId)
+{
+ int index = 0;
+ char* pCwd = null;
+ bool internalInstalled = true;
+ result r = E_SUCCESS;
+
+ SysSecureLog(NID_IO, "[data_caging] PrepareDataCaging() was called by installer backend, appRootPath: %ls, packageId: %ls",
+ appRootPath.GetPointer(), pkgId.GetPointer());
+
+ if (CleanDirectories(appRootPath, pkgId) == false)
+ {
+ SysLog(NID_IO, "CleanDirectories() failed.");
+ return false;
+ }
+
+ pCwd = get_current_dir_name();
+ SysTryCatch(NID_IO, pCwd != null, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] get_current_dir_name() was failed, errno: %d (%s).", errno, strerror(errno));
+
+ // Check whether package is installed on internal storage or not
+ r = appRootPath.IndexOf("/opt/storage/sdcard", 0, index);
+ if (r == E_SUCCESS)
+ {
+ internalInstalled = false;
+ }
+ else
+ {
+ internalInstalled = true;
+ }
+
+ umask(0000);
+
+ if (internalInstalled == true)
+ {
+ unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
+ SysTryCatch(NID_IO, pAppRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
+
+ SysTryCatch(NID_IO, chdir(pAppRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppRootPath.get());
+
+ SysTryCatch(NID_IO, CreateOspInternalDirectories(appRootPath, pkgId) == true, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] fail to create OSP Internal directories");
+ }
+ else
+ {
+ String appExRootPath(appRootPath);
+
+ int ret = 0;
+
+ appExRootPath.Append(pkgId);
+ unique_ptr<char[]> pAppExRootPath(_StringConverter::CopyToCharArrayN(appExRootPath));
+ SysTryCatch(NID_IO, pAppExRootPath != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
+
+ ret = mkdir(pAppExRootPath.get(), 0705);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), pAppExRootPath.get(), 0705);
+ goto CATCH;
+ }
+
+ SysTryCatch(NID_IO, chdir(pAppExRootPath.get()) == 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pAppExRootPath.get());
+ SysTryCatch(NID_IO, CreateOspExternalDirectories(pkgId) == true, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] fail to create OSP External directories");
+ }
+
+ SysTryCatch(NID_IO, CreateSlpDirectories() == true, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] fail to create SLP directories");
+ SysTryCatch(NID_IO, CreateSymbolicLink() == true, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] Fail to create symbolic link.");
+ SysTryCatch(NID_IO, chdir(pCwd) == 0, r = E_SYSTEM, E_SYSTEM,
+ "[E_SYSTEM] chdir() was failed (%s), path: %s", strerror(errno), pCwd);
+
+ r = E_SUCCESS;
+ SysLog(NID_IO, "[data_caging] PrepareDataCaging() succeeded.");
+
+ // fall thru
+CATCH:
+ if (pCwd != null)
+ {
+ free(pCwd);
+ }
+
+ umask(0022);
+
+ if (IsFailed(r))
+ {
+ SysLog(NID_IO, "[data_caging] PrepareDataCaging() failed.");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+_FileImpl::FinalizeDataCaging(const String& appRootPath) // for 2.0 app
+{
+ static const struct _PathInfo mountPath[] =
+ {
+ //{ "./bin" },
+ //{ "./boot" },
+ //{ "./cache" },
+ { "./csa" },
+ { "./dev/pts" },
+ { "./dev/shm" },
+ { "./dev" },
+ { "./etc" },
+ { "./lib" },
+ //{ "./lost+found" },
+ { "./media" },
+ { "./mnt" },
+ { "./opt/usr" },
+ { "./opt/var/kdb/db" },
+ { "./opt/storage/sdcard" },
+ { "./opt" },
+ //{ "./packaging" },
+ { "./proc" },
+ { "./sbin" },
+ { "./smack" },
+ { "./srv" },
+ { "./sys/kernel/debug" },
+ { "./sys" },
+ { "./tmp" },
+ { "./usr" },
+ { "./var/run" },
+ { "./var" },
+
+ { "./data/Share" },
+ { "./data/Share2" },
+ { "./Share" },
+ { "./Share2" },
+ //{ "./Clipboard" },
+ //{ "./NPKI" },
+ //{ "./System" },
+ //{ "./Tmp" },
+ { "./Media" },
+
+ { "./Storagecard/Media" },
+ { "./ShareExt" },
+ { "./Share2Ext" },
+ { "./HomeExt/Share" },
+ { "./HomeExt/Share2" },
+ { "./HomeExt" }
+ };
+
+ unique_ptr< char[] > pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
+ SysTryReturn(NID_IO, pAppRootPath != null, false, E_OUT_OF_MEMORY,
+ "[E_OUT_OF_MEMORY] The memory is insufficient.");
+
+ SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
+ "[E_SYSTEM] chdir() failed (%d, %s), path: %ls", errno, strerror(errno), appRootPath.GetPointer());
+
+ for (int i = 0; i < sizeof(mountPath) / sizeof(struct _PathInfo); ++i)
+ {
+ int ret = umount2(mountPath[i].destPath, MNT_DETACH);
+ SysTryLog(NID_IO, ret == 0, "umount2() errno: %d (%s)", errno, strerror(errno));
+ SysTryReturn(NID_IO, ret == 0 || errno == EINVAL || errno == ENOENT, false, E_SYSTEM,
+ "[E_SYSTEM] umount2() failed (%d, %s), path: %s", errno, strerror(errno), mountPath[i].destPath);
+ }
+
+ char* pkgId = strrchr(pAppRootPath.get(), '/');
+ char mountFlag[_MAX_PATH_LENGTH] = { 0, };
+ sprintf(mountFlag, "%s/%s", _INTERNAL_MOUNT_FLAG, ++pkgId);
+ int res = unlink(mountFlag);
+ if (res == -1 && errno != ENOENT)
+ {
+ SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
+ mountFlag, errno, strerror(errno));
+ return false;
+ }
+
+ memset(mountFlag, 0, _MAX_PATH_LENGTH);
+ sprintf(mountFlag, "%s/%s", _EXTERNAL_MOUNT_FLAG, pkgId);
+ res = unlink(mountFlag);
+ if (res == -1 && errno != ENOENT)
+ {
+ SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
+ mountFlag, errno, strerror(errno));
+ return false;
+ }
+
+ SysLog(NID_IO, "[data_caging] FinalizeDataCaging() succeeded, appRootPath: %ls", appRootPath.GetPointer());
+ return true;
+}
+
+int
+_FileImpl::GetAvailableUid(void)
+{
+ return _APP_UID;
+}
+
+bool
+_FileImpl::CreateOspApplicationDirectories(const String& appRootPath, const String& pkgId) // for 2.0 app
+{
+#if 0
+ struct _OspDir appSubDir[] =
+ {
+ //{ "./shared\0", 0755, false },
+ //{ "./shared/data\0", 0755, true },
+ //{ "./shared/res\0", 0755, false },
+ //{ "./shared/trusted\0", 0755, true },
+ //{ "./cache\0", 0700, true }
+ };
+ int uid = -1;
+ int ret = 0;
+ unsigned int i = 0;
+ result r = E_SUCCESS;
+#endif
+
+ SysTryReturn(NID_IO, CleanDirectories(appRootPath, pkgId) == true, false, E_SYSTEM,
+ "[E_SYSTEM] Failed to clean directories for 2.0 application compatibility.");
+
+#if 0
+ unique_ptr<char[]> pAppRootPath(_StringConverter::CopyToCharArrayN(appRootPath));
+ SysTryReturn(NID_IO, pAppRootPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
+
+ SysTryReturn(NID_IO, chdir(pAppRootPath.get()) == 0, false, E_SYSTEM,
+ "[E_SYSTEM] chdir() failed (%d, %s), path: %s", errno, strerror(errno), pAppRootPath.get());
+
+ uid = GetAvailableUid();
+
+ umask(0000);
+
+ for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); ++i)
+ {
+ ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "[E_SYSTEM] mkdir() failed (%d, %s), path: %s, mode: 0%o",
+ errno, strerror(errno), appSubDir[i].path, appSubDir[i].mode);
+ goto CATCH;
+ }
+
+ if (appSubDir[i].appPrivilege)
+ {
+ ret = chown(appSubDir[i].path, uid, uid);
+ SysTryCatch(NID_IO, ret == 0, , E_SYSTEM,
+ "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: %d",
+ errno, strerror(errno), appSubDir[i].path, uid);
+ }
+ }
+
+ umask(0022);
+
+ SysLog(NID_IO, "_FileImpl::CreateOspApplicationDirectories() succeeded.");
+ return true;
+
+CATCH:
+ umask(0022);
+
+ return false;
+#else
+ return true;
+#endif
+
+}
+
+bool
+_FileImpl::CreateOspInternalDirectories(const String& appRootPath, const String& pkgId) // for 2.0 app
+{
+ unsigned int i = 0;
+ int ret = 0;
+ int uid = -1;
+ struct _OspDir appSubDir[] =
+ {
+// { "./data", 0700, true }, // It is created by installer.
+ { "./shared", 0755, false },
+ { "./data/Share", 0000, true }, // mount from /opt/usr/share/.osp-compat/share/{pkgId}
+ { "./data/Share2", 0000, true }, // mount from /opt/usr/share/.osp-compat/share2/{pkgId}
+ { "./Share", 0000, false }, // mount from /opt/usr/share/.osp-compat/share
+ { "./Share2", 0000, false }, // mount from /opt/usr/share/.osp-compat/share2
+// { "./Clipboard", 0000, false },
+// { "./NPKI", 0000, false },
+// { "./System", 0000, false },
+// { "./Tmp", 0000, false },
+ { "./Media", 0000, false }, // mount from /opt/usr/media
+ { "./Storagecard", 0705, false },
+ { "./Storagecard/Media", 0000, false }, // mount from /opt/storage/sdcard
+ };
+#if 1
+ struct _OspDir mediaDir[] =
+ {
+ { "/opt/usr/media/Images", 0777, false },
+ { "/opt/usr/media/Sounds", 0777, false },
+ { "/opt/usr/media/Videos", 0777, false },
+ //{ "/opt/usr/media/Themes", 0777, false },
+ { "/opt/usr/media/Others", 0777, false }
+ };
+#endif
+ String ospCompatSharedPath = _EnvironmentImpl::GetOspCompatSharedPath();
+ String ospShareAppIdPath(L"share/");
+ String ospShare2AppIdPath(L"share2/");
+ result r = E_SUCCESS;
+
+ r = ospShareAppIdPath.Insert(ospCompatSharedPath, 0);
+ SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
+ "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
+
+ r = ospShare2AppIdPath.Insert(ospCompatSharedPath, 0);
+ SysTryReturn(NID_IO, !IsFailed(r), false, E_SYSTEM,
+ "[E_SYSTEM] String::Insert() failed. (error: %s)", GetErrorMessage(r));
+
+ uid = GetAvailableUid();
+
+ for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
+ {
+ ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), appSubDir[i].path, appSubDir[i].mode);
+ return false;
+ }
+ if (appSubDir[i].appPrivilege)
+ {
+ ret = chown(appSubDir[i].path, uid, uid);
+ if (ret == -1)
+ {
+ SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
+ strerror(errno), appSubDir[i].path, uid);
+ return false;
+ }
+ }
+ }
+
+ ospShareAppIdPath.Append(pkgId);
+ unique_ptr<char[]> pOspShareAppIdPath(_StringConverter::CopyToCharArrayN(ospShareAppIdPath));
+ SysTryReturn(NID_IO, pOspShareAppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
+ ret = mkdir(pOspShareAppIdPath.get(), 0705);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), pOspShareAppIdPath.get(), 0705);
+ return false;
+ }
+ ret = chown(pOspShareAppIdPath.get(), uid, uid);
+ if (ret == -1)
+ {
+ SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
+ strerror(errno), pOspShareAppIdPath.get(), uid);
+ return false;
+ }
+
+ ospShare2AppIdPath.Append(pkgId);
+ unique_ptr<char[]> pOspShare2AppIdPath(_StringConverter::CopyToCharArrayN(ospShare2AppIdPath));
+ SysTryReturn(NID_IO, pOspShare2AppIdPath != null, false, E_SYSTEM, "[E_SYSTEM] The memory is insufficient.");
+ ret = mkdir(pOspShare2AppIdPath.get(), 0705); // TODO: change to 0770
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), pOspShare2AppIdPath.get(), 0705);
+ return false;
+ }
+ ret = chown(pOspShare2AppIdPath.get(), uid, uid);
+ if (ret == -1)
+ {
+ SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
+ strerror(errno), pOspShare2AppIdPath.get(), uid);
+ return false;
+ }
+
+#if 1
+ for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); ++i)
+ {
+ ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), mediaDir[i].path, mediaDir[i].mode);
+ return false;
+ }
+ ret = chown(mediaDir[i].path, 5000, 5000);
+ SysTryReturn(NID_IO, ret == 0, false, E_SYSTEM,
+ "[E_SYSTEM] chown() failed (%d, %s), path: %s, uid: 5000, gid: 5000",
+ errno, strerror(errno), mediaDir[i].path);
+ }
+#endif
+
+ // XXX: OSP compatible application's data packed in shared/data, shared/trusted directory of SDK
+ // cannot be delivered.
+#if 0
+ if (access("./shared/data", F_OK) == 0)
+ {
+ char copyCmd[256] = { 0, };
+ sprintf(copyCmd, "cp -rf ./shared/data/* /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
+ ret = system(copyCmd);
+ SysTryReturn(NID_IO, ret != -1, false, E_SYSTEM, "Failed to copy command (%s)", copyCmd);
+
+ SysTryReturn(NID_IO, system("rm -rf ./shared/data") != -1, false, E_SYSTEM,
+ "[E_SYSTEM] rmdir() failed, path: ./shared/data");
+
+ char chownCmd[256] = { 0, };
+ sprintf(chownCmd, "chown -R 5000:5000 /opt/usr/share/.osp-compat/share/%ls/", pkgId.GetPointer());
+ SysTryReturn(NID_IO, system(chownCmd) != -1, false, E_SYSTEM, "[E_SYSTEM] chown() failed");
+ }
+#endif
+ String appSharedDataPath(appRootPath);
+ appSharedDataPath.Append(L"/shared/data");
+
+ String appSharedTrustedPath(appRootPath);
+ appSharedTrustedPath.Append(L"/shared/trusted");
+
+ SysTryReturn(NID_IO, Directory::Remove(appSharedDataPath, true) == E_SUCCESS, false, E_SYSTEM,
+ "[E_SYSTEM] Failed to remove path (%ls)", appSharedDataPath.GetPointer());
+ SysTryReturn(NID_IO, Directory::Remove(appSharedTrustedPath, true) == E_SUCCESS, false, E_SYSTEM,
+ "[E_SYSTEM] Failed to remove path (%ls)", appSharedTrustedPath.GetPointer());
+
+ ret = symlink(pOspShareAppIdPath.get(), "./shared/data");
+ SysTryReturn(NID_IO, ret == 0, false, E_SYSTEM,
+ "[E_SYSTEM] symlink() failed, errno: %d (%s), link: ./shared/data -> %s",
+ errno, strerror(errno), pOspShareAppIdPath.get());
+ ret = symlink(pOspShare2AppIdPath.get(), "./shared/trusted");
+ SysTryReturn(NID_IO, ret == 0, false, E_SYSTEM,
+ "[E_SYSTEM] symlink() failed, errno: %d (%s), link: ./shared/trusted -> %s",
+ errno, strerror(errno), pOspShare2AppIdPath.get());
+
+ return true;
+}
+
+// TODO: Need to test this method.
+bool
+_FileImpl::CreateOspExternalDirectories(const String& pkgId)
+{
+ unsigned int i = 0;
+ int ret = 0;
+ int uid = -1;
+ struct _OspDir appSubDir[] = { // virtual path
+// { "./data", 0700, true },
+ { "./System", 0000, false }, // mount from /opt/apps/com.samsung.osp/system
+ { "./Storagecard", 0705, false },
+ { "./Storagecard/Media", 0000, false } // mount from /opt/storage/sdcard
+ };
+#if 0
+ struct _OspDir mediaDir[] = { // physical path
+ { "/opt/usr/media/Images", 0777, false },
+ { "/opt/usr/media/Sounds", 0777, false },
+ { "/opt/usr/media/Videos", 0777, false },
+ //{ "/opt/usr/media/Themes", 0777, false },
+ { "/opt/usr/media/Others", 0777, false }
+ };
+#endif
+
+ for (i = 0; i < sizeof(appSubDir) / sizeof(struct _OspDir); i++)
+ {
+ ret = mkdir(appSubDir[i].path, appSubDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), appSubDir[i].path, appSubDir[i].mode);
+ return false;
+ }
+ if (appSubDir[i].appPrivilege)
+ {
+ ret = chown(appSubDir[i].path, uid, uid);
+ if (ret == -1)
+ {
+ SysLog(NID_IO, "chown() failed (%s), path: %s, uid: %d",
+ strerror(errno), appSubDir[i].path, uid);
+ return false;
+ }
+ }
+ }
+
+#if 0
+ for (i = 0; i < sizeof(mediaDir) / sizeof(struct _OspDir); i++)
+ {
+ ret = mkdir(mediaDir[i].path, mediaDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), mediaDir[i].path, mediaDir[i].mode);
+ return false;
+ }
+ }
+#endif
+
+ return true;
+}
+
+bool
+_FileImpl::CreateSlpDirectories(void)
+{
+ unsigned int i = 0;
+ int ret = 0;
+ struct _OspDir slpDir[] = { // virtual path
+ //{ "./bin", 0000, false }, // mount from /bin
+ //{ "./boot", 0000, false },
+ //{ "./cache", 0000, false },
+ { "./csa", 0000, false },
+ { "./dev", 0000, false },
+ { "./etc", 0000, false },
+ { "./lib", 0000, false },
+ //{ "./lost+found", 0000, false },
+ { "./media", 0000, false },
+ { "./mnt", 0000, false },
+ { "./opt", 0000, false },
+ //{ "./packaging", 0000, false },
+ { "./proc", 0000, false },
+ { "./sbin", 0000, false },
+ { "./smack", 0000, false },
+ { "./srv", 0000, false },
+ { "./sys", 0000, false },
+ { "./tmp", 0000, false },
+ { "./usr", 0000, false },
+ { "./var", 0000, false }
+ };
+
+ for (i = 0; i < sizeof(slpDir) / sizeof(struct _OspDir); i++)
+ {
+ ret = mkdir(slpDir[i].path, slpDir[i].mode);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "mkdir() failed (%s), path: %s, mode: 0%o",
+ strerror(errno), slpDir[i].path, slpDir[i].mode);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+_FileImpl::CreateSymbolicLink(void)
+{
+ struct _LinkDir linkDirList[] = {
+ { "/opt/home", "./home" },
+ { "/opt/home/root", "./root" },
+ { "/mnt/mmc", "./sdcard" }
+ };
+
+ for (unsigned int i = 0; i < sizeof(linkDirList) / sizeof(struct _LinkDir); ++i)
+ {
+ int ret = symlink(linkDirList[i].srcPath, linkDirList[i].destPath);
+ if (ret == -1 && errno != 17) // EEXIST
+ {
+ SysLog(NID_IO, "Failed to create symbolic link, errno: %d (%s), src path: %s, dest path: %s",
+ strerror(errno), linkDirList[i].srcPath, linkDirList[i].destPath);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
_FileImpl::VerifyFilePathCompatibility(const String& filePath, bool ospCompat)
{
if (ospCompat == true)