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