Removed dead code
[platform/core/messaging/msg-service.git] / utils / MsgUtilFile.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stddef.h>
19 #include <time.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <sys/stat.h>
23 #include <sys/smack.h>
24 #include <string.h>
25 #include <dirent.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <libgen.h>
29 #include <dlfcn.h>
30
31 #include <thumbnail_util.h>
32 #include <image_util.h>
33
34 #include "MsgStorageTypes.h"
35 #include "MsgDebug.h"
36 #include "MsgException.h"
37 #include "MsgUtilFile.h"
38 #include "MsgMmsTypes.h"
39 #include "MsgInternalTypes.h"
40 #include "MsgDrmWrapper.h"
41 #include "MsgMutex.h"
42
43 extern "C" {
44         #include <aul.h>
45 }
46
47 #define PATH_LIBCSR_CLIENT "/usr/lib/libcsr-client.so.2"
48 #define THUMB_WIDTH 320
49 #define THUMB_HEIGHT 240
50
51 MsgMutex g_mx;
52 MsgCndVar g_cv;
53
54 /*==================================================================================================
55                                      FUNCTION IMPLEMENTATION
56 ==================================================================================================*/
57 bool MakeThumbnail(char *srcPath, char *dstPath)
58 {
59         if (srcPath == NULL || dstPath == NULL) {
60                 MSG_SEC_DEBUG("Invalid Param src = %p, dst = %p", srcPath, dstPath);
61                 return false;
62         }
63
64         if (MsgAccessFile(srcPath, R_OK) == false) {
65                 MSG_SEC_DEBUG("not exist source file [%s]", srcPath);
66                 return false;
67         }
68
69         g_mx.lock();
70
71         int time_ret = 0;
72
73         int ret = THUMBNAIL_UTIL_ERROR_NONE;
74
75         ret = thumbnail_util_extract_to_file(srcPath, THUMB_WIDTH, THUMB_HEIGHT, dstPath);
76
77         if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
78                 MSG_ERR("thumbnail_util_extract_to_file is failed");
79                 g_mx.unlock();
80                 return false;
81         }
82
83         time_ret = g_cv.timedwait(g_mx.pMsgMutex(), 5);
84
85         g_mx.unlock();
86
87         if (time_ret == ETIMEDOUT) {
88                 MSG_ERR("@@ WAKE by timeout@@");
89                 return false;
90         }
91
92         if (MsgAccessFile(dstPath, F_OK) == false) {
93                 MSG_SEC_DEBUG("not exist result file [%s]", dstPath);
94                 return false;
95         }
96
97         MSG_SEC_DEBUG("Make thumbnail: success [%s]", dstPath);
98         return true;
99 }
100
101 /* File operation wrappers */
102 FILE *MsgOpenFile(const char *filepath, const char *opt)
103 {
104         if (!filepath || !opt) {
105                 MSG_FATAL("Null parameter");
106                 return NULL;
107         }
108
109         MSG_SEC_DEBUG("[FILE] filepath : [%s], opt [%s]", filepath, opt);
110
111         FILE *pFile = NULL;
112
113         try {
114                 pFile = fopen(filepath, opt);
115                 MSG_DEBUG("[FILE] pFile [%p]", pFile);
116         } catch (exception &e) {
117                 MSG_FATAL("%s", e.what());
118                 return NULL;
119         }
120
121         return pFile;
122 }
123
124 void MsgCloseFile(FILE *pFile)
125 {
126         if (!pFile) {
127                 MSG_FATAL("NULL parameter");
128                 return;
129         }
130
131         MSG_DEBUG("[FILE] pFile [%p]", pFile);
132
133         try {
134                 fclose(pFile);
135         } catch (exception &e) {
136                 MSG_FATAL("%s", e.what());
137         }
138 }
139
140 int MsgFseek(FILE *pFile, long int offset, int origin)
141 {
142         if (!pFile) {
143                 MSG_FATAL("pFile NULL");
144                 return -1;
145         }
146
147         int ret = -1;
148
149         MSG_DEBUG("[FILE] pFile [%p], offset [%ld], origin [%d]", pFile, offset, origin);
150
151         try {
152                 ret = fseek(pFile, offset, origin); /* return 0, if success. */
153         } catch (exception &e) {
154                 MSG_FATAL("%s", e.what());
155                 return -1;
156         }
157
158         return ret;
159 }
160
161 size_t MsgWriteFile(const char *pData, size_t size, size_t count, FILE *pFile)
162 {
163         if (!pData || !pFile) {
164                 MSG_FATAL("pData or pFile NULL");
165                 return 0;
166         }
167
168         size_t nWrite = 0;
169
170         MSG_DEBUG("[FILE] pData [%p], size [%zu], count [%zu], pFile [%p]", pData, size, count, pFile);
171
172         try {
173                 nWrite = fwrite(pData, size, count, pFile);
174         } catch (exception &e) {
175                 MSG_FATAL("%s", e.what());
176         }
177
178         return nWrite;
179 }
180
181 size_t MsgReadFile(void *pData, size_t size, size_t count, FILE *pFile)
182 {
183         if (!pData || !pFile) {
184                 MSG_FATAL("pData or pFile NULL");
185                 return 0;
186         }
187
188         size_t nRead = 0;
189
190         try {
191                 nRead = fread(pData, size, count, pFile);
192         } catch (exception &e) {
193                 MSG_FATAL("%s", e.what());
194         }
195
196         return nRead;
197 }
198
199 long int MsgFtell(FILE *pFile)
200 {
201         if (!pFile) {
202                 MSG_FATAL("pFile NULL");
203                 return -1L;
204         }
205
206         long int ret = -1L; /* -1L return if error occured. */
207
208         try {
209                 ret = ftell(pFile);
210         } catch (exception &e) {
211                 MSG_FATAL("%s", e.what());
212         }
213
214         return ret;
215 }
216
217 int MsgFflush(FILE *pFile)
218 {
219         if(!pFile) {
220                 MSG_FATAL("pFile NULL");
221                 return -1;
222         }
223
224         int ret = -1;
225
226         try {
227                 ret = fflush(pFile); /* return 0 if success */
228         } catch (exception &e) {
229                 MSG_FATAL("%s", e.what());
230         }
231
232         return ret;
233 }
234
235 int MsgFsync(FILE *pFile)
236 {
237         if(!pFile) {
238                 MSG_FATAL("pFile NULL");
239                 return -1;
240         }
241
242         int ret = -1;
243
244         try {
245                 ret = fdatasync(pFile->_fileno); /* return 0 if success */
246         } catch (exception &e) {
247                 MSG_FATAL("%s", e.what());
248         }
249
250         return ret;
251 }
252
253 bool MsgCreateFileName(char *pFileName)
254 {
255         if (pFileName == NULL) {
256                 MSG_DEBUG("[ERROR] pFileName is NULL");
257                 return false;
258         }
259
260         struct timespec ts;
261
262         try {
263                 if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
264                         MSG_DEBUG("clock_gettime() error: %s", g_strerror(errno));
265                         return false;
266                 }
267
268                 /* Create Random Number */
269                 srandom((unsigned int)ts.tv_nsec);
270
271                 MSG_DEBUG("ts.tv_nsec : %ld", ts.tv_nsec);
272
273                 /* between 1 - 1000000000 */
274                 snprintf(pFileName, MSG_FILENAME_LEN_MAX, "MSG_%lu.DATA", random()%1000000000+1);
275         } catch (exception& e) {
276                 MSG_FATAL("%s", e.what());
277                 return false;
278         }
279
280         return true;
281 }
282
283
284 bool MsgOpenAndReadFile(const char *pFileName, char **ppData, int *pDataSize)
285 {
286         if (!pFileName || !ppData || !pDataSize) {
287                 MSG_ERR("Invalid params");
288                 return false;
289         }
290
291         MSG_DEBUG("MsgOpenAndReadFile");
292
293         FILE *pFile = NULL;
294
295         char fullPath[MAX_FULL_PATH_SIZE] = {0};
296
297         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_IPC_DATA_PATH, pFileName);
298         MSG_SEC_DEBUG("open file name: %s", fullPath);
299
300         struct stat st;
301         if (stat(fullPath, &st) != 0) {
302                 MSG_SEC_ERR("stat(%s, &st) != 0", fullPath);
303                 return false;
304         }
305         if (S_ISDIR(st.st_mode)) {
306                 MSG_ERR("S_ISDIR(st.st_mode)");
307                 return false;
308         }
309
310         pFile = MsgOpenFile(fullPath, "rb");
311
312         if (pFile == NULL) {
313                 MSG_DEBUG("File Open Error: %s", g_strerror(errno));
314                 return false;
315         }
316
317         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
318                 MsgCloseFile(pFile);
319                 MSG_DEBUG("File Read Error: %s", g_strerror(errno));
320                 return false;
321         }
322
323         int FileSize = MsgFtell(pFile);
324
325         if (FileSize <= 0) {
326                 MSG_DEBUG("Filesize is error : %d", FileSize);
327                 *pDataSize = 0;
328                 MsgCloseFile(pFile);
329                 return false;
330         }
331
332         *ppData = new char[FileSize+1];
333         memset(*ppData, 0x00, (FileSize+1));
334
335         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
336                 MsgCloseFile(pFile);
337                 MSG_DEBUG("File seek Error: %s", g_strerror(errno));
338                 return false;
339         }
340
341         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
342                 MsgCloseFile(pFile);
343                 MSG_DEBUG("File Read Error: %s", g_strerror(errno));
344                 return false;
345         }
346
347         *pDataSize = FileSize;
348
349         MsgCloseFile(pFile);
350
351         return true;
352 }
353
354
355 bool MsgReadFileForDecode(FILE *pFile, char *pBuf, int length, int *nSize)
356 {
357         MSG_BEGIN();
358
359         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
360                 MSG_DEBUG("File Seek Error: %s", g_strerror(errno));
361                 MsgCloseFile(pFile);
362                 return false;
363         }
364
365         *nSize = MsgReadFile(pBuf, sizeof(char), length, pFile);
366
367         MSG_END();
368         return true;
369 }
370
371
372 bool MsgWriteIpcFile(const char *pFileName, const char *pData, int DataSize)
373 {
374         if (!pFileName) {
375                 MSG_DEBUG("NULL parameter, pFileName [%p], pData [%p]", pFileName, pData);
376                 return false;
377         }
378
379         char fullPath[MAX_FULL_PATH_SIZE] = {0};
380
381         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_IPC_DATA_PATH, pFileName);
382
383         FILE *pFile = MsgOpenFile(fullPath, "wb+");
384
385         if (pFile == NULL) {
386                 MSG_DEBUG("File Open Error: %s", g_strerror(errno));
387                 return false;
388         }
389
390         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
391                 MsgCloseFile(pFile);
392                 MSG_DEBUG("File Seek Error: %s", g_strerror(errno));
393                 return false;
394         }
395
396         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
397                 MsgCloseFile(pFile);
398                 MSG_DEBUG("File Write Error: %s", g_strerror(errno));
399                 return false;
400         }
401
402         MsgFflush(pFile);
403         MsgCloseFile(pFile);
404
405         return true;
406 }
407
408 int MsgReadSmilFile(const char *pFileName, char **ppData)
409 {
410         if (!pFileName) {
411                 MSG_DEBUG("pFileName is NULL");
412                 return -1;
413         }
414
415         int     nSize = 0;
416         char fullPath[MAX_FULL_PATH_SIZE] = {0};
417
418         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_SMIL_FILE_PATH, pFileName);
419
420         MSG_SEC_DEBUG("open file name: %s", fullPath);
421
422         FILE *pFile = MsgOpenFile(fullPath, "rb");
423
424         if (pFile == NULL) {
425                 MSG_DEBUG("File Open Error: %s", g_strerror(errno));
426                 return -1;
427         }
428
429         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
430                 MsgCloseFile(pFile);
431                 MSG_DEBUG("File Seek Error: %s", g_strerror(errno));
432                 return -1;
433         }
434
435         int FileSize = MsgFtell(pFile);
436
437         if (FileSize <= 0) {
438                 MSG_DEBUG("Filesize is error : %d", FileSize);
439                 MsgCloseFile(pFile);
440                 return FileSize;
441         }
442
443         *ppData = new char[FileSize + 1];
444         memset(*ppData, 0x00, (FileSize+1));
445
446         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
447                 MsgCloseFile(pFile);
448                 MSG_DEBUG("File Sead Error: %s", g_strerror(errno));
449                 return -1;
450         }
451
452         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
453                 MsgCloseFile(pFile);
454                 MSG_DEBUG("File Read Error: %s", g_strerror(errno));
455                 return -1;
456         }
457
458         /* ppData[FileSize] = '\0'; */
459
460         nSize = FileSize;
461         MsgCloseFile(pFile);
462
463         return nSize;
464 }
465
466
467 bool MsgWriteSmilFile(const char *pFilePath, char *pData, int DataSize)
468 {
469         if(!pFilePath) {
470                 MSG_DEBUG("pFilePath is NULL");
471                 return false;
472         }
473
474 #if 0
475         if (mkdir(MSG_SMIL_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
476                 if (errno == EEXIST) {
477                         MSG_SEC_DEBUG("The %s already exists", MSG_SMIL_FILE_PATH);
478                 } else {
479                         MSG_SEC_DEBUG("Error while mkdir %s", MSG_SMIL_FILE_PATH);
480                 }
481         }
482 #endif
483
484         FILE *pFile = MsgOpenFile(pFilePath, "wb+");
485
486         if (pFile == NULL) {
487                 MSG_DEBUG("File Open Error: %s", g_strerror(errno));
488                 return false;
489         }
490
491         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
492                 MsgCloseFile(pFile);
493                 MSG_DEBUG("File Seek Error: %s", g_strerror(errno));
494                 return false;
495         }
496
497         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
498                 MsgCloseFile(pFile);
499                 MSG_DEBUG("File Write Error: %s", g_strerror(errno));
500                 return false;
501         }
502
503         MsgFflush(pFile);
504         MsgCloseFile(pFile);
505
506         return true;
507 }
508
509
510 void MsgDeleteFile(const char *pFileName)
511 {
512         if (!pFileName) {
513                 MSG_FATAL("pFileName is NULL");
514                 return;
515         }
516
517         if (strlen(pFileName) == 0) {
518                 MSG_FATAL("pFileName has zero length");
519                 return;
520         }
521
522         char fullPath[MAX_FULL_PATH_SIZE] = {0};
523
524         try {
525                 snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_IPC_DATA_PATH, pFileName);
526
527                 MSG_SEC_DEBUG("%s", fullPath);
528
529                 if (remove(fullPath) != 0)
530                         MSG_SEC_ERR("File Delete Error [%s]: %s", fullPath, g_strerror(errno));
531         } catch (exception &e) {
532                 MSG_FATAL("%s", e.what());
533         }
534 }
535
536
537 void MsgDeleteSmilFile(const char *pFileName)
538 {
539         if (!pFileName) {
540                 MSG_FATAL("pFileName NULL");
541                 return;
542         }
543
544         try {
545                 char fullPath[MAX_FULL_PATH_SIZE] = {0};
546
547                 snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_SMIL_FILE_PATH, pFileName);
548
549                 if (remove(fullPath) != 0)
550                         MSG_SEC_ERR("File Delete Error [%s]: %s", fullPath, g_strerror(errno));
551         } catch (exception &e) {
552                 MSG_FATAL("%s", e.what());
553         }
554 }
555
556
557 bool MsgGetFileSize(const char *pFilePath, int *nSize)
558 {
559         if (!pFilePath) {
560                 MSG_FATAL("pFileName NULL");
561                 return false;
562         }
563
564         FILE *pFile = NULL;
565
566         pFile = MsgOpenFile(pFilePath, "rb");
567
568         if (!pFile) {
569                 MSG_DEBUG("File Open error: %s", g_strerror(errno));
570                 return false;
571         }
572
573         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
574                 MsgCloseFile(pFile);
575                 MSG_FATAL("File Read Error: %s", g_strerror(errno));
576                 return false;
577         }
578
579         *nSize = MsgFtell(pFile);
580
581         MsgCloseFile(pFile);
582
583         return true;
584 }
585
586
587 FILE *MsgOpenMMSFile(char *pFileName)
588 {
589         int len;
590
591         if (!pFileName) {
592                 MSG_DEBUG("pFileName NULL: %s", g_strerror(errno));
593                 return NULL;
594         }
595
596         len = strlen(pFileName);
597
598         for (int i = 0; i < len; i++) {
599                 switch (pFileName[i]) {
600                 case '*':
601                         pFileName[i] = '-';
602                         break;
603                 }
604         }
605
606         MSG_SEC_DEBUG("pFileName = %s", pFileName);
607
608         char fullPath[MAX_FULL_PATH_SIZE+1] = {0};
609
610         snprintf(fullPath, MAX_FULL_PATH_SIZE+1, "%s.mms", pFileName);
611
612         FILE *pFile = MsgOpenFile(fullPath, "wb+");
613
614         if (pFile == NULL) {
615                 MSG_ERR("File Open Error: %s", g_strerror(errno));
616                 return NULL;
617         }
618
619         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
620                 MsgCloseFile(pFile);
621                 MSG_ERR("File Read Error: %s", g_strerror(errno));
622                 return NULL;
623         }
624
625         return pFile;
626 }
627
628
629 bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int maxLen, int *pOffset )
630 {
631         if (!pFile || !pPtr || !pInBuffer || !pOffset) {
632                 MSG_FATAL(" NULL parameter passed");
633                 return false;
634         }
635
636         MSG_DEBUG("MsgWriteDataFromEncodeBuffer:");
637         MSG_DEBUG("pInBuffer %s", pInBuffer);
638         MSG_DEBUG("pPtr %d",  (*pPtr));
639         MSG_DEBUG("before to fwite %p", pFile);
640
641         if (MsgWriteFile(pInBuffer, sizeof(char), (*pPtr), pFile) != (size_t)(*pPtr)) {
642                 MSG_FATAL("MsgWriteFile failed");
643                 return false;
644         }
645
646         MSG_DEBUG("after to fwite \n");
647
648         MsgFflush(pFile);
649
650         memset(pInBuffer, 0, maxLen);
651
652         *pPtr = 0;
653
654         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
655                 MSG_FATAL("MsgFseek failed");
656                 return false;
657         }
658
659         *pOffset = MsgFtell(pFile);
660
661         if (*pOffset == -1L) {
662                 MSG_FATAL("MsgFtell failed");
663                 return false;
664         }
665
666         return true;
667 }
668
669
670 bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength)
671 {
672         FILE *pFile = NULL ;
673
674         if ((pFile = MsgOpenFile(pFullPath, "wb+")) == NULL) {
675                 MSG_FATAL("MsgOpenFile errer");
676                 return false;
677         }
678
679         if (MsgWriteFile(pBuff, sizeof(char), TotalLength, pFile) != (size_t)TotalLength) {
680                 MsgCloseFile(pFile);
681                 return false;
682         }
683
684         MsgFsync(pFile);        /* file is written to device immediately, it prevents missing file data from unexpected power off */
685         MsgFflush(pFile);
686         MsgCloseFile(pFile);
687
688         return true;
689 }
690
691
692 char *MsgOpenAndReadMmsFile(const char *szFilePath, int offset, int size, int *npSize)
693 {
694         FILE *pFile = NULL;
695         char *pData = NULL;
696         int     readSize = 0;
697
698         if (szFilePath == NULL) {
699                 MSG_ERR("szFilePath id NULL");
700                 goto __CATCH;
701         }
702
703         *npSize = 0;
704
705         pFile = MsgOpenFile(szFilePath, "rb");
706
707         if (pFile == NULL) {
708                 MSG_ERR("Can't open file: %s", g_strerror(errno));
709                 goto __CATCH;
710         }
711
712         if (size == -1) {
713                 if (MsgGetFileSize(szFilePath, & readSize) == false) {
714                         MSG_DEBUG("MsgGetFileSize: failed");
715                         goto __CATCH;
716                 }
717         } else {
718                 readSize = size;
719         }
720 /* restore Kies backup data size greater than FM_READ_WRITE_BUFFER_MAX */
721 #if 0
722         if (readSize > FM_READ_WRITE_BUFFER_MAX) {
723                 MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
724                 goto __CATCH;
725         }
726 #endif
727
728         pData = (char *)calloc(1, readSize + 1);
729         if ( NULL == pData ) {
730                 MSG_ERR("pData MemAlloc Fail : %s", g_strerror(errno) );
731                 goto __CATCH;
732         }
733
734         if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
735                 MSG_ERR("FmSeekFile failed : %s", g_strerror(errno) );
736                 goto __CATCH;
737         }
738
739         *npSize = MsgReadFile(pData, sizeof(char), readSize, pFile);
740
741         MsgCloseFile(pFile);
742
743         pFile = NULL;
744
745         *(pData + (*npSize)) = '\0';
746
747         return pData;
748
749 __CATCH:
750
751         if (pData) {
752                 free(pData);
753                 pData = NULL;
754         }
755
756         *npSize = 0;
757
758         if (pFile != NULL) {
759                 MsgCloseFile(pFile);
760                 pFile = NULL;
761         }
762
763         return NULL;
764 }
765
766 /* it is equivalent to "rm -rf pDirPath" */
767 int MsgRmRf(char *pDirPath)
768 {
769         struct dirent *d = NULL;
770         DIR *dir;
771
772         dir = opendir(pDirPath);
773
774         if (dir == NULL) {
775                 MSG_FATAL("error opendir: %s", g_strerror(errno));
776                 return -1;
777         }
778
779         int size = strlen(pDirPath) + 256;
780
781         char *path = (char*)malloc(size);
782
783         if (path == NULL) {
784                 MSG_DEBUG("path is NULL");
785                 closedir(dir);
786                 return -1;
787         }
788
789         bzero(path, size);
790
791         errno = 0;
792         while ((d = readdir(dir)) != NULL) {
793                 if (d->d_type == DT_DIR) {
794                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
795
796                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
797                                 continue;
798
799                         MsgRmRf(path);
800
801                         if (rmdir(path) != 0) {
802                                 if (path != NULL)
803                                         free(path);
804
805                                 closedir(dir);
806
807                                 MSG_FATAL("error rmdir: %s", g_strerror(errno));
808
809                                 return -1;
810                         }
811                 } else {
812                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
813
814                         if (MsgDrmIsDrmFile(path))
815                                 MsgDrmUnregisterFile(path);
816
817                         if (remove(path) != 0) {
818                                 if (path != NULL)
819                                         free(path);
820
821                                 closedir(dir);
822
823                                 MSG_FATAL("error remove: %s", g_strerror(errno));
824
825                                 return -1;
826                         }
827                 }
828                 d = NULL;
829         }
830
831         closedir(dir);
832
833         if (path != NULL)
834                 free(path);
835
836         if (errno != 0)
837                 return -1;
838
839         return 0;
840 }
841
842
843 int MsgGetFileSize(const char *pFileName)
844 {
845         struct stat file_stat;
846
847         if (lstat(pFileName, &file_stat)) {
848                 MSG_FATAL("error lstat: %s", g_strerror(errno));
849                 return -1;
850         }
851
852         return file_stat.st_size;
853 }
854
855
856 /* it is equivalent to "du dir_path" */
857 unsigned int MsgDu(const char *pDirPath)
858 {
859         struct dirent *d = NULL;
860         DIR *dir;
861
862         dir = opendir(pDirPath);
863
864         if (dir == NULL) {
865                 MSG_FATAL("error opendir: %s", g_strerror(errno));
866                 return -1;
867         }
868
869         int size = strlen(pDirPath) + 256;
870         char *path = (char*)malloc(size);
871         if (path == NULL) {
872                 closedir(dir);
873                 return -1;
874         }
875
876         bzero(path, size);
877
878         unsigned int totalFileSize = 0;
879
880         errno = 0;
881         while ((d = readdir(dir)) != NULL) {
882                 if(d->d_type == DT_DIR) {
883                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
884
885                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
886                                 continue;
887
888                         unsigned int dirSize = MsgDu(path);
889
890                         if (dirSize == 0) {
891                                 MSG_FATAL("error MsgDu");
892                                 closedir(dir);
893                                 free(path);
894                                 return dirSize;
895                         }
896
897                         totalFileSize += dirSize;
898                 } else {
899                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
900                         int fileSize = MsgGetFileSize(path);
901
902                         if (fileSize < 0) {
903                                 MSG_FATAL("error MsgGetFileSize");
904                                 closedir(dir);
905                                 free(path);
906                                 return fileSize;
907                         }
908
909                         totalFileSize += fileSize;
910                 }
911                 d = NULL;
912         }
913
914         closedir(dir);
915
916         free(path);
917
918         if (errno != 0)
919                 return 0;
920
921         return totalFileSize;
922 }
923
924
925 bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
926 {
927         if (!pFilePath) {
928                 MSG_FATAL("NULL check error, pFileName %p, pData %p", pFilePath, pData);
929                 return false;
930         }
931
932         char fullPath[MAX_FULL_PATH_SIZE] = {0};
933
934         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s", pFilePath);
935
936         FILE *pFile = MsgOpenFile(fullPath, "a+");
937
938         if (pFile == NULL) {
939                 MSG_FATAL("File Open Error: %s", g_strerror(errno));
940                 return false;
941         }
942
943         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
944                 MsgCloseFile(pFile);
945                 MSG_FATAL("File Sead Error: %s", g_strerror(errno));
946                 return false;
947         }
948
949         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
950                 MsgCloseFile(pFile);
951                 MSG_FATAL("File Write Error: %s", g_strerror(errno));
952                 return false;
953         }
954
955         MsgFsync(pFile);        /*file is written to device immediately, it prevents missing file data from unexpected power off */
956         MsgFflush(pFile);
957         MsgCloseFile(pFile);
958         return true;
959 }
960
961 void MsgMmsInitDir()
962 {
963         struct dirent *d = NULL;
964         DIR* dir = NULL;
965
966         dir = opendir(MSG_DATA_PATH);
967
968         if (dir == NULL) {
969                 MSG_FATAL("error opendir: %s", g_strerror(errno));
970                 return;
971         }
972
973         /* Remove temporal Mms folder */
974         while ((d = readdir(dir)) != NULL) {
975                 if (d->d_type == DT_DIR) {
976                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
977                                 continue;
978
979                         if(strstr(d->d_name, ".dir") != NULL) {
980                                 char filePath[MSG_FILEPATH_LEN_MAX] = {0, };
981                                 snprintf(filePath, MSG_FILEPATH_LEN_MAX, "%s%s", MSG_DATA_PATH, d->d_name);
982
983                                 MsgRmRf(filePath);
984                                 rmdir(filePath);
985                         }
986                 }
987                 d = NULL;
988         }
989
990         closedir(dir);
991 }
992
993 /* mode : R_OK, W_OK, X_OK, or the existence test F_OK. */
994 bool MsgAccessFile(const char *filepath, int mode)
995 {
996         int ret;
997         if (filepath == NULL) {
998                 MSG_DEBUG("filepath is NULL");
999                 return false;
1000         }
1001
1002         MSG_SEC_DEBUG("request access path = %s, mode = %d", filepath, mode);
1003
1004         ret = access(filepath, mode);
1005
1006
1007         if (ret) {
1008                 MSG_DEBUG("Fail to access file, ret = %d", ret);
1009                 return false;
1010         }
1011
1012         return true;
1013 }
1014
1015
1016 bool MsgChmod(const char *filepath, int mode)
1017 {
1018 #if 0
1019         struct stat lstat_info;
1020         struct stat fstat_info;
1021         int fd;
1022
1023         if (lstat(filepath, &lstat_info) == -1) {
1024                 MSG_SEC_DEBUG("No such file as [%s].", filepath);
1025                 return false;
1026         }
1027
1028         fd = open(filepath, O_RDONLY);
1029
1030         if (fd == -1) {
1031                 MSG_SEC_DEBUG("Fail to open [%s].", filepath);
1032                 return false;
1033         }
1034
1035         if (fstat(fd, &fstat_info) == -1) {
1036                 MSG_SEC_DEBUG("Fail to fstat [%s].", filepath);
1037                 close(fd);
1038                 return false;
1039         }
1040
1041         if (lstat_info.st_mode == fstat_info.st_mode &&
1042                         lstat_info.st_ino == fstat_info.st_ino  &&
1043                         lstat_info.st_dev == fstat_info.st_dev) {
1044                 if (fchmod(fd, mode) < 0) {
1045                         MSG_SEC_DEBUG("Fail to fchmod [%s].", filepath);
1046                         close(fd);
1047                         return false;
1048                 }
1049         }
1050
1051         close(fd);
1052 #endif
1053         return true;
1054 }
1055
1056
1057 bool MsgChown(const char *filepath, int uid, int gid)
1058 {
1059         struct stat lstat_info;
1060         struct stat fstat_info;
1061         int fd;
1062
1063         if (lstat(filepath, &lstat_info) == -1) {
1064                 MSG_SEC_INFO("No such file as [%s].", filepath);
1065                 return false;
1066         }
1067
1068         fd = open(filepath, O_RDONLY);
1069
1070         if (fd == -1) {
1071                 MSG_SEC_INFO("Fail to open [%s].", filepath);
1072                 return false;
1073         }
1074
1075         if (fstat(fd, &fstat_info) == -1) {
1076                 MSG_SEC_INFO("Fail to fstat [%s].", filepath);
1077                 close(fd);
1078                 return false;
1079         }
1080
1081         if (lstat_info.st_mode == fstat_info.st_mode &&
1082                         lstat_info.st_ino == fstat_info.st_ino  &&
1083                         lstat_info.st_dev == fstat_info.st_dev) {
1084                 if (fchown(fd, uid, gid) < 0) {
1085                         MSG_SEC_INFO("Fail to fchown [%s].", filepath);
1086                         close(fd);
1087                         return false;
1088                 }
1089         }
1090
1091         close(fd);
1092         return true;
1093 }
1094
1095 bool MsgCreateFile(const char *pFilePath, char *pData, int DataSize)
1096 {
1097         if(!pFilePath) {
1098                 MSG_DEBUG("pFilePath is NULL");
1099                 return false;
1100         }
1101
1102         FILE *pFile = MsgOpenFile(pFilePath, "wb+");
1103
1104         if (pFile == NULL) {
1105                 MSG_ERR("File Open Error: %s", g_strerror(errno));
1106                 return false;
1107         }
1108
1109         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
1110                 MsgCloseFile(pFile);
1111                 MSG_ERR("File Seek Error: %s", g_strerror(errno));
1112                 return false;
1113         }
1114
1115         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
1116                 MsgCloseFile(pFile);
1117                 MSG_ERR("File Write Error: %s", g_strerror(errno));
1118                 return false;
1119         }
1120
1121         MsgFflush(pFile);
1122         MsgFsync(pFile);
1123         MsgCloseFile(pFile);
1124
1125         return true;
1126 }
1127
1128 char *MsgGetDirName(char *file_path)
1129 {
1130         return g_path_get_dirname(file_path);
1131 }
1132
1133
1134 char *MsgGetFileName(char *file_path)
1135 {
1136         return g_path_get_basename(file_path);
1137 }
1138
1139
1140 int MsgCheckFilepathSmack(const char *app_smack_label, char *file_path)
1141 {
1142         int err = MSG_SUCCESS;
1143
1144         char *path_smack_label = NULL;
1145         char *dir_smack_label = NULL;
1146         char *dir_name = NULL;
1147
1148         if (!file_path || file_path[0] == '\0') {
1149                 return MSG_SUCCESS;
1150         }
1151
1152         struct stat st;
1153         if (stat(file_path, &st) != 0) {
1154                 MSG_SEC_ERR("stat(%s, &st) != 0", file_path);
1155                 return MSG_ERR_PERMISSION_DENIED;
1156         }
1157         if (S_ISDIR(st.st_mode)) {
1158                 MSG_ERR("S_ISDIR(st.st_mode)");
1159                 return MSG_ERR_INVALID_PARAMETER;
1160         }
1161
1162         dir_name = MsgGetDirName(file_path);
1163         if (!dir_name || !g_strcmp0(dir_name, file_path)) {
1164                 MSG_SEC_ERR("!dir_name || !g_strcmp0(dir_name, %s)", file_path);
1165                 err = MSG_ERR_INVALID_PARAMETER;
1166                 goto __RETURN;
1167         }
1168
1169         smack_getlabel(dir_name, &dir_smack_label, SMACK_LABEL_ACCESS);
1170         if (dir_smack_label == NULL) {
1171                 MSG_ERR("smack_getlabel failed (dir_smack_label)");
1172                 err = MSG_ERR_PERMISSION_DENIED;
1173                 goto __RETURN;
1174         }
1175
1176         if (smack_have_access(app_smack_label, dir_smack_label, "RX") < 1) {
1177                 MSG_ERR("smack_have_access failed (dir_smack_label)");
1178                 err = MSG_ERR_PERMISSION_DENIED;
1179                 goto __RETURN;
1180         }
1181
1182         smack_getlabel(file_path, &path_smack_label, SMACK_LABEL_ACCESS);
1183         if (path_smack_label == NULL) {
1184                 MSG_ERR("smack_getlabel failed (path_smack_label)");
1185                 err = MSG_ERR_PERMISSION_DENIED;
1186                 goto __RETURN;
1187         }
1188
1189         if (smack_have_access(app_smack_label, path_smack_label, "R") < 1) {
1190                 MSG_ERR("smack_have_access failed (path_smack_label)");
1191                 err = MSG_ERR_PERMISSION_DENIED;
1192                 goto __RETURN;
1193         }
1194
1195         MSG_DEBUG("smack_have_access pass successfully");
1196
1197 __RETURN:
1198         MSG_FREE(path_smack_label);
1199         MSG_FREE(dir_smack_label);
1200         MSG_FREE(dir_name);
1201         return err;
1202 }
1203
1204
1205 void MsgGetMimeType(char *filePath, char *mimeType, int size)
1206 {
1207         aul_get_mime_from_file(filePath, mimeType, size);
1208 }
1209
1210 int MsgTcsScanFile(const char *filepath, int *bLevel)
1211 {
1212         MSG_BEGIN();
1213
1214         int (*_csr_cs_context_create)(void **handle);
1215         int (*_csr_cs_scan_file)(void *handle, const char *filepath, void **malware);
1216         int (*_csr_cs_context_destroy)(void *handle);
1217         int (*_csr_cs_malware_get_severity)(void *malware, void *severity);
1218         int (*_csr_cs_malware_get_name)(void *malware, char **name);
1219
1220         if (MsgAccessFile(filepath, R_OK) == false) {
1221                 MSG_SEC_DEBUG("not exist source file [%s]", filepath);
1222                 return -1;
1223         }
1224
1225         MSG_SEC_DEBUG("Scanning file name : %s\n", filepath);
1226
1227         void *lib_handle = NULL;
1228         lib_handle = dlopen(PATH_LIBCSR_CLIENT, RTLD_LAZY);
1229         if (!lib_handle) {
1230                 MSG_ERR("Unable to open %s", PATH_LIBCSR_CLIENT);
1231                 return 0;
1232         }
1233
1234         _csr_cs_context_create = (int(*)(void**))dlsym(lib_handle, "csr_cs_context_create");
1235         _csr_cs_scan_file = (int(*)(void*, const char*, void**))dlsym(lib_handle, "csr_cs_scan_file");
1236         _csr_cs_context_destroy = (int(*)(void*))dlsym(lib_handle, "csr_cs_context_destroy");
1237         _csr_cs_malware_get_severity = (int(*)(void*, void*))dlsym(lib_handle, "csr_cs_malware_get_severity");
1238         _csr_cs_malware_get_name = (int(*)(void*, char**))dlsym(lib_handle, "csr_cs_malware_get_name");
1239
1240         int ret = 0;
1241         if (!_csr_cs_context_create || !_csr_cs_scan_file || !_csr_cs_context_destroy
1242                         || !_csr_cs_malware_get_severity || !_csr_cs_malware_get_name) {
1243                 MSG_ERR("Failed to load CSR symbols");
1244                 if (lib_handle)
1245                                 dlclose(lib_handle);
1246                 return -1;
1247         }
1248
1249         void *csr_handle = NULL;
1250         ret = _csr_cs_context_create(&csr_handle);
1251         if (ret != 0) {
1252                 MSG_DEBUG("csr_cs_context_create error: err = %d\n", ret);
1253                 if (lib_handle)
1254                                 dlclose(lib_handle);
1255                 return -1;
1256         }
1257
1258         do {
1259                 void *detected = NULL;
1260                 ret = _csr_cs_scan_file(csr_handle, filepath, &detected);
1261                 if (ret != 0) {
1262                         MSG_DEBUG("csr_cs_scan_file fail: err = %d\n", ret);
1263                         break;
1264                 }
1265
1266                 if (NULL == detected) {
1267                         MSG_DEBUG("Nothing detected");
1268                         break;
1269                 }
1270
1271                 int severity = 0x01; /* CSR_CS_SEVERITY_LOW */
1272                 ret = _csr_cs_malware_get_severity(detected, &severity);
1273                 if (ret != 0) {
1274                         MSG_DEBUG("csr_cs_malware_get_severity error: err = %d\n", ret);
1275                 }
1276                 MSG_DEBUG(" +-- Malware Severity class: %d\n", severity);
1277
1278                 char *name = NULL;
1279                 ret = _csr_cs_malware_get_name(detected, &name);
1280                 if (ret != 0) {
1281                         MSG_DEBUG("csr_cs_malware_get_name error: err = %d\n", ret);
1282                 }
1283                 MSG_SEC_DEBUG(" +-- Malware Name: [%s]\n", name);
1284
1285                 if (name)
1286                         free(name);
1287
1288                 if (bLevel)
1289                         *bLevel = severity;
1290
1291         } while (0);
1292
1293         ret = _csr_cs_context_destroy(csr_handle);
1294         if (ret != 0)
1295                 MSG_DEBUG("csr_cs_context_destroy error: err = %d\n", ret);
1296
1297         if (lib_handle)
1298                 dlclose(lib_handle);
1299
1300         MSG_END();
1301         return 0;
1302 }
1303
1304