aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkraxel <kraxel>2006-12-08 14:33:09 +0000
committerkraxel <kraxel>2006-12-08 14:33:09 +0000
commite9a92a328a606a429c3c5c8f5f0a6ba08c7144fc (patch)
treeeae5d72793d5ef33e9c5418ec747121c45072030
parentb9a3e0f74ccbd003bd964cd834bf09baefa0bccf (diff)
downloadxenwatch-e9a92a328a606a429c3c5c8f5f0a6ba08c7144fc.tar.gz
xenapi
-rw-r--r--.cvsignore1
-rw-r--r--GNUmakefile9
-rw-r--r--xenapi.c186
3 files changed, 196 insertions, 0 deletions
diff --git a/.cvsignore b/.cvsignore
index e5974df..a5f0085 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -6,3 +6,4 @@ xenwatch
mdns-browser
mdns-publish-xendom
vnc-client
+xenapi
diff --git a/GNUmakefile b/GNUmakefile
index c0bc90c..2abe1d9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -10,8 +10,10 @@ TARGETS := xenlog xenscreen xenscreenrc
BUILD_GTK := xenwatch mdns-browser
BUILD_MDNS := mdns-publish-xendom
BUILD_VNC := vnc-client
+BUILD_XENAPI := xenapi
NEEDS_XENSTORE := xenlog xenscreen xenwatch mdns-publish-xendom
+NEEDS_XENAPI := xenapi
NEEDS_GTK := xenwatch mdns-browser vnc-client
NEEDS_MDNS := xenwatch mdns-browser mdns-publish-xendom
NEEDS_VNC := xenwatch vnc-client
@@ -53,6 +55,12 @@ ifeq ($(HAVE_AVAHI),yes)
TARGETS += $(BUILD_MDNS)
endif
+# xen api
+ifeq ($(HAVE_XENAPI),yes)
+ $(NEEDS_XENAPI) : LDLIBS += -lxenapi
+ TARGETS += $(BUILD_XENAPI)
+endif
+
# compile flags
CFLAGS += $(call ac_inc_cflags,AVAHI VNCCLIENT VNC_TEXT)
CFLAGS += $(shell test "$(pkglst)" != "" && pkg-config --cflags $(pkglst))
@@ -92,6 +100,7 @@ xenwatch: xenwatch.o xs_view.o xs_store.o xd_view.o xd_store.o \
mdns-browser: mdns-browser.o mdns.o apps.o apps-x11.o
mdns-publish-xendom: mdns-publish-xendom.o
vnc-client: vnc-client.o vnc.o x11.o
+xenapi: xenapi.o tcp.o
xenscreenrc: xenscreen
./xenscreen -b > $@
diff --git a/xenapi.c b/xenapi.c
new file mode 100644
index 0000000..6308d8d
--- /dev/null
+++ b/xenapi.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2006 XenSource, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <libxml/parser.h>
+#include <curl/curl.h>
+
+#include <xen/api/xen_sr.h>
+#include <xen/api/xen_host.h>
+
+#include "tcp.h"
+
+static int xmlrpc_request(const void *data, size_t len, void *user_handle,
+ void *result_handle, xen_result_func result_func)
+{
+ static char *xend_host = "localhost";
+ static char *xend_serv = "8005";
+ static struct sockaddr_un xend_unix = {
+ .sun_family = PF_UNIX,
+ .sun_path = "/var/run/xend/xmlrpc.sock",
+ };
+ static char *xend_path = "/RPC2";
+
+ struct addrinfo ask;
+ char head[256];
+ char reply[256];
+ char *body;
+ int sock, lhead, lreply, lbody, rc, eof, header_seen;
+ struct timeval tv;
+ fd_set rd;
+
+ tcp_verbose = 0;
+
+ /* try tcp first */
+ memset(&ask,0,sizeof(ask));
+ ask.ai_socktype = SOCK_STREAM;
+ ask.ai_family = PF_UNSPEC;
+ sock = tcp_connect(&ask, NULL, NULL, xend_host, xend_serv);
+ if (sock >= 0)
+ goto connected;
+
+ /* failing that unix sockets */
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (0 == connect(sock, (struct sockaddr*)&xend_unix, sizeof(xend_unix)))
+ goto connected;
+
+ /* Hmm, didn't work */
+ return -1;
+
+ connected:
+ /* http header */
+ lhead = snprintf(head, sizeof(head),
+ "POST %s HTTP/1.0\r\n"
+ "Host: %s\r\n"
+ "User-Agent: xenwatch\r\n"
+ "Content-Type: text/xml\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n",
+ xend_path, xend_host, len);
+ if (tcp_verbose) {
+ write(2, head, lhead);
+ write(2, data, len);
+ }
+ write(sock, head, lhead);
+ rc = write(sock, data, len);
+ if (rc != len) {
+ fprintf(stderr,"Oops [FIXME]: unhandled partial write (%d/%d)\n", rc, len);
+ return -1;
+ }
+
+ header_seen = 0;
+ lreply = 0;
+ eof = 0;
+ while (!eof) {
+ FD_ZERO(&rd);
+ FD_SET(sock, &rd);
+ tv.tv_sec = 3;
+ tv.tv_usec = 0;
+ if (1 == select(sock+1, &rd, NULL, NULL, &tv)) {
+ rc = read(sock, reply + lreply, sizeof(reply) - lreply -1);
+ switch (rc) {
+ case -1:
+ perror("read");
+ /* fall through */
+ case 0:
+ eof = 1;
+ break;
+ default:
+ lreply += rc;
+ reply[lreply] = 0;
+ if (header_seen) {
+ result_func(reply, lreply, result_handle);
+ lreply = 0;
+ } else {
+ body = strstr(reply, "\r\n\r\n");
+ if (!body)
+ break;
+ body += 4;
+ lbody = lreply - (body - reply);
+ header_seen = 1;
+ lreply = 0;
+ if (lbody)
+ result_func(body, lbody, result_handle);
+ }
+ }
+ }
+ }
+ close(sock);
+ return 0;
+}
+
+
+static void print_error(xen_session *session)
+{
+ int i;
+
+ fprintf(stderr, "Error: %d", session->error_description_count);
+ for (i = 0; i < session->error_description_count; i++)
+ fprintf(stderr, " %s", session->error_description[i]);
+ fprintf(stderr, "\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ xen_session *session = NULL;
+ xen_string_string_map *versions = NULL;
+ xen_host host;
+ int i, rc = 1;
+
+ xmlInitParser();
+ xen_init();
+
+ session = xen_session_login_with_password(xmlrpc_request, NULL, NULL, NULL);
+
+ if (!xen_session_get_this_host(session, &host))
+ goto out;
+
+ if (!xen_host_get_software_version(session, &versions, host))
+ goto out;
+
+ for (i = 0; i < versions->size; i++) {
+ printf("%s: %s\n", versions->contents[i].key, versions->contents[i].val);
+ }
+
+ rc = 0;
+
+ out:
+ if (session && !session->ok)
+ print_error(session);
+ if (versions)
+ xen_string_string_map_free(versions);
+ if (session)
+ xen_session_logout(session);
+ xen_fini();
+ xmlCleanupParser();
+ return rc;
+}
+
+