/* Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved. */ #include #include #include #include #include #include #include typedef unsigned char u_char; #include #include "cmsg_private.h" #include "harness.h" #include "net.h" #include "ref.h" #include "sexp.h" #include "hashtable.h" #include "node.h" #include "queue.h" #include "direct.h" #include "fanout.h" #include "relay.h" #include "meta.h" #include "messages.h" #include "sexpio.h" #define WANT_CONSOLE_LISTENER 1 static void factory_handle_message(node_t *n, sexp_t *m) { parsed_message_t p; if (parse_create(m, &p)) { if (sexp_stringp(p.create.classname) && sexp_stringp(p.create.reply_sink) && sexp_stringp(p.create.reply_name)) { cmsg_bytes_t classname_bytes = sexp_data(p.create.classname); node_class_t *nc = lookup_node_class(classname_bytes); if (nc == NULL) { warn("Node class not found <<%.*s>>\n", classname_bytes.len, classname_bytes.bytes); } else { sexp_t *error = NULL; sexp_t *reply; if (new_node(nc, p.create.arg, &error) != NULL) { reply = message_create_ok(NULL); } else { reply = message_create_failed(error); } post_node(sexp_data(p.create.reply_sink), sexp_data(p.create.reply_name), reply, sexp_empty_bytes); } } return; } warn("Message not understood in factory: "); sexp_writeln(stderr_h, m); } static node_class_t factory_class = { .name = "factory", .extend = NULL, .destroy = NULL, .handle_message = factory_handle_message }; static void init_factory(void) { bind_node(cmsg_cstring_bytes("factory"), new_node(&factory_class, NULL, NULL)); } #if WANT_CONSOLE_LISTENER static void console_listener(void *arg) { IOHandle *in_handle = new_iohandle(0); while (1) { cmsg_bytes_t buf = iohandle_readwait(in_handle, 1); if (buf.len == 0) break; iohandle_drain(in_handle, buf.len); } delete_iohandle(in_handle); interrupt_harness(); } #endif int main(int argc, char *argv[]) { info("cmsg ALPHA, Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved.\n"); event_init(); signal(SIGPIPE, SIG_IGN); /* avoid EPIPE when connections drop unexpectedly */ info("Using libevent version %s\n", event_get_version()); init_sexp(); init_messages(); init_node(cmsg_cstring_bytes("server")); init_factory(); init_queue(); init_direct(); init_fanout(); init_relay(); init_meta(); #if WANT_CONSOLE_LISTENER spawn(console_listener, NULL); #endif start_net(5671); boot_harness(); done_sexp(); return 0; }