Changed the deprecated thumbnail_util APIs in msg-service
[platform/core/messaging/msg-service.git] / utils / MsgUtilFile.cpp
index f181a20..9b00350 100755 (executable)
 #include <sys/smack.h>
 #include <string.h>
 #include <dirent.h>
-#include <unistd.h>    //sync()
+#include <unistd.h>
 #include <fcntl.h>
 #include <libgen.h>
+#include <dlfcn.h>
 
-#include <media_content.h>
 #include <thumbnail_util.h>
 #include <image_util.h>
 
@@ -44,37 +44,12 @@ extern "C" {
        #include <aul.h>
 }
 
-Mutex g_mx;
-CndVar g_cv;
+#define PATH_LIBCSR_CLIENT "/usr/lib/libcsr-client.so.2"
+#define THUMB_WIDTH 320
+#define THUMB_HEIGHT 240
 
-void thumbnail_completed_cb(thumbnail_util_error_e error, const char *request_id,
-                                                                       int thumb_width, int thumb_height,
-                                                                       unsigned char *thumb_data, int thumb_size, void *user_data)
-{
-       if (!user_data) {
-               MSG_WARN("dstPath is NULL");
-               return;
-       }
-
-       MSG_BEGIN();
-
-       g_mx.lock();
-       MSG_DEBUG("=================[RESULT]");
-       MSG_DEBUG("error_code [%d]", error);
-       MSG_DEBUG("request id [%s]", request_id);
-       MSG_DEBUG("width [%d], height [%d]", thumb_width, thumb_height);
-       MSG_DEBUG("raw_data [0x%x], size [%d]", *thumb_data, thumb_size);
-
-       int ret = 0;
-       ret = image_util_encode_jpeg(thumb_data, thumb_width, thumb_height, IMAGE_UTIL_COLORSPACE_BGRA8888, 100, (char *)user_data);
-       if (ret != IMAGE_UTIL_ERROR_NONE)
-               MSG_WARN("image_util_encode_jpeg() is failed");
-
-       g_cv.signal();
-       g_mx.unlock();
-
-       MSG_END();
-}
+MsgMutex g_mx;
+MsgCndVar g_cv;
 
 /*==================================================================================================
                                      FUNCTION IMPLEMENTATION
@@ -97,24 +72,21 @@ bool MakeThumbnail(char *srcPath, char *dstPath)
 
        int ret = THUMBNAIL_UTIL_ERROR_NONE;
        char *req_id = NULL;
-       thumbnail_h thumb_h;
-       thumbnail_util_create(&thumb_h);
-       thumbnail_util_set_path(thumb_h, srcPath);
 
-       ret = thumbnail_util_extract(thumb_h, thumbnail_completed_cb, dstPath, &req_id);
-       thumbnail_util_destroy(thumb_h);
+       ret = thumbnail_util_extract_to_file(srcPath, THUMB_WIDTH, THUMB_HEIGHT, dstPath);
+
        if (req_id) {
                g_free(req_id);
                req_id = NULL;
        }
 
        if (ret != THUMBNAIL_UTIL_ERROR_NONE) {
-               MSG_ERR("thumbnail_util_extract is failed");
+               MSG_ERR("thumbnail_util_extract_to_file is failed");
                g_mx.unlock();
                return false;
        }
 
-       time_ret = g_cv.timedwait(g_mx.pMutex(), 5);
+       time_ret = g_cv.timedwait(g_mx.pMsgMutex(), 5);
 
        g_mx.unlock();
 
@@ -132,7 +104,7 @@ bool MakeThumbnail(char *srcPath, char *dstPath)
        return true;
 }
 
-// File operation wrappers
+/* File operation wrappers */
 FILE *MsgOpenFile(const char *filepath, const char *opt)
 {
        if (!filepath || !opt) {
@@ -180,10 +152,10 @@ int MsgFseek(FILE *pFile, long int offset, int origin)
 
        int ret = -1;
 
-       MSG_DEBUG("[FILE] pFile [%p], offset [%d], origin [%d]", pFile, offset, origin);
+       MSG_DEBUG("[FILE] pFile [%p], offset [%ld], origin [%d]", pFile, offset, origin);
 
        try {
-               ret = fseek(pFile, offset, origin);             // return 0, if success.
+               ret = fseek(pFile, offset, origin); /* return 0, if success. */
        } catch (exception &e) {
                MSG_FATAL("%s", e.what());
                return -1;
@@ -201,7 +173,7 @@ size_t MsgWriteFile(const char *pData, size_t size, size_t count, FILE *pFile)
 
        size_t nWrite = 0;
 
-       MSG_DEBUG("[FILE] pData [%p], size [%d], count [%d], pFile [%p]", pData, size, count, pFile);
+       MSG_DEBUG("[FILE] pData [%p], size [%zu], count [%zu], pFile [%p]", pData, size, count, pFile);
 
        try {
                nWrite = fwrite(pData, size, count, pFile);
@@ -237,7 +209,7 @@ long int MsgFtell(FILE *pFile)
                return -1L;
        }
 
-       long int ret = -1L; // -1L return if error occured.
+       long int ret = -1L; /* -1L return if error occured. */
 
        try {
                ret = ftell(pFile);
@@ -258,7 +230,7 @@ int MsgFflush(FILE *pFile)
        int ret = -1;
 
        try {
-               ret = fflush(pFile);            // return 0 if success
+               ret = fflush(pFile); /* return 0 if success */
        } catch (exception &e) {
                MSG_FATAL("%s", e.what());
        }
@@ -276,7 +248,7 @@ int MsgFsync(FILE *pFile)
        int ret = -1;
 
        try {
-               ret = fdatasync(pFile->_fileno);        // return 0 if success
+               ret = fdatasync(pFile->_fileno); /* return 0 if success */
        } catch (exception &e) {
                MSG_FATAL("%s", e.what());
        }
@@ -299,12 +271,12 @@ bool MsgCreateFileName(char *pFileName)
                        return false;
                }
 
-               // Create Random Number
+               /* Create Random Number */
                srandom((unsigned int)ts.tv_nsec);
 
-               MSG_DEBUG("ts.tv_nsec : %d", ts.tv_nsec);
+               MSG_DEBUG("ts.tv_nsec : %ld", ts.tv_nsec);
 
-               // between 1 - 1000000000
+               /* between 1 - 1000000000 */
                snprintf(pFileName, MSG_FILENAME_LEN_MAX, "MSG_%lu.DATA", random()%1000000000+1);
        } catch (exception& e) {
                MSG_FATAL("%s", e.what());
@@ -318,7 +290,7 @@ bool MsgCreateFileName(char *pFileName)
 bool MsgOpenAndReadFile(const char *pFileName, char **ppData, int *pDataSize)
 {
        if (!pFileName || !ppData || !pDataSize) {
-               MSG_ERR("Invalid params!! pFileName=%x, ppData=%x, pDataSize=%x", pFileName, ppData, pDataSize);
+               MSG_ERR("Invalid params");
                return false;
        }
 
@@ -331,6 +303,16 @@ bool MsgOpenAndReadFile(const char *pFileName, char **ppData, int *pDataSize)
        snprintf(fullPath, MAX_FULL_PATH_SIZE, "%s%s", MSG_IPC_DATA_PATH, pFileName);
        MSG_SEC_DEBUG("open file name: %s", fullPath);
 
+       struct stat st;
+       if (stat(fullPath, &st) != 0) {
+               MSG_SEC_ERR("stat(%s, &st) != 0", fullPath);
+               return false;
+       }
+       if (S_ISDIR(st.st_mode)) {
+               MSG_ERR("S_ISDIR(st.st_mode)");
+               return false;
+       }
+
        pFile = MsgOpenFile(fullPath, "rb");
 
        if (pFile == NULL) {
@@ -479,7 +461,7 @@ int MsgReadSmilFile(const char *pFileName, char **ppData)
                return -1;
        }
 
-       //ppData[FileSize] = '\0';
+       /* ppData[FileSize] = '\0'; */
 
        nSize = FileSize;
        MsgCloseFile(pFile);
@@ -488,7 +470,7 @@ int MsgReadSmilFile(const char *pFileName, char **ppData)
 }
 
 
-bool MsgWriteSmilFile(const char *pFilePath,char *pData, int DataSize)
+bool MsgWriteSmilFile(const char *pFilePath, char *pData, int DataSize)
 {
        if(!pFilePath) {
                MSG_DEBUG("pFilePath is NULL");
@@ -553,15 +535,14 @@ void MsgDeleteFile(const char *pFileName)
                if (remove(fullPath) != 0)
                        MSG_SEC_ERR("File Delete Error [%s]: %s", fullPath, g_strerror(errno));
        } catch (exception &e) {
-               MSG_FATAL ("%s", e.what());
+               MSG_FATAL("%s", e.what());
        }
-
 }
 
 
 void MsgDeleteSmilFile(const char *pFileName)
 {
-       if (!pFileName ) {
+       if (!pFileName) {
                MSG_FATAL("pFileName NULL");
                return;
        }
@@ -659,9 +640,9 @@ bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int m
        }
 
        MSG_DEBUG("MsgWriteDataFromEncodeBuffer:");
-       MSG_DEBUG("pInBuffer %x", pInBuffer);
+       MSG_DEBUG("pInBuffer %s", pInBuffer);
        MSG_DEBUG("pPtr %d",  (*pPtr));
-       MSG_DEBUG("before to fwite %x", pFile);
+       MSG_DEBUG("before to fwite %p", pFile);
 
        if (MsgWriteFile(pInBuffer, sizeof(char), (*pPtr), pFile) != (size_t)(*pPtr)) {
                MSG_FATAL("MsgWriteFile failed");
@@ -672,7 +653,7 @@ bool MsgWriteDataFromEncodeBuffer(FILE *pFile, char *pInBuffer, int *pPtr, int m
 
        MsgFflush(pFile);
 
-       memset( pInBuffer, 0, maxLen );
+       memset(pInBuffer, 0, maxLen);
 
        *pPtr = 0;
 
@@ -702,11 +683,11 @@ bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength
        }
 
        if (MsgWriteFile(pBuff, sizeof(char), TotalLength, pFile) != (size_t)TotalLength) {
-               MsgCloseFile( pFile );
+               MsgCloseFile(pFile);
                return false;
        }
 
-       MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
+       MsgFsync(pFile);        /* file is written to device immediately, it prevents missing file data from unexpected power off */
        MsgFflush(pFile);
        MsgCloseFile(pFile);
 
@@ -714,7 +695,7 @@ bool MsgOpenCreateAndOverwriteFile(char *pFullPath, char *pBuff, int TotalLength
 }
 
 
-char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *npSize )
+char *MsgOpenAndReadMmsFile(const char *szFilePath, int offset, int size, int *npSize)
 {
        FILE *pFile = NULL;
        char *pData = NULL;
@@ -727,7 +708,7 @@ char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *
 
        *npSize = 0;
 
-       pFile = MsgOpenFile( szFilePath, "rb" );
+       pFile = MsgOpenFile(szFilePath, "rb");
 
        if (pFile == NULL) {
                MSG_ERR("Can't open file: %s", g_strerror(errno));
@@ -742,11 +723,13 @@ char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *
        } else {
                readSize = size;
        }
-// restore Kies backup data size greater than FM_READ_WRITE_BUFFER_MAX
-//     if (readSize > FM_READ_WRITE_BUFFER_MAX) {
-//             MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
-//             goto __CATCH;
-//     }
+/* restore Kies backup data size greater than FM_READ_WRITE_BUFFER_MAX */
+#if 0
+       if (readSize > FM_READ_WRITE_BUFFER_MAX) {
+               MSG_DEBUG("MsgOpenAndReadMmsFile: File size tried to read too big");
+               goto __CATCH;
+       }
+#endif
 
        pData = (char *)calloc(1, readSize + 1);
        if ( NULL == pData ) {
@@ -754,7 +737,7 @@ char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *
                goto __CATCH;
        }
 
-       if (MsgFseek( pFile, offset, SEEK_SET) < 0) {
+       if (MsgFseek(pFile, offset, SEEK_SET) < 0) {
                MSG_ERR("FmSeekFile failed : %s", g_strerror(errno) );
                goto __CATCH;
        }
@@ -772,25 +755,24 @@ char *MsgOpenAndReadMmsFile( const char *szFilePath, int offset, int size, int *
 __CATCH:
 
        if (pData) {
-               free( pData );
+               free(pData);
                pData = NULL;
        }
 
        *npSize = 0;
 
        if (pFile != NULL) {
-               MsgCloseFile( pFile );
+               MsgCloseFile(pFile);
                pFile = NULL;
        }
 
        return NULL;
 }
 
-// it is equivalent to "rm -rf pDirPath"
+/* it is equivalent to "rm -rf pDirPath" */
 int MsgRmRf(char *pDirPath)
 {
        struct dirent *d = NULL;
-       struct dirent entry;
        DIR *dir;
 
        dir = opendir(pDirPath);
@@ -812,7 +794,8 @@ int MsgRmRf(char *pDirPath)
 
        bzero(path, size);
 
-       for (readdir_r(dir, &entry, &d); d != NULL; readdir_r(dir, &entry, &d)) {
+       errno = 0;
+       while ((d = readdir(dir)) != NULL) {
                if (d->d_type == DT_DIR) {
                        snprintf(path, size, "%s/%s", pDirPath, d->d_name);
 
@@ -822,7 +805,6 @@ int MsgRmRf(char *pDirPath)
                        MsgRmRf(path);
 
                        if (rmdir(path) != 0) {
-
                                if (path != NULL)
                                        free(path);
 
@@ -839,7 +821,6 @@ int MsgRmRf(char *pDirPath)
                                MsgDrmUnregisterFile(path);
 
                        if (remove(path) != 0) {
-
                                if (path != NULL)
                                        free(path);
 
@@ -858,6 +839,9 @@ int MsgRmRf(char *pDirPath)
        if (path != NULL)
                free(path);
 
+       if (errno != 0)
+               return -1;
+
        return 0;
 }
 
@@ -875,11 +859,10 @@ int MsgGetFileSize(const char *pFileName)
 }
 
 
-// it is equivalent to "du dir_path"
+/* it is equivalent to "du dir_path" */
 unsigned int MsgDu(const char *pDirPath)
 {
        struct dirent *d = NULL;
-       struct dirent entry;
        DIR *dir;
 
        dir = opendir(pDirPath);
@@ -900,8 +883,9 @@ unsigned int MsgDu(const char *pDirPath)
 
        unsigned int totalFileSize = 0;
 
-       for (readdir_r(dir, &entry, &d); d != NULL; readdir_r(dir, &entry, &d)) {
-               if( d->d_type == DT_DIR) {
+       errno = 0;
+       while ((d = readdir(dir)) != NULL) {
+               if(d->d_type == DT_DIR) {
                        snprintf(path, size, "%s/%s", pDirPath, d->d_name);
 
                        if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
@@ -937,6 +921,9 @@ unsigned int MsgDu(const char *pDirPath)
 
        free(path);
 
+       if (errno != 0)
+               return 0;
+
        return totalFileSize;
 }
 
@@ -971,7 +958,7 @@ bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
                return false;
        }
 
-       MsgFsync(pFile);        //file is written to device immediately, it prevents missing file data from unexpected power off
+       MsgFsync(pFile);        /*file is written to device immediately, it prevents missing file data from unexpected power off */
        MsgFflush(pFile);
        MsgCloseFile(pFile);
        return true;
@@ -980,7 +967,6 @@ bool MsgAppendFile(const char *pFilePath, const char *pData, int DataSize)
 void MsgMmsInitDir()
 {
        struct dirent *d = NULL;
-       struct dirent entry;
        DIR* dir = NULL;
 
        dir = opendir(MSG_DATA_PATH);
@@ -990,14 +976,14 @@ void MsgMmsInitDir()
                return;
        }
 
-       // Remove temporal Mms folder (/opt/usr/data/msg-service/msgdata/*.dir)
-       for (readdir_r(dir, &entry, &d); d != NULL; readdir_r(dir, &entry, &d)) {
+       /* Remove temporal Mms folder */
+       while ((d = readdir(dir)) != NULL) {
                if (d->d_type == DT_DIR) {
                        if ((strcmp(".", d->d_name) == 0) || (strcmp("..", d->d_name) == 0))
                                continue;
 
                        if(strstr(d->d_name, ".dir") != NULL) {
-                               char filePath[MSG_FILEPATH_LEN_MAX] = {0,};
+                               char filePath[MSG_FILEPATH_LEN_MAX] = {0, };
                                snprintf(filePath, MSG_FILEPATH_LEN_MAX, "%s%s", MSG_DATA_PATH, d->d_name);
 
                                MsgRmRf(filePath);
@@ -1010,7 +996,7 @@ void MsgMmsInitDir()
        closedir(dir);
 }
 
-//mode : R_OK, W_OK, X_OK, or the existence test F_OK.
+/* mode : R_OK, W_OK, X_OK, or the existence test F_OK. */
 bool MsgAccessFile(const char *filepath, int mode)
 {
        int ret;
@@ -1109,11 +1095,10 @@ bool MsgChown(const char *filepath, int uid, int gid)
        }
 
        close(fd);
-
        return true;
 }
 
-bool MsgCreateFile(const char *pFilePath,char *pData, int DataSize)
+bool MsgCreateFile(const char *pFilePath, char *pData, int DataSize)
 {
        if(!pFilePath) {
                MSG_DEBUG("pFilePath is NULL");
@@ -1140,7 +1125,7 @@ bool MsgCreateFile(const char *pFilePath,char *pData, int DataSize)
        }
 
        MsgFflush(pFile);
-       MsgFsync( pFile);
+       MsgFsync(pFile);
        MsgCloseFile(pFile);
 
        return true;
@@ -1223,38 +1208,103 @@ __RETURN:
 }
 
 
-bool MsgScanFile(char *filePath)
+void MsgGetMimeType(char *filePath, char *mimeType, int size)
 {
-       if (filePath == NULL) {
-               MSG_DEBUG("Invalid Parameter src = %p", filePath);
-               return false;
+       aul_get_mime_from_file(filePath, mimeType, size);
+}
+
+int MsgTcsScanFile(const char *filepath, int *bLevel)
+{
+       MSG_BEGIN();
+
+       int (*_csr_cs_context_create)(void **handle);
+       int (*_csr_cs_scan_file)(void *handle, const char *filepath, void **malware);
+       int (*_csr_cs_context_destroy)(void *handle);
+       int (*_csr_cs_malware_get_severity)(void *malware, void *severity);
+       int (*_csr_cs_malware_get_name)(void *malware, char **name);
+
+       if (MsgAccessFile(filepath, R_OK) == false) {
+               MSG_SEC_DEBUG("not exist source file [%s]", filepath);
+               return -1;
        }
 
-       msg_error_t ret = media_content_connect();
+       MSG_SEC_DEBUG("Scanning file name : %s\n", filepath);
 
-       if (ret == MEDIA_CONTENT_ERROR_NONE) {
-               if (media_content_scan_file(filePath) != MEDIA_CONTENT_ERROR_NONE) {
-                       MSG_ERR("media_content_scan_file() is failed , %d", ret);
-                       media_content_disconnect();
-                       return false;
+       void *lib_handle = NULL;
+       lib_handle = dlopen(PATH_LIBCSR_CLIENT, RTLD_LAZY);
+       if (!lib_handle) {
+               MSG_ERR("Unable to open %s", PATH_LIBCSR_CLIENT);
+               return 0;
+       }
+
+       _csr_cs_context_create = (int(*)(void**))dlsym(lib_handle, "csr_cs_context_create");
+       _csr_cs_scan_file = (int(*)(void*, const char*, void**))dlsym(lib_handle, "csr_cs_scan_file");
+       _csr_cs_context_destroy = (int(*)(void*))dlsym(lib_handle, "csr_cs_context_destroy");
+       _csr_cs_malware_get_severity = (int(*)(void*, void*))dlsym(lib_handle, "csr_cs_malware_get_severity");
+       _csr_cs_malware_get_name = (int(*)(void*, char**))dlsym(lib_handle, "csr_cs_malware_get_name");
+
+       int ret = 0;
+       if (!_csr_cs_context_create || !_csr_cs_scan_file || !_csr_cs_context_destroy
+                       || !_csr_cs_malware_get_severity || !_csr_cs_malware_get_name) {
+               MSG_ERR("Failed to load CSR symbols");
+               if (lib_handle)
+                               dlclose(lib_handle);
+               return -1;
+       }
+
+       void *csr_handle = NULL;
+       ret = _csr_cs_context_create(&csr_handle);
+       if (ret != 0) {
+               MSG_DEBUG("csr_cs_context_create error: err = %d\n", ret);
+               if (lib_handle)
+                               dlclose(lib_handle);
+               return -1;
+       }
+
+       do {
+               void *detected = NULL;
+               ret = _csr_cs_scan_file(csr_handle, filepath, &detected);
+               if (ret != 0) {
+                       MSG_DEBUG("csr_cs_scan_file fail: err = %d\n", ret);
+                       break;
                }
 
-               ret = media_content_disconnect();
+               if (NULL == detected) {
+                       MSG_DEBUG("Nothing detected");
+                       break;
+               }
 
-               if (ret != MEDIA_CONTENT_ERROR_NONE) {
-                       MSG_ERR("media_content_disconnect is failed , %d", ret);
-                       return false;
+               int severity = 0x01; /* CSR_CS_SEVERITY_LOW */
+               ret = _csr_cs_malware_get_severity(detected, &severity);
+               if (ret != 0) {
+                       MSG_DEBUG("csr_cs_malware_get_severity error: err = %d\n", ret);
                }
-       } else {
-               MSG_ERR("media_content_connect is failed , %d", ret);
-               return false;
-       }
+               MSG_DEBUG(" +-- Malware Severity class: %d\n", severity);
 
-       return true;
-}
+               char *name = NULL;
+               ret = _csr_cs_malware_get_name(detected, &name);
+               if (ret != 0) {
+                       MSG_DEBUG("csr_cs_malware_get_name error: err = %d\n", ret);
+               }
+               MSG_SEC_DEBUG(" +-- Malware Name: [%s]\n", name);
 
+               if (name)
+                       free(name);
 
-void MsgGetMimeType(char *filePath, char *mimeType, int size)
-{
-       aul_get_mime_from_file(filePath, mimeType, size);
+               if (bLevel)
+                       *bLevel = severity;
+
+       } while (0);
+
+       ret = _csr_cs_context_destroy(csr_handle);
+       if (ret != 0)
+               MSG_DEBUG("csr_cs_context_destroy error: err = %d\n", ret);
+
+       if (lib_handle)
+               dlclose(lib_handle);
+
+       MSG_END();
+       return 0;
 }
+
+