/*
 * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "util.h"
#include "VirtualMachineImpl.h"
#include "commonRef.h"
#include "inStream.h"
#include "outStream.h"
#include "eventHandler.h"
#include "eventHelper.h"
#include "threadControl.h"
#include "SDE.h"
#include "FrameID.h"

static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
static int majorVersion = 1;  /* JDWP major version */
static int minorVersion = 6;  /* JDWP minor version */

static jboolean
version(PacketInputStream *in, PacketOutputStream *out)
{
    char buf[500];
    char *vmName;
    char *vmVersion;
    char *vmInfo;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    vmVersion = gdata->property_java_version;
    if (vmVersion == NULL) {
        vmVersion = "<unknown>";
    }
    vmName = gdata->property_java_vm_name;
    if (vmName == NULL) {
        vmName = "<unknown>";
    }
    vmInfo = gdata->property_java_vm_info;
    if (vmInfo == NULL) {
        vmInfo = "<unknown>";
    }

    /*
     * Write the descriptive version information
     */
    (void)snprintf(buf, sizeof(buf),
                "%s version %d.%d\nJVM Debug Interface version %d.%d\n"
                 "JVM version %s (%s, %s)",
                  versionName, majorVersion, minorVersion,
                  jvmtiMajorVersion(), jvmtiMinorVersion(),
                  vmVersion, vmName, vmInfo);
    (void)outStream_writeString(out, buf);

    /*
     * Write the JDWP version numbers
     */
    (void)outStream_writeInt(out, majorVersion);
    (void)outStream_writeInt(out, minorVersion);

    /*
     * Write the VM version and name
     */
    (void)outStream_writeString(out, vmVersion);
    (void)outStream_writeString(out, vmName);

    return JNI_TRUE;
}

static jboolean
classesForSignature(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    char *signature;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    signature = inStream_readString(in);
    if (signature == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jint classCount;
        jclass *theClasses;
        jvmtiError error;

        error = allLoadedClasses(&theClasses, &classCount);
        if ( error == JVMTI_ERROR_NONE ) {
            /* Count classes in theClasses which match signature */
            int matchCount = 0;
            /* Count classes written to the JDWP connection */
            int writtenCount = 0;
            int i;

            for (i=0; i<classCount; i++) {
                jclass clazz = theClasses[i];
                jint status = classStatus(clazz);
                char *candidate_signature = NULL;
                jint wanted =
                    (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY|
                     JVMTI_CLASS_STATUS_PRIMITIVE);

                /* We want prepared classes, primitives, and arrays only */
                if ((status & wanted) == 0) {
                    continue;
                }

                error = classSignature(clazz, &candidate_signature, NULL);
                if (error != JVMTI_ERROR_NONE) {
                    break;
                }

                if (strcmp(candidate_signature, signature) == 0) {
                    /* Float interesting classes (those that
                     * are matching and are prepared) to the
                     * beginning of the array.
                     */
                    theClasses[i] = theClasses[matchCount];
                    theClasses[matchCount++] = clazz;
                }
                jvmtiDeallocate(candidate_signature);
            }

            /* At this point matching prepared classes occupy
             * indicies 0 thru matchCount-1 of theClasses.
             */

            if ( error ==  JVMTI_ERROR_NONE ) {
                (void)outStream_writeInt(out, matchCount);
                for (; writtenCount < matchCount; writtenCount++) {
                    jclass clazz = theClasses[writtenCount];
                    jint status = classStatus(clazz);
                    jbyte tag = referenceTypeTag(clazz);
                    (void)outStream_writeByte(out, tag);
                    (void)outStream_writeObjectRef(env, out, clazz);
                    (void)outStream_writeInt(out, map2jdwpClassStatus(status));
                    /* No point in continuing if there's an error */
                    if (outStream_error(out)) {
                        break;
                    }
                }
            }

            jvmtiDeallocate(theClasses);
        }

        if ( error != JVMTI_ERROR_NONE ) {
            outStream_setError(out, map2jdwpError(error));
        }

    } END_WITH_LOCAL_REFS(env);

    jvmtiDeallocate(signature);

    return JNI_TRUE;
}

static jboolean
allClasses1(PacketInputStream *in, PacketOutputStream *out, int outputGenerics)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jint classCount;
        jclass *theClasses;
        jvmtiError error;

        error = allLoadedClasses(&theClasses, &classCount);
        if ( error != JVMTI_ERROR_NONE ) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            /* Count classes in theClasses which are prepared */
            int prepCount = 0;
            /* Count classes written to the JDWP connection */
            int writtenCount = 0;
            int i;

            for (i=0; i<classCount; i++) {
                jclass clazz = theClasses[i];
                jint status = classStatus(clazz);
                jint wanted =
                    (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY);

                /* We want prepared classes and arrays only */
                if ((status & wanted) != 0) {
                    /* Float interesting classes (those that
                     * are prepared) to the beginning of the array.
                     */
                    theClasses[i] = theClasses[prepCount];
                    theClasses[prepCount++] = clazz;
                }
            }

            /* At this point prepared classes occupy
             * indicies 0 thru prepCount-1 of theClasses.
             */

            (void)outStream_writeInt(out, prepCount);
            for (; writtenCount < prepCount; writtenCount++) {
                char *signature = NULL;
                char *genericSignature = NULL;
                jclass clazz = theClasses[writtenCount];
                jint status = classStatus(clazz);
                jbyte tag = referenceTypeTag(clazz);
                jvmtiError error;

                error = classSignature(clazz, &signature, &genericSignature);
                if (error != JVMTI_ERROR_NONE) {
                    outStream_setError(out, map2jdwpError(error));
                    break;
                }

                (void)outStream_writeByte(out, tag);
                (void)outStream_writeObjectRef(env, out, clazz);
                (void)outStream_writeString(out, signature);
                if (outputGenerics == 1) {
                    writeGenericSignature(out, genericSignature);
                }

                (void)outStream_writeInt(out, map2jdwpClassStatus(status));
                jvmtiDeallocate(signature);
                if (genericSignature != NULL) {
                  jvmtiDeallocate(genericSignature);
                }

                /* No point in continuing if there's an error */
                if (outStream_error(out)) {
                    break;
                }
            }
            jvmtiDeallocate(theClasses);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
allClasses(PacketInputStream *in, PacketOutputStream *out)
{
    return allClasses1(in, out, 0);
}

static jboolean
allClassesWithGeneric(PacketInputStream *in, PacketOutputStream *out)
{
    return allClasses1(in, out, 1);
}

  /***********************************************************/


static jboolean
instanceCounts(PacketInputStream *in, PacketOutputStream *out)
{
    jint classCount;
    jclass *classes;
    JNIEnv *env;
    int ii;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    classCount = inStream_readInt(in);

    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    if (classCount == 0) {
        (void)outStream_writeInt(out, 0);
        return JNI_TRUE;
    }
    if (classCount < 0) {
        outStream_setError(out, JDWP_ERROR(ILLEGAL_ARGUMENT));
        return JNI_TRUE;
    }
    env = getEnv();
    classes = jvmtiAllocate(classCount * (int)sizeof(jclass));
    for (ii = 0; ii < classCount; ii++) {
        jdwpError errorCode;
        classes[ii] = inStream_readClassRef(env, in);
        errorCode = inStream_error(in);
        if (errorCode != JDWP_ERROR(NONE)) {
            /*
             * A class could have been unloaded/gc'd so
             * if we get an error, just ignore it and keep
             * going.  An instanceCount of 0 will be returned.
             */
            if (errorCode == JDWP_ERROR(INVALID_OBJECT) ||
                errorCode == JDWP_ERROR(INVALID_CLASS)) {
                inStream_clearError(in);
                classes[ii] = NULL;
                continue;
            }
            jvmtiDeallocate(classes);
            return JNI_TRUE;
        }
    }

    WITH_LOCAL_REFS(env, 1) {
        jlong      *counts;
        jvmtiError error;

        counts = jvmtiAllocate(classCount * (int)sizeof(jlong));
        /* Iterate over heap getting info on these classes */
        error = classInstanceCounts(classCount, classes, counts);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            (void)outStream_writeInt(out, classCount);
            for (ii = 0; ii < classCount; ii++) {
                (void)outStream_writeLong(out, counts[ii]);
            }
        }
        jvmtiDeallocate(counts);
    } END_WITH_LOCAL_REFS(env);
    jvmtiDeallocate(classes);
    return JNI_TRUE;
}

static jboolean
redefineClasses(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiClassDefinition *classDefs;
    jboolean ok = JNI_TRUE;
    jint classCount;
    jint i;
    JNIEnv *env;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    classCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }
    if ( classCount == 0 ) {
        return JNI_TRUE;
    }
    /*LINTED*/
    classDefs = jvmtiAllocate(classCount*(int)sizeof(jvmtiClassDefinition));
    if (classDefs == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    /*LINTED*/
    (void)memset(classDefs, 0, classCount*sizeof(jvmtiClassDefinition));

    env = getEnv();
    for (i = 0; i < classCount; ++i) {
        int byteCount;
        unsigned char * bytes;
        jclass clazz;

        clazz = inStream_readClassRef(env, in);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }
        byteCount = inStream_readInt(in);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }
        if ( byteCount <= 0 ) {
            outStream_setError(out, JDWP_ERROR(INVALID_CLASS_FORMAT));
            ok = JNI_FALSE;
            break;
        }
        bytes = (unsigned char *)jvmtiAllocate(byteCount);
        if (bytes == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
            ok = JNI_FALSE;
            break;
        }
        (void)inStream_readBytes(in, byteCount, (jbyte *)bytes);
        if (inStream_error(in)) {
            ok = JNI_FALSE;
            break;
        }

        classDefs[i].klass = clazz;
        classDefs[i].class_byte_count = byteCount;
        classDefs[i].class_bytes = bytes;
    }

    if (ok == JNI_TRUE) {
        jvmtiError error;

        error = JVMTI_FUNC_PTR(gdata->jvmti,RedefineClasses)
                        (gdata->jvmti, classCount, classDefs);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            /* zap our BP info */
            for ( i = 0 ; i < classCount; i++ ) {
                eventHandler_freeClassBreakpoints(classDefs[i].klass);
            }
        }
    }

    /* free up allocated memory */
    for ( i = 0 ; i < classCount; i++ ) {
        if ( classDefs[i].class_bytes != NULL ) {
            jvmtiDeallocate((void*)classDefs[i].class_bytes);
        }
    }
    jvmtiDeallocate(classDefs);

    return JNI_TRUE;
}

static jboolean
setDefaultStratum(PacketInputStream *in, PacketOutputStream *out)
{
    char *stratumId;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    stratumId = inStream_readString(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    } else if (strcmp(stratumId, "") == 0) {
        stratumId = NULL;
    }
    setGlobalStratumId(stratumId);

    return JNI_TRUE;
}

static jboolean
getAllThreads(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        int i;
        jint threadCount;
        jthread *theThreads;

        theThreads = allThreads(&threadCount);
        if (theThreads == NULL) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        } else {
            /* Squish out all of the debugger-spawned threads */
            threadCount = filterDebugThreads(theThreads, threadCount);

            (void)outStream_writeInt(out, threadCount);
            for (i = 0; i <threadCount; i++) {
                (void)outStream_writeObjectRef(env, out, theThreads[i]);
            }

            jvmtiDeallocate(theThreads);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
topLevelThreadGroups(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jvmtiError error;
        jint groupCount;
        jthreadGroup *groups;

        groups = NULL;
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
                    (gdata->jvmti, &groupCount, &groups);
        if (error != JVMTI_ERROR_NONE) {
            outStream_setError(out, map2jdwpError(error));
        } else {
            int i;

            (void)outStream_writeInt(out, groupCount);
            for (i = 0; i < groupCount; i++) {
                (void)outStream_writeObjectRef(env, out, groups[i]);
            }

            jvmtiDeallocate(groups);
        }

    } END_WITH_LOCAL_REFS(env);

    return JNI_TRUE;
}

static jboolean
dispose(PacketInputStream *in, PacketOutputStream *out)
{
    return JNI_TRUE;
}

static jboolean
idSizes(PacketInputStream *in, PacketOutputStream *out)
{
    (void)outStream_writeInt(out, sizeof(jfieldID));    /* fields */
    (void)outStream_writeInt(out, sizeof(jmethodID));   /* methods */
    (void)outStream_writeInt(out, sizeof(jlong));       /* objects */
    (void)outStream_writeInt(out, sizeof(jlong));       /* referent types */
    (void)outStream_writeInt(out, sizeof(FrameID));    /* frames */
    return JNI_TRUE;
}

static jboolean
suspend(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = threadControl_suspendAll();
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
resume(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = threadControl_resumeAll();
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
    }
    return JNI_TRUE;
}

static jboolean
doExit(PacketInputStream *in, PacketOutputStream *out)
{
    jint exitCode;

    exitCode = inStream_readInt(in);
    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_FALSE;
    }

    /* We send the reply from here because we are about to exit. */
    if (inStream_error(in)) {
        outStream_setError(out, inStream_error(in));
    }
    outStream_sendReply(out);

    forceExit(exitCode);

    /* Shouldn't get here */
    JDI_ASSERT(JNI_FALSE);

    /* Shut up the compiler */
    return JNI_FALSE;

}

static jboolean
createString(PacketInputStream *in, PacketOutputStream *out)
{
    JNIEnv *env;
    char *cstring;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }

    cstring = inStream_readString(in);
    if (cstring == NULL) {
        outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        return JNI_TRUE;
    }
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();

    WITH_LOCAL_REFS(env, 1) {

        jstring string;

        string = JNI_FUNC_PTR(env,NewStringUTF)(env, cstring);
        if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
            outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
        } else {
            (void)outStream_writeObjectRef(env, out, string);
        }

    } END_WITH_LOCAL_REFS(env);

    jvmtiDeallocate(cstring);

    return JNI_TRUE;
}

static jboolean
capabilities(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiCapabilities caps;
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = jvmtiGetCapabilities(&caps);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);
    return JNI_TRUE;
}

static jboolean
capabilitiesNew(PacketInputStream *in, PacketOutputStream *out)
{
    jvmtiCapabilities caps;
    jvmtiError error;

    if (gdata->vmDead) {
        outStream_setError(out, JDWP_ERROR(VM_DEAD));
        return JNI_TRUE;
    }
    error = jvmtiGetCapabilities(&caps);
    if (error != JVMTI_ERROR_NONE) {
        outStream_setError(out, map2jdwpError(error));
        return JNI_TRUE;
    }

    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_modification_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_field_access_events);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_bytecodes);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_synthetic_attribute);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_info);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_current_contended_monitor);
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_monitor_info);

    /* new since JDWP version 1.4 */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_redefine_classes);
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_add_method */ );
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE /* can_unrestrictedly_redefine_classes */ );
    /* 11: canPopFrames */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_pop_frame);
    /* 12: canUseInstanceFilters */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 13: canGetSourceDebugExtension */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_source_debug_extension);
    /* 14: canRequestVMDeathEvent */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 15: canSetDefaultStratum */
    (void)outStream_writeBoolean(out, (jboolean)JNI_TRUE);
    /* 16: canGetInstanceInfo */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_tag_objects);
    /* 17: canRequestMonitorEvents */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_generate_monitor_events);
    /* 18: canGetMonitorFrameInfo */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_owned_monitor_stack_depth_info);
    /* remaining reserved */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 19 */
    /* 20 Can get constant pool information */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_get_constant_pool);
    /* 21 Can force early return */
    (void)outStream_writeBoolean(out, (jboolean)caps.can_force_early_return);
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 22 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 23 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 24 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 25 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 26 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 27 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 28 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 29 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 30 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 31 */
    (void)outStream_writeBoolean(out, (jboolean)JNI_FALSE); /* 32 */
    return JNI_TRUE;
}

static int
countPaths(char *string) {
    int cnt = 1; /* always have one */
    char *pos = string;
    char *ps;

    ps = gdata->property_path_separator;
    if ( ps == NULL ) {
        ps = ";";
    }
    while ((pos = strchr(pos, ps[0])) != NULL) {
        ++cnt;
        ++pos;
    }
    return cnt;
}

static void
writePaths(PacketOutputStream *out, char *string) {
    char *pos;
    char *ps;
    char *buf;
    int   npaths;
    int   i;

    buf = jvmtiAllocate((int)strlen(string)+1);

    npaths = countPaths(string);
    (void)outStream_writeInt(out, npaths);

    ps = gdata->property_path_separator;
    if ( ps == NULL ) {
        ps = ";";
    }

    pos = string;
    for ( i = 0 ; i < npaths ; i++ ) {
        char *psPos;
        int   plen;

        psPos = strchr(pos, ps[0]);
        if ( psPos == NULL ) {
            plen = (int)strlen(pos);
        } else {
            plen = (int)(psPos-pos);
            psPos++;
        }
        (void)memcpy(buf, pos, plen);
        buf[plen] = 0;
        (void)outStream_writeString(out, buf);
        pos = psPos;
    }

    jvmtiDeallocate(buf);
}



static jboolean
classPaths(PacketInputStream *in, PacketOutputStream *out)
{
    char *ud;
    char *bp;
    char *cp;

    ud = gdata->property_user_dir;
    if ( ud == NULL ) {
        ud = "";
    }
    cp = gdata->property_java_class_path;
    if ( cp == NULL ) {
        cp = "";
    }
    bp = gdata->property_sun_boot_class_path;
    if ( bp == NULL ) {
        bp = "";
    }
    (void)outStream_writeString(out, ud);
    writePaths(out, cp);
    writePaths(out, bp);
    return JNI_TRUE;
}

static jboolean
disposeObjects(PacketInputStream *in, PacketOutputStream *out)
{
    int i;
    int refCount;
    jlong id;
    int requestCount;
    JNIEnv *env;

    if (gdata->vmDead) {
        /* quietly ignore */
        return JNI_TRUE;
    }

    requestCount = inStream_readInt(in);
    if (inStream_error(in)) {
        return JNI_TRUE;
    }

    env = getEnv();
    for (i = 0; i < requestCount; i++) {
        id = inStream_readObjectID(in);
        refCount = inStream_readInt(in);
        if (inStream_error(in)) {
            return JNI_TRUE;
        }
        commonRef_releaseMultiple(env, id, refCount);
    }

    return JNI_TRUE;
}

static jboolean
holdEvents(PacketInputStream *in, PacketOutputStream *out)
{
    eventHelper_holdEvents();
    return JNI_TRUE;
}

static jboolean
releaseEvents(PacketInputStream *in, PacketOutputStream *out)
{
    eventHelper_releaseEvents();
    return JNI_TRUE;
}

void *VirtualMachine_Cmds[] = { (void *)21
    ,(void *)version
    ,(void *)classesForSignature
    ,(void *)allClasses
    ,(void *)getAllThreads
    ,(void *)topLevelThreadGroups
    ,(void *)dispose
    ,(void *)idSizes
    ,(void *)suspend
    ,(void *)resume
    ,(void *)doExit
    ,(void *)createString
    ,(void *)capabilities
    ,(void *)classPaths
    ,(void *)disposeObjects
    ,(void *)holdEvents
    ,(void *)releaseEvents
    ,(void *)capabilitiesNew
    ,(void *)redefineClasses
    ,(void *)setDefaultStratum
    ,(void *)allClassesWithGeneric
    ,(void *)instanceCounts
};
