/** * Tries to repair the suite database. * * @return ALL_OK if succeeded, other value if failed */ MIDPError repair_suite_db() { /* IMPL_NOTE: should be replaced with more sophisticated routine. */ MIDPError status = ALL_OK; pcsl_string_status rc; pcsl_string suitesDataFile; char* pszTemp = NULL; /* get a full path to the _suites.dat */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &SUITE_DATA_FILENAME, &suitesDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } storage_delete_file(&pszTemp, &suitesDataFile); pcsl_string_free(&suitesDataFile); if (pszTemp != NULL) { storageFreeError(pszTemp); status = IO_ERROR; } if (g_isSuitesDataLoaded) { free_suites_data(); g_isSuitesDataLoaded = 0; } return status; }
/** * Gets the storage root for a MIDlet suite by ID. * Free the data of the string returned with pcsl_string_free(). * * @param suiteId suite ID * @param sRoot receives storage root (gets set to NULL in the case of an error) * * @return status: ALL_OK if success, * OUT_OF_MEMORY if out-of-memory */ MIDPError get_suite_storage_root(SuiteIdType suiteId, pcsl_string* sRoot) { StorageIdType storageId; const pcsl_string* root; MIDPError status; *sRoot = PCSL_STRING_EMPTY; /* get an id of the storage where the suite is located */ status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return status; } root = storage_get_root(storageId); pcsl_string_predict_size(sRoot, pcsl_string_length(root) + GET_SUITE_ID_LEN(suiteId)); if (PCSL_STRING_OK == pcsl_string_append(sRoot, root) && PCSL_STRING_OK == pcsl_string_append(sRoot, midp_suiteid2pcsl_string(suiteId))) { return ALL_OK; } pcsl_string_free(sRoot); *sRoot = PCSL_STRING_NULL; return OUT_OF_MEMORY; }
/** * Finishes the previously started transaction. * * @return ALL_OK if the transaction was successfully finished, * NOT_FOUND if the transaction has not been started, * IO_ERROR if I/O error */ MIDPError finish_transaction() { pcsl_string_status rc; pcsl_string transDataFile; char* pszTemp = NULL; MIDPError status = ALL_OK; if (!g_transactionStarted) { return NOT_FOUND; } /* transaction is finished, removed the transaction file */ /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } storage_delete_file(&pszTemp, &transDataFile); pcsl_string_free(&transDataFile); if (pszTemp != NULL) { storageFreeError(pszTemp); status = IO_ERROR; } g_transactionStarted = 0; return status; }
/** * Builds a full file name using the storage root and MIDlet suite by ID. * * @param suiteId suite ID * @param filename filename without a root path * @param sRoot receives full name of the file * * @return the status: ALL_OK if ok, OUT_OF_MEMORY if out of memory */ static MIDPError get_suite_filename(SuiteIdType suiteId, const pcsl_string* filename, pcsl_string* sRoot) { int sRoot_len; const pcsl_string* root; StorageIdType storageId; MIDPError status; /* get an id of the storage where the suite is located */ status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return status; } root = storage_get_root(storageId); *sRoot = PCSL_STRING_EMPTY; sRoot_len = pcsl_string_length(root) + GET_SUITE_ID_LEN(suiteId) + pcsl_string_length(filename); pcsl_string_predict_size(sRoot, sRoot_len); if (PCSL_STRING_OK == pcsl_string_append(sRoot, root) && PCSL_STRING_OK == pcsl_string_append(sRoot, midp_suiteid2pcsl_string(suiteId)) && PCSL_STRING_OK == pcsl_string_append(sRoot, filename)) { return ALL_OK; } else { pcsl_string_free(sRoot); *sRoot = PCSL_STRING_NULL; return OUT_OF_MEMORY; } }
/** * Opens file that keeps device and service classes. * @return handle for the file, <code>-1</code> if opening failed. */ static int openCodFile() { char *error; int handle = -1; pcsl_string name = PCSL_STRING_EMPTY; int i; if (PCSL_STRING_OK == pcsl_string_append(&name, storage_get_root(INTERNAL_STORAGE_ID))) { for (i = 0; i < BT_ADDRESS_SIZE * 2; i++) { char c = (emul_data.local_addr[i / 2] >> ((i % 2) * 4)) & 0xf; if (c <= 9) { c += '0'; } else { c += 'a'; } if (PCSL_STRING_OK != pcsl_string_append_char(&name, c)) { break; } } if (i == BT_ADDRESS_SIZE * 2) { handle = storage_open(&error, &name, OPEN_READ_WRITE); storageFreeError(error); } } pcsl_string_free(&name); return handle; }
/** * Gets the classpath for the specified MIDlet suite id. * * Note that memory for the in/out parameter classPath is * allocated by the callee. The caller is responsible for * freeing it using pcsl_mem_free(). * * @param suiteId The suite id used to identify the MIDlet suite * @param storageId storage ID, INTERNAL_STORAGE_ID for the internal storage * @param classPath The in/out parameter that contains returned class path * @param extension Extension of the file ( * * @return one of the error codes: * <pre> * ALL_OK, OUT_OF_MEMORY * </pre> */ static MIDPError get_class_path_impl(SuiteIdType suiteId, jint storageId, pcsl_string * classPath, const pcsl_string * extension) { const pcsl_string* root = storage_get_root(storageId); pcsl_string path = PCSL_STRING_NULL; jint suiteIdLen = GET_SUITE_ID_LEN(suiteId); *classPath = PCSL_STRING_NULL; /* performance hint: predict buffer capacity */ pcsl_string_predict_size(&path, pcsl_string_length(root) + suiteIdLen + pcsl_string_length(extension)); if (PCSL_STRING_OK != pcsl_string_append(&path, root) || PCSL_STRING_OK != pcsl_string_append(&path, midp_suiteid2pcsl_string(suiteId)) || PCSL_STRING_OK != pcsl_string_append(&path, extension)) { pcsl_string_free(&path); return OUT_OF_MEMORY; } *classPath = path; return ALL_OK; }
/** * Builds a full file name using the storage root and MIDlet suite by ID. * * @param suiteId suite ID * @param filename filename without a root path * @param sRoot receives full name of the file * * @return the status: ALL_OK if ok, OUT_OF_MEMORY if out of memory */ static MIDPError get_suite_filename(SuiteIdType suiteId, const pcsl_string* filename, pcsl_string* sRoot) { int sRoot_len; const pcsl_string* root; root = storage_get_root(INTERNAL_STORAGE_ID); *sRoot = PCSL_STRING_EMPTY; sRoot_len = pcsl_string_length(root) + GET_SUITE_ID_LEN(suiteId) + pcsl_string_length(filename); pcsl_string_predict_size(sRoot, sRoot_len); if (PCSL_STRING_OK == pcsl_string_append(sRoot, root) && PCSL_STRING_OK == pcsl_string_append(sRoot, midp_suiteid2pcsl_string(suiteId)) && PCSL_STRING_OK == pcsl_string_append(sRoot, filename)) { return ALL_OK; } else { pcsl_string_free(sRoot); *sRoot = PCSL_STRING_NULL; return OUT_OF_MEMORY; } }
/** * Gets the classpath for the specified MIDlet suite id. * * Note that memory for the in/out parameter classPath is * allocated by the callee. The caller is responsible for * freeing it using pcsl_mem_free(). * * @param suiteId The suite id used to identify the MIDlet suite * @param storageId storage ID, INTERNAL_STORAGE_ID for the internal storage * @param classPath The in/out parameter that contains returned class path * @param extension Extension of the file ( * * @return one of the error codes: * <pre> * ALL_OK, OUT_OF_MEMORY * </pre> */ static MIDPError get_class_path_impl(ComponentType type, SuiteIdType suiteId, ComponentIdType componentId, jint storageId, pcsl_string * pClassPath, const pcsl_string * pExtension) { const pcsl_string* root = storage_get_root(storageId); pcsl_string path = PCSL_STRING_NULL; jint suiteIdLen = GET_SUITE_ID_LEN(suiteId); jint componentIdLen = 0; #if ENABLE_DYNAMIC_COMPONENTS if (type == COMPONENT_DYNAMIC) { componentIdLen = GET_COMPONENT_ID_LEN(componentId); } #else (void)type; (void)componentId; #endif *pClassPath = PCSL_STRING_NULL; /* performance hint: predict buffer capacity */ pcsl_string_predict_size(&path, pcsl_string_length(root) + suiteIdLen + componentIdLen + + pcsl_string_length(pExtension)); if (PCSL_STRING_OK != pcsl_string_append(&path, root) || PCSL_STRING_OK != pcsl_string_append(&path, midp_suiteid2pcsl_string(suiteId))) { pcsl_string_free(&path); return OUT_OF_MEMORY; } #if ENABLE_DYNAMIC_COMPONENTS if (type == COMPONENT_DYNAMIC) { if (PCSL_STRING_OK != pcsl_string_append(&path, midp_componentid2pcsl_string(componentId))) { pcsl_string_free(&path); return OUT_OF_MEMORY; } } #endif if (PCSL_STRING_OK != pcsl_string_append(&path, pExtension)) { pcsl_string_free(&path); return OUT_OF_MEMORY; } *pClassPath = path; return ALL_OK; }
static void push_save() { char *error; bt_push_t *push = g_registry; pcsl_string full_name = PCSL_STRING_NULL; int storage; pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &BT_PUSH_FILENAME, &full_name); storage = storage_open(&error, &full_name, OPEN_READ_WRITE_TRUNCATE); pcsl_string_free(&full_name); if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Error opening `BtPush' file: %s", error); storageFreeError(error); return; } storageWrite(&error, storage, (char *)&g_count, sizeof(g_count)); while (push != NULL && error == NULL) { bt_push_t *next = push->next; storageWrite(&error, storage, (char *)&push->port, sizeof(bt_port_t)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->params, sizeof(bt_params_t)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->record.classes, sizeof(push->record.classes)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->record.size, sizeof(push->record.size)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)push->record.data, push->record.size); storageWrite(&error, storage, (char *)&push->record.id, sizeof(push->record.id)); if (error != NULL) { break; } push = next; } if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Error writing `BtPush' file: %s", error); storageFreeError(error); } storageClose(&error, storage); storageFreeError(error); }
/** * Gets location of the cached resource with specified name * for the suite with the specified suiteId. * * Note that when porting memory for the in/out parameter * filename MUST be allocated using pcsl_mem_malloc(). * The caller is responsible for freeing the memory associated * with filename parameter. * * @param suiteId The application suite ID * @param storageId storage ID, INTERNAL_STORAGE_ID for the internal storage * @param pResourceName Name of the cached resource * @param pFileName The in/out parameter that contains returned filename * @return error code that should be one of the following: * <pre> * ALL_OK, OUT_OF_MEMORY, NOT_FOUND, * SUITE_CORRUPTED_ERROR, BAD_PARAMS * </pre> */ MIDPError midp_suite_get_cached_resource_filename(SuiteIdType suiteId, StorageIdType storageId, const pcsl_string * pResourceName, pcsl_string * pFileName) { const pcsl_string* root = storage_get_root(storageId); pcsl_string returnPath = PCSL_STRING_NULL; pcsl_string resourceFileName = PCSL_STRING_NULL; jint suiteIdLen = GET_SUITE_ID_LEN(suiteId); jsize resourceNameLen = pcsl_string_length(pResourceName); *pFileName = PCSL_STRING_NULL; if (resourceNameLen > 0) { /* performance hint: predict buffer capacity */ int fileNameLen = PCSL_STRING_ESCAPED_BUFFER_SIZE( resourceNameLen + pcsl_string_length(&TMP_EXT)); pcsl_string_predict_size(&resourceFileName, fileNameLen); if ( /* Convert any slashes */ pcsl_esc_attach_string(pResourceName, &resourceFileName) != PCSL_STRING_OK || /* Add the extension */ pcsl_string_append(&resourceFileName, &TMP_EXT) != PCSL_STRING_OK) { pcsl_string_free(&resourceFileName); return OUT_OF_MEMORY; } } /* performance hint: predict buffer capacity */ pcsl_string_predict_size(&returnPath, pcsl_string_length(root) + suiteIdLen + pcsl_string_length(&resourceFileName)); if (PCSL_STRING_OK != pcsl_string_append(&returnPath, root) || PCSL_STRING_OK != pcsl_string_append(&returnPath, midp_suiteid2pcsl_string(suiteId)) || PCSL_STRING_OK != pcsl_string_append(&returnPath, &resourceFileName)) { pcsl_string_free(&resourceFileName); pcsl_string_free(&returnPath); return OUT_OF_MEMORY; } pcsl_string_free(&resourceFileName); *pFileName = returnPath; return ALL_OK; }
/** * Opens registry file * * @param write write access flag * @return operation result */ static jsr211_result open_table_file(int write) { pcsl_string fileName = PCSL_STRING_NULL_INITIALIZER; int io_mode = OPEN_READ | (write ? OPEN_WRITE : 0); if (PCSL_STRING_OK != pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &JSR211_TABLE_NAME, &fileName)) { return JSR211_FAILED; } table_file = storage_open(&io_error_message, &fileName, io_mode); pcsl_string_free(&fileName); return io_error_message? JSR211_FAILED: JSR211_OK; }
/** * Starts a new transaction of the given type. * * @param transactionType type of the new transaction * @param suiteId ID of the suite, may be UNUSED_SUITE_ID * @param pFilename name of the midlet suite's file, may be NULL * * @return ALL_OK if no errors, * IO_ERROR if I/O error */ MIDPError begin_transaction(MIDPTransactionType transactionType, SuiteIdType suiteId, const pcsl_string *pFilename) { pcsl_string_status rc; pcsl_string transDataFile; char *pszError = NULL; MIDPError status = ALL_OK; char pBuffer[MAX_FILENAME_LENGTH + sizeof(int) /* file name length */ + sizeof(suiteId) + sizeof(transactionType)]; char *p = pBuffer; int len = sizeof(suiteId) + sizeof(transactionType); *(MIDPTransactionType*)p = transactionType; p += sizeof(MIDPTransactionType); *(SuiteIdType*)p = suiteId; p += sizeof(SuiteIdType); if (pFilename != NULL) { int strLen; rc = pcsl_string_convert_to_utf16(pFilename, (jchar*)(p + sizeof(int)), MAX_FILENAME_LENGTH / sizeof(jchar), &strLen); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } *(int*)p = strLen; len += strLen; } /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } status = write_file(&pszError, &transDataFile, pBuffer, len); storageFreeError(pszError); pcsl_string_free(&transDataFile); g_transactionStarted = 1; return status; }
/** * Returns a storage system unique string for this record store file * based on the current vendor and suite of the running MIDlet. * <ul> * <li>The native storage path for the desired MIDlet suite * is acquired from the Scheduler. * * <li>The <code>filename</code> arg is converted into an ascii * equivalent safe to use directly in the underlying * file system and appended to the native storage path. See the * com.sun.midp.io.j2me.storage.File.unicodeToAsciiFilename() * method for conversion details. * * <li>Finally the extension number given by the extension parameter * is appended to the file name. * <ul> * @param suiteId ID of the MIDlet suite that owns the record store * @param storageId ID of the storage where the RMS will be located * @param name name of the record store * @param extension extension number to add to the end of the file name * * @return a unique identifier for this record store file */ static MIDP_ERROR rmsdb_get_unique_id_path(SuiteIdType suiteId, StorageIdType storageId, const pcsl_string* name, int extension, pcsl_string * res_path) { pcsl_string temp = PCSL_STRING_NULL; MIDP_ERROR midpErr; pcsl_string_status pcslErr; *res_path = PCSL_STRING_NULL; // null in case of any error if (pcsl_string_is_null(name)) { return MIDP_ERROR_ILLEGAL_ARGUMENT; } midpErr = midp_suite_get_rms_filename(suiteId, storageId, (extension == IDX_EXTENSION_INDEX ? MIDP_RMS_IDX_EXT : MIDP_RMS_DB_EXT), name, res_path); if (midpErr != MIDP_ERROR_NONE) { return midpErr; } if (pcsl_string_is_null(res_path)) { /* Assume this is special case where the suite was not installed and create a filename from the ID. */ pcslErr = pcsl_string_cat(storage_get_root(storageId), midp_suiteid2pcsl_string(suiteId), &temp); if (pcslErr != PCSL_STRING_OK || pcsl_string_is_null(&temp) ) { return MIDP_ERROR_FOREIGN; } pcslErr = pcsl_string_cat(&temp, name, res_path); pcsl_string_free(&temp); if (PCSL_STRING_OK != pcslErr) { return MIDP_ERROR_FOREIGN; } } return MIDP_ERROR_NONE; }
/** * Checks if there is an unfinished transaction. * * @return 0 there is no unfinished transaction, != 0 otherwise */ int unfinished_transaction_exists() { pcsl_string_status rc; pcsl_string transDataFile; int res = 0; if (g_transactionStarted) { return 1; } /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return 0; } res = storage_file_exists(&transDataFile); pcsl_string_free(&transDataFile); return res; }
/** * The function is called upon MIDlet suite removal. * It deletes suites's private directory and all it's content. * * @param suiteId the ID of MIDlet suite */ void jsr75_suite_remove_cleanup(SuiteIdType suiteId) { const pcsl_string* pStg = storage_get_root(INTERNAL_STORAGE_ID); const jchar jsep = pcsl_file_getfileseparator(); pcsl_string dirName1 = PCSL_STRING_NULL; pcsl_string dirName2 = PCSL_STRING_NULL; pcsl_string dirName = PCSL_STRING_NULL; pcsl_string sep = PCSL_STRING_NULL; if (pcsl_string_convert_from_utf16(&jsep, 1, &sep) != PCSL_STRING_OK) { return; } if (pcsl_string_cat(pStg, &privateDir, &dirName1) != PCSL_STRING_OK) { pcsl_string_free(&sep); return; } if (pcsl_string_cat(&dirName1, &sep, &dirName2) != PCSL_STRING_OK) { pcsl_string_free(&sep); pcsl_string_free(&dirName1); return; } if (pcsl_string_cat(&dirName2, midp_suiteid2pcsl_string(suiteId), &dirName) != PCSL_STRING_OK) { pcsl_string_free(&sep); pcsl_string_free(&dirName1); pcsl_string_free(&dirName2); return; } pcsl_string_free(&dirName1); pcsl_string_free(&dirName2); do_cleanup(&dirName, &sep); pcsl_string_free(&sep); pcsl_string_free(&dirName); }
/** * Rolls back the transaction being in progress. * * @return ALL_OK if the transaction was rolled back, * NOT_FOUND if the transaction has not been started, * IO_ERROR if I/O error */ MIDPError rollback_transaction() { MIDPError status = ALL_OK; pcsl_string_status rc; pcsl_string transDataFile; char *pszTemp = NULL; /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } storage_delete_file(&pszTemp, &transDataFile); pcsl_string_free(&transDataFile); if (pszTemp != NULL) { storageFreeError(pszTemp); status = IO_ERROR; } else { g_transactionStarted = 0; } return ALL_OK; }
/** * Moves a software package with given suite ID to the specified storage. * * @param suiteId suite ID for the installed package * @param storageId new storage ID * * @return SUITE_LOCKED if the * suite is locked, NOT_FOUND if the suite cannot be found or * invalid storage ID specified, BAD_PARAMS if attempt is made * to move suite to the external storage, GENERAL_ERROR if * VERIFY_ONCE is not enabled and if MONET is enabled */ MIDPError midp_change_suite_storage(SuiteIdType suiteId, StorageIdType newStorageId) { #ifndef VERIFY_ONCE (void)suiteId; (void)newStorageId; return GENERAL_ERROR; #else /* * if VERIFY_ONCE is enabled then MONET is disabled * so we don't have to check ENABLE_MONET. */ { pcsl_string suiteRoot; MidletSuiteData* pData = NULL; int status; void* fileIteratorHandle = NULL; lockStorageList *node = NULL; if ((UNUSED_STORAGE_ID == newStorageId) || (newStorageId >= MAX_STORAGE_NUM)) { return BAD_PARAMS; } /* * IMPL_NOTE: for security reasons we allow to move suite * only to the internal storage. */ if (newStorageId != INTERNAL_STORAGE_ID) { return BAD_PARAMS; } node = find_storage_lock(suiteId); if (node != NULL) { if (node->update != KNI_TRUE) { return SUITE_LOCKED; } } /* * This is a public API which can be called without the VM running * so we need automatically init anything needed, to make the * caller's code less complex. * * Initialization is performed in steps so that we do use any * extra resources such as the VM for the operation being performed. */ if (midpInit(REMOVE_LEVEL) != 0) { remove_storage_lock(suiteId); return OUT_OF_MEMORY; } /* check that the suite exists and it is not a preloaded one */ pData = get_suite_data(suiteId); if (pData == NULL) { remove_storage_lock(suiteId); return NOT_FOUND; } if (pData->storageId == newStorageId) { remove_storage_lock(suiteId); return BAD_PARAMS; } if (pData->type == COMPONENT_PREINSTALLED_SUITE) { remove_storage_lock(suiteId); return BAD_PARAMS; } do { jsize oldRootLength; jsize newRootLength; const pcsl_string* newRoot; const pcsl_string* oldRoot; char* pszError = NULL; pcsl_string filePath; pcsl_string newFilePath; status = begin_transaction(TRANSACTION_CHANGE_STORAGE, suiteId, NULL); if (status != ALL_OK) { break; } if ((status = get_suite_storage_root(suiteId, &suiteRoot)) != ALL_OK) { break; } fileIteratorHandle = storage_open_file_iterator(&suiteRoot); if (!fileIteratorHandle) { status = IO_ERROR; break; } newRoot = storage_get_root(newStorageId); oldRoot = storage_get_root(pData->storageId); newRootLength = pcsl_string_length(newRoot); oldRootLength = pcsl_string_length(oldRoot); status = ALL_OK; if ((status = midp_suite_get_class_path(suiteId, pData->storageId, KNI_FALSE, &filePath)) != ALL_OK) { break; } if ((status = midp_suite_get_class_path(suiteId, newStorageId, KNI_FALSE, &newFilePath)) != ALL_OK) { break; } storage_rename_file(&pszError, &filePath, &newFilePath); if (pszError != NULL) { status = IO_ERROR; storageFreeError(pszError); pcsl_string_free(&filePath); pcsl_string_free(&newFilePath); break; } pcsl_string_free(&filePath); pcsl_string_free(&newFilePath); #if ENABLE_IMAGE_CACHE moveImageCache(suiteId, pData->storageId, newStorageId); #endif pData->storageId = newStorageId; status = write_suites_data(&pszError); storageFreeError(pszError); } while (0); pcsl_string_free(&suiteRoot); storageCloseFileIterator(fileIteratorHandle); if (status != ALL_OK) { (void)rollback_transaction(); } else { (void)finish_transaction(); } remove_storage_lock(suiteId); return status; } #endif /* VERIFY_ONCE */ }
/** * Writes the file with information about the installed suites. * * Note that if the value of the global variable g_numberOfSuites * is zero, the file will be truncated. * * @param ppszError pointer to character string pointer to accept an error * * @return status code: ALL_OK if no errors, * OUT_OF_MEMORY if malloc failed * IO_ERROR if an IO_ERROR */ MIDPError write_suites_data(char** ppszError) { MIDPError status = ALL_OK; long bufferLen, pos; char* buffer = NULL; pcsl_string_status rc; pcsl_string suitesDataFile; MidletSuiteData* pData; *ppszError = NULL; /* get a full path to the _suites.dat */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &SUITE_DATA_FILENAME, &suitesDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } if (!g_numberOfSuites) { /* truncate the file with the list of the installed suites */ status = write_file(ppszError, &suitesDataFile, buffer, 0); pcsl_string_free(&suitesDataFile); return status; } /* allocate a buffer where the information about all suites will be saved */ bufferLen = g_numberOfSuites * (sizeof(MidletSuiteData) + MAX_VAR_SUITE_DATA_LEN); /* space to store the number of suites */ bufferLen += sizeof(int); buffer = (char*)pcsl_mem_malloc(bufferLen); if (buffer == NULL) { pcsl_string_free(&suitesDataFile); return OUT_OF_MEMORY; } /* assemble the information about all suites into the allocated buffer */ pos = 0; pData = g_pSuitesData; *(int*)&buffer[pos] = g_numberOfSuites; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(int)); while (pData != NULL) { memcpy((char*)&buffer[pos], (char*)pData, MIDLET_SUITE_DATA_SIZE); ADJUST_POS_IN_BUF(pos, bufferLen, MIDLET_SUITE_DATA_SIZE); /* setup pJarHash */ if (pData->jarHashLen > 0) { memcpy((char*)&buffer[pos], pData->varSuiteData.pJarHash, pData->jarHashLen); ADJUST_POS_IN_BUF(pos, bufferLen, pData->jarHashLen); } /* setup string fields */ { int i, convertedLen; jint strLen; pcsl_string* pStrings[] = { &pData->varSuiteData.midletClassName, &pData->varSuiteData.displayName, &pData->varSuiteData.iconName, &pData->varSuiteData.suiteVendor, &pData->varSuiteData.suiteName, &pData->varSuiteData.pathToJar, &pData->varSuiteData.pathToSettings }; status = ALL_OK; for (i = 0; i < (int) (sizeof(pStrings) / sizeof(pStrings[0])); i++) { strLen = pcsl_string_utf16_length(pStrings[i]); /* * We have to guarantee 4 - bytes alignment to use this: * *(jint*)&buffer[pos] = strLen; * on RISC CPUs. */ pos = SUITESTORE_ALIGN_4(pos); *(jint*)&buffer[pos] = strLen; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(jint)); /* assert(bufferLen > 0); */ if (strLen > 0) { rc = pcsl_string_convert_to_utf16(pStrings[i], (jchar*)&buffer[pos], bufferLen / sizeof(jchar), &convertedLen); if (rc != PCSL_STRING_OK) { status = OUT_OF_MEMORY; break; } ADJUST_POS_IN_BUF(pos, bufferLen, convertedLen * sizeof(jchar)); } } } if (status != ALL_OK) { break; } pData = pData->nextEntry; } if (status == ALL_OK) { /* write the buffer into the file */ status = write_file(ppszError, &suitesDataFile, buffer, pos); } /* cleanup */ pcsl_mem_free(buffer); pcsl_string_free(&suitesDataFile); return status; }
/** * Reads the file with information about the installed suites. * * Note that if the value of the global variable g_numberOfSuites * is zero, this function does nothing. * * @param ppszError pointer to character string pointer to accept an error * * @return status code: ALL_OK if no errors, * OUT_OF_MEMORY if malloc failed * IO_ERROR if an IO_ERROR, * SUITE_CORRUPTED_ERROR if the suite database is corrupted */ MIDPError read_suites_data(char** ppszError) { MIDPError status; int i; long bufferLen, pos; char* buffer = NULL; pcsl_string_status rc; pcsl_string suitesDataFile; MidletSuiteData *pSuitesData = g_pSuitesData; MidletSuiteData *pData, *pPrevData = NULL; int numOfSuites = 0; *ppszError = NULL; if (g_isSuitesDataLoaded) { return ALL_OK; } if (midpInit(LIST_LEVEL) != 0) { return OUT_OF_MEMORY; } /* get a full path to the _suites.dat */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &SUITE_DATA_FILENAME, &suitesDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } /* read the file */ status = read_file(ppszError, &suitesDataFile, &buffer, &bufferLen); pcsl_string_free(&suitesDataFile); if (status == NOT_FOUND || (status == ALL_OK && bufferLen == 0)) { /* _suites.dat is absent or empty, it's a normal situation */ g_pSuitesData = NULL; g_numberOfSuites = 0; g_isSuitesDataLoaded = 1; return ALL_OK; } if (status == ALL_OK && bufferLen < (long) sizeof(int)) { pcsl_mem_free(buffer); status = SUITE_CORRUPTED_ERROR; /* _suites.dat is corrupted */ } if (status != ALL_OK) { return status; } /* parse contents of the suite database */ pos = 0; numOfSuites = *(int*)&buffer[pos]; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(int)); for (i = 0; i < numOfSuites; i++) { pData = (MidletSuiteData*) pcsl_mem_malloc(sizeof(MidletSuiteData)); if (!pData) { status = OUT_OF_MEMORY; break; } if (pPrevData) { pPrevData->nextEntry = pData; } else { pSuitesData = pData; } /* IMPL_NOTE: introduce pcsl_mem_copy() */ if (bufferLen < (long)MIDLET_SUITE_DATA_SIZE) { status = IO_ERROR; break; } memcpy((char*)pData, (char*)&buffer[pos], MIDLET_SUITE_DATA_SIZE); ADJUST_POS_IN_BUF(pos, bufferLen, MIDLET_SUITE_DATA_SIZE); pData->nextEntry = NULL; /* this suite was not checked if it is corrupted */ pData->isChecked = 0; /* setup pJarHash */ if (pData->jarHashLen > 0) { pData->varSuiteData.pJarHash = (unsigned char*)pcsl_mem_malloc(pData->jarHashLen); if (pData->varSuiteData.pJarHash == NULL) { status = OUT_OF_MEMORY; break; } memcpy(pData->varSuiteData.pJarHash, (char*)&buffer[pos], pData->jarHashLen); ADJUST_POS_IN_BUF(pos, bufferLen, pData->jarHashLen); } else { pData->varSuiteData.pJarHash = NULL; } /* setup string fields */ { int i; jint strLen; pcsl_string* pStrings[] = { &pData->varSuiteData.midletClassName, &pData->varSuiteData.displayName, &pData->varSuiteData.iconName, &pData->varSuiteData.suiteVendor, &pData->varSuiteData.suiteName, &pData->varSuiteData.pathToJar, &pData->varSuiteData.pathToSettings }; status = ALL_OK; for (i = 0; i < (int) (sizeof(pStrings) / sizeof(pStrings[0])); i++) { if (bufferLen < (long)sizeof(jint)) { status = IO_ERROR; /* _suites.dat is corrupted */ break; } /* * We have to guarantee 4 - bytes alignment to use this: * strLen = *(jint*)&buffer[pos]; * on RISC CPUs. */ pos = SUITESTORE_ALIGN_4(pos); strLen = *(jint*)&buffer[pos]; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(jint)); if (bufferLen < (long)strLen) { status = IO_ERROR; /* _suites.dat is corrupted */ break; } if (strLen > 0) { rc = pcsl_string_convert_from_utf16( (jchar*)&buffer[pos], strLen, pStrings[i]); if (rc != PCSL_STRING_OK) { status = OUT_OF_MEMORY; break; } ADJUST_POS_IN_BUF(pos, bufferLen, strLen * sizeof(jchar)); } else { *pStrings[i] = strLen ? PCSL_STRING_NULL : PCSL_STRING_EMPTY; } } } if (status != ALL_OK) { break; } pData->nextEntry = NULL; pPrevData = pData; } /* end for (numOfSuites) */ pcsl_mem_free(buffer); if (status == ALL_OK) { g_numberOfSuites = numOfSuites; g_pSuitesData = pSuitesData; g_isSuitesDataLoaded = 1; } else { free_suites_data(); } return status; }
javacall_result bt_push_startup() { int i; char *error; pcsl_string full_name = PCSL_STRING_NULL; int storage; REPORT_INFO(LC_PUSH, "Bluetooth PushRegistry is now starting."); javacall_bt_sddb_initialize(); pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &BT_PUSH_FILENAME, &full_name); if (!storage_file_exists(&full_name)) { pcsl_string_free(&full_name); return JAVACALL_OK; } storage = storage_open(&error, &full_name, OPEN_READ); pcsl_string_free(&full_name); if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Failed to open `BtPush' file: %s", error); storageFreeError(error); return JAVACALL_FAIL; } storageRead(&error, storage, (char *)&g_count, sizeof(g_count)); for (i = 0; error == NULL && i < g_count; i++) { bt_push_t *push = (bt_push_t *)pcsl_mem_malloc(sizeof(bt_push_t)); if (push == NULL) { REPORT_ERROR(LC_PUSH, "Failed to allocate memory."); storageClose(&error, storage); storageFreeError(error); return JAVACALL_FAIL; } storageRead(&error, storage, (char *)&push->port, sizeof(push->port)); if (error != NULL) { pcsl_mem_free(push); break; } storageRead(&error, storage, (char *)&push->params, sizeof(push->params)); if (error != NULL) { pcsl_mem_free(push); break; } storageRead(&error, storage, (char *)&push->record.classes, sizeof(push->record.classes)); if (error != NULL) { pcsl_mem_free(push); break; } storageRead(&error, storage, (char *)&push->record.size, sizeof(push->record.size)); if (error != NULL) { pcsl_mem_free(push); break; } push->record.data = pcsl_mem_malloc(push->record.size); if (push->record.data == NULL) { pcsl_mem_free(push); REPORT_ERROR(LC_PUSH, "Failed to allocate memory."); storageClose(&error, storage); storageFreeError(error); return JAVACALL_FAIL; } storageRead(&error, storage, (char *)push->record.data, push->record.size); if (error != NULL) { pcsl_mem_free(push->record.data); pcsl_mem_free(push); break; } storageRead(&error, storage, (char *)&push->record.id, sizeof(push->record.id)); if (error != NULL) { pcsl_mem_free(push); break; } push->server = BT_INVALID_HANDLE; push->client = NULL; push->next = g_registry; g_registry = push; } if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Error reading `BtPush' file: %s", error); storageFreeError(error); storageClose(&error, storage); storageFreeError(error); return JAVACALL_FAIL; } REPORT_INFO1(LC_PUSH, "%d record(s) read.", g_count); storageClose(&error, storage); storageFreeError(error); if (g_count > 0) { /* Attempt to enable Bluetooth radio, if it is not already on. */ javacall_bool enabled; javacall_bt_stack_initialize(); if (javacall_bt_stack_is_enabled(&enabled) == JAVACALL_OK && enabled == JAVACALL_FALSE) { javacall_bt_stack_enable(); } } return JAVACALL_OK; }
/** * Gets location of the resource with specified type and name * for the suite with the specified suiteId. * * Note that the implementation of this function MUST allocate the memory * for the in/out parameter filename using pcsl_mem_malloc(). * The caller is responsible for freeing the memory associated * with filename parameter. * * @param suiteId The application suite ID * @param storageId storage ID where the RMS will be located * NOTE: currently this parameter is ignored due to limitation of our * implementation: RMS is always located at the same storage as the suite. * @param extension rms extension that can be MIDP_RMS_DB_EXT or * MIDP_RMS_IDX_EXT * @param pResourceName RMS name * @param pFileName The in/out parameter that contains returned filename * * @return error code that should be one of the following: * <pre> * ALL_OK, OUT_OF_MEMORY, NOT_FOUND, * SUITE_CORRUPTED_ERROR, BAD_PARAMS * </pre> */ MIDPError midp_suite_get_rms_filename(SuiteIdType suiteId, StorageIdType storageId, jint extension, const pcsl_string* pResourceName, pcsl_string* pFileName) { const pcsl_string* root; pcsl_string returnPath = PCSL_STRING_NULL; pcsl_string rmsFileName = PCSL_STRING_NULL; jint suiteIdLen = GET_SUITE_ID_LEN(suiteId); jsize resourceNameLen = pcsl_string_length(pResourceName); /* * IMPL_NOTE: currently we have a limitation that the suite's RMS * must be located at the same storage as the midlet suite. * See rms.c, rmsdb_get_record_store_space_available() for more details. */ root = storage_get_root(storageId); *pFileName = PCSL_STRING_NULL; if (resourceNameLen > 0) { const pcsl_string* ext; jsize extLen; int fileNameLen; if (MIDP_RMS_IDX_EXT == extension) { ext = &IDX_EXTENSION; extLen = pcsl_string_length(&IDX_EXTENSION); } else if (MIDP_RMS_DB_EXT == extension) { ext = &DB_EXTENSION; extLen = pcsl_string_length(&DB_EXTENSION); } else { return BAD_PARAMS; } /* performance hint: predict buffer capacity */ fileNameLen = PCSL_STRING_ESCAPED_BUFFER_SIZE(resourceNameLen + extLen); pcsl_string_predict_size(&rmsFileName, fileNameLen); if (pcsl_string_append_escaped_ascii(&rmsFileName, pResourceName) != PCSL_STRING_OK || pcsl_string_append(&rmsFileName, ext) != PCSL_STRING_OK) { pcsl_string_free(&rmsFileName); return OUT_OF_MEMORY; } } /* performance hint: predict buffer capacity */ pcsl_string_predict_size(&returnPath, pcsl_string_length(root) + suiteIdLen + pcsl_string_length(&rmsFileName)); if (PCSL_STRING_OK != pcsl_string_append(&returnPath, root) || PCSL_STRING_OK != pcsl_string_append(&returnPath, midp_suiteid2pcsl_string(suiteId)) || PCSL_STRING_OK != pcsl_string_append(&returnPath, &rmsFileName)) { pcsl_string_free(&rmsFileName); pcsl_string_free(&returnPath); return OUT_OF_MEMORY; } pcsl_string_free(&rmsFileName); *pFileName = returnPath; return ALL_OK; }
void MidpMountedRoots::update(bool notify) { DEBUG_PRINT("update"); #ifdef UNIX QValueList<QString> disks; QValueList<QString> paths; bool rebuild = false; int count = 0; // Read system mounts struct mntent *me; FILE *mntfp = setmntent("/etc/mtab", "r"); if (mntfp) { while ((me = getmntent( mntfp )) != 0) { QString disk = me->mnt_fsname; if (isValidDisk(disk)) { count++; disks.append(disk); QString path = QString(me->mnt_dir) + '/'; paths.append(path); if (!isCachedDisk(disk)) { rebuild = true; } } } endmntent(mntfp); } // Add special roots for PIM, FC and Private const pcsl_string* storage = storage_get_root(INTERNAL_STORAGE_ID); if (pcsl_string_length(storage) >= 0) { const char* cstorage = (const char*)pcsl_string_get_utf8_data(storage); QString qstorage = cstorage; pcsl_string_release_utf8_data((const jbyte*)cstorage, storage); QString fc = qstorage + "storage/"; QFile ffc(fc); // determine whether the path exists // Note: the path is created by the build system. if (ffc.exists()) { count++; const QString name = "storage"; disks.append(name); paths.append(fc); if (!isCachedDisk(name)) { rebuild = true; } } QString pim = qstorage + "pimdb/"; QFile fpim(pim); // determine whether the path exists // Note: the path is created by the build system. if (fpim.exists()) { count++; const QString name = "pimdb"; disks.append(name); paths.append(pim); if (!isCachedDisk(name)) { rebuild = true; } } QString prv = qstorage + "private/"; QFile fprv(prv); // determine whether the path exists // Note: the path is created by the build system. if (fprv.exists()) { count++; const QString name = "private"; disks.append(name); paths.append(prv); if (!isCachedDisk(name)) { rebuild = true; } } } if (rebuild || count != (int)mRoots.count()) { mRoots.clear(); QStringList::ConstIterator it = disks.begin(); QStringList::ConstIterator pit = paths.begin(); for (; it != disks.end(); ++it, ++pit) { QString disk = *it; QString path = *pit; QString root, local; if (getDiskInfo(disk, root, local)) { MidpFileRoot* fs = new MidpFileRoot(disk, path, root, local); mRoots.append(fs); } } // Call the handler if required if (notify) { disksChanged(); } } #endif }