5c7413e808f2c043fe72608078d35126d0547e64
[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
29 #include <FBaseErrorDefine.h>
30 #include <FIoFile.h>
31 #include <FIoDirectory.h>
32 #include <FAppPkgPackageAppInfo.h>
33 #include <FAppPkgPackageInfo.h>
34 #include <FBase_StringConverter.h>
35 #include <FSecCryptoSha2Hash.h>
36 #include <FApp_Aul.h>
37 #include <FAppPkg_PackageManagerImpl.h>
38 #include <FAppPkg_PackageInfoImpl.h>
39 #include <FAppPkg_PackageAppInfoImpl.h>
40
41 #include "InstallerDefs.h"
42 #include "InstallerUtil.h"
43 #include "InstallerManager.h"
44 #include "SmackManager.h"
45
46 using namespace Tizen::Base;
47 using namespace Tizen::Base::Collection;
48 using namespace Tizen::Base::Utility;
49 using namespace Tizen::App;
50 using namespace Tizen::App::Package;
51 using namespace Tizen::Io;
52 using namespace Tizen::Security::Crypto;
53
54 InstallerUtil::InstallerUtil(void)
55 {
56 }
57
58 InstallerUtil::~InstallerUtil(void)
59 {
60 }
61
62 bool
63 InstallerUtil::Remove(const Tizen::Base::String& filePath)
64 {
65         int err = -1;
66         result r = E_SUCCESS;
67         struct stat fileinfo;
68
69         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
70         TryReturn(pFilePath, false, "pFilePath is null");
71
72         err = lstat(pFilePath.get(), &fileinfo);
73         if (err < 0)
74         {
75                 AppLog("Remove(): [%s] - %s[errno(%d)]: skip", pFilePath.get(), strerror(errno), errno);
76                 return true;
77         }
78
79         if (S_ISLNK(fileinfo.st_mode))
80         {
81                 AppLog("Remove(): symlink=[%s]", pFilePath.get());
82                 err = unlink(pFilePath.get());
83                 TryReturn(err >= 0, false, "unlink() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
84         }
85         else if (S_ISDIR(fileinfo.st_mode))
86         {
87                 AppLog("Remove(): directory=[%ls]", filePath.GetPointer());
88                 r = Directory::Remove(filePath, true);
89                 TryReturn(!IsFailed(r), false, "Directory::Remove() failed, filePath=%ls", filePath.GetPointer());
90         }
91         else
92         {
93                 AppLog("Remove(): file=[%ls]", filePath.GetPointer());
94                 r = File::Remove(filePath);
95                 TryReturn(!IsFailed(r), false, "File::Remove() failed, filePath=%ls", filePath.GetPointer());
96         }
97
98         return true;
99 }
100
101 bool
102 InstallerUtil::Copy(const String& srcFilePath, const String& destFilePath)
103 {
104         int bufSize = 4096;
105         int readBytes = 0;
106         result r = E_SUCCESS;
107
108         // AppLog("+ Copy(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
109
110         File srcFile;
111         File destFile;
112
113         std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
114         TryReturn(pBuf, false, "pBuf is null");
115
116         r = srcFile.Construct(srcFilePath, L"r");
117         TryReturn(!IsFailed(r), false, "srcFile.Construct is failed");
118
119         r = destFile.Construct(destFilePath, L"w");
120         TryReturn(!IsFailed(r), false, "destFile.Construct is failed");
121
122         do
123         {
124                 readBytes = srcFile.Read(pBuf.get(), bufSize);
125                 if (readBytes > 0)
126                 {
127                         r = destFile.Write(pBuf.get(), readBytes);
128                         TryReturn(!IsFailed(r), false, "destFile.Write is failed");
129                 }
130         }
131         while (readBytes > 0);
132
133         return true;
134 }
135
136 bool
137 InstallerUtil::CopyDirectory(const String& srcFilePath, const String& destFilePath)
138 {
139         result r = E_SUCCESS;
140         bool res = false;
141
142         res = File::IsFileExist(srcFilePath);
143         if (res == false)
144         {
145                 AppLog("CopyDirectory(): src=[%ls]: skip", srcFilePath.GetPointer());
146                 return true;
147         }
148
149         std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
150         TryReturn(pDir, false, "pDir is null.");
151
152         r = pDir->Construct(srcFilePath);
153         TryReturn(!IsFailed(r), false, "pDir->Construct() failed, srcFilePath=[%ls].", srcFilePath.GetPointer());
154
155         std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
156         TryReturn(pDirEnum, false, "pDirEnum is null.");
157
158         while (pDirEnum->MoveNext() == E_SUCCESS)
159         {
160                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
161
162                 String entryName = entry.GetName();
163                 String srcEntryDir = srcFilePath;
164                 srcEntryDir += L"/";
165                 srcEntryDir += entryName;
166
167                 if (entryName == L"." || entryName == L"..")
168                 {
169                         continue;
170                 }
171
172                 // if file or directory is symbolic link, skip this.
173                 if (InstallerUtil::IsSymlink(srcEntryDir) == true)
174                 {
175                         continue;
176                 }
177
178                 String destEntryDir = destFilePath;
179                 destEntryDir += L"/";
180                 destEntryDir += entryName;
181
182                 if (entry.IsDirectory() == false)
183                 {
184                         // file
185                         Directory::Create(destFilePath, true);
186                         InstallerUtil::Copy(srcEntryDir, destEntryDir);
187                 }
188                 else
189                 {
190                         Directory::Create(destEntryDir, true);
191                         CopyDirectory(srcEntryDir, destEntryDir);
192                 }
193         }
194
195         AppLog("CopyDirectory(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
196         return true;
197 }
198
199 bool
200 InstallerUtil::IsSymlink(const Tizen::Base::String& filePath)
201 {
202         int err = -1;
203         struct stat fileinfo;
204
205         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
206         TryReturn(pFilePath, false, "pFilePath is null");
207
208         err = lstat(pFilePath.get(), &fileinfo);
209         TryReturn(err >= 0, false, "lstat() failed(%s), file=[%s]", strerror(errno), pFilePath.get());
210
211         if (S_ISLNK(fileinfo.st_mode))
212         {
213                 return true;
214         }
215
216         return false;
217 }
218
219 bool
220 InstallerUtil::GetRealPath(const String& filePath, String& realPath)
221 {
222         char* pRealPath = null;
223
224         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
225         TryReturn(pFilePath, false, "pFilePath is null");
226
227         char tmpPath[PATH_MAX] = {0};
228         pRealPath = realpath(pFilePath.get(), tmpPath);
229         TryReturn(pRealPath, false, "pRealPath is null");
230
231         realPath = tmpPath;
232
233         AppLog("GetRealPath(): path=[%ls], realPath=[%ls]", filePath.GetPointer(), realPath.GetPointer());
234
235         return true;
236 }
237
238 bool
239 InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath)
240 {
241         int err = -1;
242         bool res = false;
243
244         res = File::IsFileExist(oldPath);
245         if (res == false)
246         {
247                 AppLog("CreateSymlink(): oldPath=[%ls] not found", oldPath.GetPointer());
248                 return true;
249         }
250
251         std::unique_ptr<char[]> pOldPath(_StringConverter::CopyToCharArrayN(oldPath));
252         TryReturn(pOldPath, false, "pOldPath is null");
253
254         std::unique_ptr<char[]> pNewPath(_StringConverter::CopyToCharArrayN(newPath));
255         TryReturn(pNewPath, false, "pNewPath is null");
256
257         err = symlink(pOldPath.get(), pNewPath.get());
258         TryReturn(err == 0, false, "symlink() is failed(%s), oldpath=[%s], newpath=[%s]", strerror(errno), pOldPath.get(), pNewPath.get());
259
260         SmackManager smackManager;
261         String label("_");
262         smackManager.AddLabelDir(label, 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& filePath, int mode, bool appOwner)
299 {
300         result r = E_SUCCESS;
301         bool res = false;
302
303         res = File::IsFileExist(filePath);
304         if (res == false)
305         {
306                 AppLog("path=[%ls]: skip", filePath.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(filePath);
314         TryReturn(!IsFailed(r), false, "pDir->Construct() failed, filePath=[%ls]", filePath.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 = filePath;
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                         filePath.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         pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
381         if (!pHandle)
382         {
383                 AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
384                 return false;
385         }
386
387         drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>(dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
388         pErrorMsg = dlerror();
389         if ((pErrorMsg != null) || (drm_oem_sapps_is_drm_file == null))
390         {
391                 AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
392                 dlclose(pHandle);
393                 return false;
394         }
395
396         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
397         TryReturn(pFilePath, false, "pFilePath is null.");
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         pHandle = dlopen("/usr/lib/libdrm-service-core-sapps.so.0", RTLD_LAZY | RTLD_GLOBAL);
425         if (!pHandle)
426         {
427                 AppLog("dlopen() failed. [%ls][%s]", path.GetPointer(), dlerror());
428                 return false;
429         }
430
431         drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int, const char*, int)>(dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
432         pErrorMsg = dlerror();
433         if ((pErrorMsg != null) || (drm_oem_sapps_decrypt_package == null))
434         {
435                 AppLog("dlsym() failed. [%ls][%s]", path.GetPointer(), pErrorMsg);
436                 dlclose(pHandle);
437                 return false;
438         }
439
440         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(path));
441         TryReturn(pFilePath, false, "pFilePath is null.");
442
443         std::unique_ptr<char[]> pDecryptedPath(_StringConverter::CopyToCharArrayN(decryptedPath));
444         TryReturn(pDecryptedPath, false, "pDecryptedPath is null.");
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
1059         _PackageInfoImpl* pPackageInfoImpl = _PackageInfoImpl::GetInstance(pPackageInfo.get());
1060         TryReturn(pPackageInfoImpl, false, "GetInstance() failed.");
1061
1062         std::unique_ptr< IList > pPackageAppList(pPackageInfoImpl->GetPackageAppInfoListN());
1063         TryReturn(pPackageAppList, false, "GetPackageAppInfoListN() failed.");
1064
1065         for (int i = 0; i < pPackageAppList->GetCount(); i++)
1066         {
1067                 PackageAppInfo* pPackageAppInfo = dynamic_cast < PackageAppInfo* >(pPackageAppList->GetAt(i));
1068                 TryReturn(pPackageAppInfo, false, "pPackageAppList->GetAt(%d) failed.", i);
1069
1070                 AppId appId = pPackageAppInfo->GetAppId();
1071                 TerminateApp(appId);
1072         }
1073
1074         return true;
1075 }