Merge branch 'master' into tizen_2.0
[platform/core/messaging/msg-service.git] / utils / MsgUtilFile.cpp
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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 <string.h>
24 #include <dirent.h>
25 #include <unistd.h>     //sync()
26
27 #include "MsgStorageTypes.h"
28 #include "MsgDebug.h"
29 #include "MsgException.h"
30 #include "MsgUtilFile.h"
31 #include "MsgMmsTypes.h"
32 #include "MsgInternalTypes.h"
33 #include "MsgDrmWrapper.h"
34
35
36 /*==================================================================================================
37                                      FUNCTION IMPLEMENTATION
38 ==================================================================================================*/
39 // File operation wrappers
40 FILE *MsgOpenFile(const char *filepath, const char *opt)
41 {
42         if (!filepath || !opt) {
43                 MSG_FATAL("Null parameter");
44                 return NULL;
45         }
46
47         MSG_DEBUG("[FILE] filepath : [%s], opt [%s]", filepath, opt);
48
49         FILE *pFile = NULL;
50
51         try {
52                 pFile = fopen(filepath, opt);
53                 MSG_DEBUG("[FILE] pFile [%p]", pFile);
54         } catch (exception &e) {
55                 MSG_FATAL("%s", e.what());
56                 return NULL;
57         }
58
59         return pFile;
60 }
61
62 void MsgCloseFile(FILE *pFile)
63 {
64         if (!pFile) {
65                 MSG_FATAL("NULL parameter");
66                 return;
67         }
68
69         MSG_DEBUG("[FILE] pFile [%p]", pFile);
70
71         try {
72                 fclose(pFile);
73         } catch (exception &e) {
74                 MSG_FATAL("%s", e.what());
75         }
76 }
77
78 int MsgFseek(FILE *pFile, long int offset, int origin)
79 {
80         if (!pFile) {
81                 MSG_FATAL("pFile NULL");
82                 return -1;
83         }
84
85         int ret = -1;
86
87         MSG_DEBUG("[FILE] pFile [%p], offset [%d], origin [%d]", pFile, offset, origin);
88
89         try {
90                 ret = fseek(pFile, offset, origin);             // return 0, if success.
91         } catch (exception &e) {
92                 MSG_FATAL("%s", e.what());
93                 return -1;
94         }
95
96         return ret;
97 }
98
99 size_t MsgWriteFile(const char *pData, size_t size, size_t count, FILE *pFile)
100 {
101         if (!pData || !pFile) {
102                 MSG_FATAL("pData or pFile NULL");
103                 return 0;
104         }
105
106         size_t nWrite = 0;
107
108         MSG_DEBUG("[FILE] pData [%p], size [%d], count [%d], pFile [%p]", pData, size, count, pFile);
109
110         try {
111                 nWrite = fwrite(pData, size, count, pFile);
112         } catch (exception &e) {
113                 MSG_FATAL("%s", e.what());
114         }
115
116         return nWrite;
117 }
118
119 size_t MsgReadFile(void *pData, size_t size, size_t count, FILE *pFile)
120 {
121         if (!pData || !pFile) {
122                 MSG_FATAL("pData or pFile NULL");
123                 return 0;
124         }
125
126         size_t nRead = 0;
127
128         try {
129                 nRead = fread(pData, size, count, pFile);
130         } catch (exception &e) {
131                 MSG_FATAL("%s", e.what());
132         }
133
134         return nRead;
135 }
136
137 long int MsgFtell(FILE *pFile)
138 {
139         if (!pFile) {
140                 MSG_FATAL("pFile NULL");
141                 return -1L;
142         }
143
144         long int ret = -1L; // -1L return if error occured.
145
146         try {
147                 ret = ftell(pFile);
148         } catch (exception &e) {
149                 MSG_FATAL("%s", e.what());
150         }
151
152         return ret;
153 }
154
155 int MsgFflush(FILE *pFile)
156 {
157         if(!pFile) {
158                 MSG_FATAL("pFile NULL");
159                 return -1;
160         }
161
162         int ret = -1;
163
164         try {
165                 ret = fflush(pFile);            // return 0 if success
166         } catch (exception &e) {
167                 MSG_FATAL("%s", e.what());
168         }
169
170         return ret;
171 }
172
173 int MsgFsync(FILE *pFile)
174 {
175         if(!pFile) {
176                 MSG_FATAL("pFile NULL");
177                 return -1;
178         }
179
180         int ret = -1;
181
182         try {
183                 ret = fdatasync(pFile->_fileno);        // return 0 if success
184         } catch (exception &e) {
185                 MSG_FATAL("%s", e.what());
186         }
187
188         return ret;
189 }
190
191 bool MsgCreateFileName(char *pFileName)
192 {
193         if (pFileName == NULL) {
194                 MSG_DEBUG("[ERROR] pFileName is NULL");
195                 return false;
196         }
197
198         struct timespec ts;
199
200         try {
201                 if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
202                         MSG_DEBUG("clock_gettime() error: %s", strerror(errno));
203                         return false;
204                 }
205
206                 // Create Random Number
207                 srandom((unsigned int)ts.tv_nsec);
208
209                 MSG_DEBUG("ts.tv_nsec : %d", ts.tv_nsec);
210
211                 // between 1 - 1000000000
212                 snprintf(pFileName, MSG_FILENAME_LEN_MAX, "MSG_%lu.DATA", random()%1000000000+1);
213         } catch (exception& e) {
214                 MSG_FATAL("%s", e.what());
215                 return false;
216         }
217
218         return true;
219 }
220
221
222 bool MsgOpenAndReadFile(const char *pFileName, char **ppData, int *pDataSize)
223 {
224         MSG_DEBUG("MsgOpenAndReadFile");
225
226         FILE *pFile = NULL;
227
228         char fullPath[MAX_FULL_PATH_SIZE] = {0};
229
230         snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
231         MSG_DEBUG("open file name: %s", fullPath);
232
233
234         pFile = MsgOpenFile(fullPath, "rb");
235
236         if (pFile == NULL) {
237                 MSG_DEBUG("File Open Error: %s", strerror(errno));
238                 return false;
239         }
240
241         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
242                 MsgCloseFile(pFile);
243                 MSG_DEBUG("File Read Error: %s", strerror(errno));
244                 return false;
245         }
246
247         int FileSize = MsgFtell(pFile);
248
249         if (FileSize <= 0) {
250                 MSG_DEBUG("Filesize is error : %d", FileSize);
251                 *pDataSize = 0;
252                 MsgCloseFile(pFile);
253                 return false;
254         }
255
256         *ppData = new char[FileSize+1];
257         memset(*ppData, 0x00, (FileSize+1));
258
259         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
260                 MsgCloseFile(pFile);
261                 MSG_DEBUG("File seek Error: %s", strerror(errno));
262                 return false;
263         }
264
265         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
266                 MsgCloseFile(pFile);
267                 MSG_DEBUG("File Read Error: %s", strerror(errno));
268                 return false;
269         }
270
271         *pDataSize = FileSize;
272
273         MsgCloseFile(pFile);
274
275         return true;
276 }
277
278
279 bool MsgReadFileForDecode(FILE *pFile, char *pBuf, int length, int *nSize)
280 {
281         MSG_BEGIN();
282
283         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
284                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
285                 MsgCloseFile(pFile);
286                 return false;
287         }
288
289         *nSize = MsgReadFile(pBuf, sizeof(char), length, pFile);
290
291         MSG_END();
292         return true;
293 }
294
295
296 bool MsgWriteIpcFile(const char *pFileName, const char *pData, int DataSize)
297 {
298         if (!pFileName) {
299                 MSG_DEBUG("NULL parameter, pFileName [%p], pData [%p]", pFileName, pData);
300                 return false;
301         }
302
303         char fullPath[MAX_FULL_PATH_SIZE] = {0};
304
305         snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
306
307         FILE *pFile = MsgOpenFile(fullPath, "wb+");
308
309         if (pFile == NULL) {
310                 MSG_DEBUG("File Open Error: %s", strerror(errno));
311                 return false;
312         }
313
314         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
315                 MsgCloseFile(pFile);
316                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
317                 return false;
318         }
319
320         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
321                 MsgCloseFile(pFile);
322                 MSG_DEBUG("File Write Error: %s", strerror(errno));
323                 return false;
324         }
325
326         MsgFflush(pFile);
327         MsgCloseFile(pFile);
328
329         if (chmod(fullPath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ) != 0) {
330                 MSG_DEBUG("File chmod Error: %s", strerror(errno));
331         }
332
333         if (chown(fullPath, 0, 6502 ) != 0) {
334                 MSG_DEBUG("File chown Error: %s", strerror(errno));
335         }
336
337         return true;
338 }
339
340 int MsgReadSmilFile(const char *pFileName, char **ppData)
341 {
342         if (!pFileName) {
343                 MSG_DEBUG("pFileName is NULL");
344                 return -1;
345         }
346
347         int     nSize = 0;
348         char fullPath[MAX_FULL_PATH_SIZE] = {0};
349
350         snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
351
352         MSG_DEBUG("open file name: %s", fullPath);
353
354         FILE *pFile = MsgOpenFile(fullPath, "rb");
355
356         if (pFile == NULL) {
357                 MSG_DEBUG("File Open Error: %s", strerror(errno));
358                 return -1;
359         }
360
361         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
362                 MsgCloseFile(pFile);
363                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
364                 return -1;
365         }
366
367         int FileSize = MsgFtell(pFile);
368
369         if (FileSize <= 0) {
370                 MSG_DEBUG("Filesize is error : %d", FileSize);
371                 MsgCloseFile(pFile);
372                 return FileSize;
373         }
374
375         *ppData = new char[FileSize + 1];
376
377         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
378                 MsgCloseFile(pFile);
379                 MSG_DEBUG("File Sead Error: %s", strerror(errno));
380                 return -1;
381         }
382
383         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
384                 MsgCloseFile(pFile);
385                 MSG_DEBUG("File Read Error: %s", strerror(errno));
386                 return -1;
387         }
388
389         ppData[FileSize] = '\0';
390
391         nSize = FileSize;
392
393         MsgCloseFile(pFile);
394
395         return nSize;
396 }
397
398
399 bool MsgWriteSmilFile(const char *pFilePath,char *pData, int DataSize)
400 {
401         if(!pFilePath) {
402                 MSG_DEBUG("pFilePath is NULL");
403                 return false;
404         }
405
406         if (mkdir(MSG_SMIL_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
407                 if (errno == EEXIST) {
408                         MSG_DEBUG("The %s already exists", MSG_SMIL_FILE_PATH);
409                 } else {
410                         MSG_DEBUG("Error while mkdir %s", MSG_SMIL_FILE_PATH);
411                 }
412         }
413
414         FILE *pFile = MsgOpenFile(pFilePath, "wb+");
415
416         if (pFile == NULL) {
417                 MSG_DEBUG("File Open Error: %s", strerror(errno));
418                 return false;
419         }
420
421         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
422                 MsgCloseFile(pFile);
423                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
424                 return false;
425         }
426
427         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
428                 MsgCloseFile(pFile);
429                 MSG_DEBUG("File Write Error: %s", strerror(errno));
430                 return false;
431         }
432
433         MsgFflush(pFile);
434         MsgCloseFile(pFile);
435
436         return true;
437 }
438
439
440 void MsgDeleteFile(const char *pFileName)
441 {
442         if (!pFileName) {
443                 MSG_FATAL("pFileName is NULL");
444                 return;
445         }
446
447         if (strlen(pFileName) == 0) {
448                 MSG_FATAL("pFileName has zero length");
449                 return;
450         }
451
452         char fullPath[MAX_FULL_PATH_SIZE] = {0};
453
454         try {
455                 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
456
457                 MSG_DEBUG("%s", fullPath);
458
459                 if (remove(fullPath) != 0)
460                         MSG_FATAL("File Delete Error [%s]: %s", fullPath, strerror(errno));
461         } catch (exception &e) {
462                 MSG_FATAL ("%s", e.what());
463         }
464
465 }
466
467
468 void MsgDeleteSmilFile(const char *pFileName)
469 {
470         if (!pFileName ) {
471                 MSG_FATAL("pFileName NULL");
472                 return;
473         }
474
475         try {
476                 char fullPath[MAX_FULL_PATH_SIZE] = {0};
477
478                 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
479
480                 if (remove(fullPath) != 0)
481                         MSG_FATAL("File Delete Error [%s]: %s", fullPath, strerror(errno));
482         } catch (exception &e) {
483                 MSG_FATAL("%s", e.what());
484         }
485 }
486
487
488 bool MsgGetFileSize(const char *pFilePath, int *nSize)
489 {
490         if (!pFilePath) {
491                 MSG_FATAL("pFileName NULL");
492                 return false;
493         }
494
495         FILE *pFile = NULL;
496
497         pFile = MsgOpenFile(pFilePath, "rb");
498
499         if (!pFile) {
500                 MSG_DEBUG("File Open error: %s", strerror(errno));
501                 return false;
502         }
503
504         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
505                 MsgCloseFile(pFile);
506                 MSG_FATAL("File Read Error: %s", strerror(errno));
507                 return false;
508         }
509
510         *nSize = MsgFtell(pFile);
511
512         MsgCloseFile(pFile);
513
514         return true;
515 }
516
517
518 FILE *MsgOpenMMSFile(char *pFileName)
519 {
520         int len;
521
522         if (!pFileName) {
523                 MSG_DEBUG("pFileName NULL: %s", strerror(errno));
524                 return NULL;
525         }
526
527         len = strlen(pFileName);
528
529         for (int i = 0; i < len; i++) {
530                 switch (pFileName[i]) {
531                 case '*':
532                         pFileName[i] = '-';
533                         break;
534                 }
535         }
536
537         MSG_DEBUG("pFileName = %s", pFileName);
538
539         char fullPath[MAX_FULL_PATH_SIZE+1] = {0};
540
541         snprintf(fullPath, MAX_FULL_PATH_SIZE+1, "%s.mms", pFileName);
542
543         FILE *pFile = MsgOpenFile(fullPath, "wb+");
544
545         if (pFile == NULL) {
546                 MSG_FATAL("File Open Error: %s", strerror(errno));
547                 return NULL;
548         }
549
550         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
551                 MsgCloseFile(pFile);
552                 MSG_DEBUG("File Read Error: %s", strerror(errno));
553                 return NULL;
554         }
555
556         return pFile;
557 }
558
559
560 bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int maxLen, int *pOffset )
561 {
562         if (!pFile || !pPtr || !pInBuffer || !pOffset) {
563                 MSG_FATAL(" NULL parameter passed");
564                 return false;
565         }
566
567         MSG_DEBUG("MsgWriteDataFromEncodeBuffer:");
568         MSG_DEBUG("pInBuffer %x", pInBuffer);
569         MSG_DEBUG("pPtr %d",  (*pPtr));
570         MSG_DEBUG("before to fwite %x", pFile);
571
572         if (MsgWriteFile(pInBuffer, sizeof(char), (*pPtr), pFile) != (size_t)(*pPtr)) {
573                 MSG_FATAL("MsgWriteFile failed");
574                 return false;
575         }
576
577         MSG_DEBUG("after to fwite \n");
578
579         MsgFflush(pFile);
580
581         memset( pInBuffer, 0, maxLen );
582
583         *pPtr = 0;
584
585         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
586                 MSG_FATAL("MsgFseek failed");
587                 return false;
588         }
589
590         *pOffset = MsgFtell(pFile);
591
592         if (*pOffset == -1L) {
593                 MSG_FATAL("MsgFtell failed");
594                 return false;
595         }
596
597         return true;
598 }
599
600
601 bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength)
602 {
603         FILE *pFile = NULL ;
604         mode_t file_mode;
605
606         file_mode = (S_IRUSR | S_IWUSR);
607
608         if ((pFile = MsgOpenFile(pFullPath, "wb+")) == NULL) {
609                 MSG_FATAL("MsgOpenFile errer");
610                 return false;
611         }
612
613         if (MsgWriteFile(pBuff, sizeof(char), TotalLength, pFile) != (size_t)TotalLength) {
614                 MsgCloseFile( pFile );
615                 return false;
616         }
617
618         MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
619         MsgFflush(pFile);
620         MsgCloseFile(pFile);
621
622         if (chmod(pFullPath, file_mode) < 0)
623                 MSG_FATAL("File chmod Error: %s", strerror(errno));
624
625         return true;
626 }
627
628
629 char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *npSize )
630 {
631         FILE *pFile = NULL;
632         char *pData = NULL;
633         int     readSize = 0;
634
635         if (szFilePath == NULL) {
636                 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] szFilePath id NULL");
637                 goto __CATCH;
638         }
639
640         *npSize = 0;
641
642         pFile = MsgOpenFile( szFilePath, "rb" );
643
644         if (pFile == NULL) {
645                 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] Can't open filepath", strerror(errno));
646                 goto __CATCH;
647         }
648
649         if( size == -1 ) {
650                 if (MsgGetFileSize(szFilePath, & readSize) == false) {
651                         MSG_DEBUG("MsgGetFileSize: failed");
652                         goto __CATCH;
653                 }
654         } else {
655                 readSize = size;
656         }
657
658         if (readSize > FM_READ_WRITE_BUFFER_MAX) {
659                 MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
660                 goto __CATCH;
661         }
662
663         pData = (char *)malloc(readSize + 1);
664         if ( NULL == pData ) {
665                 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] pData MemAlloc Fail", strerror(errno) );
666                 goto __CATCH;
667         }
668         memset( pData, 0, readSize + 1 );
669
670         if (MsgFseek( pFile, offset, SEEK_SET) < 0) {
671                 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] FmSeekFile failed", strerror(errno) );
672                 goto __CATCH;
673         }
674
675         *npSize = MsgReadFile(pData, sizeof(char), readSize, pFile);
676
677         MsgCloseFile(pFile);
678
679         pFile = NULL;
680
681         *(pData + (*npSize)) = '\0';
682
683         return pData;
684
685 __CATCH:
686
687         if (pData) {
688                 free( pData );
689                 pData = NULL;
690         }
691
692         *npSize = 0;
693
694         if (pFile != NULL) {
695                 MsgCloseFile( pFile );
696                 pFile = NULL;
697         }
698
699         return NULL;
700 }
701
702 // it is equivalent to "rm -rf pDirPath"
703 int MsgRmRf(char *pDirPath)
704 {
705         struct dirent *d;
706         DIR *dir;
707
708         dir = opendir(pDirPath);
709
710         if (dir == NULL) {
711                 MSG_FATAL("error opendir: %s", strerror(errno));
712                 return -1;
713         }
714
715         int size = strlen(pDirPath) + 256;
716
717         char *path = (char*)malloc(size);
718
719         if (path == NULL) {
720                 MSG_DEBUG("path is NULL");
721                 closedir(dir);
722                 return -1;
723         }
724
725         bzero(path, size);
726
727         while ((d = readdir(dir)) != NULL) {
728                 if (d->d_type == DT_DIR) {
729                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
730
731                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
732                                 continue;
733
734                         MsgRmRf(path);
735
736                         if (rmdir(path) != 0) {
737
738                                 if (path != NULL)
739                                         free(path);
740
741                                 closedir(dir);
742
743                                 MSG_FATAL("error rmdir: %s", strerror(errno));
744
745                                 return -1;
746                         }
747                 } else {
748                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
749
750                         if (MsgDrmIsDrmFile(path))
751                                 MsgDrmUnregisterFile(path);
752
753                         if (remove(path) != 0) {
754
755                                 if (path != NULL)
756                                         free(path);
757
758                                 closedir(dir);
759
760                                 MSG_FATAL("error remove: %s", strerror(errno));
761
762                                 return -1;
763                         }
764                 }
765         }
766
767         closedir(dir);
768
769         if (path != NULL)
770                 free(path);
771
772         return 0;
773 }
774
775
776 int MsgGetFileSize(const char *pFileName)
777 {
778         struct stat file_stat;
779
780         if (lstat(pFileName, &file_stat)) {
781                 MSG_FATAL("error lstat: %s", strerror(errno));
782                 return -1;
783         }
784
785         return file_stat.st_size;
786 }
787
788
789 // it is equivalent to "du dir_path"
790 unsigned int MsgDu(const char *pDirPath)
791 {
792         struct dirent *d;
793         DIR *dir;
794
795         dir = opendir(pDirPath);
796
797         if (dir == NULL) {
798                 MSG_FATAL("error opendir: %s", strerror(errno));
799                 return -1;
800         }
801
802         int size = strlen(pDirPath) + 256;
803         char *path = (char*)malloc(size);
804         bzero(path, size);
805
806         unsigned int totalFileSize = 0;
807
808         while ((d = readdir(dir)) != NULL) {
809                 if( d->d_type == DT_DIR) {
810                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
811
812                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
813                                 continue;
814
815                         unsigned int dirSize = MsgDu(path);
816
817                         if (dirSize == 0) {
818                                 MSG_FATAL("error MsgDu");
819                                 closedir(dir);
820                                 free(path);
821                                 return dirSize;
822                         }
823
824                         totalFileSize += dirSize;
825                 } else {
826                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
827                         int fileSize = MsgGetFileSize(path);
828
829                         if (fileSize < 0) {
830                                 MSG_FATAL("error MsgGetFileSize");
831                                 closedir(dir);
832                                 free(path);
833                                 return fileSize;
834                         }
835
836                         totalFileSize += fileSize;
837                 }
838         }
839
840         closedir(dir);
841
842         free(path);
843
844         return totalFileSize;
845 }
846
847
848 bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
849 {
850         if (!pFilePath) {
851                 MSG_FATAL("NULL check error, pFileName %p, pData %p", pFilePath, pData);
852                 return false;
853         }
854
855         char fullPath[MAX_FULL_PATH_SIZE] = {0};
856
857         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s", pFilePath);
858
859         FILE *pFile = MsgOpenFile(fullPath, "a+");
860
861         if (pFile == NULL) {
862                 MSG_FATAL("File Open Error: %s", strerror(errno));
863                 return false;
864         }
865
866         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
867                 MsgCloseFile(pFile);
868                 MSG_FATAL("File Sead Error: %s", strerror(errno));
869                 return false;
870         }
871
872         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
873                 MsgCloseFile(pFile);
874                 MSG_FATAL("File Write Error: %s", strerror(errno));
875                 return false;
876         }
877
878         MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
879         MsgFflush(pFile);
880         MsgCloseFile(pFile);
881         return true;
882 }
883
884 void MsgMmsInitDir()
885 {
886         struct dirent *d = NULL;
887         DIR* dir = NULL;
888
889         dir = opendir(MSG_DATA_PATH);
890
891         if (dir == NULL) {
892                 MSG_FATAL("error opendir: %s", strerror(errno));
893                 return;
894         }
895
896         // Remove temporal Mms folder (/opt/usr/data/msg-service/msgdata/*.dir)
897         while ((d = readdir(dir)) != NULL) {
898                 if (d->d_type == DT_DIR) {
899                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
900                                 continue;
901
902                         if(strstr(d->d_name, ".dir") != NULL) {
903                                 char filePath[MSG_FILEPATH_LEN_MAX] = {0,};
904                                 snprintf(filePath, MSG_FILEPATH_LEN_MAX, MSG_DATA_PATH"%s", d->d_name);
905
906                                 MsgRmRf(filePath);
907                                 rmdir(filePath);
908                         }
909                 }
910         }
911
912         closedir(dir);
913 }
914
915 //mode : R_OK, W_OK, X_OK, or the existence test F_OK.
916 bool MsgAccessFile(const char *filepath, int mode)
917 {
918         int ret;
919         if (filepath == NULL) {
920                 MSG_DEBUG("filepath is NULL");
921                 return false;
922         }
923
924         MSG_DEBUG("request access path = %s, mode = %d", filepath, mode);
925
926         ret = access(filepath, mode);
927
928
929         if (ret) {
930                 MSG_DEBUG("Fail to access file, ret = %d", ret);
931                 return false;
932         }
933
934         return true;
935 }