/** * Cleans up all data memebers of given data structure, * <br>but <code>handler</code> itself is not cleared. * @param handler pointer on data structure * <code>JSR211_content_handler</code> to be cleared. */ void jsr211_cleanHandlerData(JSR211_content_handler *handler) { // clean up handler structure if (pcsl_string_is_null(&(handler->id)) == PCSL_FALSE) { pcsl_string_free(&(handler->id)); } if (pcsl_string_is_null(&(handler->class_name)) == PCSL_FALSE) { pcsl_string_free(&(handler->class_name)); } if (handler->type_num > 0 && handler->types != NULL) { free_pcsl_string_list(handler->types, handler->type_num); } if (handler->suff_num > 0 && handler->suffixes != NULL) { free_pcsl_string_list(handler->suffixes, handler->suff_num); } if (handler->act_num > 0 && handler->actions != NULL) { free_pcsl_string_list(handler->actions, handler->act_num); } if (handler->locale_num > 0 && handler->locales != NULL) { free_pcsl_string_list(handler->locales, handler->locale_num); } if (handler->act_num > 0 && handler->locale_num > 0 && handler->action_map != NULL) { free_pcsl_string_list(handler->action_map, handler->act_num * handler->locale_num); } if (handler->access_num > 0 && handler->accesses != NULL) { free_pcsl_string_list(handler->accesses, handler->access_num); } }
/* * Insert a new node to the front of the linked list * * @param suiteId : ID of the suite * @param name : Name of the record store * @param handle : Handle of the opened file * * @return 0 if node is successfully inserted * return OUT_OF_MEM_LEN if memory allocation fails * */ static int recordStoreCreateLock(SuiteIdType suiteId, const pcsl_string * name_str, int handle) { lockFileList* newNodePtr; newNodePtr = (lockFileList *)midpMalloc(sizeof(lockFileList)); if (newNodePtr == NULL) { return OUT_OF_MEM_LEN; } newNodePtr->suiteId = suiteId; /*IMPL_NOTE: check for error codes instead of null strings*/ pcsl_string_dup(name_str, &newNodePtr->recordStoreName); if (pcsl_string_is_null(&newNodePtr->recordStoreName)) { midpFree(newNodePtr); return OUT_OF_MEM_LEN; } newNodePtr->handle = handle; newNodePtr->next = NULL; if (lockFileListPtr == NULL) { lockFileListPtr = newNodePtr; } else { newNodePtr->next = lockFileListPtr; lockFileListPtr = newNodePtr; } return 0; }
/** * Looks to see if the storage file for record store * identified by <code>uidPath</code> exists * * @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 true if the file exists, false if it does not. */ int rmsdb_record_store_exists(SuiteIdType suiteId, const pcsl_string* name, int extension) { pcsl_string filename; int intStatus; StorageIdType storageId; MIDPError status; /* * 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, extension, &filename)) { return 0; } if (pcsl_string_is_null(&filename)) { return 0; } intStatus = storage_file_exists(&filename); pcsl_string_free(&filename); return 0 != intStatus; }
QString pcsl_string2QString(const pcsl_string &pstring) { /* * Example From the QT toolkit doc for QString.isNull() * QString a; // a.unicode() == 0, a.length() == 0 * QString b = ""; // b.unicode() == "", b.length() == 0 * a.isNull(); // TRUE, because a.unicode() == 0 * a.isEmpty(); // TRUE, because a.length() == 0 * b.isNull(); // FALSE, because b.unicode() != 0 * b.isEmpty(); // TRUE, because b.length() == 0 */ QString qstring; if (pcsl_string_is_null(&pstring)) { // we want isNull to be true qstring = QString::null; } else if (pcsl_string_length(&pstring) == 0) { // we want isEmpty to be true qstring = ""; } else { const pcsl_string* const mmstring = &pstring; GET_PCSL_STRING_DATA_AND_LENGTH(mmstring) qstring.setUtf16((const ushort *)mmstring_data, mmstring_len); RELEASE_PCSL_STRING_DATA_AND_LENGTH } return qstring; }
/** * 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; }
static MidpProperties verifyMfMustProperties(MidpProperties mfsmp) { /* MUST fields in MANIFEST */ /* pcsl_string MIDlet-<n> for each MIDlet */ pcsl_string * midlet_1; pcsl_string * name; pcsl_string * version; pcsl_string * vendor; pcsl_string * profile; pcsl_string * configuration; name = midp_find_property(&mfsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(name)) { REPORT_WARN(LC_AMS, "Missing suite name"); mfsmp.status = NO_SUITE_NAME_PROP; return mfsmp; } vendor = midp_find_property(&mfsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(vendor)) { REPORT_WARN(LC_AMS, "Missing suite vendor"); mfsmp.status = NO_SUITE_VENDOR_PROP; return mfsmp; } version = midp_find_property(&mfsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(version)) { REPORT_WARN(LC_AMS, "Missing suite version"); mfsmp.status = NO_SUITE_VERSION_PROP; return mfsmp; } if (!midpCheckVersion(version)) { REPORT_WARN(LC_AMS, "Corrupted suite version"); mfsmp.status = BAD_SUITE_VERSION_PROP; return mfsmp; } profile = midp_find_property(&mfsmp, &MICROEDITION_PROFILE_PROP); if (pcsl_string_is_null(profile)) { REPORT_WARN(LC_AMS, "Missing Midp-Profile"); mfsmp.status = NO_MICROEDITION_PROFILE_PROP; return mfsmp; } configuration = midp_find_property(&mfsmp, &MICROEDITION_CONFIGURATION_PROP); if (pcsl_string_is_null(configuration)) { REPORT_WARN(LC_AMS, "Missing Midp-Configuration"); mfsmp.status = NO_MICROEDITION_CONFIGURATION_PROP; return mfsmp; } midlet_1 = midp_find_property(&mfsmp, &MIDLET_ONE_PROP); if (pcsl_string_is_null(midlet_1)) { REPORT_WARN(LC_AMS, "Missing Midlet-1"); mfsmp.status = NO_MIDLET_ONE_PROP; return mfsmp; } return mfsmp; } /* verifyMfMustProperties */
/** * Helper function to initialize fields from Strings. * @param str string to store * @param object into which it should be stored * @param fieldid of field to store the jstring * @return false if the String could not allocate */ static jboolean storeField(const pcsl_string* str, jobject invocObj, jfieldID fid, jobject tmpobj) { if (str == NULL || pcsl_string_is_null(str)) { KNI_ReleaseHandle(tmpobj); } else { if (PCSL_STRING_OK != midp_jstring_from_pcsl_string(str, tmpobj)) { return KNI_FALSE; } } KNI_SetObjectField(invocObj, fid, tmpobj); return KNI_TRUE; }
/** * Write pcsl_string to storage. * First write a jint with length, then the text in utf-16 encoding. * * @param ppszError in the case of error, receives address of a string * describing the problem * @param handle handle of the file to write to * @param str string to be written */ void storage_write_utf16_string(char** ppszError, int handle, const pcsl_string* str) { jint length; if(pcsl_string_is_null(str)) { length = -1; } else { length = pcsl_string_length(str); } storageWrite(ppszError, handle, (char*)&length, sizeof (length)); /* are there data to write? */ if (NULL == *ppszError && length > 0) { const jchar* data = pcsl_string_get_utf16_data(str); if(NULL == data) { *ppszError = (char *)OUT_OF_MEM_ERROR; } else { storageWrite(ppszError, handle, (char*)data, length * sizeof (jchar)); pcsl_string_release_utf16_data(data, str); } } }
/** * Looks to see if the storage file for record store * identified by <code>uidPath</code> exists * * @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 true if the file exists, false if it does not. */ int rmsdb_record_store_exists(pcsl_string* filenameBase, const pcsl_string* name, int extension) { pcsl_string filename; int intStatus; /* * 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, extension, &filename)) { return 0; } if (pcsl_string_is_null(&filename)) { return 0; } intStatus = storage_file_exists(&filename); pcsl_string_free(&filename); return 0 != intStatus; }
extern "C" void pcsl_string2QString(const pcsl_string &pstring, QString &qstring) { /* * Example From the QT toolkit doc for QString.isNull() * QString a; // a.unicode() == 0, a.length() == 0 * QString b = ""; // b.unicode() == "", b.length() == 0 * a.isNull(); // TRUE, because a.unicode() == 0 * a.isEmpty(); // TRUE, because a.length() == 0 * b.isNull(); // FALSE, because b.unicode() != 0 * b.isEmpty(); // TRUE, because b.length() == 0 */ if (pcsl_string_is_null(&pstring)) { // we want isNull to be true qstring = (const char *)NULL; } else if (pcsl_string_length(&pstring) == 0) { // we want isEmpty to be true qstring = ""; } else { const pcsl_string* const mmstring = &pstring; GET_PCSL_STRING_DATA_AND_LENGTH(mmstring) qstring.setUnicodeCodes((const ushort *)mmstring_data, mmstring_len); RELEASE_PCSL_STRING_DATA_AND_LENGTH } }
/** * Gets the amount of storage on the device that this suite is using. * This includes the JAD, JAR, management data, and RMS. * * @param suiteId ID of the suite * * @return number of bytes of storage the suite is using or less than * OUT_OF_MEM_LEN if out of memory */ long midp_get_suite_storage_size(SuiteIdType suiteId) { long used = 0; long rms = 0; pcsl_string filename[NUM_SUITE_FILES]; int i; char* pszError; StorageIdType storageId; MIDPError status; MidletSuiteData* pData; pcsl_string filenameBase; // get the filename base from the suite id status = build_suite_filename(suiteId, &PCSL_STRING_EMPTY, &filenameBase); if (status != ALL_OK) { return status; } pData = get_suite_data(suiteId); if (pData) { used = (jint)pData->suiteSize; } if (used <= 0) { /* Suite size is not cached (should not happen!), calculate it. */ for (i = 0; i < NUM_SUITE_FILES; i++) { filename[i] = PCSL_STRING_NULL; } /* * 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(LIST_LEVEL) != 0) { return OUT_OF_MEM_LEN; } status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return OUT_OF_MEM_LEN; } status = build_suite_filename(suiteId, &INSTALL_INFO_FILENAME, &filename[0]); if (status != ALL_OK) { return status; } status = build_suite_filename(suiteId, &SETTINGS_FILENAME, &filename[1]); if (status != ALL_OK) { return status; } midp_suite_get_class_path(suiteId, storageId, KNI_TRUE, &filename[2]); get_property_file(suiteId, KNI_TRUE, &filename[3]); for (i = 0; i < NUM_SUITE_FILES; i++) { long tmp; if (pcsl_string_is_null(&filename[i])) { continue; } tmp = storage_size_of_file_by_name(&pszError, &filename[i]); pcsl_string_free(&filename[i]); if (pszError != NULL) { storageFreeError(pszError); continue; } used += tmp; } if (pData) { /* cache the calculated size */ pData->suiteSize = (jint)used; status = write_suites_data(&pszError); if (status != ALL_OK) { storageFreeError(pszError); return OUT_OF_MEM_LEN; } } } rms = rmsdb_get_rms_storage_size(&filenameBase, suiteId); if (rms == OUT_OF_MEM_LEN) { return OUT_OF_MEM_LEN; } return used + rms; }
static MidpProperties midpParseMf(jchar* jchar_buffer) { MidpProperties mfsmp = {0, ALL_OK, NULL}; pcsl_string mfkey; pcsl_string mfkey_trimmed; pcsl_string mfvalue; pcsl_string mfvalue_trimmed; pcsl_string mfline; MIDPError err; pcsl_string_status rc; int countLines = 0; int index = 0; int count = 0; if (!jchar_buffer) { mfsmp.status = BAD_PARAMS; return mfsmp; } countLines = count_mf_lines(jchar_buffer); if (countLines <= 0) { REPORT_INFO(LC_AMS, "midpParseMf(): Empty manifest."); mfsmp.status = OUT_OF_MEMORY; return mfsmp; } mfsmp.pStringArr = alloc_pcsl_string_list(countLines * 2); if (mfsmp.pStringArr == NULL) { mfsmp.status = OUT_OF_MEMORY; return mfsmp; } mfsmp.numberOfProperties = countLines; for (count = 0; count < countLines * 2 ; /* count increased at the end of for */ ) { /* memory for the line is allocated here */ /* line continuation striped out */ err = readMfLine(&jchar_buffer, &mfline); if (OUT_OF_MEMORY == err) { midp_free_properties(&mfsmp); mfsmp.status = OUT_OF_MEMORY; return mfsmp; } else if (END_OF_MF == err) { /* we are done */ mfsmp.status = ALL_OK; break; } index = pcsl_string_index_of(&mfline, ':'); if (index <= 0) { mfsmp.status = BAD_MF_KEY; pcsl_string_free(&mfline); continue; } /* memory for mfkey is allocated here */ if (PCSL_STRING_OK != pcsl_string_substring(&mfline, 0, index, &mfkey)) { midp_free_properties(&mfsmp); mfsmp.status = OUT_OF_MEMORY; pcsl_string_free(&mfline); return mfsmp; } rc = pcsl_string_trim(&mfkey, &mfkey_trimmed); pcsl_string_free(&mfkey); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfline); return mfsmp; } if (pcsl_string_length(&mfkey_trimmed) < 1) { mfsmp.status = BAD_PARAMS; pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); continue; } err = checkMfKeyChars(&mfkey_trimmed); if (OUT_OF_MEMORY == err) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); return mfsmp; } else if (BAD_MF_KEY == err) { mfsmp.status = BAD_MF_KEY; pcsl_string_free(&mfline); pcsl_string_free(&mfkey_trimmed); continue; } rc = pcsl_string_substring(&mfline, index + 1, pcsl_string_length(&mfline), &mfvalue); /* free the mfline once we have got the key and value */ pcsl_string_free(&mfline); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); return mfsmp; } /* memory for value is allocated here */ rc = pcsl_string_trim(&mfvalue, &mfvalue_trimmed); pcsl_string_free(&mfvalue); if (PCSL_STRING_OK != rc) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); return mfsmp; } if (pcsl_string_is_null(&mfvalue_trimmed)) { mfsmp.status = NULL_LEN; pcsl_string_free(&mfkey_trimmed); continue; } err = checkMfValueChars(&mfvalue_trimmed); if (OUT_OF_MEMORY == err) { mfsmp.status = OUT_OF_MEMORY; midp_free_properties(&mfsmp); pcsl_string_free(&mfkey_trimmed); pcsl_string_free(&mfvalue_trimmed); return mfsmp; } else if (BAD_MF_VALUE == err) { mfsmp.status = BAD_MF_VALUE; pcsl_string_free(&mfkey_trimmed); pcsl_string_free(&mfvalue_trimmed); continue; } printPcslStringWithMessage("midpParseMf()", &mfkey_trimmed); printPcslStringWithMessage(" = ", &mfvalue_trimmed); /* Store key:value pair. */ mfsmp.pStringArr[count] = mfkey_trimmed; mfsmp.pStringArr[count+1] = mfvalue_trimmed; count += 2; } /* end of for */ mfsmp = verifyMfMustProperties(mfsmp); REPORT_INFO3(LC_AMS, "End of midpParseMf: Status=%d, count=%d, countLines=%d", mfsmp.status, count, countLines); return mfsmp; } /* end of midpParseMf */
/** * Copy a native Invocation to the supplied Invocation instance. * @param invoc the native InvocStore * @param mode the mode of copyout * @param invocObj the Invocation object to copy to * @param argsObj an object to use to refer to the arguments array * @param obj a temporary object handle * @return 0 if there were problems allocating Java Strings; * 1 if all the copies succeeded; * -1 if the Java Arrays allocated for args or data were insufficient */ static int copyOut(StoredInvoc *invoc, int mode, jobject invocObj, jobject argsObj, jobject obj) { int datalen = 0; int arraylen = 0; /* Set the required lengths for args and data arrays. */ KNI_SetIntField(invocObj, argsLenFid, invoc->argsLen); KNI_SetIntField(invocObj, dataLenFid, invoc->dataLen); /* Check if size of argument array and data array are correct. */ KNI_GetObjectField(invocObj, dataFid, obj); datalen = KNI_GetArrayLength(obj); if (datalen != invoc->dataLen) { /* Data array allocated by Java is not correct size. */ return -1; } KNI_GetObjectField(invocObj, argumentsFid, obj); arraylen = KNI_GetArrayLength(obj); if (arraylen != invoc->argsLen) { /* Args array allocated by Java is not correct size. */ return -1; } /* Copy out all the string fields. */ if (!(storeField(&invoc->url, invocObj, urlFid, obj) && storeField(&invoc->type, invocObj, typeFid, obj) && storeField(&invoc->action, invocObj, actionFid, obj) && storeField(&invoc->ID, invocObj, IDFid, obj) && storeField(&invoc->invokingClassname, invocObj, invokingClassnameFid, obj) && storeField(&invoc->invokingAuthority, invocObj, invokingAuthorityFid, obj) && storeField(&invoc->invokingAppName, invocObj, invokingAppNameFid, obj) && storeField(&invoc->invokingID, invocObj, invokingIDFid, obj) && storeField(&invoc->username, invocObj, usernameFid, obj) && storeField(&invoc->password, invocObj, passwordFid, obj))) { /* Some String allocation failed. */ return 0; } KNI_SetIntField(invocObj, invokingSuiteIdFid, invoc->invokingSuiteId); /* See if the suite and classname are needed. */ if (mode == MODE_TID || mode == MODE_TID_PREV || mode == MODE_TID_NEXT) { if (!storeField(&invoc->classname, invocObj, classnameFid, obj)) { /* A string allocation failed. */ return 0; } KNI_SetIntField(invocObj, suiteIdFid, invoc->suiteId); } /* Return the arguments if any; array length already checked. */ if (invoc->argsLen > 0) { int ndx; pcsl_string* args; /* For each stored arg create a string and store in the array. * No stored arg is null. If a string cannot be created * it is due to insufficient heap memory. */ KNI_GetObjectField(invocObj, argumentsFid, argsObj); args = invoc->args; for (ndx = 0; ndx < invoc->argsLen; ndx++, args++) { if (!pcsl_string_is_null(args)) { if (PCSL_STRING_OK != midp_jstring_from_pcsl_string(args, obj)) { /* String create failed; exit now. */ return 0; } } else { KNI_ReleaseHandle(obj); } KNI_SetObjectArrayElement(argsObj, ndx, obj); } } /* Return the data array if any; array length was already checked. */ if (invoc->dataLen > 0) { KNI_GetObjectField(invocObj, dataFid, obj); KNI_SetRawArrayRegion(obj, 0, invoc->dataLen, invoc->data); } KNI_SetBooleanField(invocObj, responseRequiredFid, invoc->responseRequired); KNI_SetIntField(invocObj, statusFid, invoc->status); KNI_SetIntField(invocObj, tidFid, invoc->tid); KNI_SetIntField(invocObj, previousTidFid, invoc->previousTid); /* Successful copy out. */ return 1; }
static MidpProperties verifyJadMustProperties(MidpProperties jadsmp) { /* 5 MUST fields in JAD */ pcsl_string * name = NULL; pcsl_string * version = NULL; pcsl_string * vendor = NULL; pcsl_string * jarUrl = NULL; pcsl_string * jarSizeString = NULL; int permittedJarSize = 0; jint jarSizeByJad = 0; jarUrl = midp_find_property(&jadsmp, &JAR_URL_PROP); if (pcsl_string_is_null(jarUrl)) { REPORT_INFO(LC_AMS, "Missing Jar URL"); jadsmp.status = NO_JAR_URL_PROP; return jadsmp; } jarSizeString = midp_find_property(&jadsmp, &JAR_SIZE_PROP); if (pcsl_string_is_null(jarSizeString)) { REPORT_INFO(LC_AMS, "Missing Jar size"); jadsmp.status = NO_JAR_SIZE_PROP; return jadsmp; } if (PCSL_STRING_OK != pcsl_string_convert_to_jint(jarSizeString, &jarSizeByJad)) { /* NUMBER_ERROR */ REPORT_INFO1(LC_AMS, "JAD size ERROR %d", jarSizeByJad); jadsmp.status = NUMBER_ERROR; return jadsmp; } /* verify that requested jar size is not to big */ permittedJarSize = midpGetMaxJarSizePermitted(); if (jarSizeByJad > permittedJarSize) { REPORT_INFO2(LC_AMS, "Jar size requested by Jad is to big %d > %d", jarSizeByJad, permittedJarSize); REPORT_INFO(LC_AMS, "Out Of Storage"); jadsmp.status = OUT_OF_STORAGE; return jadsmp; } name = midp_find_property(&jadsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(name)) { REPORT_INFO(LC_AMS, "Missing suite name"); jadsmp.status = NO_SUITE_NAME_PROP; return jadsmp; } vendor = midp_find_property(&jadsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(vendor)) { REPORT_INFO(LC_AMS, "Missing suite vendor"); jadsmp.status = NO_SUITE_VENDOR_PROP; return jadsmp; } version = midp_find_property(&jadsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(version)) { REPORT_INFO(LC_AMS, "Missing suite version"); jadsmp.status = NO_SUITE_VERSION_PROP; return jadsmp; } if (!midpCheckVersion(version)) { REPORT_INFO(LC_AMS, "Corrupted suite version"); jadsmp.status = NO_SUITE_VERSION_PROP; return jadsmp; } return jadsmp; } /* verifyJadMUSTProperties */
static MidpProperties midpParseJad(jchar* jchar_buffer) { MidpProperties jadsmp = {0, ALL_OK, NULL}; pcsl_string jadkey; pcsl_string jadkey_trimmed; pcsl_string jadvalue; pcsl_string jadvalue_trimmed; pcsl_string jadline; MIDPError err; pcsl_string_status rc; int countLines = 0; jint index = 0; int count = 0; if (!jchar_buffer) { jadsmp.status = BAD_PARAMS; return jadsmp; } countLines = count_jad_lines(jchar_buffer); if (countLines <= 0) { REPORT_INFO(LC_AMS, "midpParseJad(): Empty jad file."); jadsmp.status = OUT_OF_MEMORY; return jadsmp; } jadsmp.pStringArr = alloc_pcsl_string_list(countLines * 2); if (jadsmp.pStringArr == NULL) { jadsmp.status = OUT_OF_MEMORY; return jadsmp; } jadsmp.numberOfProperties = countLines; for (count = 0; count < countLines * 2 ; /* count increased at the end of for */ ) { /* memory for the line is allocated here */ err = readJadLine(&jchar_buffer, &jadline); if (OUT_OF_MEMORY == err) { midp_free_properties(&jadsmp); jadsmp.status = OUT_OF_MEMORY; return jadsmp; } else if (END_OF_JAD == err) { /* we are done */ jadsmp.status = ALL_OK; break; } index = pcsl_string_index_of(&jadline, ':'); if (index <= 0) { jadsmp.status = BAD_JAD_KEY; pcsl_string_free(&jadline); continue; } /* memory for key is allocated here */ if (PCSL_STRING_OK != pcsl_string_substring(&jadline, 0, index, &jadkey)) { midp_free_properties(&jadsmp); jadsmp.status = OUT_OF_MEMORY; pcsl_string_free(&jadline); return jadsmp; } rc = pcsl_string_trim(&jadkey, &jadkey_trimmed); pcsl_string_free(&jadkey); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadline); return jadsmp; } if (pcsl_string_length(&jadkey_trimmed) < 1) { jadsmp.status = BAD_PARAMS; pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); continue; } err = checkJadKeyChars(&jadkey_trimmed); if (OUT_OF_MEMORY == err) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); return jadsmp; } else if (BAD_JAD_KEY == err) { jadsmp.status = BAD_JAD_KEY; pcsl_string_free(&jadline); pcsl_string_free(&jadkey_trimmed); continue; } rc = pcsl_string_substring(&jadline, index + 1, pcsl_string_length(&jadline), &jadvalue); /* free the jadline once we have got the key and value */ pcsl_string_free(&jadline); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); return jadsmp; } /* memory for value is allocated here */ rc = pcsl_string_trim(&jadvalue, &jadvalue_trimmed); pcsl_string_free(&jadvalue); if (PCSL_STRING_OK != rc) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); return jadsmp; } if (pcsl_string_is_null(&jadvalue_trimmed)) { jadsmp.status = NULL_LEN; pcsl_string_free(&jadkey_trimmed); continue; } err = checkJadValueChars(&jadvalue_trimmed); if (OUT_OF_MEMORY == err) { jadsmp.status = OUT_OF_MEMORY; midp_free_properties(&jadsmp); pcsl_string_free(&jadkey_trimmed); pcsl_string_free(&jadvalue_trimmed); return jadsmp; } else if (BAD_JAD_VALUE == err) { jadsmp.status = BAD_JAD_VALUE; pcsl_string_free(&jadkey_trimmed); pcsl_string_free(&jadvalue_trimmed); continue; } printPcslStringWithMessage("midpParseJad()", &jadkey_trimmed); printPcslStringWithMessage("midpParseJad()", &jadvalue_trimmed); /* Store key:value pair. */ jadsmp.pStringArr[count] = jadkey_trimmed; jadsmp.pStringArr[count+1] = jadvalue_trimmed; count += 2; } /* end of for */ jadsmp = verifyJadMustProperties(jadsmp); REPORT_INFO3(LC_AMS, "End jad parsing. Status=%d, count=%d, countLines=%d.", jadsmp.status, count, countLines); return jadsmp; } /* end of midpParseJad */
/** * Compares JAD and Manifest file properties that MUST be the same. * The properties are: * <B>MIDlet-Name</B> * <B>MIDlet-Vendor</B> * <B>MIDlet-Version</B> * * @param jadsmp MidpProperties struct that contains parsed JAD properties. * @param mfsmp MidpProperties struct that contains parsed Manifest properties. * @return On success: ALL_OK * On mismatch: * SUITE_NAME_PROP_NOT_MATCH * SUITE_VENDOR_PROP_NOT_MATCH * SUITE_VERSION_PROP_NOT_MATCH * On missing property: * NO_SUITE_NAME_PROP * NO_SUITE_VENDOR_PROP * NO_SUITE_VERSION_PROP */ int compareJADandManifestProperties(MidpProperties* jadsmp, MidpProperties* mfsmp) { /* three properties MUST be similar in jad and manifest */ const pcsl_string* jad_name = &PCSL_STRING_NULL; const pcsl_string* jad_version = &PCSL_STRING_NULL; const pcsl_string* jad_vendor = &PCSL_STRING_NULL; const pcsl_string* mf_name = &PCSL_STRING_NULL; const pcsl_string* mf_version = &PCSL_STRING_NULL; const pcsl_string* mf_vendor = &PCSL_STRING_NULL; /* compare jad and manifest properties */ jad_name = midp_find_property(jadsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(jad_name)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_NAME_PROP from JAD. This should not happen at this stage!"); return NO_SUITE_NAME_PROP; } mf_name = midp_find_property(mfsmp, &SUITE_NAME_PROP); if (pcsl_string_is_null(mf_name)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_NAME_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_NAME_PROP; /* handle it some how */ } if ( ! pcsl_string_equals(jad_name, mf_name)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad names are not equal."); return SUITE_NAME_PROP_NOT_MATCH; } jad_vendor = midp_find_property(jadsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(jad_vendor)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VENDOR_PROP from JAD. This should not happen at this stage!\n"); return NO_SUITE_VENDOR_PROP; } mf_vendor = midp_find_property(mfsmp, &SUITE_VENDOR_PROP); if (pcsl_string_is_null(mf_vendor)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VENDOR_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_VENDOR_PROP; } if ( ! pcsl_string_equals(jad_vendor, mf_vendor)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad vendors are not equal."); return SUITE_VENDOR_PROP_NOT_MATCH; } jad_version = midp_find_property(jadsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(jad_version)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VERSION_PROP from JAD. This should not happen at this stage!"); return NO_SUITE_VERSION_PROP; } mf_version = midp_find_property(mfsmp, &SUITE_VERSION_PROP); if (pcsl_string_is_null(mf_version)) { REPORT_ERROR(LC_AMS, "Can't get SUITE_VERSION_PROP from Manifest. This should not happen at this stage!"); return NO_SUITE_VERSION_PROP; } { if (0 != midpCompareVersion(jad_version, mf_version)) { /* versions are not equal */ REPORT_ERROR(LC_AMS, "Manifest and Jad versions are not equal."); return SUITE_VERSION_PROP_NOT_MATCH; } } return ALL_OK; } /* end of compareJADandManifestProperties */
/** * Returns an array of the names of record stores owned by the * MIDlet suite. * * @param suiteId * @param ppNames pointer to pointer that will be filled in with names * * @return number of record store names or OUT_OF_MEM_LEN */ int rmsdb_get_record_store_list(SuiteIdType suiteId, pcsl_string* *const ppNames) { int numberOfStores; pcsl_string root; pcsl_string* pStores; pcsl_string filename; pcsl_string ascii_name = PCSL_STRING_NULL_INITIALIZER; int i; void* handle = NULL; MIDPError status; int f_errc; pcsl_string_status s_errc; StorageIdType storageId; /* IMPL_NOTE: how can we get it statically? */ const int dbext_len = pcsl_string_length(&DB_EXTENSION); *ppNames = NULL; /* * 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 OUT_OF_MEM_LEN; } status = midp_suite_get_rms_filename(suiteId, storageId, -1, &PCSL_STRING_EMPTY, &root); if (status != ALL_OK) { return OUT_OF_MEM_LEN; } if (pcsl_string_is_null(&root)) { return 0; } numberOfStores = rmsdb_get_number_of_record_stores_int(&root); if (numberOfStores <= 0) { pcsl_string_free(&root); return numberOfStores; } pStores = alloc_pcsl_string_list(numberOfStores); if (pStores == NULL) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } handle = storage_open_file_iterator(&root); if (!handle) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } /* the main loop */ for(i=0,f_errc=0,s_errc=0;;) { f_errc = storage_get_next_file_in_iterator(&root, handle, &filename); if (0 != f_errc) { f_errc = 0; break; } if (pcsl_string_ends_with(&filename, &DB_EXTENSION)) { s_errc = pcsl_string_substring(&filename, pcsl_string_length(&root), pcsl_string_length(&filename) - dbext_len, &ascii_name); pcsl_string_free(&filename); if (PCSL_STRING_OK != s_errc ) { break; } s_errc = escaped_ascii_to_unicode(&ascii_name, &pStores[i]); pcsl_string_free(&ascii_name); if (PCSL_STRING_OK != s_errc ) { break; } i++; } pcsl_string_free(&filename); /* IMPL_NOTE: do we need this one? isn't it useless? */ if (i == numberOfStores) { break; } } pcsl_string_free(&root); storageCloseFileIterator(handle); if (f_errc || s_errc) { /* The loop stopped because we ran out of memory. */ free_pcsl_string_list(pStores, i); return OUT_OF_MEM_LEN; } *ppNames = pStores; return numberOfStores; }
/** * Returns an array of the names of record stores owned by the * MIDlet suite. * * @param filenameBase filenameBase of the suite * @param ppNames pointer to pointer that will be filled in with names * * @return number of record store names or OUT_OF_MEM_LEN */ int rmsdb_get_record_store_list(pcsl_string* filenameBase, pcsl_string* *const ppNames) { int numberOfStores; pcsl_string root; pcsl_string* pStores; pcsl_string filename; pcsl_string ascii_name = PCSL_STRING_NULL_INITIALIZER; int i; void* handle = NULL; MIDPError status; int f_errc; pcsl_string_status s_errc; /* IMPL_NOTE: how can we get it statically? */ const int dbext_len = pcsl_string_length(&DB_EXTENSION); *ppNames = NULL; /* * IMPL_NOTE: for security reasons the record store is always * located in the internal storage. */ status = buildSuiteFilename(filenameBase, &PCSL_STRING_EMPTY, -1, &root); if (status != MIDP_ERROR_NONE) { return status; } if (pcsl_string_is_null(&root)) { return 0; } numberOfStores = rmsdb_get_number_of_record_stores_int(&root); if (numberOfStores <= 0) { pcsl_string_free(&root); return numberOfStores; } pStores = alloc_pcsl_string_list(numberOfStores); if (pStores == NULL) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } handle = storage_open_file_iterator(&root); if (!handle) { pcsl_string_free(&root); return OUT_OF_MEM_LEN; } /* the main loop */ for (i=0,f_errc=0,s_errc=0;;) { f_errc = storage_get_next_file_in_iterator(&root, handle, &filename); if (0 != f_errc) { f_errc = 0; break; } if (pcsl_string_ends_with(&filename, &DB_EXTENSION)) { s_errc = pcsl_string_substring(&filename, pcsl_string_length(&root), pcsl_string_length(&filename) - dbext_len, &ascii_name); pcsl_string_free(&filename); if (PCSL_STRING_OK != s_errc ) { break; } s_errc = pcsl_esc_extract_attached(0, &ascii_name, &pStores[i]); pcsl_string_free(&ascii_name); if (PCSL_STRING_OK != s_errc ) { break; } i++; } pcsl_string_free(&filename); /* IMPL_NOTE: do we need this one? isn't it useless? */ if (i == numberOfStores) { break; } } pcsl_string_free(&root); storageCloseFileIterator(handle); if (f_errc || s_errc) { /* The loop stopped because we ran out of memory. */ free_pcsl_string_list(pStores, i); return OUT_OF_MEM_LEN; } *ppNames = pStores; return numberOfStores; }
/** * Runs a MIDlet from an installed MIDlet suite. This is an example of * how to use the public MIDP API. * * @param argc The total number of arguments * @param argv An array of 'C' strings containing the arguments * * @return <tt>0</tt> for success, otherwise <tt>-1</tt> * * IMPL_NOTE:determine if it is desirable for user targeted output * messages to be sent via the log/trace service, or if * they should remain as printf calls */ int runMidlet(int argc, char** commandlineArgs) { int status = -1; SuiteIdType suiteId = UNUSED_SUITE_ID; pcsl_string classname = PCSL_STRING_NULL; pcsl_string arg0 = PCSL_STRING_NULL; pcsl_string arg1 = PCSL_STRING_NULL; pcsl_string arg2 = PCSL_STRING_NULL; int repeatMidlet = 0; char* argv[RUNMIDLET_MAX_ARGS]; int i, used; int debugOption = MIDP_NO_DEBUG; char *progName = commandlineArgs[0]; char* appDir = NULL; char* confDir = NULL; char* additionalPath; SuiteIdType* pSuites = NULL; int numberOfSuites = 0; int ordinalSuiteNumber = -1; char* chSuiteNum = NULL; MIDPError errCode; char** ppParamsFromPlatform; char** ppSavedParams = NULL; int savedNumberOfParams = 0, numberOfParams = 0; JVM_Initialize(); /* It's OK to call this more than once */ /* get midp application directory, set it */ appDir = getApplicationDir(argv[0]); if (appDir == NULL) { REPORT_ERROR(LC_AMS, "Failed to recieve midp application directory"); return -1; } midpSetAppDir(appDir); /* get midp configuration directory, set it */ confDir = getConfigurationDir(argv[0]); if (confDir == NULL) { REPORT_ERROR(LC_AMS, "Failed to recieve midp configuration directory"); return -1; } midpSetConfigDir(confDir); if (midpInitialize() != 0) { REPORT_ERROR(LC_AMS, "Not enough memory"); return -1; } /* Set Java heap parameters now so they can been overridden from command line */ setHeapParameters(); /* * Check if there are some parameters passed to us from the platform * (i.e., in the current implementation, they are read from a file). */ errCode = ams_get_startup_params(&ppParamsFromPlatform, &numberOfParams); if (errCode == ALL_OK && numberOfParams > 0) { savedNumberOfParams = numberOfParams; ppSavedParams = ppParamsFromPlatform; while ((used = JVM_ParseOneArg(numberOfParams, ppParamsFromPlatform)) > 0) { numberOfParams -= used; ppParamsFromPlatform += used; } if (numberOfParams + 1 > RUNMIDLET_MAX_ARGS) { REPORT_ERROR(LC_AMS, "(1) Number of arguments exceeds supported limit"); ams_free_startup_params(ppSavedParams, savedNumberOfParams); return -1; } argv[0] = progName; for (i = 0; i < numberOfParams; i++) { /* argv[0] is the program name */ argv[i + 1] = ppParamsFromPlatform[i]; } } /* if savedNumberOfParams > 0, ignore the command-line parameters */ if (savedNumberOfParams <= 0) { /* * Debugger port: command-line argument overrides * configuration settings. */ { char* debuggerPortString = midpRemoveCommandOption("-port", commandlineArgs, &argc); if (debuggerPortString != NULL) { int debuggerPort; if (sscanf(debuggerPortString, "%d", &debuggerPort) != 1) { REPORT_ERROR(LC_AMS, "Invalid debugger port format"); return -1; } setInternalProperty("VmDebuggerPort", debuggerPortString); } } /* * Parse options for the VM. This is desirable on a 'development' platform * such as linux_qte. For actual device ports, copy this block of code only * if your device can handle command-line arguments. */ /* * JVM_ParseOneArg expects commandlineArgs[0] to contain the first actual * parameter */ argc --; commandlineArgs ++; while ((used = JVM_ParseOneArg(argc, commandlineArgs)) > 0) { argc -= used; commandlineArgs += used; } /* Restore commandlineArgs[0] to contain the program name. */ argc ++; commandlineArgs --; commandlineArgs[0] = progName; } /* * Not all platforms allow rewriting the command line arg array, * make a copy */ if ((numberOfParams <= 0 && argc > RUNMIDLET_MAX_ARGS) || (numberOfParams > RUNMIDLET_MAX_ARGS)) { REPORT_ERROR(LC_AMS, "Number of arguments exceeds supported limit"); ams_free_startup_params(ppSavedParams, savedNumberOfParams); return -1; } if (savedNumberOfParams <= 0) { for (i = 0; i < argc; i++) { argv[i] = commandlineArgs[i]; } } else { /* * if savedNumberOfParams is greater than zero, command-line parameters * are ignored */ argc = numberOfParams + 1; /* +1 because argv[0] is the program name */ } /* * IMPL_NOTE: corresponding VM option is called "-debugger" */ if (midpRemoveOptionFlag("-debug", argv, &argc) != NULL) { debugOption = MIDP_DEBUG_SUSPEND; } if (midpRemoveOptionFlag("-loop", argv, &argc) != NULL) { repeatMidlet = 1; } /* run the midlet suite by its ordinal number */ if ((chSuiteNum = midpRemoveCommandOption("-ordinal", argv, &argc)) != NULL) { /* the format of the string is "number:" */ if (sscanf(chSuiteNum, "%d", &ordinalSuiteNumber) != 1) { REPORT_ERROR(LC_AMS, "Invalid suite number format"); ams_free_startup_params(ppSavedParams, savedNumberOfParams); return -1; } } /* additionalPath gets appended to the classpath */ additionalPath = midpRemoveCommandOption("-classpathext", argv, &argc); if (argc == 1 && ordinalSuiteNumber == -1) { REPORT_ERROR(LC_AMS, "Too few arguments given."); ams_free_startup_params(ppSavedParams, savedNumberOfParams); return -1; } if (argc > 6) { REPORT_ERROR(LC_AMS, "Too many arguments given\n"); ams_free_startup_params(ppSavedParams, savedNumberOfParams); return -1; } do { int onlyDigits; int len; int i; if (argc > 5) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[5], &arg2)) { REPORT_ERROR(LC_AMS, "Out of Memory"); break; } } if (argc > 4) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[4], &arg1)) { REPORT_ERROR(LC_AMS, "Out of Memory"); break; } } if (argc > 3) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[3], &arg0)) { REPORT_ERROR(LC_AMS, "Out of Memory"); break; } } if (argc > 2) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[2], &classname)) { REPORT_ERROR(LC_AMS, "Out of Memory"); break; } } /* if the storage name only digits, convert it */ onlyDigits = 1; len = strlen(argv[1]); for (i = 0; i < len; i++) { if (!isdigit((argv[1])[i])) { onlyDigits = 0; break; } } if (ordinalSuiteNumber != -1 || onlyDigits) { /* load IDs of the installed suites */ MIDPError err = midp_get_suite_ids(&pSuites, &numberOfSuites); if (err != ALL_OK) { REPORT_ERROR1(LC_AMS, "Error in midp_get_suite_ids(), code %d", err); break; } } if (ordinalSuiteNumber != -1) { /* run the midlet suite by its ordinal number */ if (ordinalSuiteNumber > numberOfSuites || ordinalSuiteNumber < 1) { REPORT_ERROR(LC_AMS, "Suite number out of range"); midp_free_suite_ids(pSuites, numberOfSuites); break; } suiteId = pSuites[ordinalSuiteNumber - 1]; } else if (onlyDigits) { /* run the midlet suite by its ID */ int i; /* the format of the string is "number:" */ if (sscanf(argv[1], "%d", &suiteId) != 1) { REPORT_ERROR(LC_AMS, "Invalid suite ID format"); break; } for (i = 0; i < numberOfSuites; i++) { if (suiteId == pSuites[i]) { break; } } if (i == numberOfSuites) { REPORT_ERROR(LC_AMS, "Suite with the given ID was not found"); break; } } else { /* Run by ID */ suiteId = INTERNAL_SUITE_ID; if (strcmp(argv[1], "internal") && strcmp(argv[1], "-1") && additionalPath == NULL) { /* * If the argument is not a suite ID, it might be a full * path to the midlet suite's jar file. * In this case this path is added to the classpath and * the suite is run without installation (it is useful * for internal test and development purposes). */ additionalPath = argv[1]; } } if (pcsl_string_is_null(&classname)) { int res = find_midlet_class(suiteId, 1, &classname); if (OUT_OF_MEM_LEN == res) { REPORT_ERROR(LC_AMS, "Out of Memory"); break; } if (NULL_LEN == res) { REPORT_ERROR(LC_AMS, "Could not find the first MIDlet"); break; } } do { status = midp_run_midlet_with_args_cp(suiteId, &classname, &arg0, &arg1, &arg2, debugOption, additionalPath); } while (repeatMidlet && status != MIDP_SHUTDOWN_STATUS); if (pSuites != NULL) { midp_free_suite_ids(pSuites, numberOfSuites); suiteId = UNUSED_SUITE_ID; } } while (0); pcsl_string_free(&arg0); pcsl_string_free(&arg1); pcsl_string_free(&arg2); pcsl_string_free(&classname); switch (status) { case MIDP_SHUTDOWN_STATUS: break; case MIDP_ERROR_STATUS: REPORT_ERROR(LC_AMS, "The MIDlet suite could not be run."); break; case SUITE_NOT_FOUND_STATUS: REPORT_ERROR(LC_AMS, "The MIDlet suite was not found."); break; default: break; } if (JVM_GetConfig(JVM_CONFIG_SLAVE_MODE) == KNI_FALSE) { midpFinalize(); } ams_free_startup_params(ppSavedParams, savedNumberOfParams); return status; }
/** * Runs a MIDlet from an installed MIDlet suite. This is an example of * how to use the public MIDP API. * * @param argc The total number of arguments * @param argv An array of 'C' strings containing the arguments * * @return <tt>0</tt> for success, otherwise <tt>-1</tt> * * IMPL_NOTE:determine if it is desirable for user targeted output * messages to be sent via the log/trace service, or if * they should remain as printf calls */ int runMidlet(int argc, char** commandlineArgs) { int status = -1; SuiteIdType suiteId = UNUSED_SUITE_ID; pcsl_string classname = PCSL_STRING_NULL; pcsl_string arg0 = PCSL_STRING_NULL; pcsl_string arg1 = PCSL_STRING_NULL; pcsl_string arg2 = PCSL_STRING_NULL; int repeatMidlet = 0; char* argv[RUNMIDLET_MAX_ARGS]; int i, used; int debugOption = MIDP_NO_DEBUG; char *progName = commandlineArgs[0]; char* midpHome = NULL; char* additionalPath; SuiteIdType* pSuites = NULL; int numberOfSuites = 0; JVM_Initialize(); /* It's OK to call this more than once */ /* * Set Java heap capacity now so it can been overridden from command line. */ JVM_SetConfig(JVM_CONFIG_HEAP_CAPACITY, MIDP_HEAP_REQUIREMENT); /* * Parse options for the VM. This is desirable on a 'development' platform * such as linux_qte. For actual device ports, copy this block of code only * if your device can handle command-line arguments. */ /* JVM_ParseOneArg expects commandlineArgs[0] to contain the first actual * parameter */ argc --; commandlineArgs ++; while ((used = JVM_ParseOneArg(argc, commandlineArgs)) > 0) { argc -= used; commandlineArgs += used; } /* Restore commandlineArgs[0] to contain the program name. */ argc ++; commandlineArgs --; commandlineArgs[0] = progName; /* * Not all platforms allow rewriting the command line arg array, * make a copy */ if (argc > RUNMIDLET_MAX_ARGS) { REPORT_ERROR(LC_AMS, "Number of arguments exceeds supported limit"); fprintf(stderr, "Number of arguments exceeds supported limit\n"); return -1; } for (i = 0; i < argc; i++) { argv[i] = commandlineArgs[i]; } if (midpRemoveOptionFlag("-debug", argv, &argc) != NULL) { debugOption = MIDP_DEBUG_SUSPEND; } if (midpRemoveOptionFlag("-loop", argv, &argc) != NULL) { repeatMidlet = 1; } /* additionalPath gets appended to the classpath */ additionalPath = midpRemoveCommandOption("-classpathext", argv, &argc); if (argc == 1) { REPORT_ERROR(LC_AMS, "Too few arguments given."); fprintf(stderr, runUsageText); return -1; } if (argc > 6) { REPORT_ERROR(LC_AMS, "Too many arguments given\n"); fprintf(stderr, "Too many arguments given\n%s", runUsageText); return -1; } /* get midp home directory, set it */ midpHome = midpFixMidpHome(argv[0]); if (midpHome == NULL) { return -1; } /* set up midpHome before calling initialize */ midpSetHomeDir(midpHome); if (midpInitialize() != 0) { REPORT_ERROR(LC_AMS, "Not enough memory"); fprintf(stderr, "Not enough memory\n"); return -1; } do { int onlyDigits; int len; int i; if (argc > 5) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[5], &arg2)) { REPORT_ERROR(LC_AMS, "Out of Memory"); fprintf(stderr, "Out Of Memory\n"); break; } } if (argc > 4) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[4], &arg1)) { REPORT_ERROR(LC_AMS, "Out of Memory"); fprintf(stderr, "Out Of Memory\n"); break; } } if (argc > 3) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[3], &arg0)) { REPORT_ERROR(LC_AMS, "Out of Memory"); fprintf(stderr, "Out Of Memory\n"); break; } } if (argc > 2) { if (PCSL_STRING_OK != pcsl_string_from_chars(argv[2], &classname)) { REPORT_ERROR(LC_AMS, "Out of Memory"); fprintf(stderr, "Out Of Memory\n"); break; } } /* if the storage name only digits, convert it */ onlyDigits = 1; len = strlen(argv[1]); for (i = 0; i < len; i++) { if (!isdigit((argv[1])[i])) { onlyDigits = 0; break; } } if (onlyDigits) { /* Run by number */ int suiteNumber; MIDPError err; /* the format of the string is "number:" */ if (sscanf(argv[1], "%d", &suiteNumber) != 1) { REPORT_ERROR(LC_AMS, "Invalid suite number format"); fprintf(stderr, "Invalid suite number format\n"); break; } err = midp_get_suite_ids(&pSuites, &numberOfSuites); if (err != ALL_OK) { REPORT_ERROR1(LC_AMS, "Error in midp_get_suite_ids(), code %d", err); fprintf(stderr, "Error in midp_get_suite_ids(), code %d.\n", err); break; } if (suiteNumber > numberOfSuites || suiteNumber < 1) { REPORT_ERROR(LC_AMS, "Suite number out of range"); fprintf(stderr, "Suite number out of range\n"); midp_free_suite_ids(pSuites, numberOfSuites); break; } suiteId = pSuites[suiteNumber - 1]; } else { /* Run by ID */ suiteId = INTERNAL_SUITE_ID; /* IMPL_NOTE: consider handling of other IDs. */ if (strcmp(argv[1], "internal") && additionalPath == NULL) { /* * If the argument is not a suite ID, it might be a full * path to the midlet suite's jar file. * In this case this path is added to the classpath and * the suite is run without installation (it is useful * for internal test and development purposes). */ additionalPath = argv[1]; } } if (pcsl_string_is_null(&classname)) { int res = find_midlet_class(suiteId, 1, &classname); if (OUT_OF_MEM_LEN == res) { REPORT_ERROR(LC_AMS, "Out of Memory"); fprintf(stderr, "Out Of Memory\n"); break; } if (NULL_LEN == res) { REPORT_ERROR(LC_AMS, "Could not find the first MIDlet"); fprintf(stderr, "Could not find the first MIDlet\n"); break; } } do { status = midp_run_midlet_with_args_cp(suiteId, &classname, &arg0, &arg1, &arg2, debugOption, additionalPath); } while (repeatMidlet && status != MIDP_SHUTDOWN_STATUS); if (pSuites != NULL) { midp_free_suite_ids(pSuites, numberOfSuites); suiteId = UNUSED_SUITE_ID; } } while (0); pcsl_string_free(&arg0); pcsl_string_free(&arg1); pcsl_string_free(&arg2); pcsl_string_free(&classname); switch (status) { case MIDP_SHUTDOWN_STATUS: break; case MIDP_ERROR_STATUS: REPORT_ERROR(LC_AMS, "The MIDlet suite could not be run."); fprintf(stderr, "The MIDlet suite could not be run.\n"); break; case SUITE_NOT_FOUND_STATUS: REPORT_ERROR(LC_AMS, "The MIDlet suite was not found."); fprintf(stderr, "The MIDlet suite was not found.\n"); break; default: break; } midpFinalize(); return status; }