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