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