From ce50294cec7978de1edda2170ae590237803c98e Mon Sep 17 00:00:00 2001 From: root Date: Wed, 18 Jun 2008 21:41:01 +0200 Subject: [PATCH] Joepie! --- Makefile | 7 + handler_avahi.c | 401 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ handler_avahi.h | 89 ++++++++++++ handler_example.c | 199 +++++++++++++++++++++++++++ handler_example.h | 78 +++++++++++ handler_virt.c | 264 +++++++++++++++++++++++++++++++++++ handler_virt.h | 62 +++++++++ 7 files changed, 1100 insertions(+) create mode 100644 Makefile create mode 100644 handler_avahi.c create mode 100644 handler_avahi.h create mode 100644 handler_example.c create mode 100644 handler_example.h create mode 100644 handler_virt.c create mode 100644 handler_virt.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f87904f --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: handler_example.c + gcc -fPIC -shared -I/opt/cherokee/include -o libplugin_example.so handler_example.c + gcc -fPIC -shared -I/opt/cherokee/include -lavahi-client -o libplugin_avahi.so handler_avahi.c + gcc -fPIC -shared -I/opt/cherokee/include -lavahi-client -lvirt -o libplugin_virt.so handler_avahi.c handler_virt.c + +install: + cp *.so /opt/cherokee/lib/cherokee/. diff --git a/handler_avahi.c b/handler_avahi.c new file mode 100644 index 0000000..ff902a0 --- /dev/null +++ b/handler_avahi.c @@ -0,0 +1,401 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "handler_avahi.h" +#include + +#include +#include + +#include +#include + +/* Plug-in initialization + * + * In this function you can use any of these: + * http_delete | http_get | http_post | http_put + * + * For a full list: cherokee_http_method_t + * + * It is what your handler to be implements. + * + */ +PLUGIN_INFO_HANDLER_EASIEST_INIT (avahi, http_get); + + +/* Methods implementation + */ + +static ret_t +props_free (cherokee_handler_avahi_props_t *props) +{ + if (props->threaded_poll) + avahi_threaded_poll_stop(props->threaded_poll); + + if (props->sb) + avahi_service_browser_free(props->sb); + + if (props->client) + avahi_client_free(props->client); + + if (props->threaded_poll) + avahi_threaded_poll_free(props->threaded_poll); + +// cherokee_avl_mrproper (&props->entries, (cherokee_func_free_t) cherokee_buffer_mrproper); + cherokee_avl_mrproper (&props->entries, NULL); + + return cherokee_module_props_free_base (MODULE_PROPS(props)); +} + + +ret_t +cherokee_handler_avahi_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) +{ + cherokee_list_t *i; + cherokee_handler_avahi_props_t *props; + int error; + + if (*_props == NULL) { + CHEROKEE_NEW_STRUCT (n, handler_avahi_props); + + cherokee_module_props_init_base (MODULE_PROPS(n), + MODULE_PROPS_FREE(props_free)); + + /* Look at handler_avahi.h + * This is an avahi of configuration. + */ + cherokee_buffer_init (&n->service_type); + + *_props = MODULE_PROPS(n); + } + + props = PROP_AVAHI(*_props); + + cherokee_config_node_foreach (i, conf) { + cherokee_config_node_t *subconf = CONFIG_NODE(i); + + if (equal_buf_str (&subconf->key, "service_type")) { + cherokee_buffer_add_buffer (&props->service_type, &subconf->val); + } else { + PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf->key.buf); + return ret_error; + } + } + + props->client = NULL; + props->sb = NULL; + props->threaded_poll = NULL; + + cherokee_avl_init(&props->entries); + + if (!(props->threaded_poll = avahi_threaded_poll_new())) { + return ret_error; + } + + if (!(props->client = avahi_client_new(avahi_threaded_poll_get(props->threaded_poll), 0, client_callback, props, &error))) { + return ret_error; + } + + /* create some browsers on the client object here, if you wish */ + if (!(props->sb = avahi_service_browser_new(props->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, props->service_type.buf, NULL, 0, browse_callback, props))) { + TRACE ("avahi", "Failed to create service browser: %s (%s)\n", avahi_strerror(avahi_client_errno(props->client)), props->service_type.buf); + return ret_error; + } + + /* Finally, start the event loop thread */ + if (avahi_threaded_poll_start(props->threaded_poll) < 0) { + return ret_error; + } + + + return ret_ok; +} + +ret_t +cherokee_handler_avahi_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props) +{ + ret_t ret; + + CHEROKEE_NEW_STRUCT (n, handler_avahi); + + /* Init the base class object + */ + cherokee_handler_init_base(HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(avahi)); + + MODULE(n)->init = (handler_func_init_t) cherokee_handler_avahi_init; + MODULE(n)->free = (module_func_free_t) cherokee_handler_avahi_free; + HANDLER(n)->step = (handler_func_step_t) cherokee_handler_avahi_step; + HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_avahi_add_headers; + + HANDLER(n)->support = hsupport_length | hsupport_range; + + /* Init + */ + ret = cherokee_buffer_init (&n->buffer); + if (unlikely(ret != ret_ok)) + return ret; + + ret = cherokee_buffer_ensure_size (&n->buffer, 4*1024); + if (unlikely(ret != ret_ok)) + return ret; + + *hdl = HANDLER(n); + + return ret_ok; +} + + +ret_t +cherokee_handler_avahi_free (cherokee_handler_avahi_t *hdl) +{ + cherokee_buffer_mrproper (&hdl->buffer); + + return ret_ok; +} + +static ret_t +while_func_entries (cherokee_buffer_t *key, void *value, void *param) { + cherokee_buffer_t *buf = (cherokee_buffer_t *)param; + + cherokee_buffer_add_buffer (buf, key); + cherokee_buffer_add_str (buf, " - "); + cherokee_buffer_add (buf, value, strlen(value)); + cherokee_buffer_add_str (buf, "\n"); + + return ret_ok; +} + +static void +avahi_build_page (cherokee_handler_avahi_t *hdl) +{ + ret_t ret; + cherokee_buffer_t *buf; + + /* Init + */ + buf = &hdl->buffer; + + /* Useful output + */ + + /* First, block the event loop */ + avahi_threaded_poll_lock(HDL_AVAHI_PROPS(hdl)->threaded_poll); + + /* Than, do your stuff */ + cherokee_avl_while (&HDL_AVAHI_PROPS(hdl)->entries, (cherokee_avl_while_func_t) while_func_entries, (void *) buf, NULL, NULL); + + /* Finally, unblock the event loop */ + avahi_threaded_poll_unlock(HDL_AVAHI_PROPS(hdl)->threaded_poll); +} + +ret_t +cherokee_handler_avahi_init (cherokee_handler_avahi_t *hdl) +{ + ret_t ret; + void *param; + cint_t web_interface = 1; + + /* Build the page + */ + if (web_interface) { + avahi_build_page (hdl); + } + + hdl->action = send_page; + + return ret_ok; +} + + +ret_t +cherokee_handler_avahi_step (cherokee_handler_avahi_t *hdl, cherokee_buffer_t *buffer) +{ + cherokee_buffer_add_buffer (buffer, &hdl->buffer); + return ret_eof_have_data; +} + + +ret_t +cherokee_handler_avahi_add_headers (cherokee_handler_avahi_t *hdl, cherokee_buffer_t *buffer) +{ + if (hdl->buffer.len == 0) { + cherokee_connection_t *conn = HANDLER_CONN(hdl); + conn->error_code = http_not_found; + } + + cherokee_buffer_add_va (buffer, "Content-Length: %d"CRLF, hdl->buffer.len); + + switch (hdl->action) { + case send_page: + default: + cherokee_buffer_add_str (buffer, "Content-Type: text/plain"CRLF); + break; + } + + return ret_ok; +} + + +/* Avahi example stuff */ + +static void resolve_callback( + AvahiServiceResolver *r, + AVAHI_GCC_UNUSED AvahiIfIndex interface, + AVAHI_GCC_UNUSED AvahiProtocol protocol, + AvahiResolverEvent event, + const char *name, + const char *type, + const char *domain, + const char *host_name, + const AvahiAddress *address, + uint16_t port, + AvahiStringList *txt, + AvahiLookupResultFlags flags, + void* userdata) { + assert(r); + + /* Called whenever a service has been resolved successfully or timed out */ + + switch (event) { + case AVAHI_RESOLVER_FAILURE: + fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); + break; + + case AVAHI_RESOLVER_FOUND: { + char a[AVAHI_ADDRESS_STR_MAX], *t; + + avahi_address_snprint(a, sizeof(a), address); + +/* cherokee_buffer_t buf; + cherokee_buffer_t buf2; + cherokee_buffer_t *buf2a; + cherokee_buffer_init(&buf); + cherokee_buffer_init(&buf2); + cherokee_buffer_add(&buf, name, strlen(name)); + cherokee_buffer_add(&buf2, a, strlen(a)); + cherokee_buffer_dup(&buf2, &buf2a); + cherokee_avl_add(&PROP_AVAHI(userdata)->entries, &buf, buf2a); + cherokee_buffer_mrproper(&buf); + cherokee_buffer_mrproper(&buf2);*/ + + cherokee_avl_add_ptr (&PROP_AVAHI(userdata)->entries, name, (void *) host_name); + + fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain); + + t = avahi_string_list_to_string(txt); + fprintf(stderr, + "\t%s:%u (%s)\n" + "\tTXT=%s\n" + "\tcookie is %u\n" + "\tis_local: %i\n" + "\tour_own: %i\n" + "\twide_area: %i\n" + "\tmulticast: %i\n" + "\tcached: %i\n", + host_name, port, a, + t, + avahi_string_list_get_service_cookie(txt), + !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), + !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), + !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), + !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), + !!(flags & AVAHI_LOOKUP_RESULT_CACHED)); + + avahi_free(t); + } + } + + avahi_service_resolver_free(r); +} + +static void browse_callback( + AvahiServiceBrowser *b, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *name, + const char *type, + const char *domain, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) { + + AvahiClient *c = PROP_AVAHI(userdata)->client; + assert(b); + + /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ + + switch (event) { + case AVAHI_BROWSER_FAILURE: + fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); + avahi_threaded_poll_stop(PROP_AVAHI(userdata)->threaded_poll); + return; + + case AVAHI_BROWSER_NEW: + fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); + + /* We ignore the returned resolver object. In the callback + function we free it. If the server is terminated before + the callback function is called the server will free + the resolver for us. */ + + if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, userdata))) + fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); + + break; + + case AVAHI_BROWSER_REMOVE: { + void **val; +/* cherokee_buffer_t buf; + cherokee_buffer_init(&buf); + cherokee_buffer_add(&buf, name, strlen(name)); + if (cherokee_avl_del(&PROP_AVAHI(userdata)->entries, &buf, val) == ret_ok) { + cherokee_buffer_mrproper((cherokee_buffer_t *) *val); + } + cherokee_buffer_mrproper(&buf);*/ + + cherokee_avl_del_ptr(&PROP_AVAHI(userdata)->entries, name, val); + + fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain); + break; + } + + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); + break; + } +} + +static void client_callback(AvahiClient *c, AvahiClientState state, void * userdata) { + assert(c); + + /* Called whenever the client or server state changes */ + + if (state == AVAHI_CLIENT_FAILURE) { + fprintf(stderr, "Server connection failure: %s\n", avahi_strerror(avahi_client_errno(c))); + avahi_threaded_poll_stop(PROP_AVAHI(userdata)->threaded_poll); + } +} + diff --git a/handler_avahi.h b/handler_avahi.h new file mode 100644 index 0000000..78e1276 --- /dev/null +++ b/handler_avahi.h @@ -0,0 +1,89 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef CHEROKEE_HANDLER_AVAHI_H +#define CHEROKEE_HANDLER_AVAHI_H + +#include + +#include +#include + +#include +#include +#include +#include + +/* Data types + */ +typedef struct { + cherokee_module_props_t base; + + /* A table to store all our output */ + cherokee_avl_t entries; + + AvahiClient *client; + AvahiServiceBrowser *sb; + AvahiThreadedPoll *threaded_poll; + + /* Configuration parameters */ + cherokee_buffer_t service_type; +} cherokee_handler_avahi_props_t; + +typedef struct { + /* Shared structures */ + cherokee_handler_t handler; + + /* A buffer is your output 'to be' */ + cherokee_buffer_t buffer; + + enum { + send_page, + send_yourmother /* not advised but possible */ + } action; /* this could implement a state machine */ +} cherokee_handler_avahi_t; + +#define HDL_AVAHI(x) ((cherokee_handler_avahi_t *)(x)) +#define PROP_AVAHI(x) ((cherokee_handler_avahi_props_t *)(x)) +#define HDL_AVAHI_PROPS(x) (PROP_AVAHI(MODULE(x)->props)) + + +/* Library init function + */ +void PLUGIN_INIT_NAME(avahi) (cherokee_plugin_loader_t *loader); +ret_t cherokee_handler_avahi_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props); + +/* virtual methods implementation + */ +ret_t cherokee_handler_avahi_init (cherokee_handler_avahi_t *hdl); +ret_t cherokee_handler_avahi_free (cherokee_handler_avahi_t *hdl); +ret_t cherokee_handler_avahi_step (cherokee_handler_avahi_t *hdl, cherokee_buffer_t *buffer); +ret_t cherokee_handler_avahi_add_headers (cherokee_handler_avahi_t *hdl, cherokee_buffer_t *buffer); + +static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata); +static void resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata); +static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata); + +#endif /* CHEROKEE_HANDLER_AVAHI_H */ diff --git a/handler_example.c b/handler_example.c new file mode 100644 index 0000000..c31366e --- /dev/null +++ b/handler_example.c @@ -0,0 +1,199 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "handler_example.h" +#include + +/* +#include "util.h" +#include "connection.h" +#include "connection-protected.h" +#include "server.h" +#include "server-protected.h" +#include "plugin_loader.h" +#include "connection_info.h" +*/ + +/* Plug-in initialization + * + * In this function you can use any of these: + * http_delete | http_get | http_post | http_put + * + * For a full list: cherokee_http_method_t + * + * It is what your handler to be implements. + * + */ +PLUGIN_INFO_HANDLER_EASIEST_INIT (example, http_get); + + +/* Methods implementation + */ +static ret_t +props_free (cherokee_handler_example_props_t *props) +{ + return cherokee_module_props_free_base (MODULE_PROPS(props)); +} + + +ret_t +cherokee_handler_example_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) +{ + cherokee_list_t *i; + cherokee_handler_example_props_t *props; + + if (*_props == NULL) { + CHEROKEE_NEW_STRUCT (n, handler_example_props); + + cherokee_module_props_init_base (MODULE_PROPS(n), + MODULE_PROPS_FREE(props_free)); + + /* Look at handler_example.h + * This is an example of configuration. + */ + n->example_config = false; + + *_props = MODULE_PROPS(n); + } + + props = PROP_EXAMPLE(*_props); + + cherokee_config_node_foreach (i, conf) { + cherokee_config_node_t *subconf = CONFIG_NODE(i); + + if (equal_buf_str (&subconf->key, "example_config")) { + props->example_config = atoi(subconf->val.buf); + } else { + PRINT_MSG ("ERROR: Handler file: Unknown key: '%s'\n", subconf->key.buf); + return ret_error; + } + } + + return ret_ok; +} + +ret_t +cherokee_handler_example_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props) +{ + ret_t ret; + CHEROKEE_NEW_STRUCT (n, handler_example); + + /* Init the base class object + */ + cherokee_handler_init_base(HANDLER(n), cnt, HANDLER_PROPS(props), PLUGIN_INFO_HANDLER_PTR(example)); + + MODULE(n)->init = (handler_func_init_t) cherokee_handler_example_init; + MODULE(n)->free = (module_func_free_t) cherokee_handler_example_free; + HANDLER(n)->step = (handler_func_step_t) cherokee_handler_example_step; + HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_example_add_headers; + + HANDLER(n)->support = hsupport_length | hsupport_range; + + /* Init + */ + ret = cherokee_buffer_init (&n->buffer); + if (unlikely(ret != ret_ok)) + return ret; + + ret = cherokee_buffer_ensure_size (&n->buffer, 4*1024); + if (unlikely(ret != ret_ok)) + return ret; + + *hdl = HANDLER(n); + return ret_ok; +} + + +ret_t +cherokee_handler_example_free (cherokee_handler_example_t *hdl) +{ + cherokee_buffer_mrproper (&hdl->buffer); + return ret_ok; +} + +static void +example_build_page (cherokee_handler_example_t *hdl) +{ + ret_t ret; + cherokee_server_t *srv; + cherokee_buffer_t *buf; + + /* Init + */ + buf = &hdl->buffer; + srv = HANDLER_SRV(hdl); + + /* Useful output + */ + cherokee_buffer_add_str (buf, "Hello World"); + + /* But we did configure something! + */ + if (HDL_EXAMPLE_PROPS(hdl)->example_config) { + cherokee_buffer_add_str (buf, "!!!"); + } +} + +ret_t +cherokee_handler_example_init (cherokee_handler_example_t *hdl) +{ + ret_t ret; + void *param; + cint_t web_interface = 1; + + /* Build the page + */ + if (web_interface) { + example_build_page (hdl); + } + + hdl->action = send_page; + + return ret_ok; +} + + +ret_t +cherokee_handler_example_step (cherokee_handler_example_t *hdl, cherokee_buffer_t *buffer) +{ + cherokee_buffer_add_buffer (buffer, &hdl->buffer); + return ret_eof_have_data; +} + + +ret_t +cherokee_handler_example_add_headers (cherokee_handler_example_t *hdl, cherokee_buffer_t *buffer) +{ + cherokee_buffer_add_va (buffer, "Content-Length: %d"CRLF, hdl->buffer.len); + + switch (hdl->action) { + case send_page: + default: + cherokee_buffer_add_str (buffer, "Content-Type: text/html"CRLF); + break; + } + + return ret_ok; +} diff --git a/handler_example.h b/handler_example.h new file mode 100644 index 0000000..cbc5ddd --- /dev/null +++ b/handler_example.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef CHEROKEE_HANDLER_EXAMPLE_H +#define CHEROKEE_HANDLER_EXAMPLE_H + +/* +#include "common.h" +#include "buffer.h" +#include "handler.h" +#include "connection.h" +#include "plugin_loader.h" +*/ + +#include + +/* Data types + */ +typedef struct { + cherokee_module_props_t base; + + /* Configuration parameters */ + cherokee_boolean_t example_config; +} cherokee_handler_example_props_t; + +typedef struct { + /* Shared structures */ + cherokee_handler_t handler; + + /* A buffer is your output 'to be' */ + cherokee_buffer_t buffer; + + enum { + send_page, + send_yourmother /* not advised but possible */ + } action; /* this could implement a state machine */ +} cherokee_handler_example_t; + +#define HDL_EXAMPLE(x) ((cherokee_handler_example_t *)(x)) +#define PROP_EXAMPLE(x) ((cherokee_handler_example_props_t *)(x)) +#define HDL_EXAMPLE_PROPS(x) (PROP_EXAMPLE(MODULE(x)->props)) + + +/* Library init function + */ +void PLUGIN_INIT_NAME(example) (cherokee_plugin_loader_t *loader); +ret_t cherokee_handler_example_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props); + +/* virtual methods implementation + */ +ret_t cherokee_handler_example_init (cherokee_handler_example_t *hdl); +ret_t cherokee_handler_example_free (cherokee_handler_example_t *hdl); +ret_t cherokee_handler_example_step (cherokee_handler_example_t *hdl, cherokee_buffer_t *buffer); +ret_t cherokee_handler_example_add_headers (cherokee_handler_example_t *hdl, cherokee_buffer_t *buffer); + +#endif /* CHEROKEE_HANDLER_EXAMPLE_H */ diff --git a/handler_virt.c b/handler_virt.c new file mode 100644 index 0000000..8bb40e0 --- /dev/null +++ b/handler_virt.c @@ -0,0 +1,264 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "handler_virt.h" +#include "handler_avahi.h" +#include + +/* Plug-in initialization + * + * In this function you can use any of these: + * http_delete | http_get | http_post | http_put + * + * For a full list: cherokee_http_method_t + * + * It is what your handler to be implements. + * + */ +PLUGIN_INFO_HANDLER_EASIEST_INIT (virt, http_get | http_post); + + +/* Methods implementation + */ +static ret_t +props_free (cherokee_handler_virt_props_t *props) +{ + return cherokee_module_props_free_base (MODULE_PROPS(props)); +} + + +ret_t +cherokee_handler_virt_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props) +{ + cherokee_list_t *i; + cherokee_handler_virt_props_t *props; + + if (*_props == NULL) { + CHEROKEE_NEW_STRUCT (n, handler_virt_props); + + cherokee_module_props_init_base (MODULE_PROPS(n), + MODULE_PROPS_FREE(props_free)); + + /* Look at handler_virt.h + * This is an virt of configuration. + */ + + *_props = MODULE_PROPS(n); + } + + props = PROP_VIRT(*_props); + +// cherokee_config_node_foreach (i, conf) { +// cherokee_config_node_t *subconf = CONFIG_NODE(i); + +// if (equal_buf_str (&subconf->key, "virt_config")) { +// props->virt_config = atoi(subconf->val.buf); +// } +// } + + return cherokee_handler_avahi_configure (conf, srv, _props); +} + +ret_t +cherokee_handler_virt_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props) +{ + ret_t ret; + +// cherokee_handler_avahi_base_t *avahi; + + /* Create the new handler CGI object + */ + ret = cherokee_handler_avahi_new (hdl, cnt, props); + if (unlikely(ret != ret_ok)) + return ret; + +// avahi = HDL_AVAHI_BASE(*hdl); + + /* Redefine the init method + */ + + MODULE(*hdl)->init = (handler_func_init_t) cherokee_handler_virt_init; + + return ret_ok; +} + +static ret_t +while_func_entries (cherokee_buffer_t *key, void *value, void *param) { + virConnectPtr conn = NULL; + cherokee_buffer_t uri = CHEROKEE_BUF_INIT; + cherokee_buffer_t *buf = (cherokee_buffer_t *)param; + + cherokee_buffer_add_va (&uri, "xen://%s/", value); + + if (!(conn = virConnectOpenReadOnly (uri.buf))) { + return ret_error; + } else { + virDomainPtr dom; + if (!(dom = virDomainLookupByName(conn, (const char *) key->buf))) { + return ret_error; + } else { + char *xml = virDomainGetXMLDesc(dom, 0); + cherokee_buffer_add(buf, xml, strlen(xml)); + } + virConnectClose(conn); + } + + cherokee_buffer_mrproper(&uri); + + return ret_ok; +} + +static ret_t +virt_build_page (cherokee_handler_t *hdl) +{ + ret_t ret; + cherokee_buffer_t *buf; + cherokee_connection_t *conn; + char *user, *vm, *command, *arguments; + + enum { + not_implemented = -1, + nothing = 0, + domainGetXMLDesc, + domainGetName + } actions; + + /* Init + */ + buf = &HDL_AVAHI(hdl)->buffer; + conn = HANDLER_CONN(hdl); + + /* Useful output + */ + + { + cherokee_buffer_t *dup; + cherokee_buffer_dup(&conn->request, &dup); + char *token = dup->buf; + actions = nothing; +// *token++; + +// printf("%s\n", token); + + token = strtok(dup->buf, "/"); + + if (!(user = strtok(NULL, "/"))) { + conn->error_code = http_bad_request; + cherokee_buffer_mrproper(dup); + return ret_error; + } + if (!(vm = strtok(NULL, "/"))) { + conn->error_code = http_bad_request; + cherokee_buffer_mrproper(dup); + return ret_error; + } + + if (!(command = strtok(NULL, "/"))) { + conn->error_code = http_bad_request; + cherokee_buffer_mrproper(dup); + return ret_error; + } else { + actions = not_implemented; + if (strcmp(command, "virDomainGetXMLDesc") == 0) actions = domainGetXMLDesc; + if (strcmp(command, "virDomainGetName") == 0) actions = domainGetName; + } + + + if (actions == not_implemented) { + conn->error_code = http_not_implemented; + return ret_error; + } + + if (actions != nothing) { + virConnectPtr virConn = NULL; + char *host_name = NULL; + cherokee_buffer_t domu = CHEROKEE_BUF_INIT; + cherokee_buffer_t uri = CHEROKEE_BUF_INIT; + cherokee_buffer_add_va(&domu, "%s_%s", user, vm); + + /* First, block the event loop */ + avahi_threaded_poll_lock(HDL_AVAHI_PROPS(hdl)->threaded_poll); + + /* Than, do your stuff */ + cherokee_avl_get_ptr(&HDL_AVAHI_PROPS(hdl)->entries, domu.buf, &host_name); + cherokee_buffer_add_va (&uri, "xen://%s/", host_name); + printf("%s\n", uri.buf); + + /* Finally, unblock the event loop */ + avahi_threaded_poll_unlock(HDL_AVAHI_PROPS(hdl)->threaded_poll); + + if (!(virConn = virConnectOpenReadOnly (uri.buf))) { + conn->error_code = http_service_unavailable; + return ret_error; + } else { + virDomainPtr dom; + if (!(dom = virDomainLookupByName(virConn, domu.buf))) { + conn->error_code = http_not_found; + return ret_error; + } else { + switch (actions) { + case domainGetXMLDesc: { + char *xml = virDomainGetXMLDesc(dom, 0); + cherokee_buffer_add(buf, xml, strlen(xml)); + break; + } + case domainGetName: { + const char *name = virDomainGetName (dom); + cherokee_buffer_add(buf, name, strlen(name)); + break; + } + } + } + virConnectClose(virConn); + } + cherokee_buffer_mrproper(&domu); + cherokee_buffer_mrproper(&uri); + } + + cherokee_buffer_mrproper(dup); + + } + + return ret_ok; +} + +ret_t +cherokee_handler_virt_init (cherokee_handler_t *hdl) +{ + ret_t ret; + void *param; + cint_t web_interface = 1; + + /* Build the page + */ + if (web_interface) { + if ((ret = virt_build_page (hdl)) != ret_ok) + return ret; + } + + HDL_AVAHI(hdl)->action = send_page; + + return ret_ok; +} diff --git a/handler_virt.h b/handler_virt.h new file mode 100644 index 0000000..e58ebc8 --- /dev/null +++ b/handler_virt.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* Cherokee + * + * Authors: + * Alvaro Lopez Ortega + * Stefan de Konink + * + * Copyright (C) 2001-2008 Alvaro Lopez Ortega + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef CHEROKEE_HANDLER_VIRT_H +#define CHEROKEE_HANDLER_VIRT_H + +/* +#include "common.h" +#include "buffer.h" +#include "handler.h" +#include "connection.h" +#include "plugin_loader.h" +*/ + +#include +#include +#include "handler_avahi.h" + +/* Data types + */ +typedef struct { + cherokee_handler_avahi_props_t base; + + /* Configuration parameters */ +} cherokee_handler_virt_props_t; + +#define HDL_VIRT(x) ((cherokee_handler_virt_t *)(x)) +#define PROP_VIRT(x) ((cherokee_handler_virt_props_t *)(x)) +#define HDL_VIRT_PROPS(x) (PROP_VIRT(MODULE(x)->props)) + +/* Library init function + */ +void PLUGIN_INIT_NAME(virt) (cherokee_plugin_loader_t *loader); +ret_t cherokee_handler_virt_new (cherokee_handler_t **hdl, cherokee_connection_t *cnt, cherokee_module_props_t *props); + +/* virtual methods implementation + */ +ret_t cherokee_handler_virt_init (cherokee_handler_t *hdl); + +#endif /* CHEROKEE_HANDLER_VIRT_H */ -- 2.11.4.GIT