static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)

{

    char buf[1024];

    VncShareMode mode;

    int size;



    mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;

    switch (vs->vd->share_policy) {

    case VNC_SHARE_POLICY_IGNORE:

        /*

         * Ignore the shared flag.  Nothing to do here.

         *

         * Doesn't conform to the rfb spec but is traditional qemu

         * behavior, thus left here as option for compatibility

         * reasons.

         */

        break;

    case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:

        /*

         * Policy: Allow clients ask for exclusive access.

         *

         * Implementation: When a client asks for exclusive access,

         * disconnect all others. Shared connects are allowed as long

         * as no exclusive connection exists.

         *

         * This is how the rfb spec suggests to handle the shared flag.

         */

        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            VncState *client;

            QTAILQ_FOREACH(client, &vs->vd->clients, next) {

                if (vs == client) {

                    continue;

                }

                if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&

                    client->share_mode != VNC_SHARE_MODE_SHARED) {

                    continue;

                }

                vnc_disconnect_start(client);

            }

        }

        if (mode == VNC_SHARE_MODE_SHARED) {

            if (vs->vd->num_exclusive > 0) {

                vnc_disconnect_start(vs);

                return 0;

            }

        }

        break;

    case VNC_SHARE_POLICY_FORCE_SHARED:

        /*

         * Policy: Shared connects only.

         * Implementation: Disallow clients asking for exclusive access.

         *

         * Useful for shared desktop sessions where you don't want

         * someone forgetting to say -shared when running the vnc

         * client disconnect everybody else.

         */

        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            vnc_disconnect_start(vs);

            return 0;

        }

        break;

    }

    vnc_set_share_mode(vs, mode);



    if (vs->vd->num_shared > vs->vd->connections_limit) {

        vnc_disconnect_start(vs);

        return 0;

    }



    vs->client_width = pixman_image_get_width(vs->vd->server);

    vs->client_height = pixman_image_get_height(vs->vd->server);

    vnc_write_u16(vs, vs->client_width);

    vnc_write_u16(vs, vs->client_height);



    pixel_format_message(vs);



    if (qemu_name)

        size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);

    else

        size = snprintf(buf, sizeof(buf), "QEMU");



    vnc_write_u32(vs, size);

    vnc_write(vs, buf, size);

    vnc_flush(vs);



    vnc_client_cache_auth(vs);

    vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);



    vnc_read_when(vs, protocol_client_msg, 1);



    return 0;

}

static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)

{

    char buf[1024];

    VncShareMode mode;

    int size;



    mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;

    switch (vs->vd->share_policy) {

    case VNC_SHARE_POLICY_IGNORE:

        













        break;

    case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:

        

















        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            VncState *client;

            QTAILQ_FOREACH(client, &vs->vd->clients, next) {

                if (vs == client) {

                    continue;

                }

                if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&

                    client->share_mode != VNC_SHARE_MODE_SHARED) {

                    continue;

                }

                vnc_disconnect_start(client);

            }

        }

        if (mode == VNC_SHARE_MODE_SHARED) {

            if (vs->vd->num_exclusive > 0) {

                vnc_disconnect_start(vs);

                return 0;

            }

        }

        break;

    case VNC_SHARE_POLICY_FORCE_SHARED:

        















        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            vnc_disconnect_start(vs);

            return 0;

        }

        break;

    }

    vnc_set_share_mode(vs, mode);



    if (vs->vd->num_shared > vs->vd->connections_limit) {

        vnc_disconnect_start(vs);

        return 0;

    }



    vs->client_width = pixman_image_get_width(vs->vd->server);

    vs->client_height = pixman_image_get_height(vs->vd->server);

    vnc_write_u16(vs, vs->client_width);

    vnc_write_u16(vs, vs->client_height);



    pixel_format_message(vs);



    if (qemu_name)

        size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);

    else

        size = snprintf(buf, sizeof(buf), "QEMU");



    vnc_write_u32(vs, size);

    vnc_write(vs, buf, size);

    vnc_flush(vs);



    vnc_client_cache_auth(vs);

    vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);



    vnc_read_when(vs, protocol_client_msg, 1);



    return 0;

}

static int FUNC_0(VncState *VAR_0, uint8_t *VAR_1, size_t VAR_2)

{

    char VAR_3[1024];

    VncShareMode mode;

    int VAR_4;



    mode = VAR_1[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;

    switch (VAR_0->vd->share_policy) {

    case VNC_SHARE_POLICY_IGNORE:

        













        break;

    case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:

        

















        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            VncState *client;

            QTAILQ_FOREACH(client, &VAR_0->vd->clients, next) {

                if (VAR_0 == client) {

                    continue;

                }

                if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&

                    client->share_mode != VNC_SHARE_MODE_SHARED) {

                    continue;

                }

                vnc_disconnect_start(client);

            }

        }

        if (mode == VNC_SHARE_MODE_SHARED) {

            if (VAR_0->vd->num_exclusive > 0) {

                vnc_disconnect_start(VAR_0);

                return 0;

            }

        }

        break;

    case VNC_SHARE_POLICY_FORCE_SHARED:

        















        if (mode == VNC_SHARE_MODE_EXCLUSIVE) {

            vnc_disconnect_start(VAR_0);

            return 0;

        }

        break;

    }

    vnc_set_share_mode(VAR_0, mode);



    if (VAR_0->vd->num_shared > VAR_0->vd->connections_limit) {

        vnc_disconnect_start(VAR_0);

        return 0;

    }



    VAR_0->client_width = pixman_image_get_width(VAR_0->vd->server);

    VAR_0->client_height = pixman_image_get_height(VAR_0->vd->server);

    vnc_write_u16(VAR_0, VAR_0->client_width);

    vnc_write_u16(VAR_0, VAR_0->client_height);



    pixel_format_message(VAR_0);



    if (qemu_name)

        VAR_4 = snprintf(VAR_3, sizeof(VAR_3), "QEMU (%s)", qemu_name);

    else

        VAR_4 = snprintf(VAR_3, sizeof(VAR_3), "QEMU");



    vnc_write_u32(VAR_0, VAR_4);

    vnc_write(VAR_0, VAR_3, VAR_4);

    vnc_flush(VAR_0);



    vnc_client_cache_auth(VAR_0);

    vnc_qmp_event(VAR_0, QAPI_EVENT_VNC_INITIALIZED);



    vnc_read_when(VAR_0, protocol_client_msg, 1);



    return 0;

}

static int FUNC_0(VncState *VAR_0, uint8_t *VAR_1, size_t VAR_2)
{ char VAR_3[1024]; VncShareMode mode; int VAR_4; mode = VAR_1[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE; switch (VAR_0->vd->share_policy) { case VNC_SHARE_POLICY_IGNORE:
break; case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
if (mode == VNC_SHARE_MODE_EXCLUSIVE) { VncState *client; QTAILQ_FOREACH(client, &VAR_0->vd->clients, next) { if (VAR_0 == client) { continue; } if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
client->share_mode != VNC_SHARE_MODE_SHARED) { continue; } vnc_disconnect_start(client); } } if (mode == VNC_SHARE_MODE_SHARED) { if (VAR_0->vd->num_exclusive > 0) { vnc_disconnect_start(VAR_0); return 0; } } break; case VNC_SHARE_POLICY_FORCE_SHARED:
if (mode == VNC_SHARE_MODE_EXCLUSIVE) { vnc_disconnect_start(VAR_0); return 0; } break; } vnc_set_share_mode(VAR_0, mode); if (VAR_0->vd->num_shared > VAR_0->vd->connections_limit) { vnc_disconnect_start(VAR_0); return 0; } VAR_0->client_width = pixman_image_get_width(VAR_0->vd->server); VAR_0->client_height = pixman_image_get_height(VAR_0->vd->server); vnc_write_u16(VAR_0, VAR_0->client_width); vnc_write_u16(VAR_0, VAR_0->client_height); pixel_format_message(VAR_0); if (qemu_name)
VAR_4 = snprintf(VAR_3, sizeof(VAR_3), "QEMU (%s)", qemu_name); else
VAR_4 = snprintf(VAR_3, sizeof(VAR_3), "QEMU"); vnc_write_u32(VAR_0, VAR_4); vnc_write(VAR_0, VAR_3, VAR_4); vnc_flush(VAR_0); vnc_client_cache_auth(VAR_0); vnc_qmp_event(VAR_0, QAPI_EVENT_VNC_INITIALIZED); vnc_read_when(VAR_0, protocol_client_msg, 1); return 0; }