Signature configuration on
[platform/framework/native/installer.git] / src / Util / InstallerUtil.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17 /**
18  * @file        InstallerUtil.cpp
19  * @brief       This is the implementation file for %InstallerUtil class.
20  */
21
22 #include <sys/stat.h>
23 #include <dirent.h>
24 #include <dlfcn.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <unique_ptr.h>
28 #include <vconf.h>
29
30 #include <FBaseErrorDefine.h>
31 #include <FIoFile.h>
32 #include <FIoDirectory.h>
33 #include <FIoRegistry.h>
34 #include <FAppPkgPackageAppInfo.h>
35 #include <FAppPkgPackageInfo.h>
36 #include <FBase_StringConverter.h>
37 #include <FSecCryptoSha2Hash.h>
38 #include <FApp_Aul.h>
39 #include <FAppPkg_PackageManagerImpl.h>
40 #include <FAppPkg_PackageInfoImpl.h>
41 #include <FAppPkg_PackageAppInfoImpl.h>
42
43 #include "InstallerDefs.h"
44 #include "InstallerUtil.h"
45 #include "InstallerManager.h"
46 #include "SmackManager.h"
47
48 using namespace Tizen::Base;
49 using namespace Tizen::Base::Collection;
50 using namespace Tizen::Base::Utility;
51 using namespace Tizen::App;
52 using namespace Tizen::App::Package;
53 using namespace Tizen::Io;
54 using namespace Tizen::Security::Crypto;
55
56 InstallerUtil::InstallerUtil(void)
57 {
58 }
59
60 InstallerUtil::~InstallerUtil(void)
61 {
62 }
63
64 bool
65 InstallerUtil::Remove(const Tizen::Base::String& filePath)
66 {
67         int err = -1;
68         result r = E_SUCCESS;
69         struct stat fileinfo;
70
71         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
72         TryReturn(pFilePath, false, "pFilePath is null");
73
74         err = lstat(pFilePath.get(), &fileinfo);
75         if (err < 0)
76         {
77                 AppLog("Remove(): skip, path=[%s][%s](%d)", pFilePath.get(), strerror(errno), errno);
78                 return true;
79         }
80
81         if (S_ISLNK(fileinfo.st_mode))
82         {
83                 AppLog("Remove(): symlink=[%s]", pFilePath.get());
84                 err = unlink(pFilePath.get());
85                 TryReturn(err >= 0, false, "unlink() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
86         }
87         else if (S_ISDIR(fileinfo.st_mode))
88         {
89                 AppLog("Remove(): directory=[%ls]", filePath.GetPointer());
90                 r = Directory::Remove(filePath, true);
91                 TryReturn(!IsFailed(r), false, "Directory::Remove() failed, filePath=%ls", filePath.GetPointer());
92         }
93         else
94         {
95                 AppLog("Remove(): file=[%ls]", filePath.GetPointer());
96                 r = File::Remove(filePath);
97                 TryReturn(!IsFailed(r), false, "File::Remove() failed, filePath=%ls", filePath.GetPointer());
98         }
99
100         return true;
101 }
102
103 bool
104 InstallerUtil::Copy(const String& srcFilePath, const String& destFilePath)
105 {
106         int bufSize = 4096;
107         int readBytes = 0;
108         result r = E_SUCCESS;
109
110         // AppLog("+ Copy(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
111
112         File srcFile;
113         File destFile;
114
115         std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
116         TryReturn(pBuf, false, "pBuf is null");
117
118         r = srcFile.Construct(srcFilePath, L"r");
119         TryReturn(!IsFailed(r), false, "srcFile.Construct is failed");
120
121         r = destFile.Construct(destFilePath, L"w");
122         TryReturn(!IsFailed(r), false, "destFile.Construct is failed");
123
124         do
125         {
126                 readBytes = srcFile.Read(pBuf.get(), bufSize);
127                 if (readBytes > 0)
128                 {
129                         r = destFile.Write(pBuf.get(), readBytes);
130                         TryReturn(!IsFailed(r), false, "destFile.Write is failed");
131                 }
132         }
133         while (readBytes > 0);
134
135         return true;
136 }
137
138 bool
139 InstallerUtil::CopyDirectory(const String& srcFilePath, const String& destFilePath)
140 {
141         result r = E_SUCCESS;
142         bool res = false;
143
144         res = File::IsFileExist(srcFilePath);
145         if (res == false)
146         {
147                 AppLog("CopyDirectory(): src=[%ls]: skip", srcFilePath.GetPointer());
148                 return true;
149         }
150
151         std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
152         TryReturn(pDir, false, "pDir is null.");
153
154         r = pDir->Construct(srcFilePath);
155         TryReturn(!IsFailed(r), false, "pDir->Construct() failed, srcFilePath=[%ls].", srcFilePath.GetPointer());
156
157         std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
158         TryReturn(pDirEnum, false, "pDirEnum is null.");
159
160         while (pDirEnum->MoveNext() == E_SUCCESS)
161         {
162                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
163
164                 String entryName = entry.GetName();
165                 String srcEntryDir = srcFilePath;
166                 srcEntryDir += L"/";
167                 srcEntryDir += entryName;
168
169                 if (entryName == L"." || entryName == L"..")
170                 {
171                         continue;
172                 }
173
174                 // if file or directory is symbolic link, skip this.
175                 if (InstallerUtil::IsSymlink(srcEntryDir) == true)
176                 {
177                         continue;
178                 }
179
180                 String destEntryDir = destFilePath;
181                 destEntryDir += L"/";
182                 destEntryDir += entryName;
183
184                 if (entry.IsDirectory() == false)
185                 {
186                         // file
187                         Directory::Create(destFilePath, true);
188                         InstallerUtil::Copy(srcEntryDir, destEntryDir);
189                 }
190                 else
191                 {
192                         Directory::Create(destEntryDir, true);
193                         CopyDirectory(srcEntryDir, destEntryDir);
194                 }
195         }
196
197         AppLog("CopyDirectory(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
198         return true;
199 }
200
201 bool
202 InstallerUtil::IsSymlink(const Tizen::Base::String& filePath)
203 {
204         int err = -1;
205         struct stat fileinfo;
206
207         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
208         TryReturn(pFilePath, false, "pFilePath is null");
209
210         err = lstat(pFilePath.get(), &fileinfo);
211         TryReturn(err >= 0, false, "lstat() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
212
213         if (S_ISLNK(fileinfo.st_mode))
214         {
215                 return true;
216         }
217
218         return false;
219 }
220
221 bool
222 InstallerUtil::GetRealPath(const String& filePath, String& realPath)
223 {
224         char* pRealPath = null;
225
226         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
227         TryReturn(pFilePath, false, "pFilePath is null");
228
229         char tmpPath[PATH_MAX] = {0};
230         pRealPath = realpath(pFilePath.get(), tmpPath);
231         TryReturn(pRealPath, false, "pRealPath is null");
232
233         realPath = tmpPath;
234
235         AppLog("GetRealPath(): path=[%ls], realPath=[%ls]", filePath.GetPointer(), realPath.GetPointer());
236
237         return true;
238 }
239
240 bool
241 InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath, bool SmackLabelToRealPath)
242 {
243         int err = -1;
244         bool res = false;
245
246         res = File::IsFileExist(oldPath);
247         if (res == false)
248         {
249                 AppLog("CreateSymlink(): oldPath=[%ls] not found.", oldPath.GetPointer());
250                 return true;
251         }
252
253         res = File::IsFileExist(newPath);
254         if (res == true)
255         {
256                 AppLog("CreateSymlink(): newPath=[%ls] is alreay exist.", oldPath.GetPointer());
257                 return true;
258         }
259
260         std::unique_ptr<char[]> pOldPath(_StringConverter::CopyToCharArrayN(oldPath));
261         TryReturn(pOldPath, false, "pOldPath is null");
262
263         std::unique_ptr<char[]> pNewPath(_StringConverter::CopyToCharArrayN(newPath));
264         TryReturn(pNewPath, false, "pNewPath is null");
265
266         err = symlink(pOldPath.get(), pNewPath.get());
267         TryReturn(err == 0, false, "symlink() is failed(%s), oldpath=[%s], newpath=[%s]", strerror(errno), pOldPath.get(), pNewPath.get());
268
269         SmackManager smackManager;
270         String label("_");
271
272         if (SmackLabelToRealPath == true)
273         {
274                 smackManager.AddLabelDir(label, newPath);
275         }
276         else
277         {
278                 smackManager.AddLabelSymlink(label, newPath);
279         }
280
281         AppLog("CreateSymlink(): [%ls] -> [%ls]", newPath.GetPointer(), oldPath.GetPointer());
282
283         return true;
284 }
285
286 bool
287 InstallerUtil::ChangeMode(const String& filePath, int mode)
288 {
289         int err = -1;
290
291         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
292         TryReturn(pFilePath, false, "pFilePath is null");
293
294         err = chmod(pFilePath.get(), mode);
295         TryReturn(err == 0, false, "chmod() is failed(%s), file=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode);
296
297         return true;
298 }
299
300 bool
301 InstallerUtil::ChangeOwner(const String& filePath)
302 {
303         int err = -1;
304
305         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
306         TryReturn(pFilePath, false, "pFilePath is null");
307
308         err = chown(pFilePath.get(), APP_OWNER_ID, APP_GROUP_ID);
309         TryReturn(err == 0, false, "chown() is failed(%s), file=[%s]", strerror(errno), pFilePath.get());
310
311         return true;
312 }
313
314 bool
315 InstallerUtil::ChangeDirectoryPermission(const String& file, int mode, bool appOwner)
316 {
317         result r = E_SUCCESS;
318         bool res = false;
319
320         res = File::IsFileExist(file);
321         if (res == false)
322         {
323                 AppLog("path=[%ls]: skip", file.GetPointer());
324                 return true;
325         }
326
327         std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
328         TryReturn(pDir, false, "pDir is null.");
329
330         r = pDir->Construct(file);
331         TryReturn(!IsFailed(r), false, "pDir->Construct() failed, file=[%ls]", file.GetPointer());
332
333         std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
334         TryReturn(pDirEnum, false, "pDirEnum is null.");
335
336         while (pDirEnum->MoveNext() == E_SUCCESS)
337         {
338                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
339                 String entryName = entry.GetName();
340                 if (entryName.IsEmpty() == true)
341                 {
342                         AppLog("entryName is empty.", entryName.GetPointer());
343                         continue;
344                 }
345
346                 String entryDir = file;
347                 entryDir += L"/";
348                 entryDir += entryName;
349
350                 if (entryName == L".")
351                 {
352                         if (appOwner == true)
353                         {
354                                 InstallerUtil::ChangeOwner(entryDir);
355                         }
356                         InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
357                         continue;
358                 }
359                 else if (entryName == L"..")
360                 {
361                         continue;
362                 }
363
364                 if (entry.IsDirectory() == false)
365                 {
366                         if (appOwner == true)
367                         {
368                                 InstallerUtil::ChangeOwner(entryDir);
369                         }
370                         InstallerUtil::ChangeMode(entryDir, mode);
371                 }
372                 else
373                 {
374                         ChangeDirectoryPermission(entryDir, mode, appOwner);
375                         if (appOwner == true)
376                         {
377                                 InstallerUtil::ChangeOwner(entryDir);
378                         }
379                         InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
380                 }
381         }
382
383         AppLog("path=[%ls], mode=[%04o], appOwner=[%s]",
384                         file.GetPointer(), mode, appOwner?"true":"false");
385
386         return true;
387 }
388
389 bool
390 InstallerUtil::IsDrmFile(const String& path)
391 {
392         int ret = 0;
393         void* pHandle = null;
394         char* pErrorMsg = null;
395         int (*drm_oem_sapps_is_drm_file)(const char* pDcfPath, int dcfPathLen);
396
397         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
398         TryReturn(pFilePath, false, "pFilePath is null.");
399
400         pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
401         if (!pHandle)
402         {
403                 AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
404                 return false;
405         }
406
407         drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>(dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
408         pErrorMsg = dlerror();
409         if ((pErrorMsg != null) || (drm_oem_sapps_is_drm_file == null))
410         {
411                 AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
412                 dlclose(pHandle);
413                 return false;
414         }
415
416         AppLog("[drm] drm_oem_sapps_is_drm_file(%s, %d)", pFilePath.get(), strlen(pFilePath.get()));
417         ret = drm_oem_sapps_is_drm_file(pFilePath.get(), strlen(pFilePath.get()));
418         AppLog("[drm] drm_oem_sapps_is_drm_file(), result = [%d]", ret);
419
420         dlclose(pHandle);
421
422         if (ret == 1)
423         {
424                 AppLog("file[%ls] is DRM file.", path.GetPointer());
425                 return true;
426         }
427         else
428         {
429                 return false;
430         }
431 }
432
433 bool
434 InstallerUtil::DecryptPackage(const String& path, const String& decryptedPath)
435 {
436         int ret = 0;
437         void* pHandle = null;
438         char* pErrorMsg = null;
439         int (*drm_oem_sapps_decrypt_package)(const char* pDcfPath, int dcfPathLen, const char* pDecryptedFile, int decryptedFileLen);
440
441         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
442         TryReturn(pFilePath, false, "pFilePath is null.");
443
444         std::unique_ptr<char[]> pDecryptedPath(_StringConverter::CopyToCharArrayN(decryptedPath));
445         TryReturn(pDecryptedPath, false, "pDecryptedPath is null.");
446
447         pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
448         if (!pHandle)
449         {
450                 AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
451                 return false;
452         }
453
454         drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int, const char*, int)>(dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
455         pErrorMsg = dlerror();
456         if ((pErrorMsg != null) || (drm_oem_sapps_decrypt_package == null))
457         {
458                 AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
459                 dlclose(pHandle);
460                 return false;
461         }
462
463         AppLog("[drm] drm_oem_sapps_decrypt_package(%s, %d, %s, %d)", pFilePath.get(), strlen(pFilePath.get()), pDecryptedPath.get(), strlen(pDecryptedPath.get()));
464         ret = drm_oem_sapps_decrypt_package(pFilePath.get(), strlen(pFilePath.get()), pDecryptedPath.get(), strlen(pDecryptedPath.get()));
465         AppLog("[drm] drm_oem_sapps_decrypt_package(), result = [%d]", ret);
466
467         dlclose(pHandle);
468
469         if (ret == 1)
470         {
471                 AppLog("[%ls] -> [%ls] is decrypted.", path.GetPointer(), decryptedPath.GetPointer());
472                 return true;
473         }
474         else
475         {
476                 return false;
477         }
478 }
479
480 String
481 InstallerUtil::GetCategory(int categoryType)
482 {
483         String category;
484
485         if (categoryType == CATEGORY_TYPE_IME)
486         {
487                 category = L"Ime";
488         }
489         else if (categoryType == CATEGORY_TYPE_HOME_SCREEN)
490         {
491                 category = L"home-screen";
492         }
493         else if (categoryType == CATEGORY_TYPE_LOCK_SCREEN)
494         {
495                 category = L"lock-screen";
496         }
497
498         return category;
499 }
500
501 int
502 InstallerUtil::GetCategoryType(char* pCategory)
503 {
504         CategoryType category = CATEGORY_TYPE_NONE;
505
506         if (strcasecmp(pCategory, "Ime") == 0)
507         {
508                 category = CATEGORY_TYPE_IME;
509         }
510         else if (strcasecmp(pCategory, "home-screen") == 0)
511         {
512                 category = CATEGORY_TYPE_HOME_SCREEN;
513         }
514         else if (strcasecmp(pCategory, "lock-screen") == 0)
515         {
516                 category = CATEGORY_TYPE_LOCK_SCREEN;
517         }
518
519         return category;
520 }
521
522 bool
523 InstallerUtil::CreateSymlinkForAppDirectory(const String& inPath, String& outPath)
524 {
525         String appId;
526
527         int length = inPath.GetLength();
528         inPath.SubString(length - PACKAGE_ID_LENGTH, PACKAGE_ID_LENGTH, appId);
529
530         String newPath;
531         newPath = PATH_OPT_APPS;
532         newPath += L"/";
533         newPath += appId;
534
535         if (inPath != newPath)
536         {
537                 InstallerUtil::CreateSymlink(inPath, newPath);
538         }
539
540         outPath = newPath;
541         AppLog("CreateSymlinkForAppDirectory(): output path=[%ls]", outPath.GetPointer());
542
543         return true;
544 }
545
546 bool
547 InstallerUtil::CreateInfoFile(const String& filePath, const String* pContext)
548 {
549         result r = E_SUCCESS;
550         File file;
551
552         r = file.Construct(filePath, "w");
553         TryReturn(!IsFailed(r), false, "file.Construct() failed, filePath=[%ls]", filePath.GetPointer());
554
555         AppLog("------------------------------------------");
556         AppLog("CreateInfoFile(), filePath = [%ls]", filePath.GetPointer());
557
558         if (pContext)
559         {
560                 r = file.Write(*pContext);
561                 TryReturn(!IsFailed(r), false, "file.Write() failed, filePath=[%ls]", filePath.GetPointer());
562                 AppLog("string = [%ls]", pContext->GetPointer());
563         }
564         AppLog("------------------------------------------");
565
566         return true;
567 }
568
569 bool
570 InstallerUtil::DumpLog(const char* pBuf)
571 {
572         TryReturn(pBuf, false, "pBuf is null");
573
574         char temp[4096] = {0};
575         int bufLen = strlen(pBuf);
576         strncpy(temp, pBuf, sizeof(temp)-1);
577
578         char* pStart = &temp[0];
579
580         for (int i = 0; i < bufLen; i++)
581         {
582                 if (temp[i] == '\n')
583                 {
584                         temp[i] = 0;
585                         AppLog("%s", pStart);
586                         pStart = temp + i + 1;
587                 }
588         }
589
590         return true;
591 }
592
593 #define LOG_PRINT_LINE_MAX 20
594 #define LOG_BUFFER_COUNT_MAX 4096
595 bool
596 InstallerUtil::DumpLogData(char *pData, int dataLen)
597 {
598         const char      *szData = (const char*)pData;
599         char            ch = 0;
600         int                     i = 0, j = 0, idx = 0, idx2 = 0, high = 0, low = 0, temp = 0;
601
602         char            buf[LOG_PRINT_LINE_MAX + 2]                     = {0};
603         char            buf2[(LOG_PRINT_LINE_MAX + 2) * 3]      = {0};
604         char            buf_out[sizeof(buf) + sizeof(buf2) + 1] = {0};
605
606
607         if (dataLen > LOG_BUFFER_COUNT_MAX)
608         {
609                 dataLen = LOG_BUFFER_COUNT_MAX;
610         }
611
612         // 16 characters by 20 line are proper. // too many logs decrease performance.
613 //      if (dataLen > 16*20)
614 //              dataLen = 16*20;
615
616         AppLog("------------------------------------------");
617
618         while (i < (int)dataLen)
619         {
620                 ch      = szData[i];
621
622                 /* make ascii table */
623                 if (ch >= 32 && ch <= 128)
624                 {
625                         buf[idx++]      = ch;
626                 }
627                 else
628                         buf[idx++]      = '.';
629
630                 // make binary table
631                 high = (ch & 0xf0)>>4;
632                 low = ch & 0x0f;
633
634                 buf2[idx2++]    = LogChangeHexToStr(high);
635                 buf2[idx2++]    = LogChangeHexToStr(low);
636                 buf2[idx2++]    = ' ';
637
638                 if (idx >= LOG_PRINT_LINE_MAX)
639                 {
640                         memcpy(buf_out, buf2, idx2);
641
642                         buf_out[idx2++] = ' ';
643                         buf_out[idx2++] = ' ';
644
645                         memcpy(buf_out + idx2, buf, idx);
646                         buf_out[idx2+idx]       = '\0';
647
648                         idx             = 0;
649                         idx2    = 0;
650
651                         AppLog("%s\n", buf_out);
652                 }
653
654                 i++;
655         }
656
657         // last line
658         if (idx > 0)
659         {
660                 memcpy(buf_out, buf2, idx2);
661                 temp    = idx2;
662
663                 for (j = 0; j < (LOG_PRINT_LINE_MAX * 3) - temp; j++)
664                 {
665                         buf_out[idx2++] = ' ';
666                 }
667
668                 buf_out[idx2++] = ' ';
669                 buf_out[idx2++] = ' ';
670
671                 memcpy(buf_out+idx2, buf, idx);
672                 buf_out[idx2+idx]       = '\0';
673
674                 AppLog("%s\n", buf_out);
675         }
676
677         AppLog("------------------------------------------");
678
679         return true;
680 }
681
682 char
683 InstallerUtil::LogChangeHexToStr(int hex)
684 {
685         char ch = '0';
686
687         const static char       hexValues[]     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
688
689
690         if (hex >= 0 && hex <= 0x0F)
691         {
692                 ch      = hexValues[hex];
693         }
694         else
695         {
696                 AppLog("LogChangeHexToStr: Error! [Hex Val: %d]\n", hex);
697         }
698
699         return ch;
700 }
701
702 bool
703 InstallerUtil::CreateLog(const String& logFile)
704 {
705         File file;
706
707         result r = file.Construct(logFile, "w");
708         if (IsFailed(r))
709         {
710                 return false;
711         }
712
713         return true;
714 }
715
716 bool
717 InstallerUtil::AppendLog(const char* pFunction, int lineNumber, bool fatal, const char* pFormat, ...)
718 {
719         File file;
720
721         InstallerManager *pManager = InstallerManager::GetInstance();
722         if (pManager == null)
723         {
724                 return false;
725         }
726
727         if (pManager->IsFileLogOn() == false)
728         {
729                 return true;
730         }
731
732         String logFile = pManager->GetLogFilePath();
733         result r = file.Construct(logFile, "a");
734         if (IsFailed(r))
735         {
736                 return false;
737         }
738
739         va_list args;
740         va_start(args, pFormat);
741         const int bufSize = 1024;
742         char logs[bufSize+1] = {0};
743         char logs2[bufSize+1] = {0};
744         if (fatal == false)
745         {
746                 snprintf(logs, bufSize, "     | %s (%d). > %s", (char*)pFunction, lineNumber, pFormat);
747         }
748         else
749         {
750                 snprintf(logs, bufSize, "[TRY]| %s (%d). > %s", (char*)pFunction, lineNumber, pFormat);
751         }
752
753         vsnprintf(logs2, bufSize, logs, args);
754         int length = strlen(logs2);
755         logs2[length] = '\n';
756
757         r = file.Write(logs2, length+1);
758         if (IsFailed(r))
759         {
760                 va_end(args);
761                 return false;
762         }
763
764         if (pManager->IsHistoryFileLogOn() == true)
765         {
766                 File historyLogFile;
767                 String historyLogFilePath = pManager->GetHistoryLogFilePath();
768                 r = historyLogFile.Construct(historyLogFilePath, "a");
769                 if (!IsFailed(r))
770                 {
771                         r = historyLogFile.Write(logs2, length+1);
772                         if (!IsFailed(r))
773                         {
774                                 // success
775                         }
776                 }
777         }
778
779         va_end(args);
780
781         return true;
782 }
783
784 bool
785 InstallerUtil::PrintLog(const String& logFile)
786 {
787         InstallerManager *pManager = InstallerManager::GetInstance();
788         if (pManager == null)
789         {
790                 return false;
791         }
792
793         if (pManager->IsFileLogOn() == false)
794         {
795                 return true;
796         }
797
798         File file;
799         FileAttributes attribute;
800
801         result r = File::GetAttributes(logFile, attribute);
802         if (IsFailed(r))
803         {
804                 return false;
805         }
806
807         int bufSize = 4096;
808         std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
809         if (pBuf == null)
810         {
811                 return false;
812         }
813
814         r = file.Construct(logFile, "r");
815         if (IsFailed(r))
816         {
817                 return false;
818         }
819
820         int readBytes = 0;
821         do
822         {
823                 memset(pBuf.get(), 0, bufSize);
824                 readBytes = file.Read(pBuf.get(), bufSize);
825                 if (readBytes > 0)
826                 {
827                         fprintf(stderr, "%s", pBuf.get());
828                 }
829         }
830         while (readBytes > 0);
831
832         return true;
833 }
834
835 bool
836 InstallerUtil::GetRdsList(const PackageId& packageId, IList* pDeletedList, IList* pAddedList, IList* pModifiedList)
837 {
838         bool res = true;
839         FILE* fp = null;
840         char rdsFilePath[1024] = {0};
841         char buffer[1024] = {0};
842         InstallerRdsState state = INSTALLER_RDS_STATE_NONE;
843
844         snprintf(rdsFilePath, sizeof(rdsFilePath), "%s/%ls/%s", DIR_APPLICATIONS_TMP, packageId.GetPointer(), INSTALLER_RDS_FILE_NAME);
845
846         fp = fopen(rdsFilePath, "r");
847         TryReturn(fp, false, "fp is null.");
848         AppLog(".rds_delta file");
849         int line = 1;
850
851         while (fgets(buffer, sizeof(buffer), fp) != null)
852         {
853                 bool isMetadata = false;
854
855                 if (buffer[0] == '#')
856                 {
857                         if (strcasestr(buffer, INSTALLER_RDS_DELETE_STR))
858                         {
859                                 state = INSTALLER_RDS_STATE_DELETE;
860                         }
861                         else if (strcasestr(buffer, INSTALLER_RDS_ADD_STR))
862                         {
863                                 state = INSTALLER_RDS_STATE_ADD;
864                         }
865                         else if (strcasestr(buffer, INSTALLER_RDS_MODIFY_STR))
866                         {
867                                 state = INSTALLER_RDS_STATE_MODIFY;
868                         }
869
870                         isMetadata = true;
871                 }
872
873                 if (state == INSTALLER_RDS_STATE_NONE)
874                 {
875                         AppLog("Unknown RDS State, INSTALLER_RDS_STATE_NONE");
876                         continue;
877                 }
878
879                 std::unique_ptr<String> pStr(new (std::nothrow) String(buffer));
880                 TryCatch(pStr, res = false, "pStr is null.");
881                 TryCatch(pStr->IsEmpty() == false, res = false, "pStr is empty.");
882
883                 pStr->Trim();
884                 AppLog(".rds_delta: line(%03d)=[%ls]", line, pStr->GetPointer());
885                 line++;
886
887                 if (isMetadata == true)
888                         continue;
889
890                 if (state == INSTALLER_RDS_STATE_DELETE)
891                 {
892                         pDeletedList->Add(pStr.release());
893                 }
894                 else if (state == INSTALLER_RDS_STATE_ADD)
895                 {
896                         pAddedList->Add(pStr.release());
897                 }
898                 else if (state == INSTALLER_RDS_STATE_MODIFY)
899                 {
900                         pModifiedList->Add(pStr.release());
901                 }
902
903                 memset(buffer, 0, sizeof(buffer));
904         }
905
906 CATCH:
907         fclose(fp);
908         return res;
909 }
910
911 const char*
912 InstallerUtil::GetInstallerOperationString(int operation)
913 {
914         if (operation == INSTALLER_OPERATION_INSTALL)
915         {
916                 return "Install";
917         }
918         else if (operation == INSTALLER_OPERATION_UNINSTALL)
919         {
920                 return "Uninstall";
921         }
922         else if (operation == INSTALLER_OPERATION_REINSTALL)
923         {
924                 return "Reinstall";
925         }
926
927         return "Unknown";
928 }
929
930 bool
931 InstallerUtil::GetFileDigest(const String& filePath, String& digestValue)
932 {
933         const int bufSize = 64*1024;
934         int readBytes = 0;
935         result r = E_SUCCESS;
936
937         File file;
938         std::unique_ptr<Sha2Hash> pHash(new (std::nothrow) Sha2Hash());
939
940         r = pHash->SetAlgorithm("SHA2/256");
941         TryReturn(!IsFailed(r), false, "pHash->SetAlgorithm() is failed.");
942
943         r = pHash->Initialize();
944         TryReturn(!IsFailed(r), false, "pHash->Initialize() is failed.");
945
946         std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
947         TryReturn(pBuf, false, "pBuf is null");
948
949         r = file.Construct(filePath, L"r");
950         TryReturn(!IsFailed(r), false, "file.Construct() is failed.");
951
952         do
953         {
954                 readBytes = file.Read(pBuf.get(), bufSize);
955                 AppLog("readBytes for Hash=[%d]", readBytes);
956
957                 if (readBytes > 0)
958                 {
959                         ByteBuffer buffer;
960                         r = buffer.Construct((const byte*)pBuf.get(), 0, readBytes, bufSize);
961                         TryReturn(!IsFailed(r), false, "buffer.Construct() is failed.");
962
963                         r = pHash->Update(buffer);
964                         TryReturn(!IsFailed(r), false, "pHash->Update() is failed.");
965                 }
966         }
967         while (readBytes > 0);
968
969         std::unique_ptr<ByteBuffer> pResultBuf(pHash->FinalizeN());
970         TryReturn(pResultBuf, false, "pResultBuf is null.");
971
972         r = StringUtil::EncodeToBase64String(*pResultBuf, digestValue);
973         TryReturn(!IsFailed(r), false, "EncodeToBase64String() is failed.");
974
975         return true;
976 }
977
978 IMap*
979 InstallerUtil::ParseN(const String& str, const String& tokenDelimiter)
980 {
981         TryReturn(str.IsEmpty() == false, null, "str is empty.");
982         TryReturn(tokenDelimiter.IsEmpty() == false, null, "tokenDelimiter is empty.");
983
984         std::unique_ptr< HashMap > pMap(new (std::nothrow) HashMap);
985         TryReturn(pMap, null, "pMap is null.");
986
987         result r = pMap->Construct();
988         TryReturn(!IsFailed(r), null, "pMap->Construct() is failed.");
989
990         StringTokenizer strTok(str, tokenDelimiter);
991         while(strTok.HasMoreTokens() == true)
992         {
993                 String token;
994                 r = strTok.GetNextToken(token);
995                 TryReturn(!IsFailed(r), null, "strTok.GetNextToken() is failed.");
996
997                 AppLog("token = [%ls]", token.GetPointer());
998
999                 StringTokenizer infoTok(token, L"=");
1000
1001                 if (infoTok.GetTokenCount() != 2)
1002                 {
1003                         AppLog("'=' is not existed.");
1004                         continue;
1005                 }
1006
1007                 std::unique_ptr< String > pKey(new (std::nothrow) String);
1008                 r = infoTok.GetNextToken(*pKey);
1009                 TryReturn(!IsFailed(r), null, "infoTok.GetNextToken(*pKey) is failed.");
1010                 AppLog(" - key = [%ls]", pKey->GetPointer());
1011
1012                 std::unique_ptr< String > pValue(new (std::nothrow) String);
1013                 r = infoTok.GetNextToken(*pValue);
1014                 TryReturn(!IsFailed(r), null, "infoTok.GetNextToken(*pValue) is failed.");
1015                 AppLog(" - value = [%ls]", pValue->GetPointer());
1016
1017                 r = pMap->Add(pKey.release(), pValue.release());
1018                 TryReturn(!IsFailed(r), null, "pMap->Add() is failed.");
1019         }
1020
1021         if (pMap->GetCount() <= 0)
1022         {
1023                 AppLog("pMap->GetCount() is invalid.");
1024                 return null;
1025         }
1026
1027         return pMap.release();
1028 }
1029
1030 bool
1031 InstallerUtil::TerminateApp(const AppId& appId)
1032 {
1033         bool res = true;
1034
1035         if (_Aul::IsRunning(appId) == true)
1036         {
1037                 AppLog("App(%ls) is running.", appId.GetPointer());
1038
1039                 result r = _Aul::TerminateApplication(appId);
1040                 TryReturn(r == E_SUCCESS, false, "TerminateApplication() failed. [%ls]", appId.GetPointer());
1041
1042                 for (int j = 0; j < TERMINATE_RETRY_COUNT; j++)
1043                 {
1044                         res = _Aul::IsRunning(appId);
1045                         if (res == false)
1046                         {
1047                                 AppLog("App(%ls) is terminated.", appId.GetPointer());
1048                                 break;
1049                         }
1050                         else
1051                         {
1052                                 AppLog("App(%ls) is not terminated yet. wait count = [%d]", appId.GetPointer(), j);
1053                                 usleep(100000);
1054                         }
1055                 }
1056
1057                 if (res == true)
1058                 {
1059                         AppLog("App(%ls) can't be terminated.", appId.GetPointer());
1060                         return false;
1061                 }
1062         }
1063         else
1064         {
1065                 AppLog("App(%ls) is not running.", appId.GetPointer());
1066         }
1067
1068         return true;
1069 }
1070
1071 bool
1072 InstallerUtil::TerminateApps(const PackageId& packageId)
1073 {
1074         std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId));
1075         TryReturn(pPackageInfo, false, "GetPackageInfoN() failed.");
1076
1077         _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get());
1078         TryReturn(pPackageInfoImpl, false, "GetInstance() failed.");
1079
1080         std::unique_ptr< IList > pPackageAppList(pPackageInfoImpl->GetPackageAppInfoListN());
1081         TryReturn(pPackageAppList, false, "GetPackageAppInfoListN() failed.");
1082
1083         for (int i = 0; i < pPackageAppList->GetCount(); i++)
1084         {
1085                 PackageAppInfo* pPackageAppInfo = dynamic_cast < PackageAppInfo* >(pPackageAppList->GetAt(i));
1086                 TryReturn(pPackageAppInfo, false, "pPackageAppList->GetAt(%d) failed.", i);
1087
1088                 AppId appId = pPackageAppInfo->GetAppId();
1089                 TerminateApp(appId);
1090         }
1091
1092         return true;
1093 }
1094
1095 bool
1096 InstallerUtil::IsUninstallable(const PackageId& packageId)
1097 {
1098         bool res = false;
1099
1100         std::unique_ptr< PackageInfo > pPackageInfo(_PackageManagerImpl::GetInstance()->GetPackageInfoN(packageId));
1101         TryReturn(pPackageInfo, false, "GetPackageInfoN() failed.");
1102
1103         _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get());
1104         TryReturn(pPackageInfoImpl, false, "GetInstance() failed.");
1105
1106         res = pPackageInfoImpl->IsUninstallable();
1107
1108         AppLog("packageId[%ls]: Uninstallable = [%s]", packageId.GetPointer(), res?"true":"false");
1109
1110         return res;
1111 }
1112
1113 bool
1114 InstallerUtil::IsCscPackage(const PackageId& packageId, String& cscInfo)
1115 {
1116         bool res = false;
1117         int result = 0;
1118         char* pPath = null;
1119         pkgmgrinfo_pkginfo_h handle = null;
1120
1121         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
1122         TryReturn(pPackageId, false, "pPackageId is null.");
1123
1124         result = pkgmgrinfo_pkginfo_get_pkginfo(pPackageId.get(), &handle);
1125         TryReturn(result == PMINFO_R_OK, false, "pkgmgrinfo_pkginfo_get_pkginfo() failed. result=[%d], package=[%s]", result, pPackageId.get());
1126
1127         result = pkgmgrinfo_pkginfo_get_csc_path(handle, &pPath);
1128         TryReturn(result == PMINFO_R_OK, false, "pkgmgrinfo_pkginfo_get_csc_path() failed. result=[%d], package=[%s]", result, pPackageId.get());
1129
1130         AppLog("csc_path = [%s]", pPath);
1131
1132         cscInfo = pPath;
1133
1134         if (cscInfo.IsEmpty() == false)
1135         {
1136                 res = true;
1137                 AppLog("packageId[%ls]: cscInfo = [%ls]", packageId.GetPointer(), cscInfo.GetPointer());
1138         }
1139
1140         if (handle)
1141         {
1142                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1143         }
1144
1145         return res;
1146 }
1147
1148 bool
1149 InstallerUtil::IsDefaultExternalStorage()
1150 {
1151         int res = 0;
1152         int storage = 0;
1153         int mmcStatus = VCONFKEY_SYSMAN_MMC_REMOVED;
1154
1155         res = vconf_get_int("db/setting/default_memory/download", &storage);
1156         TryReturn(res == 0, false, "vconf_get_int(db/setting/default_memory/download) failed.");
1157
1158         AppLog("Storage = [%d]", storage);
1159
1160         if (storage == 1)
1161         {
1162                 res = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus);
1163                 TryReturn(res == 0, false, "vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
1164
1165                 if ((mmcStatus == VCONFKEY_SYSMAN_MMC_REMOVED) || (mmcStatus == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED))
1166                 {
1167                         AppLog("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
1168                 }
1169                 else
1170                 {
1171                         AppLog("mmcStatus is MMC_MOUNTED.");
1172                         return true;
1173                 }
1174         }
1175
1176         return false;
1177 }
1178
1179 bool
1180 InstallerUtil::IsSignatureVerificationEnabled()
1181 {
1182         result r;
1183         Registry reg;
1184         String section(L"feature");
1185         String entry(L"signature");
1186         String value;
1187
1188         r = reg.Construct(CONFIG_PATH, "r");
1189         TryReturn(!IsFailed(r), false, "CONFIG file is not found.");
1190
1191         r = reg.GetValue(section, entry, value);
1192         TryReturn(!IsFailed(r), false, "GetValue is failed. entry = [%ls]", entry.GetPointer());
1193
1194         AppLog("[%ls is %ls.]", entry.GetPointer(), value.GetPointer());
1195
1196         if (value == L"on")
1197         {
1198                 return true;
1199         }
1200
1201         return false;
1202 }