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