3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
5 * This file is part of msg-service.
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>
14 * PROPRIETARY/CONFIDENTIAL
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.
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.
39 #include <unistd.h> //sync()
41 #include "MsgStorageTypes.h"
43 #include "MsgException.h"
44 #include "MsgUtilFile.h"
45 #include "MsgMmsTypes.h"
46 #include "MsgInternalTypes.h"
47 #include "MsgDrmWrapper.h"
50 /*==================================================================================================
51 FUNCTION IMPLEMENTATION
52 ==================================================================================================*/
53 // File operation wrappers
54 FILE *MsgOpenFile(const char *filepath, const char *opt)
56 if (!filepath || !opt) {
57 MSG_FATAL("Null parameter");
61 MSG_DEBUG("[FILE] filepath : [%s], opt [%s]", filepath, opt);
66 pFile = fopen(filepath, opt);
67 MSG_DEBUG("[FILE] pFile [%p]", pFile);
68 } catch (exception &e) {
69 MSG_FATAL("%s", e.what());
76 void MsgCloseFile(FILE *pFile)
79 MSG_FATAL("NULL parameter");
83 MSG_DEBUG("[FILE] pFile [%p]", pFile);
87 } catch (exception &e) {
88 MSG_FATAL("%s", e.what());
92 int MsgFseek(FILE *pFile, long int offset, int origin)
95 MSG_FATAL("pFile NULL");
101 MSG_DEBUG("[FILE] pFile [%p], offset [%d], origin [%d]", pFile, offset, origin);
104 ret = fseek(pFile, offset, origin); // return 0, if success.
105 } catch (exception &e) {
106 MSG_FATAL("%s", e.what());
113 size_t MsgWriteFile(const char *pData, size_t size, size_t count, FILE *pFile)
115 if (!pData || !pFile) {
116 MSG_FATAL("pData or pFile NULL");
122 MSG_DEBUG("[FILE] pData [%p], size [%d], count [%d], pFile [%p]", pData, size, count, pFile);
125 nWrite = fwrite(pData, size, count, pFile);
126 } catch (exception &e) {
127 MSG_FATAL("%s", e.what());
133 size_t MsgReadFile(void *pData, size_t size, size_t count, FILE *pFile)
135 if (!pData || !pFile) {
136 MSG_FATAL("pData or pFile NULL");
143 nRead = fread(pData, size, count, pFile);
144 } catch (exception &e) {
145 MSG_FATAL("%s", e.what());
151 long int MsgFtell(FILE *pFile)
154 MSG_FATAL("pFile NULL");
158 long int ret = -1L; // -1L return if error occured.
162 } catch (exception &e) {
163 MSG_FATAL("%s", e.what());
169 int MsgFflush(FILE *pFile)
172 MSG_FATAL("pFile NULL");
179 ret = fflush(pFile); // return 0 if success
180 } catch (exception &e) {
181 MSG_FATAL("%s", e.what());
187 int MsgFsync(FILE *pFile)
190 MSG_FATAL("pFile NULL");
197 ret = fdatasync(pFile->_fileno); // return 0 if success
198 } catch (exception &e) {
199 MSG_FATAL("%s", e.what());
205 bool MsgCreateFileName(char *pFileName)
207 if (pFileName == NULL) {
208 MSG_DEBUG("[ERROR] pFileName is NULL");
215 if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
216 MSG_DEBUG("clock_gettime() error: %s", strerror(errno));
220 // Create Random Number
221 srandom((unsigned int)ts.tv_nsec);
223 MSG_DEBUG("ts.tv_nsec : %d", ts.tv_nsec);
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());
236 bool MsgOpenAndReadFile(const char *pFileName, char **ppData, int *pDataSize)
238 MSG_DEBUG("MsgOpenAndReadFile");
242 char fullPath[MAX_FULL_PATH_SIZE] = {0};
244 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
245 MSG_DEBUG("open file name: %s", fullPath);
248 pFile = MsgOpenFile(fullPath, "rb");
251 MSG_DEBUG("File Open Error: %s", strerror(errno));
255 if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
257 MSG_DEBUG("File Read Error: %s", strerror(errno));
261 int FileSize = MsgFtell(pFile);
264 MSG_DEBUG("Filesize is error : %d", FileSize);
270 *ppData = new char[FileSize];
272 if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
274 MSG_DEBUG("File seek Error: %s", strerror(errno));
278 if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
280 MSG_DEBUG("File Read Error: %s", strerror(errno));
284 *pDataSize = FileSize;
292 bool MsgReadFileForDecode(FILE *pFile, char *pBuf, int length, int *nSize)
296 if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
297 MSG_DEBUG("File Seek Error: %s", strerror(errno));
302 *nSize = MsgReadFile(pBuf, sizeof(char), length, pFile);
309 bool MsgWriteIpcFile(const char *pFileName, const char *pData, int DataSize)
312 MSG_DEBUG("NULL parameter, pFileName [%p], pData [%p]", pFileName, pData);
316 char fullPath[MAX_FULL_PATH_SIZE] = {0};
318 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
320 FILE *pFile = MsgOpenFile(fullPath, "wb+");
323 MSG_DEBUG("File Open Error: %s", strerror(errno));
327 if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
329 MSG_DEBUG("File Seek Error: %s", strerror(errno));
333 if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
335 MSG_DEBUG("File Write Error: %s", strerror(errno));
342 if (chmod(fullPath, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ) != 0) {
343 MSG_DEBUG("File chmod Error: %s", strerror(errno));
346 if (chown(fullPath, 0, 6502 ) != 0) {
347 MSG_DEBUG("File chown Error: %s", strerror(errno));
353 int MsgReadSmilFile(const char *pFileName, char **ppData)
356 MSG_DEBUG("pFileName is NULL");
361 char fullPath[MAX_FULL_PATH_SIZE] = {0};
363 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
365 MSG_DEBUG("open file name: %s", fullPath);
367 FILE *pFile = MsgOpenFile(fullPath, "rb");
370 MSG_DEBUG("File Open Error: %s", strerror(errno));
374 if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
376 MSG_DEBUG("File Seek Error: %s", strerror(errno));
380 int FileSize = MsgFtell(pFile);
383 MSG_DEBUG("Filesize is error : %d", FileSize);
388 *ppData = new char[FileSize + 1];
390 if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
392 MSG_DEBUG("File Sead Error: %s", strerror(errno));
396 if (MsgReadFile(*ppData, sizeof(char), FileSize, pFile) != (size_t)FileSize) {
398 MSG_DEBUG("File Read Error: %s", strerror(errno));
402 ppData[FileSize] = '\0';
412 bool MsgWriteSmilFile(const char *pFilePath,char *pData, int DataSize)
415 MSG_DEBUG("pFilePath is NULL");
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);
423 MSG_DEBUG("Error while mkdir %s", MSG_SMIL_FILE_PATH);
427 FILE *pFile = MsgOpenFile(pFilePath, "wb+");
430 MSG_DEBUG("File Open Error: %s", strerror(errno));
434 if (MsgFseek(pFile, 0L, SEEK_SET) < 0) {
436 MSG_DEBUG("File Seek Error: %s", strerror(errno));
440 if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
442 MSG_DEBUG("File Write Error: %s", strerror(errno));
453 void MsgDeleteFile(const char *pFileName)
456 MSG_FATAL("pFileName is NULL");
460 if (strlen(pFileName) == 0) {
461 MSG_FATAL("pFileName has zero length");
465 char fullPath[MAX_FULL_PATH_SIZE] = {0};
468 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_IPC_DATA_PATH"%s", pFileName);
470 MSG_DEBUG("%s", fullPath);
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());
481 void MsgDeleteSmilFile(const char *pFileName)
484 MSG_FATAL("pFileName NULL");
489 char fullPath[MAX_FULL_PATH_SIZE] = {0};
491 snprintf(fullPath, MAX_FULL_PATH_SIZE, MSG_SMIL_FILE_PATH"%s", pFileName);
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());
501 bool MsgGetFileSize(const char *pFilePath, int *nSize)
504 MSG_FATAL("pFileName NULL");
510 pFile = MsgOpenFile(pFilePath, "rb");
513 MSG_DEBUG("File Open error: %s", strerror(errno));
517 if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
519 MSG_FATAL("File Read Error: %s", strerror(errno));
523 *nSize = MsgFtell(pFile);
531 FILE *MsgOpenMMSFile(char *pFileName)
536 MSG_DEBUG("pFileName NULL: %s", strerror(errno));
540 len = strlen(pFileName);
542 for (int i = 0; i < len; i++) {
543 switch (pFileName[i]) {
550 MSG_DEBUG("pFileName = %s", pFileName);
552 char fullPath[MAX_FULL_PATH_SIZE+1] = {0};
554 snprintf(fullPath, MAX_FULL_PATH_SIZE+1, "%s.mms", pFileName);
556 FILE *pFile = MsgOpenFile(fullPath, "wb+");
559 MSG_FATAL("File Open Error: %s", strerror(errno));
563 if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
565 MSG_DEBUG("File Read Error: %s", strerror(errno));
573 bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int maxLen, int *pOffset )
575 if (!pFile || !pPtr || !pInBuffer || !pOffset) {
576 MSG_FATAL(" NULL parameter passed");
580 MSG_DEBUG("MsgWriteDataFromEncodeBuffer:");
581 MSG_DEBUG("pInBuffer %x", pInBuffer);
582 MSG_DEBUG("pPtr %d", (*pPtr));
583 MSG_DEBUG("before to fwite %x", pFile);
585 if (MsgWriteFile(pInBuffer, sizeof(char), (*pPtr), pFile) != (size_t)(*pPtr)) {
586 MSG_FATAL("MsgWriteFile failed");
590 MSG_DEBUG("after to fwite \n");
594 memset( pInBuffer, 0, maxLen );
598 if (MsgFseek(pFile, 0L, SEEK_END) < 0) {
599 MSG_FATAL("MsgFseek failed");
603 *pOffset = MsgFtell(pFile);
605 if (*pOffset == -1L) {
606 MSG_FATAL("MsgFtell failed");
614 bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength)
619 file_mode = (S_IRUSR | S_IWUSR);
621 if ((pFile = MsgOpenFile(pFullPath, "wb+")) == NULL) {
622 MSG_FATAL("MsgOpenFile errer");
626 if (MsgWriteFile(pBuff, sizeof(char), TotalLength, pFile) != (size_t)TotalLength) {
627 MsgCloseFile( pFile );
631 MsgFsync(pFile); //file is written to device immediately, it prevents missing file data from unexpected power off
635 if (chmod(pFullPath, file_mode) < 0)
636 MSG_FATAL("File chmod Error: %s", strerror(errno));
642 char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *npSize )
648 if (szFilePath == NULL) {
649 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] szFilePath id NULL");
655 pFile = MsgOpenFile( szFilePath, "rb" );
658 MSG_DEBUG("MsgOpenAndReadMmsFile: [ERROR] Can't open filepath", strerror(errno));
663 if (MsgGetFileSize(szFilePath, & readSize) == false) {
664 MSG_DEBUG("MsgGetFileSize: failed");
671 if (readSize > FM_READ_WRITE_BUFFER_MAX) {
672 MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
676 pData = (char *)malloc(readSize + 1);
677 if ( NULL == pData ) {
678 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] pData MemAlloc Fail", strerror(errno) );
681 memset( pData, 0, readSize + 1 );
683 if (MsgFseek( pFile, offset, SEEK_SET) < 0) {
684 MSG_DEBUG( "MsgOpenAndReadMmsFile: [ERROR] FmSeekFile failed", strerror(errno) );
688 *npSize = MsgReadFile(pData, sizeof(char), readSize, pFile);
694 *(pData + (*npSize)) = '\0';
708 MsgCloseFile( pFile );
715 // it is equivalent to "rm -rf pDirPath"
716 int MsgRmRf(char *pDirPath)
721 dir = opendir(pDirPath);
724 MSG_FATAL("error opendir: %s", strerror(errno));
728 int size = strlen(pDirPath) + 256;
730 char *path = (char*)malloc(size);
733 MSG_DEBUG("path is NULL");
739 while ((d = readdir(dir)) != NULL) {
740 if (d->d_type == DT_DIR) {
741 snprintf(path, size, "%s/%s", pDirPath, d->d_name);
743 if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
748 if (rmdir(path) != 0) {
755 MSG_FATAL("error rmdir: %s", strerror(errno));
760 snprintf(path, size, "%s/%s", pDirPath, d->d_name);
762 if (MsgDrmIsDrmFile(path))
763 MsgDrmUnregisterFile(path);
765 if (remove(path) != 0) {
772 MSG_FATAL("error remove: %s", strerror(errno));
788 int MsgGetFileSize(const char *pFileName)
790 struct stat file_stat;
792 if (lstat(pFileName, &file_stat)) {
793 MSG_FATAL("error lstat: %s", strerror(errno));
797 return file_stat.st_size;
801 // it is equivalent to "du dir_path"
802 unsigned int MsgDu(const char *pDirPath)
807 dir = opendir(pDirPath);
810 MSG_FATAL("error opendir: %s", strerror(errno));
814 int size = strlen(pDirPath) + 256;
815 char *path = (char*)malloc(size);
818 unsigned int totalFileSize = 0;
820 while ((d = readdir(dir)) != NULL) {
821 if( d->d_type == DT_DIR) {
822 snprintf(path, size, "%s/%s", pDirPath, d->d_name);
824 if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
827 unsigned int dirSize = MsgDu(path);
830 MSG_FATAL("error MsgDu");
834 totalFileSize += dirSize;
836 snprintf(path, size, "%s/%s", pDirPath, d->d_name);
837 int fileSize = MsgGetFileSize(path);
840 MSG_FATAL("error MsgGetFileSize");
844 totalFileSize += fileSize;
852 return totalFileSize;
856 bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
859 MSG_FATAL("NULL check error, pFileName %p, pData %p", pFilePath, pData);
863 char fullPath[MAX_FULL_PATH_SIZE] = {0};
865 snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s", pFilePath);
867 FILE *pFile = MsgOpenFile(fullPath, "a+");
870 MSG_FATAL("File Open Error: %s", strerror(errno));
874 if (MsgFseek(pFile, 0L, SEEK_CUR) < 0) {
876 MSG_FATAL("File Sead Error: %s", strerror(errno));
880 if (MsgWriteFile(pData, sizeof(char), DataSize, pFile) != (size_t)DataSize) {
882 MSG_FATAL("File Write Error: %s", strerror(errno));
886 MsgFsync(pFile); //file is written to device immediately, it prevents missing file data from unexpected power off
893 * Remove temporal Mms folder (/opt/data/msg-service/msgdata/*.dir)
898 struct dirent *d = NULL;
901 dir = opendir(MSG_DATA_PATH);
904 MSG_FATAL("error opendir: %s", strerror(errno));
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))
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);