/**
 * 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;
}
Пример #2
0
/*
 * Rename a file in storage.
 *
 * If not successful *ppszError will set to point to an error string,
 * on success it will be set to NULL.
 */
void
storage_rename_file(char** ppszError, const pcsl_string* oldFilename_str,
                    const pcsl_string* newFilename_str) {
    int status;
    *ppszError = NULL;

    DEBUGP2F("renaming %s", oldFilename_str);
    DEBUGP2F(" to %s\n", newFilename_str);

    if (!storage_file_exists(oldFilename_str)) {
        *ppszError = (char *)NOT_EXIST_RENAME_ERROR;
    }

    if (storage_file_exists(newFilename_str)) {
        storage_delete_file(ppszError, newFilename_str);
        if (*ppszError != NULL) {
            return;
        }
    }

    status = pcsl_file_rename(oldFilename_str, newFilename_str);

    if (status < 0) {
        *ppszError = storage_get_last_file_error("storageRename", newFilename_str);
        return;
    }

    *ppszError = NULL;
}
/**
 * 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;
}
/**
 * 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;
}
/**
 * Removes the files belonging to the specified component, or to all
 * components owned by the given suite.
 *
 * @param suiteId ID of the suite whose components are being removed
 * @param componentId ID of the component to remove or UNUSED_COMPONENT_ID
 *                    if all components of the suite are being removed 
 *
 * @return status code, ALL_OK if no errors
 */
static MIDPError
delete_components_files(SuiteIdType suiteId, ComponentIdType componentId) {
    pcsl_string componentFileName;
    char* pszError;
    int suiteFound = 0;
    MIDPError status = ALL_OK;
    MidletSuiteData* pData = g_pSuitesData;

    /* handle the list entries having the given suiteId */
    while (pData != NULL) {
        if (pData->suiteId == suiteId) {
            suiteFound = 1;
            
            if (pData->type == COMPONENT_DYNAMIC &&
                    (componentId == UNUSED_COMPONENT_ID ||
                        pData->componentId == componentId)) {
                /* remove the file holding the component */
                status = get_jar_path(COMPONENT_DYNAMIC,
                    (jint)pData->componentId, &componentFileName);
                if (status != ALL_OK) {
                    break;
                }

                storage_delete_file(&pszError, &componentFileName);

                if (pszError != NULL) {
                    storageFreeError(pszError);
                    /* it's an error only if the file exists */
                    if (storage_file_exists(&componentFileName)) {
                        status = IO_ERROR;
                        pcsl_string_free(&componentFileName);
                        break;
                    }
                }

                pcsl_string_free(&componentFileName);
            }
        }

        pData = pData->nextEntry;
    }

    if (status == ALL_OK && suiteFound == 0) {
        /* suite doesn't exist */
        status = NOT_FOUND;
    }

    return status;
}
Пример #6
0
/**
 * Removes the storage file for record store <code>filename</code>
 * if it exists.
 *
 * @param ppszError pointer to a string that will hold an error message
 *        if there is a problem, or null if the function is
 *        successful (This function sets <tt>ppszError</tt>'s value.)
 * @param suiteId ID of the MIDlet suite that owns the record store
 * @param name name of the record store
 * @param extension extension number to add to the end of the file name
 *
 * @return 1 if successful
 *         0 if an IOException occurred
 *        -1 if file is locked by another isolate
 *        -2 if out of memory error occurs
 *
 */
int
rmsdb_record_store_delete(char** ppszError,
                          SuiteIdType suiteId,
                          const pcsl_string* name_str,
                          int extension) {
    StorageIdType storageId;
    MIDPError status;
    pcsl_string filename_str;
    lockFileList* searchedNodePtr = NULL;

    *ppszError = NULL;

    if ((extension == DB_EXTENSION_INDEX)&&(lockFileListPtr != NULL)) {
        /* linked list is already initialised for a db file */
        searchedNodePtr = findLockById(suiteId, name_str);
        if (searchedNodePtr != NULL) {
            /* File is in use by another isolate */
            *ppszError = (char *)FILE_LOCK_ERROR;
            return -1;
        }
    }

    /*
     * IMPL Note: here is assumed that the record store is located in the same
     * storage as the midlet suite. This may not be true.
     */
    status = midp_suite_get_suite_storage(suiteId, &storageId);
    if (status != ALL_OK) {
        return 0;
    }

    if (MIDP_ERROR_NONE != rmsdb_get_unique_id_path(suiteId, storageId,
            name_str, extension, &filename_str)) {
        return -2;
    }
    storage_delete_file(ppszError, &filename_str);

    pcsl_string_free(&filename_str);

    if (*ppszError != NULL) {
        return 0;
    }

    return 1;
}
Пример #7
0
/**
 * multitape_metadata_delete(S, C, mdat):
 * Delete specified metadata file; ${mdat} must have been initialized by a
 * call to multitape_metadata_get_by(hash|name).  Call
 * chunks_delete_extrastats on ${C} and the metadata file length.
 */
int
multitape_metadata_delete(STORAGE_D * S, CHUNKS_D * C,
    struct tapemetadata * mdat)
{
	uint8_t hbuf[32];

	if (crypto_hash_data(CRYPTO_KEY_HMAC_NAME,
	    (uint8_t *)mdat->name, strlen(mdat->name), hbuf))
		goto err0;
	if (storage_delete_file(S, 'm', hbuf))
		goto err0;
	chunks_delete_extrastats(C, mdat->metadatalen);

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Пример #8
0
/**
 * Removes the storage file for record store <code>filename</code>
 * if it exists.
 *
 * @param ppszError pointer to a string that will hold an error message
 *        if there is a problem, or null if the function is
 *        successful (This function sets <tt>ppszError</tt>'s value.)
 * @param filenameBase filenameBase of the MIDlet suite that owns the record 
 * store
 * @param name name of the record store
 * @param extension extension number to add to the end of the file name
 *
 * @return 1 if successful
 *         0 if an IOException occurred
 *        -1 if file is locked by another isolate
 *        -2 if out of memory error occurs
 *
 */
int
rmsdb_record_store_delete(char** ppszError,
                          pcsl_string* filenameBase,
                          const pcsl_string* name_str,
                          int extension) {
    pcsl_string filename_str;
#if ENABLE_RECORDSTORE_FILE_LOCK
    lockFileList* searchedNodePtr = NULL;
#endif

    *ppszError = NULL;

#if ENABLE_RECORDSTORE_FILE_LOCK
    if (extension == DB_EXTENSION_INDEX) {
        searchedNodePtr = rmsdb_find_file_lock_by_id(filenameBase, name_str);
        if (searchedNodePtr != NULL) {
            /* File is in use by another isolate */
            *ppszError = (char *)FILE_LOCK_ERROR;
            return -1;
        }
    }
#endif

    /*
     * IMPL_NOTE: for security reasons the record store is always
     * located in the internal storage.
     */
    if (MIDP_ERROR_NONE != rmsdb_get_unique_id_path(filenameBase, 
                INTERNAL_STORAGE_ID, name_str, extension, &filename_str)) {
        return -2;
    }
    storage_delete_file(ppszError, &filename_str);

    pcsl_string_free(&filename_str);

    if (*ppszError != NULL) {
        return 0;
    }

    return 1;
}
/**
 * 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;
}
/**
 * Removes a software package given its suite ID
 * <p>
 * If the component is in use it must continue to be available
 * to the other components that are using it.  The resources it
 * consumes must not be released until it is not in use.
 *
 * @param suiteId ID of the suite
 *
 * @return ALL_OK if no errors,
 *         NOT_FOUND if the suite does not exist,
 *         SUITE_LOCKED if the suite is locked,
 *         BAD_PARAMS this suite cannot be removed
 */
MIDPError
midp_remove_suite(SuiteIdType suiteId) {
    pcsl_string filename;
    char* pszError;
    pcsl_string suiteRoot;
    MIDPError status;
    int operationStarted = 0;
    void* fileIteratorHandle = NULL;
    MidpProperties properties;
    pcsl_string* pproperty;
    MidletSuiteData* pData = NULL;
    pcsl_string filenameBase;

    lockStorageList *node = NULL;

    /* get the filename base from the suite id */
    status = build_suite_filename(suiteId, &PCSL_STRING_EMPTY, 
                                          &filenameBase);
    if (status != ALL_OK) {
        return status;
    }
    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) {
        return OUT_OF_MEMORY;
    }

    do {
        int rc; /* return code for rmsdb_... and storage_... */

        /* load _suites.dat */
        status = read_suites_data(&pszError);
        storageFreeError(pszError);
        if (status != ALL_OK) {
            break;
        }

        /* check that the suite exists and it is not a preloaded one */
        pData = get_suite_data(suiteId);

        if (pData == NULL) {
            status = NOT_FOUND;
            break;
        }

        /* notify the listeners that we starting to remove the suite */
        operationStarted = 1;
        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,
            SUITESTORE_OPERATION_START, ALL_OK, pData);

        if (pData->type == COMPONENT_PREINSTALLED_SUITE) {
            status = BAD_PARAMS;
            break;
        }

        status = begin_transaction(TRANSACTION_REMOVE_SUITE, suiteId, NULL);
        if (status != ALL_OK) {
            return status;
        }

        /*
         * Remove the files
         * Call the native RMS method to remove the RMS data.
         * This function call is needed for portability
         */
        rc = rmsdb_remove_record_stores_for_suite(&filenameBase, suiteId);
        if (rc == KNI_FALSE) {
            status = SUITE_LOCKED;
            break;
        }

        pushdeletesuite(suiteId);

        /*
         * If there is a delete notify property, add the value to the delete
         * notify URL list.
         */
        properties = midp_get_suite_properties(suiteId);
        if (properties.numberOfProperties > 0) {
            pproperty = midp_find_property(&properties, &DELETE_NOTIFY_PROP);
            if (pcsl_string_length(pproperty) > 0) {
                midpAddDeleteNotification(suiteId, pproperty);
            }

            pproperty = midp_find_property(&properties, &INSTALL_NOTIFY_PROP);
            if (pcsl_string_length(pproperty) > 0) {
                /*
                 * Remove any pending install notifications since they are only
                 * retried when the suite is run.
                 */
                midpRemoveInstallNotification(suiteId);
            }

            midp_free_properties(&properties);
        }

        if ((status = get_suite_storage_root(suiteId, &suiteRoot)) != ALL_OK) {
            break;
        }

        fileIteratorHandle = storage_open_file_iterator(&suiteRoot);
        if (!fileIteratorHandle) {
            status = IO_ERROR;
            break;
        }

#if ENABLE_ICON_CACHE
        midp_remove_suite_icons(suiteId);
#endif        

        for (;;) {
            rc = storage_get_next_file_in_iterator(&suiteRoot,
                fileIteratorHandle, &filename);
            if (0 != rc) {
                break;
            }
            storage_delete_file(&pszError, &filename);
            pcsl_string_free(&filename);
            if (pszError != NULL) {
                storageFreeError(pszError);
                break;
            }
        }

    } while (0);

    pcsl_string_free(&suiteRoot);
    storageCloseFileIterator(fileIteratorHandle);

    (void)finish_transaction();

    /*
     * Notify the listeners the we've finished removing the suite.
     * It should be done before remove_from_suite_list_and_save()
     * call because it frees pData structure.
     */
    if (operationStarted) {
        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,
            SUITESTORE_OPERATION_END, status, pData);
    }

    if (status == ALL_OK) {
        (void)remove_from_suite_list_and_save(suiteId);
    }

    remove_storage_lock(suiteId);

    return status;
}