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