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.
18 * @file InstallerUtil.cpp
19 * @brief This is the implementation file for %InstallerUtil class.
26 #include <unique_ptr.h>
28 #include <FBaseErrorDefine.h>
30 #include <FIoDirectory.h>
31 #include <FBase_StringConverter.h>
33 #include "InstallerDefs.h"
34 #include "InstallerUtil.h"
35 #include "InstallerManager.h"
36 #include "SmackManager.h"
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::App;
41 using namespace Tizen::Io;
43 InstallerUtil::InstallerUtil(void)
47 InstallerUtil::~InstallerUtil(void)
52 InstallerUtil::Remove(const Tizen::Base::String& filePath)
58 std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
59 TryReturn(pFilePath, false, "pFilePath is null");
61 err = lstat(pFilePath.get(), &fileinfo);
64 AppLog("Remove(): [%s] - %s[errno(%d)]: skip", pFilePath.get(), strerror(errno), errno);
68 if (S_ISLNK(fileinfo.st_mode))
70 AppLog("Remove(): symlink, path=[%s]", pFilePath.get());
71 err = unlink(pFilePath.get());
72 TryReturn(err >= 0, false, "unlink() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
74 else if (S_ISDIR(fileinfo.st_mode))
76 AppLog("Remove(): directory, path=[%ls]", filePath.GetPointer());
77 r = Directory::Remove(filePath, true);
78 TryReturn(!IsFailed(r), false, "Directory::Remove() failed, filePath=%ls", filePath.GetPointer());
82 AppLog("Remove(): file, path=[%ls]", filePath.GetPointer());
83 r = File::Remove(filePath);
84 TryReturn(!IsFailed(r), false, "File::Remove() failed, filePath=%ls", filePath.GetPointer());
91 InstallerUtil::Copy(const String& srcFilePath, const String& destFilePath)
97 // AppLog("+ Copy(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
102 std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
103 TryReturn(pBuf, false, "pBuf is null");
105 r = srcFile.Construct(srcFilePath, L"r");
106 TryReturn(!IsFailed(r), false, "srcFile.Construct is failed");
108 r = destFile.Construct(destFilePath, L"w");
109 TryReturn(!IsFailed(r), false, "destFile.Construct is failed");
113 readBytes = srcFile.Read(pBuf.get(), bufSize);
116 r = destFile.Write(pBuf.get(), readBytes);
117 TryReturn(!IsFailed(r), false, "destFile.Write is failed");
120 while (readBytes > 0);
126 InstallerUtil::CopyDirectory(const String& srcFilePath, const String& destFilePath)
128 result r = E_SUCCESS;
131 res = File::IsFileExist(srcFilePath);
134 AppLog("CopyDirectory(): src=[%ls]: skip", srcFilePath.GetPointer());
138 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
139 TryReturn(pDir, false, "pDir is null.");
141 r = pDir->Construct(srcFilePath);
142 TryReturn(!IsFailed(r), false, "pDir->Construct() failed, srcFilePath=[%ls].", srcFilePath.GetPointer());
144 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
145 TryReturn(pDirEnum, false, "pDirEnum is null.");
147 while (pDirEnum->MoveNext() == E_SUCCESS)
149 DirEntry entry = pDirEnum->GetCurrentDirEntry();
151 String entryName = entry.GetName();
152 String srcEntryDir = srcFilePath;
154 srcEntryDir += entryName;
156 if (entryName == L"." || entryName == L"..")
161 // if file or directory is symbolic link, skip this.
162 if (InstallerUtil::IsSymlink(srcEntryDir) == true)
167 String destEntryDir = destFilePath;
168 destEntryDir += L"/";
169 destEntryDir += entryName;
171 if (entry.IsDirectory() == false)
174 Directory::Create(destFilePath, true);
175 InstallerUtil::Copy(srcEntryDir, destEntryDir);
179 Directory::Create(destEntryDir, true);
180 CopyDirectory(srcEntryDir, destEntryDir);
184 AppLog("CopyDirectory(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
189 InstallerUtil::IsSymlink(const Tizen::Base::String& filePath)
192 struct stat fileinfo;
194 std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
195 TryReturn(pFilePath, false, "pFilePath is null");
197 err = lstat(pFilePath.get(), &fileinfo);
198 TryReturn(err >= 0, false, "lstat() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
200 if (S_ISLNK(fileinfo.st_mode))
209 InstallerUtil::GetRealPath(const String& filePath, String& realPath)
211 char* pRealPath = null;
213 std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
214 TryReturn(pFilePath, false, "pFilePath is null");
216 char tmpPath[PATH_MAX] = {0};
217 pRealPath = realpath(pFilePath.get(), tmpPath);
218 TryReturn(pRealPath, false, "pRealPath is null");
222 AppLog("GetRealPath(): path=[%ls], realPath=[%ls]", filePath.GetPointer(), realPath.GetPointer());
228 InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath)
233 res = File::IsFileExist(oldPath);
236 AppLog("CreateSymlink(): oldPath=[%ls] not found", oldPath.GetPointer());
240 std::unique_ptr<char[]> pOldPath(_StringConverter::CopyToCharArrayN(oldPath));
241 TryReturn(pOldPath, false, "pOldPath is null");
243 std::unique_ptr<char[]> pNewPath(_StringConverter::CopyToCharArrayN(newPath));
244 TryReturn(pNewPath, false, "pNewPath is null");
246 err = symlink(pOldPath.get(), pNewPath.get());
247 TryReturn(err == 0, false, "symlink() is failed(%s), oldpath=[%s], newpath=[%s]", strerror(errno), pOldPath.get(), pNewPath.get());
249 SmackManager smackManager;
251 smackManager.AddLabelDir(label, newPath);
253 AppLog("CreateSymlink(): [%ls] -> [%ls]", newPath.GetPointer(), oldPath.GetPointer());
259 InstallerUtil::ChangeMode(const String& filePath, int mode)
263 std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
264 TryReturn(pFilePath, false, "pFilePath is null");
266 err = chmod(pFilePath.get(), mode);
267 TryReturn(err == 0, false, "chmod() is failed(%s), filepath=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode);
273 InstallerUtil::ChangeOwner(const String& filePath)
277 std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
278 TryReturn(pFilePath, false, "pFilePath is null");
280 err = chown(pFilePath.get(), APP_OWNER_ID, APP_GROUP_ID);
281 TryReturn(err == 0, false, "chown() is failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
287 InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode, bool appOwner)
289 result r = E_SUCCESS;
292 res = File::IsFileExist(filePath);
295 AppLog("path=[%ls]: skip", filePath.GetPointer());
299 std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
300 TryReturn(pDir, false, "pDir is null.");
302 r = pDir->Construct(filePath);
303 TryReturn(!IsFailed(r), false, "pDir->Construct() failed, filePath=[%ls]", filePath.GetPointer());
305 std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
306 TryReturn(pDirEnum, false, "pDirEnum is null.");
308 while (pDirEnum->MoveNext() == E_SUCCESS)
310 DirEntry entry = pDirEnum->GetCurrentDirEntry();
311 String entryName = entry.GetName();
312 if (entryName.IsEmpty() == true)
314 AppLog("entryName is empty.", entryName.GetPointer());
318 String entryDir = filePath;
320 entryDir += entryName;
322 if (entryName == L".")
324 if (appOwner == true)
326 InstallerUtil::ChangeOwner(entryDir);
328 InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
331 else if (entryName == L"..")
336 if (entry.IsDirectory() == false)
338 if (appOwner == true)
340 InstallerUtil::ChangeOwner(entryDir);
342 InstallerUtil::ChangeMode(entryDir, mode);
346 ChangeDirectoryPermission(entryDir, mode, appOwner);
347 if (appOwner == true)
349 InstallerUtil::ChangeOwner(entryDir);
351 InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
355 AppLog("path=[%ls], mode=[%04o], appOwner=[%s]",
356 filePath.GetPointer(), mode, appOwner?"true":"false");
362 InstallerUtil::IsDrmFile(const String& path)
368 InstallerUtil::DecryptPackage(const String& packagePath)
374 InstallerUtil::GetCategory(int categoryType)
378 if (categoryType == CATEGORY_TYPE_IME)
382 else if (categoryType == CATEGORY_TYPE_HOME_SCREEN)
384 category = L"home-screen";
386 else if (categoryType == CATEGORY_TYPE_LOCK_SCREEN)
388 category = L"lock-screen";
395 InstallerUtil::GetCategoryType(char* pCategory)
397 CategoryType category = CATEGORY_TYPE_NONE;
399 if (strcasecmp(pCategory, "Ime") == 0)
401 category = CATEGORY_TYPE_IME;
403 else if (strcasecmp(pCategory, "home-screen") == 0)
405 category = CATEGORY_TYPE_HOME_SCREEN;
407 else if (strcasecmp(pCategory, "lock-screen") == 0)
409 category = CATEGORY_TYPE_LOCK_SCREEN;
416 InstallerUtil::CreateSymlinkForAppDirectory(const String& inPath, String& outPath)
420 int length = inPath.GetLength();
421 inPath.SubString(length - PACKAGE_ID_LENGTH, PACKAGE_ID_LENGTH, appId);
424 newPath = PATH_OPT_APPS;
428 if (inPath != newPath)
430 InstallerUtil::CreateSymlink(inPath, newPath);
434 AppLog("CreateSymlinkForAppDirectory(): output path=[%ls]", outPath.GetPointer());
440 InstallerUtil::CreateInfoFile(const String& filePath, const String* pContext)
442 result r = E_SUCCESS;
445 r = file.Construct(filePath, "w");
446 TryReturn(!IsFailed(r), false, "file.Construct() failed, filePath=[%ls]", filePath.GetPointer());
448 AppLog("------------------------------------------");
449 AppLog("CreateInfoFile(), filePath = [%ls]", filePath.GetPointer());
453 r = file.Write(*pContext);
454 TryReturn(!IsFailed(r), false, "file.Write() failed, filePath=[%ls]", filePath.GetPointer());
455 AppLog("string = [%ls]", pContext->GetPointer());
457 AppLog("------------------------------------------");
463 InstallerUtil::DumpLog(const char* pBuf)
465 char temp[4096] = {0};
466 TryReturn(pBuf, false, "pBuf is null");
468 int bufLen = strlen(pBuf);
469 strncpy(temp, pBuf, sizeof(temp));
471 char *pStart = &temp[0];
473 for (int i = 0; i < bufLen; i++)
478 AppLog("%s", pStart);
479 pStart = temp + i + 1;
486 #define LOG_PRINT_LINE_MAX 20
487 #define LOG_BUFFER_COUNT_MAX 4096
489 InstallerUtil::DumpLogData(char *pData, int dataLen)
491 const char *szData = (const char*)pData;
493 int i = 0, j = 0, idx = 0, idx2 = 0, high = 0, low = 0, temp = 0;
495 char buf[LOG_PRINT_LINE_MAX + 2] = {0};
496 char buf2[(LOG_PRINT_LINE_MAX + 2) * 3] = {0};
497 char buf_out[sizeof(buf) + sizeof(buf2) + 1] = {0};
500 if (dataLen > LOG_BUFFER_COUNT_MAX)
502 dataLen = LOG_BUFFER_COUNT_MAX;
505 // 16 characters by 20 line are proper. // too many logs decrease performance.
506 // if (dataLen > 16*20)
509 AppLog("------------------------------------------");
511 while (i < (int)dataLen)
515 /* make ascii table */
516 if (ch >= 32 && ch <= 128)
524 high = (ch & 0xf0)>>4;
527 buf2[idx2++] = LogChangeHexToStr(high);
528 buf2[idx2++] = LogChangeHexToStr(low);
531 if (idx >= LOG_PRINT_LINE_MAX)
533 memcpy(buf_out, buf2, idx2);
535 buf_out[idx2++] = ' ';
536 buf_out[idx2++] = ' ';
538 memcpy(buf_out + idx2, buf, idx);
539 buf_out[idx2+idx] = '\0';
544 AppLog("%s\n", buf_out);
553 memcpy(buf_out, buf2, idx2);
556 for (j = 0; j < (LOG_PRINT_LINE_MAX * 3) - temp; j++)
558 buf_out[idx2++] = ' ';
561 buf_out[idx2++] = ' ';
562 buf_out[idx2++] = ' ';
564 memcpy(buf_out+idx2, buf, idx);
565 buf_out[idx2+idx] = '\0';
567 AppLog("%s\n", buf_out);
570 AppLog("------------------------------------------");
576 InstallerUtil::LogChangeHexToStr(int hex)
580 const static char hexValues[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
583 if (hex >= 0 && hex <= 0x0F)
589 AppLog("LogChangeHexToStr: Error! [Hex Val: %d]\n", hex);
596 InstallerUtil::CreateLog(const String& logFile)
600 result r = file.Construct(logFile, "w");
610 InstallerUtil::AppendLog(const char* pFunction, int lineNumber, bool fatal, const char* pFormat, ...)
614 InstallerManager *pManager = InstallerManager::GetInstance();
615 if (pManager == null)
620 if (pManager->IsFileLogOn() == false)
625 String logFile = pManager->GetLogFilePath();
626 result r = file.Construct(logFile, "a");
633 va_start(args, pFormat);
634 const int bufSize = 1024;
635 char logs[bufSize+1] = {0};
636 char logs2[bufSize+1] = {0};
639 snprintf(logs, bufSize, " | %s (%d). > %s", (char*)pFunction, lineNumber, pFormat);
643 snprintf(logs, bufSize, "[TRY]| %s (%d). > %s", (char*)pFunction, lineNumber, pFormat);
646 vsnprintf(logs2, bufSize, logs, args);
647 int length = strlen(logs2);
648 logs2[length] = '\n';
650 r = file.Write(logs2, length+1);
662 InstallerUtil::PrintLog(const String& logFile)
664 InstallerManager *pManager = InstallerManager::GetInstance();
665 if (pManager == null)
670 if (pManager->IsFileLogOn() == false)
676 FileAttributes attribute;
678 result r = File::GetAttributes(logFile, attribute);
685 std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
691 r = file.Construct(logFile, "r");
700 memset(pBuf.get(), 0, bufSize);
701 readBytes = file.Read(pBuf.get(), bufSize);
704 fprintf(stderr, "%s", pBuf.get());
707 while (readBytes > 0);
713 InstallerUtil::GetRdsList(const PackageId& packageId, IList* pDeletedList, IList* pAddedList, IList* pModifiedList)
717 char rdsFilePath[1024] = {0};
718 char buffer[1024] = {0};
719 InstallerRdsState state = INSTALLER_RDS_STATE_NONE;
721 snprintf(rdsFilePath, sizeof(rdsFilePath), "%s/%ls/%s", DIR_APPLICATIONS_TMP, packageId.GetPointer(), INSTALLER_RDS_FILE_NAME);
723 fp = fopen(rdsFilePath, "r");
724 TryReturn(fp, false, "fp is null.");
725 AppLog(".rds_delta file");
728 while (fgets(buffer, sizeof(buffer), fp) != null)
730 bool isMetadata = false;
732 if (buffer[0] == '#')
734 if (strcasestr(buffer, INSTALLER_RDS_DELETE_STR))
736 state = INSTALLER_RDS_STATE_DELETE;
738 else if (strcasestr(buffer, INSTALLER_RDS_ADD_STR))
740 state = INSTALLER_RDS_STATE_ADD;
742 else if (strcasestr(buffer, INSTALLER_RDS_MODIFY_STR))
744 state = INSTALLER_RDS_STATE_MODIFY;
750 if (state == INSTALLER_RDS_STATE_NONE)
752 AppLog("Unknown RDS State, INSTALLER_RDS_STATE_NONE");
756 std::unique_ptr<String> pStr(new (std::nothrow) String(buffer));
757 TryCatch(pStr, res = false, "pStr is null.");
758 TryCatch(pStr->IsEmpty() == false, res = false, "pStr is empty.");
761 AppLog(".rds_delta: line(%03d)=[%ls]", line, pStr->GetPointer());
764 if (isMetadata == true)
767 if (state == INSTALLER_RDS_STATE_DELETE)
769 pDeletedList->Add(pStr.release());
771 else if (state == INSTALLER_RDS_STATE_ADD)
773 pAddedList->Add(pStr.release());
775 else if (state == INSTALLER_RDS_STATE_MODIFY)
777 pModifiedList->Add(pStr.release());
780 memset(buffer, 0, sizeof(buffer));
789 InstallerUtil::GetInstallerOperationString(int operation)
791 if (operation == INSTALLER_OPERATION_INSTALL)
795 else if (operation == INSTALLER_OPERATION_UNINSTALL)
799 else if (operation == INSTALLER_OPERATION_REINSTALL)