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