Example #1
0
static void loadSuiteIds() {
    int i;
    MIDPError status;

    /*
     * 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;
    }

    status = midp_get_suite_ids(&pSuiteIds, &numberOfSuiteIds);
    if (status != ALL_OK) {
        REPORT_ERROR(LC_AMS, "Can't load suite IDs.");
        fprintf(stderr, "Can't load suite IDs: error %d.\n", status);
        return;
    }

    pSuiteRunState = (jint*)midpMalloc(numberOfSuiteIds*sizeof(jint));
    if (pSuiteRunState == NULL) {
        REPORT_ERROR(LC_AMS, "Out of Memory");
        fprintf(stderr, "Out Of Memory\n");
        return;
    }

    for (i = 0; i < numberOfSuiteIds; i++) {
        pSuiteRunState[i] = MIDP_MIDLET_STATE_DESTROYED;
    }
}
/**
 * Checks the integrity of the suite storage database and of the
 * installed suites.
 *
 * @param fullCheck 0 to check just an integrity of the database,
 *                    other value for full check
 * @param delCorruptedSuites != 0 to delete the corrupted suites,
 *                           0 - to keep them (for re-installation).
 *
 * @return ALL_OK if no errors,
 *         SUITE_CORRUPTED_ERROR if the suite database was corrupted
 *                               but has been successfully repaired,
 *         another error code if the database is corrupted and
 *         could not be repaired
 */
MIDPError
midp_check_suites_integrity(int fullCheck, int delCorruptedSuites) {
    MIDPError status;
    char *pszError = NULL;
    int dbWasCorrupted = 0;

    /* Check if there is a previously started transaction exists. */
    if (unfinished_transaction_exists()) {
        (void)rollback_transaction();
    }

    /* Check if the suite database is corrupted and repair it if needed. */
    status = read_suites_data(&pszError);
    if (status == SUITE_CORRUPTED_ERROR) {
        dbWasCorrupted = 1;
        status = repair_suite_db();
    }
    if (status != ALL_OK) {
        /* give up, user interaction is needed */
        return status;
    }

    /* if fullCheck is true, check all installed suites */
    if (fullCheck) {
        int i, numOfSuites;
        SuiteIdType suiteId, *pSuiteIds = NULL;

        status = midp_get_suite_ids(&pSuiteIds, &numOfSuites);

        if (status == ALL_OK) {
            for (i = 0; i < numOfSuites; i++) {
                suiteId = pSuiteIds[i];

                if (check_for_corrupted_suite(suiteId) ==
                        SUITE_CORRUPTED_ERROR) {
                    dbWasCorrupted = 1;
                    if (delCorruptedSuites) {
                        midp_remove_suite(suiteId);
                    }
                }
            }

            if (pSuiteIds != NULL) {
                midp_free_suite_ids(pSuiteIds, numOfSuites);
            }
        }
    }

    return dbWasCorrupted ? SUITE_CORRUPTED_ERROR : ALL_OK;
}
Example #3
0
/**
 * Lists all installed MIDlet suites. 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
listMidlets(int argc, char* argv[]) {
    int   status = -1;
    int   i;
    long  size;
    char* midpHome = NULL;

    (void)argv;                                   /* Avoid compiler warnings */
    if (argc > 1) {
        REPORT_ERROR(LC_AMS, "Too many arguments given");
        fprintf(stderr, "Too many arguments given\n");
        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 {
        SuiteIdType* pSuites = NULL;
        int numberOfSuites = 0;
        MIDPError err;

        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 (numberOfSuites == 0) {
            REPORT_ERROR(LC_AMS, "No MIDlet Suites installed on phone");
            printf("** No MIDlet Suites installed on phone\n");
            status = 0;
            break;
        }

        for (i = 0; i < numberOfSuites; i++) {
            MidpInstallInfo info;
            MidpProperties properties;

            info = midp_get_suite_install_info(pSuites[i]);
            if (BAD_ID_INFO_STATUS(info)) {
                REPORT_ERROR(LC_AMS, "Suite list is corrupt");
                fprintf(stderr, "Suite list is corrupt\n");
                break;
            }

            if (OUT_OF_MEM_INFO_STATUS(info)) {
                REPORT_ERROR(LC_AMS, "Out Of Memory for Info");
                fprintf(stderr, "Out Of Memory for Info\n");
                break;
            }

            if (SUITE_CORRUPTED_ERR_STATUS(info)) {
                /*
                 * Installinfo is not initialsed in case of an error
                 * so no need to free it
                 */
                REPORT_ERROR1(LC_AMS, "Error : Suite %d is corrupted", (i+1));
                fprintf(stderr, "Error : Suite %d is corrupted\n", (i+1));
                continue;
            }

            if (READ_ERROR_INFO_STATUS(info)) {
                REPORT_ERROR(LC_AMS, "Corrupt install info");
                fprintf(stderr, "Corrupt install info\n");
                break;
            }

            properties = midp_get_suite_properties(pSuites[i]);
            if (OUT_OF_MEM_PROPERTY_STATUS(properties)) {
                midp_free_install_info(&info);
                midp_free_properties(&properties);
                REPORT_ERROR(LC_AMS, "Out Of Memory for properties");
                fprintf(stderr, "Out Of Memory for properties\n");
                break;
            }

            if (CORRUPTED_PROPERTY_STATUS(properties)) {
                midp_free_install_info(&info);
                midp_free_properties(&properties);
                REPORT_ERROR1(LC_AMS, "Error : Suite %d is corrupted", (i+1));
                fprintf(stderr, "Error : Suite %d is corrupted\n", (i+1));
                continue;
            }

            if (READ_ERROR_PROPERTY_STATUS(properties)) {
                midp_free_install_info(&info);
                midp_free_properties(&properties);
                REPORT_ERROR(LC_AMS, "Corrupt properties");
                fprintf(stderr, "Corrupt properties\n");
                break;
            }

            printf("[%d]\n", (i + 1));
            printProperty("  Name: ", &SUITE_NAME_PROP, properties);
            printProperty("  Vendor: ", &SUITE_VENDOR_PROP, properties);
            printProperty("  Version: ", &SUITE_VERSION_PROP, properties);
            printProperty("  Description: ", &SUITE_DESC_PROP, properties);

            if (info.authPathLen > 0) {
                int j;

                puts("  Authorized by: ");
                for (j = 0; j < info.authPathLen; j++) {
                    print_field("    ", &info.authPath_as[j]);
                }
            }

            print_field("  SecurityDomain: ", &info.domain_s);
            printf("  Verified: %s\n",
                (info.pVerifyHash != NULL ? "true" : "false"));
            printf("  Suite ID: %ld\n", (long)pSuites[i]);
            print_field("  JAD URL: ", &info.jadUrl_s);
            print_field("  JAR URL: ", &info.jarUrl_s);
            size = midp_get_suite_storage_size(pSuites[i]);
            if (size < 0) {
                fprintf(stderr, "Ran out of memory getting the size\n");
            } else {
                printf("  Size: %ldK\n", (size + 1023) / 1024);
            }

            midp_free_install_info(&info);
            midp_free_properties(&properties);
        }

        midp_free_suite_ids(pSuites, numberOfSuites);

        status = 0;
    } while (0);

    midpFinalize();

    return status;
}
Example #4
0
/**
 * 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;
}
Example #5
0
/**
 * 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;
}
/**
 * Deletes 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 removeMidlet(int argc, char* argv[]) {
    int   status = -1;
    char* appDir = NULL;

    if (argc == 1) {
        fprintf(stderr, removeUsageText);
        return -1;
    }

    if (argc > 2) {
        REPORT_ERROR1(LC_AMS, "Too many arguments given\n%s", removeUsageText);
        fprintf(stderr, "Too many arguments given\n%s", removeUsageText);
        return -1;
    }

    /* get midp home directory, set it */
    appDir = getApplicationDir(argv[0]);
    if (appDir == NULL) {
        return -1;
    }
    /* set up appDir before calling initialize */
    midpSetAppDir(appDir);

    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;
        SuiteIdType* pSuites = NULL;
        int numberOfSuites = 0;
        MIDPError err;

        /* 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) {
            /* Remove by number */
            int suiteNumber;

            /* 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;
            }

            /* The suite number for the first suite is 1. */
            midp_remove_suite(pSuites[suiteNumber - 1]);

            midp_free_suite_ids(pSuites, numberOfSuites);
        } else if (strcmp(argv[1], "all") == 0) {
            /* Remove all */
            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;
            }

            for (i = 0; i < numberOfSuites; i++) {
                midp_remove_suite(pSuites[i]);
            }

            midp_free_suite_ids(pSuites, numberOfSuites);
        } else {
            REPORT_ERROR2(LC_AMS, "Invalid argument: '%s'.\n%s",
                          argv[1], removeUsageText);
            fprintf(stderr, "Invalid argument: '%s'.\n%s",
                    argv[1], removeUsageText);
        }

        status = 0;
    } while (0);

    midpFinalize();

    return status;
}