// // Open Service Platform // Copyright (c) 2012 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /** * @file InstallerUtil.cpp * @brief This is the implementation file for %InstallerUtil class. */ #include #include #include #include #include #include #include #include #include #include "InstallerDefs.h" #include "InstallerUtil.h" #include using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::App; using namespace Tizen::Io; InstallerUtil::InstallerUtil(void) { } InstallerUtil::~InstallerUtil(void) { } bool InstallerUtil::Remove(const Tizen::Base::String& filePath) { int err = -1; result r = E_SUCCESS; struct stat fileinfo; AppLogTag(OSP_INSTALLER, "+ Remove(): path=[%ls]", filePath.GetPointer()); std::unique_ptr pFilePath(_StringConverter::CopyToCharArrayN(filePath)); TryReturn(pFilePath, false, "[osp-installer] pFilePath is null"); err = lstat(pFilePath.get(), &fileinfo); if (err < 0) { AppLogTag(OSP_INSTALLER, "Remove(): lstat(%s): %s[errno:%d]: skip", pFilePath.get(), strerror(errno), errno); return true; } if (S_ISLNK(fileinfo.st_mode)) { AppLogTag(OSP_INSTALLER, "Remove(): symlink, path=[%s]", pFilePath.get()); err = unlink(pFilePath.get()); TryReturn(err >= 0, false, "[osp-installer] unlink() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get()); } else if (S_ISDIR(fileinfo.st_mode)) { AppLogTag(OSP_INSTALLER, "Remove(): directory, path=[%ls]", filePath.GetPointer()); r = Directory::Remove(filePath, true); TryReturn(!IsFailed(r), false, "[osp-installer] Directory::Remove() failed, filePath=%ls", filePath.GetPointer()); } else { AppLogTag(OSP_INSTALLER, "Remove(): file, path=[%ls]", filePath.GetPointer()); r = File::Remove(filePath); TryReturn(!IsFailed(r), false, "[osp-installer] File::Remove() failed, filePath=%ls", filePath.GetPointer()); } return true; } bool InstallerUtil::Copy(const String& srcFilePath, const String& destFilePath) { const int bufSize = 4096; int readBytes = 0; result r = E_SUCCESS; AppLogTag(OSP_INSTALLER, "+ Copy(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer()); File srcFile; File destFile; std::unique_ptr pBuf(new char[bufSize]); TryReturn(pBuf, false, "[osp-installer] pBuf is null"); r = srcFile.Construct(srcFilePath, L"r"); TryReturn(!IsFailed(r), false, "[osp-installer] srcFile.Construct is failed"); r = destFile.Construct(destFilePath, L"w"); TryReturn(!IsFailed(r), false, "[osp-installer] destFile.Construct is failed"); do { readBytes = srcFile.Read(pBuf.get(), bufSize); if (readBytes > 0) { r = destFile.Write(pBuf.get(), readBytes); TryReturn(!IsFailed(r), false, "[osp-installer] destFile.Write is failed"); } } while (readBytes > 0); return true; } bool InstallerUtil::CopyDirectory(const String& srcFilePath, const String& destFilePath) { result r = E_SUCCESS; AppLogTag(OSP_INSTALLER, "+ CopyDirectory(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer()); std::unique_ptr pDir(new Directory); TryReturn(pDir, false, "[osp-installer] pDir is null."); r = pDir->Construct(srcFilePath); TryReturn(!IsFailed(r), false, "[osp-installer] pDir->Construct() failed, srcFilePath=[%ls].", srcFilePath.GetPointer()); std::unique_ptr pDirEnum(pDir->ReadN()); TryReturn(pDirEnum, false, "[osp-installer] pDirEnum is null."); while (pDirEnum->MoveNext() == E_SUCCESS) { DirEntry entry = pDirEnum->GetCurrentDirEntry(); String entryName = entry.GetName(); String srcEntryDir = srcFilePath; srcEntryDir += L"/"; srcEntryDir += entryName; if (entryName == L"." || entryName == L"..") { continue; } // if file or directory is symbolic link, skip this. if (InstallerUtil::IsSymlink(srcEntryDir) == true) { continue; } String destEntryDir = destFilePath; destEntryDir += L"/"; destEntryDir += entryName; if (entry.IsDirectory() == false) { // file Directory::Create(destFilePath, true); InstallerUtil::Copy(srcEntryDir, destEntryDir); } else { Directory::Create(destEntryDir, true); CopyDirectory(srcEntryDir, destEntryDir); } } return true; } bool InstallerUtil::IsSymlink(const Tizen::Base::String& filePath) { int err = -1; struct stat fileinfo; std::unique_ptr pFilePath(_StringConverter::CopyToCharArrayN(filePath)); TryReturn(pFilePath, false, "[osp-installer] pFilePath is null"); err = lstat(pFilePath.get(), &fileinfo); TryReturn(err >= 0, false, "[osp-installer] lstat() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get()); if (S_ISLNK(fileinfo.st_mode)) { return true; } return false; } bool InstallerUtil::GetRealPath(const String& filePath, String& realPath) { char* pRealPath = null; AppLogTag(OSP_INSTALLER, "+ GetRealPath(): path=[%ls], realPath=[%ls]", filePath.GetPointer(), realPath.GetPointer()); std::unique_ptr pFilePath(_StringConverter::CopyToCharArrayN(filePath)); TryReturn(pFilePath, false, "[osp-installer] pFilePath is null"); char tmpPath[PATH_MAX] = {0}; pRealPath = realpath(pFilePath.get(), tmpPath); TryReturn(pRealPath, false, "[osp-installer] pRealPath is null"); realPath = tmpPath; return true; } bool InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath) { int err = -1; bool res = false; AppLogTag(OSP_INSTALLER, "+ CreateSymlink(): oldPath=[%ls], newPath=[%ls]", oldPath.GetPointer(), newPath.GetPointer()); res = File::IsFileExist(oldPath); TryReturn(res == true, false, "[osp-installer] file not found, oldPath=[%ls]", oldPath.GetPointer()); std::unique_ptr pOldPath(_StringConverter::CopyToCharArrayN(oldPath)); TryReturn(pOldPath, false, "[osp-installer] pOldPath is null"); std::unique_ptr pNewPath(_StringConverter::CopyToCharArrayN(newPath)); TryReturn(pNewPath, false, "[osp-installer] pNewPath is null"); err = symlink(pOldPath.get(), pNewPath.get()); TryReturn(err == 0, false, "[osp-installer] symlink() is failed(%s), oldpath=[%s], newpath=[%s]", strerror(errno), pOldPath.get(), pNewPath.get()); AppLogTag(OSP_INSTALLER, "CreateSymlink(): [%ls] -> [%ls]", newPath.GetPointer(), oldPath.GetPointer()); return true; } bool InstallerUtil::ChangeMode(const String& filePath, int mode) { int err = -1; std::unique_ptr pFilePath(_StringConverter::CopyToCharArrayN(filePath)); TryReturn(pFilePath, false, "[osp-installer] pFilePath is null"); err = chmod(pFilePath.get(), mode); TryReturn(err == 0, false, "[osp-installer] chmod() is failed(%s), filepath=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode); return true; } bool InstallerUtil::ChangeOwner(const String& filePath) { int err = -1; std::unique_ptr pFilePath(_StringConverter::CopyToCharArrayN(filePath)); TryReturn(pFilePath, false, "[osp-installer] pFilePath is null"); err = chown(pFilePath.get(), APP_OWNER_ID, APP_GROUP_ID); TryReturn(err == 0, false, "[osp-installer] chown() is failed(%s), filepath=[%s]", strerror(errno), pFilePath.get()); return true; } bool InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode) { result r = E_SUCCESS; bool res = false; AppLogTag(OSP_INSTALLER, "+ ChangeDirectoryPermission(): path=[%ls], mode=[%04o]", filePath.GetPointer(), mode); res = File::IsFileExist(filePath); if (res == false) { AppLogTag(OSP_INSTALLER, "ChangeDirectoryPermission(): path=[%ls]: skip", filePath.GetPointer()); return true; } std::unique_ptr pDir(new Directory); TryReturn(pDir, false, "[osp-installer] pDir is null."); r = pDir->Construct(filePath); TryReturn(!IsFailed(r), false, "[osp-installer] pDir->Construct() failed, filePath=[%ls]", filePath.GetPointer()); std::unique_ptr pDirEnum(pDir->ReadN()); TryReturn(pDirEnum, false, "[osp-installer] pDirEnum is null."); while (pDirEnum->MoveNext() == E_SUCCESS) { DirEntry entry = pDirEnum->GetCurrentDirEntry(); String entryName = entry.GetName(); String entryDir = filePath; entryDir += L"/"; entryDir += entryName; if (entryName == L".") { InstallerUtil::ChangeOwner(entryDir); InstallerUtil::ChangeMode(entryDir, mode); continue; } else if (entryName == L"..") { continue; } if (entry.IsDirectory() == false) { InstallerUtil::ChangeOwner(entryDir); InstallerUtil::ChangeMode(entryDir, mode); } else { ChangeDirectoryPermission(entryDir, mode); InstallerUtil::ChangeMode(entryDir, mode); } } return true; } bool InstallerUtil::IsDrmFile(const Tizen::Base::String& path) { bool res = true; char* pFilePath = null; result r = E_SUCCESS; int isDrm = 0; pFilePath = _StringConverter::CopyToCharArrayN(path); TryCatch(pFilePath, r = GetLastResult(), "[osp-installer] pFilePath is null"); isDrm = drm_oem_intel_isDrmFile(pFilePath); if(isDrm == 1) { AppLogTag(OSP_INSTALLER, "IsDrmFile() called, packagePath=%ls is drm file", path.GetPointer()); } else { res = false; AppLogTag(OSP_INSTALLER, "IsDrmFile() called, packagePath=%ls isn't drm file", path.GetPointer()); } CATCH: delete [] pFilePath; return res; } bool InstallerUtil::DecryptPackage(const Tizen::Base::String& packagePath) { bool res = true; char* pFilePath = null; result r = E_SUCCESS; int result = 0; pFilePath = _StringConverter::CopyToCharArrayN(packagePath); TryCatch(pFilePath, r = GetLastResult(), "[osp-installer] pFilePath is null"); result = drm_oem_intel_decrypt_package(pFilePath, pFilePath); if(result == 1) { AppLogTag(OSP_INSTALLER, "DecryptPackage() called, packagePath=%ls, decrpyt success", packagePath.GetPointer()); } else { AppLogTag(OSP_INSTALLER, "DecryptPackage() called, packagePath=%ls, decrypt failed", packagePath.GetPointer()); res = false; } CATCH: delete [] pFilePath; return res; } String InstallerUtil::GetCategory(int categoryType) { String category; if (categoryType == CATEGORY_TYPE_IME) { category = L"Ime"; } else if (categoryType == CATEGORY_TYPE_HOME_SCREEN) { category = L"home-screen"; } else if (categoryType == CATEGORY_TYPE_LOCK_SCREEN) { category = L"lock-screen"; } return category; } CategoryType InstallerUtil::GetCategoryType(char* pCategory) { CategoryType category = CATEGORY_TYPE_NONE; if (strcasecmp(pCategory, "Ime") == 0) { category = CATEGORY_TYPE_IME; } else if (strcasecmp(pCategory, "home-screen") == 0) { category = CATEGORY_TYPE_HOME_SCREEN; } else if (strcasecmp(pCategory, "lock-screen") == 0) { category = CATEGORY_TYPE_LOCK_SCREEN; } return category; } bool InstallerUtil::CreateSymlinkForAppDirectory(const String& inPath, String& outPath) { String appId; AppLogTag(OSP_INSTALLER, "+ CreateSymlinkForAppDirectory(): path=[%ls]", inPath.GetPointer()); int length = inPath.GetLength(); inPath.SubString(length - APPID_LENGTH, APPID_LENGTH, appId); String newPath; newPath = PATH_OPT_APPS; newPath += L"/"; newPath += appId; if (inPath != newPath) { InstallerUtil::CreateSymlink(inPath, newPath); } outPath = newPath; AppLogTag(OSP_INSTALLER, "CreateSymlinkForAppDirectory(): output path=[%ls]", outPath.GetPointer()); return true; } bool InstallerUtil::DumpLog(const char* pBuf) { char temp[4096] = {0}; TryReturn(pBuf, false, "[osp-installer] pBuf is null"); int bufLen = strlen(pBuf); strncpy(temp, pBuf, sizeof(temp)); char *pStart = &temp[0]; for (int i = 0; i < bufLen; i++) { if (temp[i] == '\n') { temp[i] = 0; AppLogTag(OSP_INSTALLER, "%s", pStart); pStart = temp + i + 1; } } return true; } #define LOG_PRINT_LINE_MAX 20 #define LOG_BUFFER_COUNT_MAX 4096 bool InstallerUtil::DumpLogData(char *pData, int dataLen) { const char *szData = (const char*)pData; char ch = 0; int i = 0, j = 0, idx = 0, idx2 = 0, high = 0, low = 0, temp = 0; char buf[LOG_PRINT_LINE_MAX + 2] = {0}; char buf2[(LOG_PRINT_LINE_MAX + 2) * 3] = {0}; char buf_out[sizeof(buf) + sizeof(buf2) + 1] = {0}; if (dataLen > LOG_BUFFER_COUNT_MAX) { dataLen = LOG_BUFFER_COUNT_MAX; } // 16 characters by 20 line are proper. // too many logs decrease performance. // if (dataLen > 16*20) // dataLen = 16*20; AppLogTag(OSP_INSTALLER, "------------------------------------------"); while (i < (int)dataLen) { ch = szData[i]; /* make ascii table */ if (ch >= 32 && ch <= 128) { buf[idx++] = ch; } else buf[idx++] = '.'; // make binary table high = (ch & 0xf0)>>4; low = ch & 0x0f; buf2[idx2++] = LogChangeHexToStr(high); buf2[idx2++] = LogChangeHexToStr(low); buf2[idx2++] = ' '; if (idx >= LOG_PRINT_LINE_MAX) { memcpy(buf_out, buf2, idx2); buf_out[idx2++] = ' '; buf_out[idx2++] = ' '; memcpy(buf_out + idx2, buf, idx); buf_out[idx2+idx] = '\0'; idx = 0; idx2 = 0; AppLogTag(OSP_INSTALLER, "%s\n", buf_out); } i++; } // last line if (idx > 0) { memcpy(buf_out, buf2, idx2); temp = idx2; for (j = 0; j < (LOG_PRINT_LINE_MAX * 3) - temp; j++) { buf_out[idx2++] = ' '; } buf_out[idx2++] = ' '; buf_out[idx2++] = ' '; memcpy(buf_out+idx2, buf, idx); buf_out[idx2+idx] = '\0'; AppLogTag(OSP_INSTALLER, "%s\n", buf_out); } AppLogTag(OSP_INSTALLER, "------------------------------------------"); return TRUE; } char InstallerUtil::LogChangeHexToStr(int hex) { char ch = '0'; const static char hexValues[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0}; if (hex >= 0 && hex <= 0x0F) { ch = hexValues[hex]; } else { AppLogTag(OSP_INSTALLER, "LogChangeHexToStr: Error! [Hex Val: %d]\n", hex); } return ch; }