/** * Writes the contents of the given buffer into the given file. * * Note that if the length of the input buffer is zero or less, * the file will be truncated. * * @param ppszError pointer to character string pointer to accept an error * @param pFileName file to write * @param inBuffer buffer with data that will be stored * @param inBufferLen length of the inBuffer * * @return status code (ALL_OK if there was no errors) */ MIDPError write_file(char** ppszError, const pcsl_string* pFileName, char* inBuffer, long inBufferLen) { int handle, status = ALL_OK; char* pszTemp; pcsl_string tmpFileName; pcsl_string_status rc; *ppszError = NULL; /* get the name of the temporary file */ rc = pcsl_string_cat(pFileName, &TMP_FILE_EXTENSION, &tmpFileName); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } /* open the file */ handle = storage_open(ppszError, &tmpFileName, OPEN_READ_WRITE_TRUNCATE); if (*ppszError != NULL) { pcsl_string_free(&tmpFileName); return IO_ERROR; } /* write the whole buffer */ if (inBufferLen > 0) { storageWrite(ppszError, handle, inBuffer, inBufferLen); } if (*ppszError != NULL) { status = IO_ERROR; } /* close the file */ storageClose(&pszTemp, handle); storageFreeError(pszTemp); if (status == ALL_OK) { /* rename the temporary file */ storage_rename_file(ppszError, &tmpFileName, pFileName); if (*ppszError != NULL) { status = IO_ERROR; storage_delete_file(&pszTemp, &tmpFileName); storageFreeError(pszTemp); } } else { storage_delete_file(&pszTemp, &tmpFileName); storageFreeError(pszTemp); } pcsl_string_free(&tmpFileName); return (MIDPError)status; }
/** * 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 */ }