2.0_beta
[platform/core/messaging/msg-service.git] / utils / MsgUtilFile.cpp
1 /*
2 * Copyright 2012  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];
257
258         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
259                 MsgCloseFile(pFile);
260                 MSG_DEBUG("File seek Error: %s", strerror(errno));
261                 return false;
262         }
263
264         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
265                 MsgCloseFile(pFile);
266                 MSG_DEBUG("File Read Error: %s", strerror(errno));
267                 return false;
268         }
269
270         *pDataSize = FileSize;
271
272         MsgCloseFile(pFile);
273
274         return true;
275 }
276
277
278 bool MsgReadFileForDecode(FILE *pFile, char *pBuf, int length, int *nSize)
279 {
280         MSG_BEGIN();
281
282         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
283                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
284                 MsgCloseFile(pFile);
285                 return false;
286         }
287
288         *nSize = MsgReadFile(pBuf, sizeof(char), length, pFile);
289
290         MSG_END();
291         return true;
292 }
293
294
295 bool MsgWriteIpcFile(const char *pFileName, const char *pData, int DataSize)
296 {
297         if (!pFileName) {
298                 MSG_DEBUG("NULL parameter, pFileName [%p], pData [%p]", pFileName, pData);
299                 return false;
300         }
301
302         char fullPath[MAX_FULL_PATH_SIZE] = {0};
303
304         snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
305
306         FILE *pFile = MsgOpenFile(fullPath, "wb+");
307
308         if (pFile == NULL) {
309                 MSG_DEBUG("File Open Error: %s", strerror(errno));
310                 return false;
311         }
312
313         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
314                 MsgCloseFile(pFile);
315                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
316                 return false;
317         }
318
319         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
320                 MsgCloseFile(pFile);
321                 MSG_DEBUG("File Write Error: %s", strerror(errno));
322                 return false;
323         }
324
325         MsgFflush(pFile);
326         MsgCloseFile(pFile);
327
328         if (chmod(fullPath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ) != 0) {
329                 MSG_DEBUG("File chmod Error: %s", strerror(errno));
330         }
331
332         if (chown(fullPath, 0, 6502 ) != 0) {
333                 MSG_DEBUG("File chown Error: %s", strerror(errno));
334         }
335
336         return true;
337 }
338
339 int MsgReadSmilFile(const char *pFileName, char **ppData)
340 {
341         if (!pFileName) {
342                 MSG_DEBUG("pFileName is NULL");
343                 return -1;
344         }
345
346         int     nSize = 0;
347         char fullPath[MAX_FULL_PATH_SIZE] = {0};
348
349         snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
350
351         MSG_DEBUG("open file name: %s", fullPath);
352
353         FILE *pFile = MsgOpenFile(fullPath, "rb");
354
355         if (pFile == NULL) {
356                 MSG_DEBUG("File Open Error: %s", strerror(errno));
357                 return -1;
358         }
359
360         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
361                 MsgCloseFile(pFile);
362                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
363                 return -1;
364         }
365
366         int FileSize = MsgFtell(pFile);
367
368         if (FileSize <= 0) {
369                 MSG_DEBUG("Filesize is error : %d", FileSize);
370                 MsgCloseFile(pFile);
371                 return FileSize;
372         }
373
374         *ppData = new char[FileSize + 1];
375
376         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
377                 MsgCloseFile(pFile);
378                 MSG_DEBUG("File Sead Error: %s", strerror(errno));
379                 return -1;
380         }
381
382         if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
383                 MsgCloseFile(pFile);
384                 MSG_DEBUG("File Read Error: %s", strerror(errno));
385                 return -1;
386         }
387
388         ppData[FileSize] = '\0';
389
390         nSize = FileSize;
391
392         MsgCloseFile(pFile);
393
394         return nSize;
395 }
396
397
398 bool MsgWriteSmilFile(const char *pFilePath,char *pData, int DataSize)
399 {
400         if(!pFilePath) {
401                 MSG_DEBUG("pFilePath is NULL");
402                 return false;
403         }
404
405         if (mkdir(MSG_SMIL_FILE_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
406                 if (errno == EEXIST) {
407                         MSG_DEBUG("The %s already exists", MSG_SMIL_FILE_PATH);
408                 } else {
409                         MSG_DEBUG("Error while mkdir %s", MSG_SMIL_FILE_PATH);
410                 }
411         }
412
413         FILE *pFile = MsgOpenFile(pFilePath, "wb+");
414
415         if (pFile == NULL) {
416                 MSG_DEBUG("File Open Error: %s", strerror(errno));
417                 return false;
418         }
419
420         if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
421                 MsgCloseFile(pFile);
422                 MSG_DEBUG("File Seek Error: %s", strerror(errno));
423                 return false;
424         }
425
426         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
427                 MsgCloseFile(pFile);
428                 MSG_DEBUG("File Write Error: %s", strerror(errno));
429                 return false;
430         }
431
432         MsgFflush(pFile);
433         MsgCloseFile(pFile);
434
435         return true;
436 }
437
438
439 void MsgDeleteFile(const char *pFileName)
440 {
441         if (!pFileName) {
442                 MSG_FATAL("pFileName is NULL");
443                 return;
444         }
445
446         if (strlen(pFileName) == 0) {
447                 MSG_FATAL("pFileName has zero length");
448                 return;
449         }
450
451         char fullPath[MAX_FULL_PATH_SIZE] = {0};
452
453         try {
454                 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
455
456                 MSG_DEBUG("%s", fullPath);
457
458                 if (remove(fullPath) != 0)
459                         MSG_FATAL("File Delete Error [%s]: %s", fullPath, strerror(errno));
460         } catch (exception &e) {
461                 MSG_FATAL ("%s", e.what());
462         }
463
464 }
465
466
467 void MsgDeleteSmilFile(const char *pFileName)
468 {
469         if (!pFileName ) {
470                 MSG_FATAL("pFileName NULL");
471                 return;
472         }
473
474         try {
475                 char fullPath[MAX_FULL_PATH_SIZE] = {0};
476
477                 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
478
479                 if (remove(fullPath) != 0)
480                         MSG_FATAL("File Delete Error [%s]: %s", fullPath, strerror(errno));
481         } catch (exception &e) {
482                 MSG_FATAL("%s", e.what());
483         }
484 }
485
486
487 bool MsgGetFileSize(const char *pFilePath, int *nSize)
488 {
489         if (!pFilePath) {
490                 MSG_FATAL("pFileName NULL");
491                 return false;
492         }
493
494         FILE *pFile = NULL;
495
496         pFile = MsgOpenFile(pFilePath, "rb");
497
498         if (!pFile) {
499                 MSG_DEBUG("File Open error: %s", strerror(errno));
500                 return false;
501         }
502
503         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
504                 MsgCloseFile(pFile);
505                 MSG_FATAL("File Read Error: %s", strerror(errno));
506                 return false;
507         }
508
509         *nSize = MsgFtell(pFile);
510
511         MsgCloseFile(pFile);
512
513         return true;
514 }
515
516
517 FILE *MsgOpenMMSFile(char *pFileName)
518 {
519         int len;
520
521         if (!pFileName) {
522                 MSG_DEBUG("pFileName NULL: %s", strerror(errno));
523                 return NULL;
524         }
525
526         len = strlen(pFileName);
527
528         for (int i = 0; i < len; i++) {
529                 switch (pFileName[i]) {
530                 case '*':
531                         pFileName[i] = '-';
532                         break;
533                 }
534         }
535
536         MSG_DEBUG("pFileName = %s", pFileName);
537
538         char fullPath[MAX_FULL_PATH_SIZE+1] = {0};
539
540         snprintf(fullPath, MAX_FULL_PATH_SIZE+1, "%s.mms", pFileName);
541
542         FILE *pFile = MsgOpenFile(fullPath, "wb+");
543
544         if (pFile == NULL) {
545                 MSG_FATAL("File Open Error: %s", strerror(errno));
546                 return NULL;
547         }
548
549         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
550                 MsgCloseFile(pFile);
551                 MSG_DEBUG("File Read Error: %s", strerror(errno));
552                 return NULL;
553         }
554
555         return pFile;
556 }
557
558
559 bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int maxLen, int *pOffset )
560 {
561         if (!pFile || !pPtr || !pInBuffer || !pOffset) {
562                 MSG_FATAL(" NULL parameter passed");
563                 return false;
564         }
565
566         MSG_DEBUG("MsgWriteDataFromEncodeBuffer:");
567         MSG_DEBUG("pInBuffer %x", pInBuffer);
568         MSG_DEBUG("pPtr %d",  (*pPtr));
569         MSG_DEBUG("before to fwite %x", pFile);
570
571         if (MsgWriteFile(pInBuffer, sizeof(char), (*pPtr), pFile) != (size_t)(*pPtr)) {
572                 MSG_FATAL("MsgWriteFile failed");
573                 return false;
574         }
575
576         MSG_DEBUG("after to fwite \n");
577
578         MsgFflush(pFile);
579
580         memset( pInBuffer, 0, maxLen );
581
582         *pPtr = 0;
583
584         if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
585                 MSG_FATAL("MsgFseek failed");
586                 return false;
587         }
588
589         *pOffset = MsgFtell(pFile);
590
591         if (*pOffset == -1L) {
592                 MSG_FATAL("MsgFtell failed");
593                 return false;
594         }
595
596         return true;
597 }
598
599
600 bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength)
601 {
602         FILE *pFile = NULL ;
603         mode_t file_mode;
604
605         file_mode = (S_IRUSR | S_IWUSR);
606
607         if ((pFile = MsgOpenFile(pFullPath, "wb+")) == NULL) {
608                 MSG_FATAL("MsgOpenFile errer");
609                 return false;
610         }
611
612         if (MsgWriteFile(pBuff, sizeof(char), TotalLength, pFile) != (size_t)TotalLength) {
613                 MsgCloseFile( pFile );
614                 return false;
615         }
616
617         MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
618         MsgFflush(pFile);
619         MsgCloseFile(pFile);
620
621         if (chmod(pFullPath, file_mode) < 0)
622                 MSG_FATAL("File chmod Error: %s", strerror(errno));
623
624         return true;
625 }
626
627
628 char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *npSize )
629 {
630         FILE *pFile = NULL;
631         char *pData = NULL;
632         int     readSize = 0;
633
634         if (szFilePath == NULL) {
635                 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] szFilePath id NULL");
636                 goto __CATCH;
637         }
638
639         *npSize = 0;
640
641         pFile = MsgOpenFile( szFilePath, "rb" );
642
643         if (pFile == NULL) {
644                 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] Can't open filepath", strerror(errno));
645                 goto __CATCH;
646         }
647
648         if( size == -1 ) {
649                 if (MsgGetFileSize(szFilePath, & readSize) == false) {
650                         MSG_DEBUG("MsgGetFileSize: failed");
651                         goto __CATCH;
652                 }
653         } else {
654                 readSize = size;
655         }
656
657         if (readSize > FM_READ_WRITE_BUFFER_MAX) {
658                 MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
659                 goto __CATCH;
660         }
661
662         pData = (char *)malloc(readSize + 1);
663         if ( NULL == pData ) {
664                 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] pData MemAlloc Fail", strerror(errno) );
665                 goto __CATCH;
666         }
667         memset( pData, 0, readSize + 1 );
668
669         if (MsgFseek( pFile, offset, SEEK_SET) < 0) {
670                 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] FmSeekFile failed", strerror(errno) );
671                 goto __CATCH;
672         }
673
674         *npSize = MsgReadFile(pData, sizeof(char), readSize, pFile);
675
676         MsgCloseFile(pFile);
677
678         pFile = NULL;
679
680         *(pData + (*npSize)) = '\0';
681
682         return pData;
683
684 __CATCH:
685
686         if (pData) {
687                 free( pData );
688                 pData = NULL;
689         }
690
691         *npSize = 0;
692
693         if (pFile != NULL) {
694                 MsgCloseFile( pFile );
695                 pFile = NULL;
696         }
697
698         return NULL;
699 }
700
701 // it is equivalent to "rm -rf pDirPath"
702 int MsgRmRf(char *pDirPath)
703 {
704         struct dirent *d;
705         DIR *dir;
706
707         dir = opendir(pDirPath);
708
709         if (dir == NULL) {
710                 MSG_FATAL("error opendir: %s", strerror(errno));
711                 return -1;
712         }
713
714         int size = strlen(pDirPath) + 256;
715
716         char *path = (char*)malloc(size);
717
718         if (path == NULL) {
719                 MSG_DEBUG("path is NULL");
720                 return -1;
721         }
722
723         bzero(path, size);
724
725         while ((d = readdir(dir)) != NULL) {
726                 if (d->d_type == DT_DIR) {
727                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
728
729                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
730                                 continue;
731
732                         MsgRmRf(path);
733
734                         if (rmdir(path) != 0) {
735
736                                 if (path != NULL)
737                                         free(path);
738
739                                 closedir(dir);
740
741                                 MSG_FATAL("error rmdir: %s", strerror(errno));
742
743                                 return -1;
744                         }
745                 } else {
746                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
747
748                         if (MsgDrmIsDrmFile(path))
749                                 MsgDrmUnregisterFile(path);
750
751                         if (remove(path) != 0) {
752
753                                 if (path != NULL)
754                                         free(path);
755
756                                 closedir(dir);
757
758                                 MSG_FATAL("error remove: %s", strerror(errno));
759
760                                 return -1;
761                         }
762                 }
763         }
764
765         closedir(dir);
766
767         if (path != NULL)
768                 free(path);
769
770         return 0;
771 }
772
773
774 int MsgGetFileSize(const char *pFileName)
775 {
776         struct stat file_stat;
777
778         if (lstat(pFileName, &file_stat)) {
779                 MSG_FATAL("error lstat: %s", strerror(errno));
780                 return -1;
781         }
782
783         return file_stat.st_size;
784 }
785
786
787 // it is equivalent to "du dir_path"
788 unsigned int MsgDu(const char *pDirPath)
789 {
790         struct dirent *d;
791         DIR *dir;
792
793         dir = opendir(pDirPath);
794
795         if (dir == NULL) {
796                 MSG_FATAL("error opendir: %s", strerror(errno));
797                 return -1;
798         }
799
800         int size = strlen(pDirPath) + 256;
801         char *path = (char*)malloc(size);
802         bzero(path, size);
803
804         unsigned int totalFileSize = 0;
805
806         while ((d = readdir(dir)) != NULL) {
807                 if( d->d_type == DT_DIR) {
808                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
809
810                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
811                                 continue;
812
813                         unsigned int dirSize = MsgDu(path);
814
815                         if (dirSize == 0) {
816                                 MSG_FATAL("error MsgDu");
817                                 return dirSize;
818                         }
819
820                         totalFileSize += dirSize;
821                 } else {
822                         snprintf(path, size, "%s/%s", pDirPath, d->d_name);
823                         int fileSize = MsgGetFileSize(path);
824
825                         if (fileSize < 0) {
826                                 MSG_FATAL("error MsgGetFileSize");
827                                 return fileSize;
828                         }
829
830                         totalFileSize += fileSize;
831                 }
832         }
833
834         closedir(dir);
835
836         free(path);
837
838         return totalFileSize;
839 }
840
841
842 bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
843 {
844         if (!pFilePath) {
845                 MSG_FATAL("NULL check error, pFileName %p, pData %p", pFilePath, pData);
846                 return false;
847         }
848
849         char fullPath[MAX_FULL_PATH_SIZE] = {0};
850
851         snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s", pFilePath);
852
853         FILE *pFile = MsgOpenFile(fullPath, "a+");
854
855         if (pFile == NULL) {
856                 MSG_FATAL("File Open Error: %s", strerror(errno));
857                 return false;
858         }
859
860         if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
861                 MsgCloseFile(pFile);
862                 MSG_FATAL("File Sead Error: %s", strerror(errno));
863                 return false;
864         }
865
866         if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
867                 MsgCloseFile(pFile);
868                 MSG_FATAL("File Write Error: %s", strerror(errno));
869                 return false;
870         }
871
872         MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
873         MsgFflush(pFile);
874         MsgCloseFile(pFile);
875         return true;
876 }
877
878 void MsgMmsInitDir()
879 {
880         struct dirent *d = NULL;
881         DIR* dir = NULL;
882
883         dir = opendir(MSG_DATA_PATH);
884
885         if (dir == NULL) {
886                 MSG_FATAL("error opendir: %s", strerror(errno));
887                 return;
888         }
889
890         // Remove temporal Mms folder (/opt/data/msg-service/msgdata/*.dir)
891         while ((d = readdir(dir)) != NULL) {
892                 if (d->d_type == DT_DIR) {
893                         if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
894                                 continue;
895
896                         if(strstr(d->d_name, ".dir") != NULL) {
897                                 char filePath[MSG_FILEPATH_LEN_MAX] = {0,};
898                                 snprintf(filePath, MSG_FILEPATH_LEN_MAX, MSG_DATA_PATH"%s", d->d_name);
899
900                                 MsgRmRf(filePath);
901                                 rmdir(filePath);
902                         }
903                 }
904         }
905
906         closedir(dir);
907 }