#include <sys/stat.h>
#include <dirent.h>
+#include <dlfcn.h>
#include <errno.h>
#include <unistd.h>
#include <unique_ptr.h>
+#include <vconf.h>
#include <FBaseErrorDefine.h>
#include <FIoFile.h>
#include <FIoDirectory.h>
+#include <FAppPkgPackageAppInfo.h>
+#include <FAppPkgPackageInfo.h>
#include <FBase_StringConverter.h>
+#include <FSecCryptoSha2Hash.h>
+#include <FApp_Aul.h>
+#include <FAppPkg_PackageManagerImpl.h>
+#include <FAppPkg_PackageInfoImpl.h>
+#include <FAppPkg_PackageAppInfoImpl.h>
#include "InstallerDefs.h"
#include "InstallerUtil.h"
using namespace Tizen::Base;
using namespace Tizen::Base::Collection;
+using namespace Tizen::Base::Utility;
using namespace Tizen::App;
+using namespace Tizen::App::Package;
using namespace Tizen::Io;
+using namespace Tizen::Security::Crypto;
InstallerUtil::InstallerUtil(void)
{
if (S_ISLNK(fileinfo.st_mode))
{
- AppLog("Remove(): symlink, path=[%s]", pFilePath.get());
+ AppLog("Remove(): symlink=[%s]", pFilePath.get());
err = unlink(pFilePath.get());
- TryReturn(err >= 0, false, "unlink() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
+ TryReturn(err >= 0, false, "unlink() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
}
else if (S_ISDIR(fileinfo.st_mode))
{
- AppLog("Remove(): directory, path=[%ls]", filePath.GetPointer());
+ AppLog("Remove(): directory=[%ls]", filePath.GetPointer());
r = Directory::Remove(filePath, true);
TryReturn(!IsFailed(r), false, "Directory::Remove() failed, filePath=%ls", filePath.GetPointer());
}
else
{
- AppLog("Remove(): file, path=[%ls]", filePath.GetPointer());
+ AppLog("Remove(): file=[%ls]", filePath.GetPointer());
r = File::Remove(filePath);
TryReturn(!IsFailed(r), false, "File::Remove() failed, filePath=%ls", filePath.GetPointer());
}
TryReturn(pFilePath, false, "pFilePath is null");
err = lstat(pFilePath.get(), &fileinfo);
- TryReturn(err >= 0, false, "lstat() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
+ TryReturn(err >= 0, false, "lstat() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
if (S_ISLNK(fileinfo.st_mode))
{
}
bool
-InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath)
+InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath, bool SmackLabelToRealPath)
{
int err = -1;
bool res = false;
SmackManager smackManager;
String label("_");
- smackManager.AddLabelDir(label, newPath);
+
+ if (SmackLabelToRealPath == true)
+ {
+ smackManager.AddLabelDir(label, newPath);
+ }
+ else
+ {
+ smackManager.AddLabelSymlink(label, newPath);
+ }
AppLog("CreateSymlink(): [%ls] -> [%ls]", newPath.GetPointer(), oldPath.GetPointer());
TryReturn(pFilePath, false, "pFilePath is null");
err = chmod(pFilePath.get(), mode);
- TryReturn(err == 0, false, "chmod() is failed(%s), filepath=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode);
+ TryReturn(err == 0, false, "chmod() is failed(%s), file=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode);
return true;
}
TryReturn(pFilePath, false, "pFilePath is null");
err = chown(pFilePath.get(), APP_OWNER_ID, APP_GROUP_ID);
- TryReturn(err == 0, false, "chown() is failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
+ TryReturn(err == 0, false, "chown() is failed(%s), file=[%s]", strerror(errno), pFilePath.get());
return true;
}
bool
-InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode, bool appOwner)
+InstallerUtil::ChangeDirectoryPermission(const String& file, int mode, bool appOwner)
{
result r = E_SUCCESS;
bool res = false;
- res = File::IsFileExist(filePath);
+ res = File::IsFileExist(file);
if (res == false)
{
- AppLog("path=[%ls]: skip", filePath.GetPointer());
+ AppLog("path=[%ls]: skip", file.GetPointer());
return true;
}
std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
TryReturn(pDir, false, "pDir is null.");
- r = pDir->Construct(filePath);
- TryReturn(!IsFailed(r), false, "pDir->Construct() failed, filePath=[%ls]", filePath.GetPointer());
+ r = pDir->Construct(file);
+ TryReturn(!IsFailed(r), false, "pDir->Construct() failed, file=[%ls]", file.GetPointer());
std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
TryReturn(pDirEnum, false, "pDirEnum is null.");
continue;
}
- String entryDir = filePath;
+ String entryDir = file;
entryDir += L"/";
entryDir += entryName;
}
AppLog("path=[%ls], mode=[%04o], appOwner=[%s]",
- filePath.GetPointer(), mode, appOwner?"true":"false");
+ file.GetPointer(), mode, appOwner?"true":"false");
return true;
}
bool
InstallerUtil::IsDrmFile(const String& path)
{
- return false;
+ int ret = 0;
+ void* pHandle = null;
+ char* pErrorMsg = null;
+ int (*drm_oem_sapps_is_drm_file)(const char* pDcfPath, int dcfPathLen);
+
+ std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
+ TryReturn(pFilePath, false, "pFilePath is null.");
+
+ pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
+ if (!pHandle)
+ {
+ AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
+ return false;
+ }
+
+ drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>(dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
+ pErrorMsg = dlerror();
+ if ((pErrorMsg != null) || (drm_oem_sapps_is_drm_file == null))
+ {
+ AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
+ dlclose(pHandle);
+ return false;
+ }
+
+ AppLog("[drm] drm_oem_sapps_is_drm_file(%s, %d)", pFilePath.get(), strlen(pFilePath.get()));
+ ret = drm_oem_sapps_is_drm_file(pFilePath.get(), strlen(pFilePath.get()));
+ AppLog("[drm] drm_oem_sapps_is_drm_file(), result = [%d]", ret);
+
+ dlclose(pHandle);
+
+ if (ret == 1)
+ {
+ AppLog("file[%ls] is DRM file.", path.GetPointer());
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
bool
-InstallerUtil::DecryptPackage(const String& packagePath)
+InstallerUtil::DecryptPackage(const String& path, const String& decryptedPath)
{
- return true;
+ int ret = 0;
+ void* pHandle = null;
+ char* pErrorMsg = null;
+ int (*drm_oem_sapps_decrypt_package)(const char* pDcfPath, int dcfPathLen, const char* pDecryptedFile, int decryptedFileLen);
+
+ std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
+ TryReturn(pFilePath, false, "pFilePath is null.");
+
+ std::unique_ptr<char[]> pDecryptedPath(_StringConverter::CopyToCharArrayN(decryptedPath));
+ TryReturn(pDecryptedPath, false, "pDecryptedPath is null.");
+
+ pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
+ if (!pHandle)
+ {
+ AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
+ return false;
+ }
+
+ drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int, const char*, int)>(dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
+ pErrorMsg = dlerror();
+ if ((pErrorMsg != null) || (drm_oem_sapps_decrypt_package == null))
+ {
+ AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
+ dlclose(pHandle);
+ return false;
+ }
+
+ AppLog("[drm] drm_oem_sapps_decrypt_package(%s, %d, %s, %d)", pFilePath.get(), strlen(pFilePath.get()), pDecryptedPath.get(), strlen(pDecryptedPath.get()));
+ ret = drm_oem_sapps_decrypt_package(pFilePath.get(), strlen(pFilePath.get()), pDecryptedPath.get(), strlen(pDecryptedPath.get()));
+ AppLog("[drm] drm_oem_sapps_decrypt_package(), result = [%d]", ret);
+
+ dlclose(pHandle);
+
+ if (ret == 1)
+ {
+ AppLog("[%ls] -> [%ls] is decrypted.", path.GetPointer(), decryptedPath.GetPointer());
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
String
bool
InstallerUtil::DumpLog(const char* pBuf)
{
- char temp[4096] = {0};
TryReturn(pBuf, false, "pBuf is null");
+ char temp[4096] = {0};
int bufLen = strlen(pBuf);
- strncpy(temp, pBuf, sizeof(temp));
+ strncpy(temp, pBuf, sizeof(temp)-1);
- char *pStart = &temp[0];
+ char* pStart = &temp[0];
for (int i = 0; i < bufLen; i++)
{
r = file.Write(logs2, length+1);
if (IsFailed(r))
{
+ va_end(args);
return false;
}
+
+ if (pManager->IsHistoryFileLogOn() == true)
+ {
+ File historyLogFile;
+ String historyLogFilePath = pManager->GetHistoryLogFilePath();
+ r = historyLogFile.Construct(historyLogFilePath, "a");
+ if (!IsFailed(r))
+ {
+ r = historyLogFile.Write(logs2, length+1);
+ if (!IsFailed(r))
+ {
+ // success
+ }
+ }
+ }
+
va_end(args);
return true;
bool
InstallerUtil::GetRdsList(const PackageId& packageId, IList* pDeletedList, IList* pAddedList, IList* pModifiedList)
{
+ bool res = true;
FILE* fp = null;
char rdsFilePath[1024] = {0};
char buffer[1024] = {0};
}
std::unique_ptr<String> pStr(new (std::nothrow) String(buffer));
- TryReturn(pStr, false, "pStr is null.");
- TryReturn(pStr->IsEmpty() == false, false, "pStr is empty.");
+ TryCatch(pStr, res = false, "pStr is null.");
+ TryCatch(pStr->IsEmpty() == false, res = false, "pStr is empty.");
pStr->Trim();
AppLog(".rds_delta: line(%03d)=[%ls]", line, pStr->GetPointer());
memset(buffer, 0, sizeof(buffer));
}
- return true;
+CATCH:
+ fclose(fp);
+ return res;
}
const char*
return "Unknown";
}
+bool
+InstallerUtil::GetFileDigest(const String& filePath, String& digestValue)
+{
+ const int bufSize = 64*1024;
+ int readBytes = 0;
+ result r = E_SUCCESS;
+
+ File file;
+ std::unique_ptr<Sha2Hash> pHash(new (std::nothrow) Sha2Hash());
+
+ r = pHash->SetAlgorithm("SHA2/256");
+ TryReturn(!IsFailed(r), false, "pHash->SetAlgorithm() is failed.");
+
+ r = pHash->Initialize();
+ TryReturn(!IsFailed(r), false, "pHash->Initialize() is failed.");
+
+ std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
+ TryReturn(pBuf, false, "pBuf is null");
+
+ r = file.Construct(filePath, L"r");
+ TryReturn(!IsFailed(r), false, "file.Construct() is failed.");
+
+ do
+ {
+ readBytes = file.Read(pBuf.get(), bufSize);
+ AppLog("readBytes for Hash=[%d]", readBytes);
+
+ if (readBytes > 0)
+ {
+ ByteBuffer buffer;
+ r = buffer.Construct((const byte*)pBuf.get(), 0, readBytes, bufSize);
+ TryReturn(!IsFailed(r), false, "buffer.Construct() is failed.");
+
+ r = pHash->Update(buffer);
+ TryReturn(!IsFailed(r), false, "pHash->Update() is failed.");
+ }
+ }
+ while (readBytes > 0);
+
+ std::unique_ptr<ByteBuffer> pResultBuf(pHash->FinalizeN());
+ TryReturn(pResultBuf, false, "pResultBuf is null.");
+
+ r = StringUtil::EncodeToBase64String(*pResultBuf, digestValue);
+ TryReturn(!IsFailed(r), false, "EncodeToBase64String() is failed.");
+
+ return true;
+}
+
+IMap*
+InstallerUtil::ParseN(const String& str, const String& tokenDelimiter)
+{
+ TryReturn(str.IsEmpty() == false, null, "str is empty.");
+ TryReturn(tokenDelimiter.IsEmpty() == false, null, "tokenDelimiter is empty.");
+
+ std::unique_ptr< HashMap > pMap(new (std::nothrow) HashMap);
+ TryReturn(pMap, null, "pMap is null.");
+
+ result r = pMap->Construct();
+ TryReturn(!IsFailed(r), null, "pMap->Construct() is failed.");
+
+ StringTokenizer strTok(str, tokenDelimiter);
+ while(strTok.HasMoreTokens() == true)
+ {
+ String token;
+ r = strTok.GetNextToken(token);
+ TryReturn(!IsFailed(r), null, "strTok.GetNextToken() is failed.");
+
+ AppLog("token = [%ls]", token.GetPointer());
+
+ StringTokenizer infoTok(token, L"=");
+
+ if (infoTok.GetTokenCount() != 2)
+ {
+ AppLog("'=' is not existed.");
+ continue;
+ }
+
+ std::unique_ptr< String > pKey(new (std::nothrow) String);
+ r = infoTok.GetNextToken(*pKey);
+ TryReturn(!IsFailed(r), null, "infoTok.GetNextToken(*pKey) is failed.");
+ AppLog(" - key = [%ls]", pKey->GetPointer());
+
+ std::unique_ptr< String > pValue(new (std::nothrow) String);
+ r = infoTok.GetNextToken(*pValue);
+ TryReturn(!IsFailed(r), null, "infoTok.GetNextToken(*pValue) is failed.");
+ AppLog(" - value = [%ls]", pValue->GetPointer());
+
+ r = pMap->Add(pKey.release(), pValue.release());
+ TryReturn(!IsFailed(r), null, "pMap->Add() is failed.");
+ }
+
+ if (pMap->GetCount() <= 0)
+ {
+ AppLog("pMap->GetCount() is invalid.");
+ return null;
+ }
+
+ return pMap.release();
+}
+
+bool
+InstallerUtil::TerminateApp(const AppId& appId)
+{
+ bool res = true;
+
+ if (_Aul::IsRunning(appId) == true)
+ {
+ AppLog("App(%ls) is running.", appId.GetPointer());
+
+ result r = _Aul::TerminateApplication(appId);
+ TryReturn(r == E_SUCCESS, false, "TerminateApplication() failed. [%ls]", appId.GetPointer());
+
+ for (int j = 0; j < TERMINATE_RETRY_COUNT; j++)
+ {
+ res = _Aul::IsRunning(appId);
+ if (res == false)
+ {
+ AppLog("App(%ls) is terminated.", appId.GetPointer());
+ break;
+ }
+ else
+ {
+ AppLog("App(%ls) is not terminated yet. wait count = [%d]", appId.GetPointer(), j);
+ usleep(100000);
+ }
+ }
+
+ if (res == true)
+ {
+ AppLog("App(%ls) can't be terminated.", appId.GetPointer());
+ return false;
+ }
+ }
+ else
+ {
+ AppLog("App(%ls) is not running.", appId.GetPointer());
+ }
+
+ return true;
+}
+
+bool
+InstallerUtil::TerminateApps(const PackageId& packageId)
+{
+ std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId));
+ TryReturn(pPackageInfo, false, "GetPackageInfoN() failed.");
+
+ _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get());
+ TryReturn(pPackageInfoImpl, false, "GetInstance() failed.");
+
+ std::unique_ptr< IList > pPackageAppList(pPackageInfoImpl->GetPackageAppInfoListN());
+ TryReturn(pPackageAppList, false, "GetPackageAppInfoListN() failed.");
+
+ for (int i = 0; i < pPackageAppList->GetCount(); i++)
+ {
+ PackageAppInfo* pPackageAppInfo = dynamic_cast < PackageAppInfo* >(pPackageAppList->GetAt(i));
+ TryReturn(pPackageAppInfo, false, "pPackageAppList->GetAt(%d) failed.", i);
+
+ AppId appId = pPackageAppInfo->GetAppId();
+ TerminateApp(appId);
+ }
+
+ return true;
+}
+
+bool
+InstallerUtil::IsUninstallable(const PackageId& packageId)
+{
+ bool res = false;
+
+ std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId));
+ TryReturn(pPackageInfo, false, "GetPackageInfoN() failed.");
+
+ _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get());
+ TryReturn(pPackageInfoImpl, false, "GetInstance() failed.");
+
+ res = pPackageInfoImpl->IsUninstallable();
+
+ AppLog("packageId[%ls]: Uninstallable = [%s]", packageId.GetPointer(), res?"true":"false");
+
+ return res;
+}
+
+bool
+InstallerUtil::IsCscPackage(const PackageId& packageId, String& cscInfo)
+{
+ bool res = false;
+ int result = 0;
+ char* pPath = null;
+ pkgmgrinfo_pkginfo_h handle = null;
+
+ std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
+ TryReturn(pPackageId, false, "pPackageId is null.");
+
+ result = pkgmgrinfo_pkginfo_get_pkginfo(pPackageId.get(), &handle);
+ TryReturn(result == PMINFO_R_OK, false, "pkgmgrinfo_pkginfo_get_pkginfo() failed. result=[%d], package=[%s]", result, pPackageId.get());
+
+ result = pkgmgrinfo_pkginfo_get_csc_path(handle, &pPath);
+ TryReturn(result == PMINFO_R_OK, false, "pkgmgrinfo_pkginfo_get_csc_path() failed. result=[%d], package=[%s]", result, pPackageId.get());
+
+ AppLog("csc_path = [%s]", pPath);
+
+ cscInfo = pPath;
+
+ if (cscInfo.IsEmpty() == false)
+ {
+ res = true;
+ AppLog("packageId[%ls]: cscInfo = [%ls]", packageId.GetPointer(), cscInfo.GetPointer());
+ }
+
+ if (handle)
+ {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ }
+
+ return res;
+}
+
+bool
+InstallerUtil::IsDefaultExternalStorage()
+{
+ int res = 0;
+ int storage = 0;
+ int mmcStatus = VCONFKEY_SYSMAN_MMC_REMOVED;
+
+ res = vconf_get_int("db/setting/default_memory/download", &storage);
+ TryReturn(res == 0, false, "vconf_get_int(db/setting/default_memory/download) failed.");
+
+ AppLog("Storage = [%d]", storage);
+
+ if (storage == 1)
+ {
+ res = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus);
+ TryReturn(res == 0, false, "vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
+
+ if ((mmcStatus == VCONFKEY_SYSMAN_MMC_REMOVED) || (mmcStatus == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED))
+ {
+ AppLog("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
+ }
+ else
+ {
+ AppLog("mmcStatus is MMC_MOUNTED.");
+ return true;
+ }
+ }
+
+ return false;
+}