Index: qemu-kvm-0.10/qemu/vnc.c
===================================================================
--- qemu-kvm-0.10.orig/qemu/vnc.c
+++ qemu-kvm-0.10/qemu/vnc.c
@@ -166,19 +166,136 @@ struct VncState
static VncDisplay *vnc_display; /* needed for info vnc */
static DisplayChangeListener *dcl;
+static char *addr_to_string(const char *format,
+ struct sockaddr_storage *sa,
+ socklen_t salen) {
+ char *addr;
+ char host[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+ int err;
+
+ if ((err = getnameinfo((struct sockaddr *)sa, salen,
+ host, sizeof(host),
+ serv, sizeof(serv),
+ NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
+ VNC_DEBUG("Cannot resolve address %d: %s\n",
+ err, gai_strerror(err));
+ return NULL;
+ }
+
+ if (asprintf(&addr, format, host, serv) < 0)
+ return NULL;
+
+ return addr;
+}
+
+static char *vnc_socket_local_addr(const char *format, int fd) {
+ struct sockaddr_storage sa;
+ socklen_t salen;
+
+ salen = sizeof(sa);
+ if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
+ return NULL;
+
+ return addr_to_string(format, &sa, salen);
+}
+
+static char *vnc_socket_remote_addr(const char *format, int fd) {
+ struct sockaddr_storage sa;
+ socklen_t salen;
+
+ salen = sizeof(sa);
+ if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
+ return NULL;
+
+ return addr_to_string(format, &sa, salen);
+}
+
+static const char *vnc_auth_name(VncDisplay *vd) {
+ switch (vd->auth) {
+ case VNC_AUTH_INVALID:
+ return "invalid";
+ case VNC_AUTH_NONE:
+ return "none";
+ case VNC_AUTH_VNC:
+ return "vnc";
+ case VNC_AUTH_RA2:
+ return "ra2";
+ case VNC_AUTH_RA2NE:
+ return "ra2ne";
+ case VNC_AUTH_TIGHT:
+ return "tight";
+ case VNC_AUTH_ULTRA:
+ return "ultra";
+ case VNC_AUTH_TLS:
+ return "tls";
+ case VNC_AUTH_VENCRYPT:
+#ifdef CONFIG_VNC_TLS
+ switch (vd->subauth) {
+ case VNC_AUTH_VENCRYPT_PLAIN:
+ return "vencrypt+plain";
+ case VNC_AUTH_VENCRYPT_TLSNONE:
+ return "vencrypt+tls+none";
+ case VNC_AUTH_VENCRYPT_TLSVNC:
+ return "vencrypt+tls+vnc";
+ case VNC_AUTH_VENCRYPT_TLSPLAIN:
+ return "vencrypt+tls+plain";
+ case VNC_AUTH_VENCRYPT_X509NONE:
+ return "vencrypt+x509+none";
+ case VNC_AUTH_VENCRYPT_X509VNC:
+ return "vencrypt+x509+vnc";
+ case VNC_AUTH_VENCRYPT_X509PLAIN:
+ return "vencrypt+x509+plain";
+ default:
+ return "vencrypt";
+ }
+#else
+ return "vencrypt";
+#endif
+ }
+ return "unknown";
+}
+
+#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
+
+static void do_info_vnc_client(VncState *client)
+{
+ char *clientAddr =
+ vnc_socket_remote_addr(" address: %s:%s\n",
+ client->csock);
+ if (!clientAddr)
+ return;
+
+ term_puts("Client:\n");
+ term_puts(clientAddr);
+ free(clientAddr);
+}
+
void do_info_vnc(void)
{
- if (vnc_display == NULL || vnc_display->display == NULL)
- term_printf("VNC server disabled\n");
- else {
- term_printf("VNC server active on: ");
- term_print_filename(vnc_display->display);
- term_printf("\n");
-
- if (vnc_display->clients == NULL)
- term_printf("No client connected\n");
- else
- term_printf("Client connected\n");
+ if (vnc_display == NULL || vnc_display->display == NULL) {
+ term_printf("Server: disabled\n");
+ } else {
+ char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
+ vnc_display->lsock);
+
+ if (!serverAddr)
+ return;
+
+ term_puts("Server:\n");
+ term_puts(serverAddr);
+ free(serverAddr);
+ term_printf(" auth: %s\n", vnc_auth_name(vnc_display));
+
+ if (vnc_display->clients) {
+ VncState *client = vnc_display->clients;
+ while (client) {
+ do_info_vnc_client(client);
+ client = client->next;
+ }
+ } else {
+ term_printf("Client: none\n");
+ }
}
}