/**
 * 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;
}
Exemple #4
0
/**
 * 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;
  }
}
Exemple #5
0
/**
 * 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;
}
Exemple #6
0
/**
 * 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;
}
Exemple #9
0
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;
}
Exemple #13
0
/**
 * 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;
}
Exemple #15
0
/**
 * 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;
}
Exemple #20
0
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;
}
Exemple #21
0
/**
 * 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;
}
Exemple #22
0
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
}