#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "crypto.h" #include "json_struct.h" #include "config_engine.h" #include "skins_res.h" #include "inet_api.h" #define MAX_DOWNLOAD_ITEMS (10) #define DEBUG_SQL_CMD (0) typedef enum { STATUS_CREATE_NEW = 0, STATUS_DOWNLOADING, STATUS_DOWNLOADED, } RES_DOWNLOAD_STATUS; typedef enum { UPG_STATUS_ADDNEW = (1 << 0), UPG_STATUS_DL_NEW = (1 << 1), UPG_STATUS_DOWNLOADED = (1 << 2), } UPGRADE_RES_STATUS; typedef struct { char* pKeyName; char* pResPath; UT_hash_handle hh; ///< UT Hash handle } SKINS_CACHE_ITEM, *PSKINS_CACHE_ITEM; static uv_rwlock_t g_SkinCacheRwLock; #ifdef PLATFORM_CPU #define DOWNLOAD_RES_ROOT_PATH (DEF_SKINS_ROOT_PATH) #else #define DOWNLOAD_RES_ROOT_PATH ("/mnt/UDISK/resources/") #endif //select * FROM upgrade_skin WHERE resVersion == 4 ORDER BY resType DESC, RANDOM() LIMIT 1 //#define SKIN_GET_SQL_CMD ("") #define ATTACH_DB_SQL_CMD ("ATTACH \'%s\' AS \'%s\'") #define UPGRADE_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS %supgrade (" \ "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ "keyName TEXT NOT NULL," \ "resType INTEGER NOT NULL," \ "priority INTEGER NOT NULL DEFAULT (1)," \ "resVersion TEXT NOT NULL," \ "localPath TEXT NOT NULL," \ "serverURL TEXT NOT NULL," \ "md5Chksum TEXT NOT NULL," \ "resReadme TEXT NOT NULL DEFAULT (\'\')," \ "resStatus INTEGER NOT NULL DEFAULT (1)," \ "dlId TEXT NOT NULL DEFAULT (\'\')," \ "dlStatus INTEGER NOT NULL DEFAULT (0)," \ "dlRetrys INTEGER NOT NULL DEFAULT (0)," \ "dlTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));") #define CREATE_TMP_TBL_SQL "CREATE TABLE IF NOT EXISTS %stmp (" \ "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ "localPath TEXT NOT NULL);" static int g_isDlFinished = FALSE; static unsigned int g_curDlItems = 0; static sqlite3* g_pMemDb = NULL; static uv_rwlock_t g_uvSkinRwLock; static uv_rwlock_t g_uvDlRwLock; static const unsigned int g_tolDefaultSkins = (sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0])); static PSKINS_CACHE_ITEM g_pSkinCackeTbl = NULL; char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom); static int __getUpgradeInfo(const char *pUpdFilePath); static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName); extern int InitSkinRomDatabase(sqlite3 *pDataBase); static int g_isVerifyRes = FALSE; static int g_isUpgradeRunning = FALSE; static int __dumpSkinsInfo(PSKIN_RES_INFO pItem, int nItems) { LOG_EX2(LOG_Debug, "Skins Items Information:\n"); LOG_EX2(LOG_Debug, "-------------------------------------------------------------" "--------------------------------------------------------\n"); LOG_EX2(LOG_Debug, "| Key Name | Type | MD5 Checksum |" " Contexts " " |\n"); LOG_EX2(LOG_Debug, "-------------------------------------------------------------" "--------------------------------------------------------\n"); for(int i = 0; i < nItems && pItem; i++, pItem++) { LOG_EX2(LOG_Debug, "| %-8s | %-8s | %-32s | %-80s |\n", pItem->pKeyName, pItem->pResVer, pItem->pMD5Chksum, pItem->pLocalPath); } LOG_EX2(LOG_Debug, "-------------------------------------------------------------" "--------------------------------------------------------\n"); } static int __verifyResMD5Chksum(const char* pPath, const char* pChksum, int resType) { const char* pMD5Chksum; if(resType == TEXT_RES) { return (TRUE); } if(pPath == NULL || pChksum == NULL) { return (FALSE); } switch(resType) { case IMAGE_RES: case VOICE_RES: pMD5Chksum = EvpMD5HashFile(pPath); if(pMD5Chksum == NULL) { return (FALSE); } if(strcmp(pMD5Chksum, pChksum) != 0) { LOG_EX(LOG_Error, "%s MD5 Verify Error: %s -> %s\n", pPath, pMD5Chksum, pChksum); free((char*)pMD5Chksum); return (FALSE); } else { free((char*)pMD5Chksum); } break; default: return (FALSE); } return (TRUE); } static void __checkRes(sqlite3_context *pContext, int argc, sqlite3_value **argv) { if(access(sqlite3_value_text(argv[0]), F_OK) != 0) { sqlite3_result_int(pContext, -1); } else if(__verifyResMD5Chksum(sqlite3_value_text(argv[0]), sqlite3_value_text(argv[1]), sqlite3_value_int(argv[2])) == FALSE) { sqlite3_result_int(pContext, -2); } else { sqlite3_result_int(pContext, 0); } } static int __cleanupSkinTbl(void) { int rc; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, SKIN_TBL_NAME); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL, SKIN_USER_DB"."); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); return 0; } static int __cleanupResTbl(void) { int rc; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, RES_TBL_NAME); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, CREATE_RES_TBL_SQL, SKIN_USER_DB"."); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); return 0; } static int __cleanupUpgTbl(void) { int rc; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "DROP TABLE %s.upgrade", SKIN_USER_DB); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, SKIN_USER_DB"."); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); return 0; } static int __cleanupTmpTbl(void) { int rc; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "DROP TABLE main.tmp"); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, "main."); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); return 0; } static int __skinCreateCfgDB(void) { int rc = 0; char* pErrMsg = NULL; UT_string *pSqlCmd = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "CREATE VIRTUAL TABLE main.%s USING %s;" "CREATE VIRTUAL TABLE main.%s USING %s;", SKIN_TBL_NAME, SKIN_MODE_NAME, RES_TBL_NAME, RES_MODE_NAME); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); return (0); } static int __skinCreateCfgFile(const char* pCfgFilePath) { char* pErrMsg = NULL; int rc = 0; static sqlite3* pSqlFileDB = NULL; UT_string *pSqlCmd = NULL; rc = sqlite3_open(":memory:", &g_pMemDb); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "sqlite3_open memory: %s\n", pCfgFilePath); return -ERR_OPEN_SQLITE3_DB; } utstring_new(pSqlCmd); utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, ""); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); unlink(pCfgFilePath); sqlite3_close(g_pMemDb); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } rc = sqlite3_open_v2(pCfgFilePath, &pSqlFileDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "sqlite3_open_v2 error: %s\n", pCfgFilePath); sqlite3_close(g_pMemDb); utstring_free(pSqlCmd); return -ERR_OPEN_SQLITE3_DB; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL""CREATE_RES_TBL_SQL, "", ""); rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); unlink(pCfgFilePath); sqlite3_close(g_pMemDb); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, ""); rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", UPGRADE_TBL_SQL_CMD, pErrMsg); sqlite3_free(pErrMsg); unlink(pCfgFilePath); sqlite3_close(g_pMemDb); utstring_free(pSqlCmd); return -ERR_SQLITE3_CREATE_TABLE; } sqlite3_close(pSqlFileDB); utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, ATTACH_DB_SQL_CMD, pCfgFilePath, SKIN_USER_DB); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Attach Database %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); utstring_free(pSqlCmd); sqlite3_free(pErrMsg); unlink(pCfgFilePath); sqlite3_close(g_pMemDb); return -ERR_SQLITE3_CREATE_TABLE; } utstring_free(pSqlCmd); rc = sqlite3_create_function(g_pMemDb, "ResCheck", 3, SQLITE_UTF8, NULL, __checkRes, NULL, NULL); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Don't Support Resurces Verify Function\n"); } if(InitSkinRomDatabase(g_pMemDb) != 0) { sqlite3_close(g_pMemDb); return (-ERR_SQL_REG_MODULE); } rc = __skinCreateCfgDB(); if(rc != 0) { sqlite3_close(g_pMemDb); return rc; } return (0); } static void __onDlFileCb(void *pData, unsigned int size, const char *pReqUrl, const char* pDlPath, const char *pTaskUuid, int iFinished, void *pUserData) { char* pId = (char*)pUserData; UT_string *pSqlCmd = NULL; int rc = 0; char* pErrMsg = NULL; if(g_curDlItems > 0) { g_curDlItems--; } if(iFinished == 0 && pId != NULL) { //LOG_EX(LOG_Debug, "Request(%s): [%s] --> [%s] Response: [%u] OK\n", pTaskUuid, pReqUrl, pDlPath, size); utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, " "dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s AND " "ResCheck(localPath, md5Chksum, resType) = 0", SKIN_USER_DB, STATUS_DOWNLOADED, 0, pId); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); } else { if(iFinished == 1) { LOG_EX(LOG_Error, "Request(%s): [%s] --> [%s] Response: [%u] Error\n", pTaskUuid, pReqUrl, pDlPath, size); } else { LOG_EX(LOG_Error, "Download %s Error: %d\n", pReqUrl, iFinished); } utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "SELECT * FROM %s.upgrade WHERE ID = %s AND dlRetrys < 5 ", SKIN_USER_DB, pId); //fprintf(stdout, "SQL:\n%s\n", utstring_body(pSqlCmd)); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __reTryDlSkinResCb, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQL %s Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); } if(pId) { free(pId); } } static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName) { UT_string *pSqlCmd = NULL; char* pErrMsg = NULL; const char* pDlTaskId = InetHttpDlFileAsync(argv[6], argv[5], __onDlFileCb, NULL, strdup(argv[0])); if(pDlTaskId != NULL) { int rc = 0; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlId = \'%s\', dlRetrys = dlRetrys + 1, " "dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s", SKIN_USER_DB, pDlTaskId, argv[0]); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); } return 0; } static int __loadDownloadSkinsCb(void *pData, int argc, char **argv, char **azColName) { const char *pDlTaskId; char* pItemId = argv[0]; char* pURL = argv[6]; char* pDlPath = argv[5]; char* pDlId = argv[10]; int dlStatus = strtol(argv[3], NULL, 10); int dlRetry = strtol(argv[4], NULL, 10) + 1; if(dlStatus == STATUS_DOWNLOADING) { if(strlen(pDlId) > 0) { InetCancelDownload(pDlId); } dlRetry++; } //LOG_EX(LOG_Debug, "Download: %s --> %s\n", pURL, pDlPath); pDlTaskId = InetHttpDlFileAsync(pURL, pDlPath, __onDlFileCb, NULL, strdup(pItemId)); if(pDlTaskId) { UT_string *pSqlCmd = NULL; int rc = 0; char* pErrMsg = NULL; g_curDlItems++; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, " "dlId = \'%s\', dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s", SKIN_USER_DB, STATUS_DOWNLOADING, dlRetry, pDlTaskId, pItemId); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); } else { LOG_EX(LOG_Error, "Download %s error\n", pURL); } return (0); } static void __uvDownloadResThread(void *pParams) { char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; LOG_EX(LOG_Debug, "Beging Download Skins\n"); while(!g_isDlFinished) { int rc = 0; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "SELECT *, STRFTIME(\"%%s\", datetime(\'now\', \'localtime\')) " "- STRFTIME(\"%%s\", upgrade.dlTime) AS diff FROM %s.upgrade " "WHERE resStatus = %d AND (dlRetrys < 5 OR diff > 600) " "AND (dlStatus = %d OR (dlStatus = %d AND diff > 600)) " "LIMIT 10 - %d", SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_CREATE_NEW, STATUS_DOWNLOADING, g_curDlItems); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __loadDownloadSkinsCb, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); sleep(1); } LOG_EX(LOG_Debug, "Download Skins Finished\n"); pthread_detach(pthread_self()); } static int __sqlCbRemoveUnusedFile(void *pData, int argc, char **argv, char **azColName) { LOG_EX(LOG_Debug, "Clean up resources: [%s]\n", argv[1]); if(access(argv[1], F_OK) == 0 && strncmp(argv[1], DEF_SKINS_ROOT_PATH, strlen(DEF_SKINS_ROOT_PATH)) != 0) { unlink(argv[1]); } } static int __createResTblCb(void *pData, int argc, char **argv, char **azColName) { int rc = 0; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; //DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "INSERT INTO %s.%s " "VALUES (NULL, \'%s\', \'%s\', \'%s\', \'%s\')", SKIN_USER_DB, RES_TBL_NAME, argv[0], argv[1], argv[2], argv[3]); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -1; } utstring_free(pSqlCmd); return 0; } static int __createSkinTblCb(void *pData, int argc, char **argv, char **azColName) { int rc = 0; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; //DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, "INSERT INTO %s.%s " "VALUES (NULL, \'%s\', %s, %s, %s, \'%s\')", SKIN_USER_DB, SKIN_TBL_NAME, argv[1], argv[2], argv[3], argv[0], argv[4]); //fprintf(stdout, "AutoId: %lld: %s\n", sqlite3_last_insert_rowid(g_pMemDb), argv[3]); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); return -1; } utstring_free(pSqlCmd); return 0; } static void __uvSyncResThread(void *pParams) { int tolCnt = 0; PSKINS_CACHE_ITEM pItem = NULL, pTemp = NULL; LOG_EX(LOG_Debug, "Beging Sync Download Skins\n"); while(TRUE) { UT_string *pSqlCmd = NULL; int rc = 0; char* pErrMsg = NULL; char **pResult = NULL; int iRow = 0, iCol = 0; int nItems = 0; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade " "WHERE resStatus = %d AND dlStatus != %d", SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); nItems = strtol(pResult[1], NULL, 10); sqlite3_free_table(pResult); if(tolCnt++ % 20 == 0) { LOG_EX(LOG_Debug, "Download: Remain %d\n", nItems); } if(nItems == 0) { g_isDlFinished = TRUE; utstring_new(pSqlCmd); sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); utstring_printf(pSqlCmd, "INSERT INTO main.tmp " "SELECT %s.ID, %s.localPath FROM %s.%s " "LEFT JOIN %s.upgrade on %s.md5Chksum = upgrade.md5Chksum " "WHERE upgrade.md5Chksum IS NULL;", RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); utstring_free(pSqlCmd); break; } __cleanupSkinTbl(); __cleanupResTbl(); utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, "SELECT resVersion, localPath, serverURL, md5Chksum, " "keyName, resType, priority, resReadme, resStatus, dlStatus " "FROM %s.upgrade WHERE resStatus = %d " "OR (resStatus = %d AND dlStatus = %d) " "GROUP BY md5Chksum", SKIN_USER_DB, UPG_STATUS_DOWNLOADED, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createResTblCb, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); utstring_free(pSqlCmd); break; } else { utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, "SELECT %s.ID, keyName, resType, priority, " "resReadme, resStatus, dlStatus, %s.md5Chksum " "FROM %s.upgrade, %s.res WHERE %s.md5Chksum = upgrade.md5Chksum" " AND (resStatus = %d OR (resStatus = %d AND dlStatus = %d)) " "ORDER BY keyName", RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, SKIN_USER_DB, RES_TBL_NAME, UPG_STATUS_DOWNLOADED, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createSkinTblCb, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); utstring_free(pSqlCmd); break; } else { sqlite3_exec(g_pMemDb, "SELECT * FROM main.tmp", __sqlCbRemoveUnusedFile, NULL, NULL); utstring_free(pSqlCmd); if(__cleanupUpgTbl() != 0) { sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); } else { sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); break; } } } } sleep(1); } LOG_EX(LOG_Debug, "Sync Download Skins Finished\n"); uv_rwlock_wrlock(&g_SkinCacheRwLock); HASH_ITER(hh, g_pSkinCackeTbl, pItem, pTemp) { free(pItem->pKeyName); free(pItem->pResPath); free(pItem); pItem = NULL; } g_pSkinCackeTbl = NULL; uv_rwlock_wrunlock(&g_SkinCacheRwLock); g_isUpgradeRunning = FALSE; pthread_detach(pthread_self()); } static int __upgStatusTblCb(void *pData, int argc, char **argv, char **azColName) { int rc = 0; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d WHERE ID = %s", SKIN_USER_DB, UPG_STATUS_DL_NEW, argv[2]); rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return -1; } utstring_free(pSqlCmd); return 0; } static int __saveUpgradeInfo(PSKIN_RES_INFO pInfo, int nItems) { int isError = FALSE; char* pErrMsg = NULL; UT_string* pSqlCmd = NULL; if(pInfo == NULL || nItems <= 0) { return (-ERR_INPUT_PARAMS); } utstring_new(pSqlCmd); sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); __cleanupUpgTbl(); __cleanupTmpTbl(); for(int i = 0; i < nItems; i++) { UT_string* pPath = NULL; PSKIN_RES_INFO pItem = &pInfo[i]; utstring_new(pPath); utstring_renew(pSqlCmd); #if 0 if(pItem->resType == VOICE_RES) { utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); } else if(pItem->resType == IMAGE_RES) { utstring_printf(pPath, "%simage/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); } else if(pItem->resType == TEXT_RES) { utstring_printf(pPath, "%s", pItem->pLocalPath); } else { utstring_free(pPath); continue; } #else utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); #endif utstring_printf(pSqlCmd, "INSERT INTO %s.upgrade (keyName, resType, resVersion, localPath, serverURL, md5Chksum)" " SELECT \'%s\', %d, \'%s\', \'%s\', \'%s\', \'%s\' ", SKIN_USER_DB, pItem->pKeyName, pItem->resType, pItem->pResVer, utstring_body(pPath), pItem->pLocalPath, pItem->pMD5Chksum); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif if((sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK)) { LOG_EX(LOG_Error, "Add Skins[%d] %s To Database Error: %s\n", i, pItem->pKeyName, utstring_body(pSqlCmd)); LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); isError = TRUE; utstring_free(pPath); break; } utstring_free(pPath); } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d " "WHERE EXISTS (SELECT %s.keyName, upgrade.md5Chksum FROM main.%s, user_db.upgrade " "WHERE upgrade.keyName = %s.keyName)", SKIN_USER_DB, UPG_STATUS_DL_NEW, SKIN_TBL_NAME, SKIN_TBL_NAME, SKIN_TBL_NAME); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __upgStatusTblCb, 0, &pErrMsg) != SQLITE_OK) { LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd)); LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); isError = TRUE; } utstring_renew(pSqlCmd); utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d " "WHERE EXISTS (SELECT %s.md5Chksum FROM %s.%s " "WHERE upgrade.md5Chksum = %s.md5Chksum);" "UPDATE %s.upgrade SET resStatus = %d, localPath = " "(SELECT %s.localPath FROM main.%s " "WHERE upgrade.md5Chksum = %s.md5Chksum) " "WHERE EXISTS (SELECT %s.md5Chksum FROM main.%s " "WHERE upgrade.md5Chksum = %s.md5Chksum);", SKIN_USER_DB, UPG_STATUS_DOWNLOADED, RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, UPG_STATUS_DOWNLOADED, RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME); #if DEBUG_SQL_CMD LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); #endif if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK) { LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd)); LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); isError = TRUE; } utstring_free(pSqlCmd); if(isError == TRUE) { sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); return (-ERR_SQL_QUERY); } else { uv_thread_t uvSyncThread, uvDlThread; sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); g_curDlItems = 0; g_isDlFinished = FALSE; uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL); uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL); } return 0; } static int __loadPreUpgradeInfo(void) { UT_string *pSqlCmd = NULL; int rc = 0; char* pErrMsg = NULL; char **pResult = NULL; int iRow = 0, iCol = 0; int nItems = 0; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade WHERE resStatus = %d AND dlStatus != %d", SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); sqlite3_free(pErrMsg); } utstring_free(pSqlCmd); nItems = strtol(pResult[1], NULL, 10); sqlite3_free_table(pResult); if(nItems > 0) { uv_thread_t uvSyncThread, uvDlThread; g_curDlItems = 0; g_isDlFinished = FALSE; g_isUpgradeRunning = TRUE; uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL); uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL); LOG_EX(LOG_Debug, "Load Pre Download Items: %d\n", nItems); } } static int __getEnumResInfo(void) { __saveUpgradeInfo((PSKIN_RES_INFO)g_emuUpgradeInfo, sizeof(g_emuUpgradeInfo) / sizeof(g_emuUpgradeInfo[0])); } int SkinUpgrade(char* pUpdData) { int nItems = 0; PSKIN_RES_INFO pUpgResInfo; cJSON *pRoot, *pList; #if 1 FILE *pFile = fopen("/mnt/UDISK/skinupgrade.txt", "w+"); fwrite(pUpdData, 1, strlen(pUpdData), pFile); fclose(pFile); #endif if (pUpdData == NULL || strlen(pUpdData) == 0) { LOG_EX(LOG_Error, "Input Params Error\n"); return (-ERR_INPUT_PARAMS); } LOG_EX(LOG_Debug, "Upgrade Cmd: [%s]\n", pUpdData); //fprintf(stdout, "%s\n", pUpdData); pRoot = cJSON_Parse(pUpdData); if(pRoot == NULL) { LOG_EX(LOG_Error, "Parse Json Error\n"); return (-ERR_NO_ITEMS); } nItems = cJSON_GetArraySize(pRoot); if(nItems <= 0) { LOG_EX(LOG_Error, "Upgrade Item: %d\n", nItems); cJSON_Delete(pRoot); return (-ERR_NO_ITEMS); } pUpgResInfo = (PSKIN_RES_INFO)malloc(sizeof(SKIN_RES_INFO) * nItems); if(pUpgResInfo == NULL) { LOG_EX(LOG_Error, "Malloc %d Memory Error\n", nItems); cJSON_Delete(pRoot); return (-ERR_MALLOC_MEMORY); } LOG_EX(LOG_Debug, "Array Size = %d\n", nItems); memset(pUpgResInfo, 0, sizeof(SKIN_RES_INFO) * nItems); pList = pRoot->child; for(int i = 0; i < nItems; i++) { pUpgResInfo[i].resType = VOICE_RES;//cJSON_GetObjectItem(pList, "resourceType")->valueint; pUpgResInfo[i].pResVer = strdup(cJSON_GetObjectItem(pList, "resourceVersion")->valuestring); pUpgResInfo[i].pKeyName = strdup(cJSON_GetObjectItem(pList, "resourceName")->valuestring); pUpgResInfo[i].pLocalPath = strdup(cJSON_GetObjectItem(pList, "url")->valuestring); pUpgResInfo[i].pMD5Chksum = strdup(cJSON_GetObjectItem(pList, "md5")->valuestring); pList = pList->next; } cJSON_Delete(pRoot); g_isUpgradeRunning = TRUE; __dumpSkinsInfo(pUpgResInfo, nItems); __saveUpgradeInfo(pUpgResInfo, nItems); free(pUpgResInfo); } char* SQLiteGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) { char *pSkinPath = strdup(""); int rc = 0; char* pErrMsg = NULL; UT_string *pSqlCmd = NULL; char **pResult = NULL; int iRow = 0, iCol = 0; int queCol = 13; int colPath = 21; utstring_new(pSqlCmd); if(g_isVerifyRes) { utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK " "FROM %s.%s, %s.%s\n" "WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n" "UNION\n" "SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK " "FROM main.%s, main.%s\n" "WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n" "ORDER BY priority DESC, rnd " "LIMIT 1", SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME, SKIN_TBL_NAME, RES_TBL_NAME, SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME); } else { utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd " "FROM %s.%s, %s.%s\n" "WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n" "UNION\n" "SELECT *, RANDOM() AS rnd " "FROM main.%s, main.%s\n" "WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n" "ORDER BY priority DESC, rnd " "LIMIT 1", SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME, SKIN_TBL_NAME, RES_TBL_NAME, SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME); queCol = 12; colPath = 20; } rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s(%d)\n", utstring_body(pSqlCmd), pErrMsg, rc); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return (pSkinPath); } if(iRow == 1 && iCol == queCol) { if(access(pResult[colPath], F_OK) != 0) { LOG_EX(LOG_Error, "Res %s --> %s not exists\n", pKeyName, pResult[colPath]); } else { free(pSkinPath); pSkinPath = strdup(pResult[colPath]); } #if 0 for(int i = 0; i <= 21; i++) { LOG_EX(LOG_Debug, "[%d]: {%s}\n", i, pResult[i]); } #endif } #if 0 int index = iCol; for(int i = 0; i < iRow; i++) { fprintf(stdout, "----------%d[%d, %d]---------\n", i, iRow, iCol); for(int j = 0; j < iCol; j++) { int tblCol = i * iCol + j; fprintf(stdout, "%s(%d, %d) = [%s]\n", pResult[tblCol], j, index, pResult[index]); index++; } } #endif sqlite3_free_table(pResult); utstring_free(pSqlCmd); if(strcmp(pSkinPath, "") == 0) { free(pSkinPath); return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); } else { return (pSkinPath); } } char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) { for(int i = 0; i < sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0]); i++) { if(strcmp(g_SkinDefaultResTable[i].pKeyName, pKeyName) == 0) { return strdup(g_SkinDefaultResTable[i].pLocalPath); } } return strdup(""); } char* GetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) { if(g_isUpgradeRunning) { return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); } else { return SQLiteGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); } } unsigned int SkinsDefaultSize(void) { return (g_tolDefaultSkins + 1); } PSKIN_RES_INFO SkinsItemById(int iId) { if(iId < 0 || iId > g_tolDefaultSkins) { return (NULL); } return ((PSKIN_RES_INFO)&g_SkinDefaultResTable[iId - 1]); } static int __verifyResValuableCb(void *pData, int argc, char **argv, char **azColName) { char sqlCmd[256]; char* pErrMsg = NULL; if(argc < 3) { return 0; } sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); for(int i = 0; i < argc; i++) { if(strcmp(azColName[i], "ID") == 0) { LOG_EX(LOG_Error, "Cleanup Bad Resources: %s\n", argv[i + 1]); memset(sqlCmd, 0, 256); sprintf(sqlCmd, "DELETE FROM %s.%s WHERE ID = %s", SKIN_USER_DB, RES_TBL_NAME, argv[i]); if(sqlite3_exec(g_pMemDb, sqlCmd, __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK) { LOG_EX(LOG_Error, "SQL: %s\nError: %s\n", sqlCmd, pErrMsg); sqlite3_free(pErrMsg); sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); return -1; } unlink(argv[i + 1]); } } sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); return (0); } static void VerifySkinResInfo(void) { UT_string *pSqlCmd = NULL; char* pErrMsg = NULL; utstring_new(pSqlCmd); utstring_printf(pSqlCmd, "SELECT ID, localPath, md5Chksum FROM %s.%s " "WHERE ResCheck(localPath, md5Chksum, 1) != 0", SKIN_USER_DB, RES_TBL_NAME); if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK) { LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); utstring_free(pSqlCmd); return; } utstring_free(pSqlCmd); } void SkinIsVerifyRes(int isVerify) { g_isVerifyRes = isVerify; } int SkinInit(void) { int rc = 0; UT_string* pPath = NULL; #if 0 int tmUsed = 0; struct timeval tmStart, tmEnd; if(DBusLibuvGetRuntime() == NULL) { int ret = 0; uv_thread_t uvThread; LOG_EX(LOG_Warn, "+++++++++++++++++++++++System Uninit\n"); DBusConnection* pBus = DBusWithLibuvInit(GetDBusDefaultLoop(), g_pModInfoTable[MODULE_SKINS].modAliase, __dusOnMsg, NULL, NULL, //KeyEventCb, &ret); if(pBus == NULL) { LOG_EX(LOG_Error, "DBusWithLibuvInit Error: %d\n", ret); return -ERR_UNINIT_ITEM; } uv_thread_create(&uvThread, uvLoopProc, NULL); } #endif uv_rwlock_init(&g_uvSkinRwLock); uv_rwlock_init(&g_uvDlRwLock); uv_rwlock_init(&g_SkinCacheRwLock); utstring_new(pPath); utstring_printf(pPath, "mkdir -p %s/image > /dev/zero", DOWNLOAD_RES_ROOT_PATH); rc = system(utstring_body(pPath)); utstring_renew(pPath); utstring_printf(pPath, "mkdir -p %s/voice > /dev/zero", DOWNLOAD_RES_ROOT_PATH); rc = system(utstring_body(pPath)); utstring_free(pPath); rc = __skinCreateCfgFile(SKINS_DB_PATH); if(rc != SQLITE_OK) { return rc; } // gettimeofday(&tmStart, NULL); VerifySkinResInfo(); // gettimeofday(&tmEnd, NULL); // tmUsed = (tmEnd.tv_sec * 1000000 + tmEnd.tv_usec) - (tmStart.tv_sec * 1000000 + tmStart.tv_usec); // LOG_EX(LOG_Debug, "VerifySkinResInfo used time: %d(us)\n", tmUsed); __loadPreUpgradeInfo(); //__getEnumResInfo(); //__getUpgradeInfo("./hotfix.txt"); //__loadDownloadItems(); //__dumpSkinsInfo(); }