IME symlink and logs
[framework/osp/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 <errno.h>
25 #include <unistd.h>
26 #include <unique_ptr.h>
27
28 #include <FBaseErrorDefine.h>
29 #include <FIoFile.h>
30 #include <FIoDirectory.h>
31 #include <FBase_StringConverter.h>
32
33 #include "InstallerDefs.h"
34 #include "InstallerUtil.h"
35
36 #include <drm-oem-intel.h>
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::App;
41 using namespace Tizen::Io;
42
43 InstallerUtil::InstallerUtil(void)
44 {
45 }
46
47 InstallerUtil::~InstallerUtil(void)
48 {
49 }
50
51 bool
52 InstallerUtil::Remove(const Tizen::Base::String& filePath)
53 {
54         int err = -1;
55         result r = E_SUCCESS;
56         struct stat fileinfo;
57
58         AppLogTag(OSP_INSTALLER, "+ Remove(): path=[%ls]", filePath.GetPointer());
59
60         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
61         TryReturn(pFilePath, false, "[osp-installer] pFilePath is null");
62
63         err = lstat(pFilePath.get(), &fileinfo);
64         if (err < 0)
65         {
66                 AppLogTag(OSP_INSTALLER, "Remove(): lstat(%s): %s[errno:%d]: skip", pFilePath.get(), strerror(errno), errno);
67                 return true;
68         }
69
70         if (S_ISLNK(fileinfo.st_mode))
71         {
72                 AppLogTag(OSP_INSTALLER, "Remove(): symlink, path=[%s]", pFilePath.get());
73                 err = unlink(pFilePath.get());
74                 TryReturn(err >= 0, false, "[osp-installer] unlink() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
75         }
76         else if (S_ISDIR(fileinfo.st_mode))
77         {
78                 AppLogTag(OSP_INSTALLER, "Remove(): directory, path=[%ls]", filePath.GetPointer());
79                 r = Directory::Remove(filePath, true);
80                 TryReturn(!IsFailed(r), false, "[osp-installer] Directory::Remove() failed, filePath=%ls", filePath.GetPointer());
81         }
82         else
83         {
84                 AppLogTag(OSP_INSTALLER, "Remove(): file, path=[%ls]", filePath.GetPointer());
85                 r = File::Remove(filePath);
86                 TryReturn(!IsFailed(r), false, "[osp-installer] File::Remove() failed, filePath=%ls", filePath.GetPointer());
87         }
88
89         return true;
90 }
91
92 bool
93 InstallerUtil::Copy(const String& srcFilePath, const String& destFilePath)
94 {
95         int bufSize = 4096;
96         int readBytes = 0;
97         result r = E_SUCCESS;
98
99         // AppLogTag(OSP_INSTALLER, "+ Copy(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
100
101         File srcFile;
102         File destFile;
103
104         std::unique_ptr<char[]> pBuf(new (std::nothrow) char[bufSize]);
105         TryReturn(pBuf, false, "[osp-installer] pBuf is null");
106
107         r = srcFile.Construct(srcFilePath, L"r");
108         TryReturn(!IsFailed(r), false, "[osp-installer] srcFile.Construct is failed");
109
110         r = destFile.Construct(destFilePath, L"w");
111         TryReturn(!IsFailed(r), false, "[osp-installer] destFile.Construct is failed");
112
113         do
114         {
115                 readBytes = srcFile.Read(pBuf.get(), bufSize);
116                 if (readBytes > 0)
117                 {
118                         r = destFile.Write(pBuf.get(), readBytes);
119                         TryReturn(!IsFailed(r), false, "[osp-installer] destFile.Write is failed");
120                 }
121         }
122         while (readBytes > 0);
123
124         return true;
125 }
126
127 bool
128 InstallerUtil::CopyDirectory(const String& srcFilePath, const String& destFilePath)
129 {
130         result r = E_SUCCESS;
131
132         AppLogTag(OSP_INSTALLER, "+ CopyDirectory(): src=[%ls], dest=[%ls]", srcFilePath.GetPointer(), destFilePath.GetPointer());
133
134         std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
135         TryReturn(pDir, false, "[osp-installer] pDir is null.");
136
137         r = pDir->Construct(srcFilePath);
138         TryReturn(!IsFailed(r), false, "[osp-installer] pDir->Construct() failed, srcFilePath=[%ls].", srcFilePath.GetPointer());
139
140         std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
141         TryReturn(pDirEnum, false, "[osp-installer] pDirEnum is null.");
142
143         while (pDirEnum->MoveNext() == E_SUCCESS)
144         {
145                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
146
147                 String entryName = entry.GetName();
148                 String srcEntryDir = srcFilePath;
149                 srcEntryDir += L"/";
150                 srcEntryDir += entryName;
151
152                 if (entryName == L"." || entryName == L"..")
153                 {
154                         continue;
155                 }
156
157                 // if file or directory is symbolic link, skip this.
158                 if (InstallerUtil::IsSymlink(srcEntryDir) == true)
159                 {
160                         continue;
161                 }
162
163                 String destEntryDir = destFilePath;
164                 destEntryDir += L"/";
165                 destEntryDir += entryName;
166
167                 if (entry.IsDirectory() == false)
168                 {
169                         // file
170                         Directory::Create(destFilePath, true);
171                         InstallerUtil::Copy(srcEntryDir, destEntryDir);
172                 }
173                 else
174                 {
175                         Directory::Create(destEntryDir, true);
176                         CopyDirectory(srcEntryDir, destEntryDir);
177                 }
178         }
179
180         return true;
181 }
182
183 bool
184 InstallerUtil::IsSymlink(const Tizen::Base::String& filePath)
185 {
186         int err = -1;
187         struct stat fileinfo;
188
189         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
190         TryReturn(pFilePath, false, "[osp-installer] pFilePath is null");
191
192         err = lstat(pFilePath.get(), &fileinfo);
193         TryReturn(err >= 0, false, "[osp-installer] lstat() failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
194
195         if (S_ISLNK(fileinfo.st_mode))
196         {
197                 return true;
198         }
199
200         return false;
201 }
202
203 bool
204 InstallerUtil::GetRealPath(const String& filePath, String& realPath)
205 {
206         char* pRealPath = null;
207
208         AppLogTag(OSP_INSTALLER, "+ GetRealPath(): path=[%ls], realPath=[%ls]", filePath.GetPointer(), realPath.GetPointer());
209
210         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
211         TryReturn(pFilePath, false, "[osp-installer] pFilePath is null");
212
213         char tmpPath[PATH_MAX] = {0};
214         pRealPath = realpath(pFilePath.get(), tmpPath);
215         TryReturn(pRealPath, false, "[osp-installer] pRealPath is null");
216
217         realPath = tmpPath;
218
219         return true;
220 }
221
222 bool
223 InstallerUtil::CreateSymlink(const String& oldPath, const String& newPath)
224 {
225         int err = -1;
226         bool res = false;
227
228         AppLogTag(OSP_INSTALLER, "+ CreateSymlink(): oldPath=[%ls], newPath=[%ls]", oldPath.GetPointer(), newPath.GetPointer());
229
230         res = File::IsFileExist(oldPath);
231         TryReturn(res == true, false, "[osp-installer] file not found, oldPath=[%ls]", oldPath.GetPointer());
232
233         std::unique_ptr<char[]> pOldPath(_StringConverter::CopyToCharArrayN(oldPath));
234         TryReturn(pOldPath, false, "[osp-installer] pOldPath is null");
235
236         std::unique_ptr<char[]> pNewPath(_StringConverter::CopyToCharArrayN(newPath));
237         TryReturn(pNewPath, false, "[osp-installer] pNewPath is null");
238
239         err = symlink(pOldPath.get(), pNewPath.get());
240         TryReturn(err == 0, false, "[osp-installer] symlink() is failed(%s), oldpath=[%s], newpath=[%s]", strerror(errno), pOldPath.get(), pNewPath.get());
241
242         AppLogTag(OSP_INSTALLER, "CreateSymlink(): [%ls] -> [%ls]", newPath.GetPointer(), oldPath.GetPointer());
243
244         return true;
245 }
246
247 bool
248 InstallerUtil::ChangeMode(const String& filePath, int mode)
249 {
250         int err = -1;
251
252         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
253         TryReturn(pFilePath, false, "[osp-installer] pFilePath is null");
254
255         err = chmod(pFilePath.get(), mode);
256         TryReturn(err == 0, false, "[osp-installer] chmod() is failed(%s), filepath=[%s], mode=[%o]", strerror(errno), pFilePath.get(), mode);
257
258         return true;
259 }
260
261 bool
262 InstallerUtil::ChangeOwner(const String& filePath)
263 {
264         int err = -1;
265
266         std::unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
267         TryReturn(pFilePath, false, "[osp-installer] pFilePath is null");
268
269         err = chown(pFilePath.get(), APP_OWNER_ID, APP_GROUP_ID);
270         TryReturn(err == 0, false, "[osp-installer] chown() is failed(%s), filepath=[%s]", strerror(errno), pFilePath.get());
271
272         return true;
273 }
274
275 bool
276 InstallerUtil::ChangeDirectoryPermission(const String& filePath, int mode, bool appOwner)
277 {
278         result r = E_SUCCESS;
279         bool res = false;
280
281         AppLogTag(OSP_INSTALLER, "+ ChangeDirectoryPermission(): path=[%ls], mode=[%04o], appOwner=[%s]",
282                         filePath.GetPointer(), mode, appOwner?"true":"false");
283
284         res = File::IsFileExist(filePath);
285         if (res == false)
286         {
287                 AppLogTag(OSP_INSTALLER, "ChangeDirectoryPermission(): path=[%ls]: skip", filePath.GetPointer());
288                 return true;
289         }
290
291         std::unique_ptr<Directory> pDir(new (std::nothrow) Directory);
292         TryReturn(pDir, false, "[osp-installer] pDir is null.");
293
294         r = pDir->Construct(filePath);
295         TryReturn(!IsFailed(r), false, "[osp-installer] pDir->Construct() failed, filePath=[%ls]", filePath.GetPointer());
296
297         std::unique_ptr<DirEnumerator> pDirEnum(pDir->ReadN());
298         TryReturn(pDirEnum, false, "[osp-installer] pDirEnum is null.");
299
300         while (pDirEnum->MoveNext() == E_SUCCESS)
301         {
302                 DirEntry entry = pDirEnum->GetCurrentDirEntry();
303
304                 String entryName = entry.GetName();
305                 String entryDir = filePath;
306                 entryDir += L"/";
307                 entryDir += entryName;
308
309                 if (entryName == L".")
310                 {
311                         if (appOwner == true)
312                         {
313                                 InstallerUtil::ChangeOwner(entryDir);
314                         }
315                         InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
316                         continue;
317                 }
318                 else if (entryName == L"..")
319                 {
320                         continue;
321                 }
322
323                 if (entry.IsDirectory() == false)
324                 {
325                         if (appOwner == true)
326                         {
327                                 InstallerUtil::ChangeOwner(entryDir);
328                         }
329                         InstallerUtil::ChangeMode(entryDir, mode);
330                 }
331                 else
332                 {
333                         ChangeDirectoryPermission(entryDir, mode, appOwner);
334                         if (appOwner == true)
335                         {
336                                 InstallerUtil::ChangeOwner(entryDir);
337                         }
338                         InstallerUtil::ChangeMode(entryDir, mode | PERM_EXECUTE);
339                 }
340         }
341
342         return true;
343 }
344
345 bool
346 InstallerUtil::IsDrmFile(const Tizen::Base::String& path)
347 {
348             bool res = true;
349             char* pFilePath = null;
350             result r = E_SUCCESS;
351             int isDrm = 0;
352
353             pFilePath = _StringConverter::CopyToCharArrayN(path);
354             TryCatch(pFilePath, r = GetLastResult(), "[osp-installer] pFilePath is null");
355
356             isDrm = drm_oem_intel_isDrmFile(pFilePath);
357                 if(isDrm == 1)
358             {
359                         AppLogTag(OSP_INSTALLER, "IsDrmFile() called, packagePath=%ls is drm file", path.GetPointer());
360                 }
361             else
362                 {
363                 res = false;
364                         AppLogTag(OSP_INSTALLER, "IsDrmFile() called, packagePath=%ls isn't  drm file", path.GetPointer());
365             }
366
367                 CATCH:
368                     delete [] pFilePath;
369                     return res;
370 }
371
372 bool
373 InstallerUtil::DecryptPackage(const Tizen::Base::String& packagePath)
374 {
375             bool res = true;
376             char* pFilePath = null;
377             result r = E_SUCCESS;
378             int result = 0;
379
380             pFilePath = _StringConverter::CopyToCharArrayN(packagePath);
381             TryCatch(pFilePath, r = GetLastResult(), "[osp-installer] pFilePath is null");
382
383             result = drm_oem_intel_decrypt_package(pFilePath, pFilePath);
384             if(result  == 1)
385             {
386                 AppLogTag(OSP_INSTALLER, "DecryptPackage() called, packagePath=%ls, decrpyt success", packagePath.GetPointer());
387             }
388             else
389             {
390                 AppLogTag(OSP_INSTALLER, "DecryptPackage() called, packagePath=%ls, decrypt failed", packagePath.GetPointer());
391                 res = false;
392             }
393
394 CATCH:
395             delete [] pFilePath;
396             return res;
397 }
398
399 String
400 InstallerUtil::GetCategory(int categoryType)
401 {
402         String category;
403
404         if (categoryType == CATEGORY_TYPE_IME)
405         {
406                 category = L"Ime";
407         }
408         else if (categoryType == CATEGORY_TYPE_HOME_SCREEN)
409         {
410                 category = L"home-screen";
411         }
412         else if (categoryType == CATEGORY_TYPE_LOCK_SCREEN)
413         {
414                 category = L"lock-screen";
415         }
416
417         return category;
418 }
419
420 CategoryType
421 InstallerUtil::GetCategoryType(char* pCategory)
422 {
423         CategoryType category = CATEGORY_TYPE_NONE;
424
425         if (strcasecmp(pCategory, "Ime") == 0)
426         {
427                 category = CATEGORY_TYPE_IME;
428         }
429         else if (strcasecmp(pCategory, "home-screen") == 0)
430         {
431                 category = CATEGORY_TYPE_HOME_SCREEN;
432         }
433         else if (strcasecmp(pCategory, "lock-screen") == 0)
434         {
435                 category = CATEGORY_TYPE_LOCK_SCREEN;
436         }
437
438         return category;
439 }
440
441 bool
442 InstallerUtil::CreateSymlinkForAppDirectory(const String& inPath, String& outPath)
443 {
444         String appId;
445
446         AppLogTag(OSP_INSTALLER, "+ CreateSymlinkForAppDirectory(): path=[%ls]", inPath.GetPointer());
447
448         int length = inPath.GetLength();
449         inPath.SubString(length - APPID_LENGTH, APPID_LENGTH, appId);
450
451         String newPath;
452         newPath = PATH_OPT_APPS;
453         newPath += L"/";
454         newPath += appId;
455
456         if (inPath != newPath)
457         {
458                 InstallerUtil::CreateSymlink(inPath, newPath);
459         }
460
461         outPath = newPath;
462         AppLogTag(OSP_INSTALLER, "CreateSymlinkForAppDirectory(): output path=[%ls]", outPath.GetPointer());
463
464         return true;
465 }
466
467 bool
468 InstallerUtil::DumpLog(const char* pBuf)
469 {
470         char temp[4096] = {0};
471         TryReturn(pBuf, false, "[osp-installer] pBuf is null");
472
473         int bufLen = strlen(pBuf);
474         strncpy(temp, pBuf, sizeof(temp));
475
476         char *pStart = &temp[0];
477
478         for (int i = 0; i < bufLen; i++)
479         {
480                 if (temp[i] == '\n')
481                 {
482                         temp[i] = 0;
483                         AppLogTag(OSP_INSTALLER, "%s", pStart);
484                         pStart = temp + i + 1;
485                 }
486         }
487
488         return true;
489 }
490
491 #define LOG_PRINT_LINE_MAX 20
492 #define LOG_BUFFER_COUNT_MAX 4096
493 bool
494 InstallerUtil::DumpLogData(char *pData, int dataLen)
495 {
496         const char      *szData = (const char*)pData;
497         char            ch = 0;
498         int                     i = 0, j = 0, idx = 0, idx2 = 0, high = 0, low = 0, temp = 0;
499
500         char            buf[LOG_PRINT_LINE_MAX + 2]                     = {0};
501         char            buf2[(LOG_PRINT_LINE_MAX + 2) * 3]      = {0};
502         char            buf_out[sizeof(buf) + sizeof(buf2) + 1] = {0};
503
504
505         if (dataLen > LOG_BUFFER_COUNT_MAX)
506         {
507                 dataLen = LOG_BUFFER_COUNT_MAX;
508         }
509
510         // 16 characters by 20 line are proper. // too many logs decrease performance.
511 //      if (dataLen > 16*20)
512 //              dataLen = 16*20;
513
514         AppLogTag(OSP_INSTALLER, "------------------------------------------");
515
516         while (i < (int)dataLen)
517         {
518                 ch      = szData[i];
519
520                 /* make ascii table */
521                 if (ch >= 32 && ch <= 128)
522                 {
523                         buf[idx++]      = ch;
524                 }
525                 else
526                         buf[idx++]      = '.';
527
528                 // make binary table
529                 high = (ch & 0xf0)>>4;
530                 low = ch & 0x0f;
531
532                 buf2[idx2++]    = LogChangeHexToStr(high);
533                 buf2[idx2++]    = LogChangeHexToStr(low);
534                 buf2[idx2++]    = ' ';
535
536                 if (idx >= LOG_PRINT_LINE_MAX)
537                 {
538                         memcpy(buf_out, buf2, idx2);
539
540                         buf_out[idx2++] = ' ';
541                         buf_out[idx2++] = ' ';
542
543                         memcpy(buf_out + idx2, buf, idx);
544                         buf_out[idx2+idx]       = '\0';
545
546                         idx             = 0;
547                         idx2    = 0;
548
549                         AppLogTag(OSP_INSTALLER, "%s\n", buf_out);
550                 }
551
552                 i++;
553         }
554
555         // last line
556         if (idx > 0)
557         {
558                 memcpy(buf_out, buf2, idx2);
559                 temp    = idx2;
560
561                 for (j = 0; j < (LOG_PRINT_LINE_MAX * 3) - temp; j++)
562                 {
563                         buf_out[idx2++] = ' ';
564                 }
565
566                 buf_out[idx2++] = ' ';
567                 buf_out[idx2++] = ' ';
568
569                 memcpy(buf_out+idx2, buf, idx);
570                 buf_out[idx2+idx]       = '\0';
571
572                 AppLogTag(OSP_INSTALLER, "%s\n", buf_out);
573         }
574
575         AppLogTag(OSP_INSTALLER, "------------------------------------------");
576
577         return TRUE;
578 }
579
580 char
581 InstallerUtil::LogChangeHexToStr(int hex)
582 {
583         char ch = '0';
584
585         const static char       hexValues[]     = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
586
587
588         if (hex >= 0 && hex <= 0x0F)
589         {
590                 ch      = hexValues[hex];
591         }
592         else
593         {
594                 AppLogTag(OSP_INSTALLER, "LogChangeHexToStr: Error! [Hex Val: %d]\n", hex);
595         }
596
597         return ch;
598 }
599
600