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