// Apply configuration tree: // * apply server configuration // * print any echo items in top-level sections // * apply sections that match methods static void server_apply_config (server_t *self) { // Apply echo commands and class methods zconfig_t *section = zconfig_child (self->config); while (section) { zconfig_t *entry = zconfig_child (section); while (entry) { if (streq (zconfig_name (entry), "echo")) zclock_log (zconfig_value (entry)); entry = zconfig_next (entry); } if (streq (zconfig_name (section), "bind")) { char *endpoint = zconfig_resolve (section, "endpoint", "?"); self->port = zsocket_bind (self->router, endpoint); } else if (streq (zconfig_name (section), "publish")) { char *location = zconfig_resolve (section, "location", "?"); char *alias = zconfig_resolve (section, "alias", "?"); mount_t *mount = mount_new (location, alias); zlist_append (self->mounts, mount); } else if (streq (zconfig_name (section), "set_anonymous")) { long enabled = atoi (zconfig_resolve (section, "enabled", "")); // Enable anonymous access without a config file zconfig_put (self->config, "security/anonymous", enabled? "1" :"0"); } section = zconfig_next (section); } server_config_self (self); }
curvezmq_keypair_t * curvezmq_keypair_load (void) { curvezmq_keypair_t *self = (curvezmq_keypair_t *) zmalloc (sizeof (curvezmq_keypair_t)); int matches = 0; // How many key octets we parsed zconfig_t *root = zconfig_load ("secret.key"); if (root) { char *secret_key = zconfig_resolve (root, "secret-key", NULL); if (secret_key) { int byte_nbr; for (byte_nbr = 0; byte_nbr < 32; byte_nbr++) matches += sscanf (secret_key + byte_nbr * 2, "%02hhX ", &self->secret_key [byte_nbr]); } char *public_key = zconfig_resolve (root, "public-key", NULL); if (public_key) { int byte_nbr; for (byte_nbr = 0; byte_nbr < 32; byte_nbr++) matches += sscanf (public_key + byte_nbr * 2, "%02hhX ", &self->public_key [byte_nbr]); } } if (matches != 64) curvezmq_keypair_destroy (&self); zconfig_destroy (&root); return self; }
static void list_security_mechanisms (server_t *self, client_t *client) { if (atoi (zconfig_resolve (self->config, "security/anonymous", "0")) == 1) fmq_msg_mechanisms_append (client->reply, "ANONYMOUS"); if (atoi (zconfig_resolve (self->config, "security/plain", "0")) == 1) fmq_msg_mechanisms_append (client->reply, "PLAIN"); }
static void server_config_self (server_t *self) { // Get standard server configuration self->monitor = atoi ( zconfig_resolve (self->config, "server/monitor", "1")) * 1000; self->heartbeat = atoi ( zconfig_resolve (self->config, "server/heartbeat", "1")) * 1000; self->monitor_at = zclock_time () + self->monitor; }
static void try_anonymous_access (server_t *self, client_t *client) { if (atoi (zconfig_resolve (self->config, "security/anonymous", "0")) == 1) client->next_event = friend_event; else if (atoi (zconfig_resolve (self->config, "security/plain", "0")) == 1) client->next_event = maybe_event; else client->next_event = foe_event; }
hydra_post_t * hydra_post_load (const char *filename) { assert (filename); zconfig_t *root = zconfig_loadf ("posts/%s", filename); if (!root) return NULL; // No such file hydra_post_t *self = NULL; char *ident = zconfig_resolve (root, "/post/ident", ""); char *subject = zconfig_resolve (root, "/post/subject", NULL); char *timestamp = zconfig_resolve (root, "/post/timestamp", NULL); char *parent_id = zconfig_resolve (root, "/post/parent-id", ""); char *mime_type = zconfig_resolve (root, "/post/mime-type", NULL); char *digest = zconfig_resolve (root, "/post/digest", NULL); char *location = zconfig_resolve (root, "/post/location", NULL); if (subject && timestamp && mime_type && digest && location && (strlen (ident) == ID_SIZE) && (strlen (parent_id) == 0 || strlen (parent_id) == ID_SIZE) && (strlen (timestamp) == 20) && (strlen (digest) == ID_SIZE)) { self = hydra_post_new (subject); strcpy (self->ident, ident); strcpy (self->timestamp, timestamp); strcpy (self->parent_id, parent_id); self->mime_type = strdup (mime_type); self->location = strdup (location); strcpy (self->digest, digest); self->content_size = atoll (zconfig_resolve (root, "/post/content-size", "0")); zchunk_destroy (&self->content); } zconfig_destroy (&root); return self; }
static zsock_t* subscriber_pull_socket_new(zconfig_t* config) { zsock_t *socket = zsock_new(ZMQ_PULL); assert(socket); zsock_set_linger(socket, 0); zsock_set_reconnect_ivl(socket, 100); // 100 ms zsock_set_reconnect_ivl_max(socket, 10 * 1000); // 10 s char *pull_spec = zconfig_resolve(config, "frontend/endpoints/subscriber/pull", "tcp://*"); char *full_spec = augment_zmq_connection_spec(pull_spec, pull_port); if (!quiet) printf("[I] subscriber: binding PULL socket to %s\n", full_spec); int rc = zsock_bind(socket, "%s", full_spec); assert(rc != -1); free(full_spec); const char *inproc_binding = "inproc://subscriber-pull"; if (!quiet) printf("[I] subscriber: binding PULL socket to %s\n", inproc_binding); rc = zsock_bind(socket, "%s", inproc_binding); assert(rc != -1); return socket; }
void zconfig_test (bool verbose) { printf (" * zconfig: "); // @selftest // Create temporary directory for test files # define TESTDIR ".test_zconfig" zsys_dir_create (TESTDIR); zconfig_t *root = zconfig_new ("root", NULL); zconfig_t *section, *item; section = zconfig_new ("headers", root); item = zconfig_new ("email", section); zconfig_set_value (item, "*****@*****.**"); item = zconfig_new ("name", section); zconfig_set_value (item, "Justin Kayce"); zconfig_put (root, "/curve/secret-key", "Top Secret"); zconfig_set_comment (root, " CURVE certificate"); zconfig_set_comment (root, " -----------------"); assert (zconfig_comments (root)); zconfig_save (root, TESTDIR "/test.cfg"); zconfig_destroy (&root); root = zconfig_load (TESTDIR "/test.cfg"); if (verbose) zconfig_save (root, "-"); char *email = zconfig_resolve (root, "/headers/email", NULL); assert (email); assert (streq (email, "*****@*****.**")); char *passwd = zconfig_resolve (root, "/curve/secret-key", NULL); assert (passwd); assert (streq (passwd, "Top Secret")); zconfig_save (root, TESTDIR "/test.cfg"); zconfig_destroy (&root); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end printf ("OK\n"); }
zcert_t * zcert_load (char *format, ...) { #if (ZMQ_VERSION_MAJOR == 4) assert (format); va_list argptr; va_start (argptr, format); char *filename = zsys_vprintf (format, argptr); va_end (argptr); // Try first to load secret certificate, which has both keys // Then fallback to loading public certificate char filename_secret [256]; snprintf (filename_secret, 256, "%s_secret", filename); zconfig_t *root = zconfig_load (filename_secret); if (!root) root = zconfig_load (filename); zcert_t *self = NULL; if (root) { char *public_text = zconfig_resolve (root, "/curve/public-key", NULL); char *secret_text = zconfig_resolve (root, "/curve/secret-key", NULL); if (public_text && strlen (public_text) == 40) { byte public_key [32] = { 0 }; byte secret_key [32] = { 0 }; zmq_z85_decode (public_key, public_text); if (secret_text && strlen (secret_text) == 40) zmq_z85_decode (secret_key, secret_text); // Load metadata into certificate self = zcert_new_from (public_key, secret_key); zconfig_t *metadata = zconfig_locate (root, "/metadata"); zconfig_t *item = metadata? zconfig_child (metadata): NULL; while (item) { zcert_set_meta (self, zconfig_name (item), zconfig_value (item)); item = zconfig_next (item); } } } zconfig_destroy (&root); zstr_free (&filename); return self; #else return NULL; #endif }
static zsock_t* subscriber_sub_socket_new(subscriber_state_t *state) { zsock_t *socket = zsock_new(ZMQ_SUB); assert(socket); zsock_set_rcvhwm(socket, state->rcv_hwm); // set subscription if (!state->subscriptions || zlist_size(state->subscriptions) == 0) { if (!state->subscriptions) state->subscriptions = zlist_new(); zlist_append(state->subscriptions, zconfig_resolve(state->config, "/logjam/subscription", "")); } char *subscription = zlist_first(state->subscriptions); bool subscribed_to_all = false; while (subscription) { printf("[I] subscriber: subscribing to '%s'\n", subscription); if (streq(subscription, "")) subscribed_to_all = true; zsock_set_subscribe(socket, subscription); subscription = zlist_next(state->subscriptions); } if (!subscribed_to_all) zsock_set_subscribe(socket, "heartbeat"); if (!state->devices || zlist_size(state->devices) == 0) { // convert config file to list of devices if (!state->devices) state->devices = zlist_new(); zconfig_t *endpoints = zconfig_locate(state->config, "/logjam/endpoints"); if (!endpoints) { zlist_append(state->devices, "tcp://localhost:9606"); } else { zconfig_t *endpoint = zconfig_child(endpoints); while (endpoint) { char *spec = zconfig_value(endpoint); char *new_spec = augment_zmq_connection_spec(spec, 9606); zlist_append(state->devices, new_spec); endpoint = zconfig_next(endpoint); } } } char* device = zlist_first(state->devices); while (device) { printf("[I] subscriber: connecting SUB socket to logjam-device via %s\n", device); int rc = zsock_connect(socket, "%s", device); log_zmq_error(rc, __FILE__, __LINE__); assert(rc == 0); device = zlist_next(state->devices); } return socket; }
static void try_security_mechanism (server_t *self, client_t *client) { client->next_event = foe_event; char *login, *password; if (streq (fmq_msg_mechanism (client->request), "PLAIN") && fmq_sasl_plain_decode (fmq_msg_response (client->request), &login, &password) == 0) { zconfig_t *account = zconfig_locate (self->config, "security/plain/account"); while (account) { if (streq (zconfig_resolve (account, "login", ""), login) && streq (zconfig_resolve (account, "password", ""), password)) { client->next_event = friend_event; break; } account = zconfig_next (account); } } free (login); free (password); }
static zsock_t* subscriber_pub_socket_new(zconfig_t* config) { zsock_t *socket = zsock_new(ZMQ_PUB); assert(socket); zsock_set_sndhwm(socket, 10000); char *pub_spec = zconfig_resolve(config, "frontend/endpoints/subscriber/pub", "tcp://127.0.0.1:9651"); if (!quiet) printf("[I] subscriber: binding PUB socket to %s\n", pub_spec); int rc = zsock_bind(socket, "%s", pub_spec); assert(rc != -1); return socket; }
int main(int argc, char * const *argv) { setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0); process_arguments(argc, argv); // load config if (!zsys_file_exists(config_file_name)) { fprintf(stderr, "[W] missing config file: %s\n", config_file_name); config = zconfig_new("", NULL); } else if (zsys_file_exists(config_file_name)) { // load config config_file_init(); config = zconfig_load((char*)config_file_name); } // configure graylog endpoint if (interface == NULL) interface = zconfig_resolve(config, "/graylog/endpoint", DEFAULT_INTERFACE); // set inbound high-water-mark if (rcv_hwm == -1) rcv_hwm = atoi(zconfig_resolve(config, "/logjam/high_water_mark", DEFAULT_RCV_HWM_STR)); // set outbound high-water-mark if (snd_hwm == -1) snd_hwm = atoi(zconfig_resolve(config, "/graylog/high_water_mark", DEFAULT_SND_HWM_STR)); if (!quiet) printf("[I] started %s\n" "[I] interface %s\n" "[I] rcv-hwm: %d\n" "[I] snd-hwm: %d\n" , argv[0], interface, rcv_hwm, snd_hwm); return graylog_forwarder_run_controller_loop(config, hosts, subscriptions, rcv_hwm, snd_hwm); }
static zsock_t* subscriber_router_socket_new(zconfig_t* config) { zsock_t *socket = zsock_new(ZMQ_ROUTER); assert(socket); zsock_set_linger(socket, 0); zsock_set_reconnect_ivl(socket, 100); // 100 ms zsock_set_reconnect_ivl_max(socket, 10 * 1000); // 10 s char *router_spec = zconfig_resolve(config, "frontend/endpoints/subscriber/router", "tcp://*"); char *full_spec = augment_zmq_connection_spec(router_spec, router_port); if (!quiet) printf("[I] subscriber: binding ROUTER socket to %s\n", full_spec); int rc = zsock_bind(socket, "%s", full_spec); assert(rc != -1); free(full_spec); return socket; }
void zconfig_test (bool verbose) { printf (" * zconfig: "); // @selftest // We create a config of this structure: // // root // type = zqueue // frontend // option // swap = 25000000 # 25MB // subscribe = #2 // hwm = 1000 // bind = tcp://*:5555 // backend // bind = tcp://*:5556 // zconfig_t *root, *type, *frontend, *option, *hwm, *swap, *subscribe, *bind, *backend; // Left is first child, next is next sibling root = zconfig_new ("root", NULL); type = zconfig_new ("type", root); zconfig_value_set (type, "zqueue"); frontend = zconfig_new ("frontend", root); option = zconfig_new ("option", frontend); swap = zconfig_new ("swap", option); zconfig_value_set (swap, "25000000"); subscribe = zconfig_new ("subscribe", option); zconfig_value_format (subscribe, "#%d", 2); hwm = zconfig_new ("hwm", option); zconfig_value_set (hwm, "1000"); bind = zconfig_new ("bind", frontend); zconfig_value_set (bind, "tcp://*:5555"); backend = zconfig_new ("backend", root); bind = zconfig_new ("bind", backend); zconfig_value_set (bind, "tcp://*:5556"); assert (atoi (zconfig_resolve (root, "frontend/option/hwm", "0")) == 1000); assert (streq (zconfig_resolve (root, "backend/bind", ""), "tcp://*:5556")); zconfig_path_set (root, "frontend/option/hwm", "500"); assert (atoi (zconfig_resolve (root, "frontend/option/hwm", "0")) == 500); zconfig_path_set (root, "frontend/option/lwm", "200"); assert (atoi (zconfig_resolve (root, "frontend/option/lwm", "0")) == 200); zconfig_destroy (&root); assert (root == NULL); // Test loading from a ZPL file zconfig_t *config = zconfig_load ("selftest.cfg"); assert (config); // Destructor should be safe to call twice zconfig_destroy (&config); zconfig_destroy (&config); assert (config == NULL); // @end printf ("OK\n"); }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; if (argn < argc && streq (argv [argn], "-h")) { puts ("syntax: hydrad [ directory ]"); puts (" -- defaults to .hydra in current directory"); exit (0); } if (argn < argc && streq (argv [argn], "-v")) { verbose = true; argn++; } // By default, current node runs in .hydra directory; create this if // it's missing (don't create directory passed as argument); char *workdir = ".hydra"; if (argn < argc) workdir = argv [argn++]; else zsys_dir_create (workdir); // ---------------------------------------------------------------------- // This code eventually goes into a reusable hydra actor class // Switch to working directory zsys_info ("hydrad: data store in %s directory", workdir); if (zsys_dir_change (workdir)) { zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno)); return 1; } // Check we are the only process currently running here if (zsys_run_as ("hydrad.lock", NULL, NULL)) { zsys_error ("hydrad: cannot start process safely, exiting"); return 1; } // Get node identity from config file, or generate new identity zconfig_t *config = zconfig_load ("hydra.cfg"); if (!config) { // Set defaults for Hydra service config = zconfig_new ("root", NULL); zconfig_put (config, "/server/timeout", "5000"); zconfig_put (config, "/server/background", "0"); zconfig_put (config, "/server/verbose", "0"); } char *identity = zconfig_resolve (config, "/hydra/identity", NULL); if (!identity) { zuuid_t *uuid = zuuid_new (); zconfig_put (config, "/hydra/identity", zuuid_str (uuid)); zconfig_put (config, "/hydra/nickname", "Anonymous"); zconfig_save (config, "hydra.cfg"); zuuid_destroy (&uuid); } // Create store structure, if necessary zsys_dir_create ("content"); zsys_dir_create ("posts"); // Start server and bind to ephemeral TCP port. We can run many // servers on the same box, for testing. zactor_t *server = zactor_new (hydra_server, NULL); if (verbose) zstr_send (server, "VERBOSE"); // Bind Hydra service to ephemeral port and get that port number char *command; int port_nbr; zsock_send (server, "ss", "CONFIGURE", "hydra.cfg"); zsock_send (server, "ss", "BIND", "tcp://*:*"); zsock_send (server, "s", "PORT"); zsock_recv (server, "si", &command, &port_nbr); zsys_info ("hydrad: TCP server started on port=%d", port_nbr); assert (streq (command, "PORT")); free (command); // We're going to use Zyre for discovery and presence, and our own // Hydra protocol for content exchange zyre_t *zyre = zyre_new (NULL); if (verbose) zyre_set_verbose (zyre); char *hostname = zsys_hostname (); char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr); zyre_set_header (zyre, "X-HYDRA", "%s", endpoint); zstr_free (&endpoint); zstr_free (&hostname); if (zyre_start (zyre)) { zsys_info ("hydrad: can't start Zyre discovery service"); zactor_destroy (&server); zyre_destroy (&zyre); return 1; } // When we get a new peer, handle it zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (zyre)) { zyre_event_t *event = zyre_event_new (zyre); if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { zsys_debug ("hydrad: new peer name=%s endpoint=%s", zyre_event_name (event), zyre_event_header (event, "X-HYDRA")); s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose); } zyre_event_destroy (&event); } else break; } zsys_info ("hydrad: shutting down..."); zpoller_destroy (&poller); // Shutdown all services zactor_destroy (&server); zyre_destroy (&zyre); zconfig_destroy (&config); return 0; }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; bool force_foreground = false; if (argc > argn && streq (argv [argn], "-v")) { verbose = true; argn++; } if (argc > argn && streq (argv [argn], "-f")) { force_foreground = true; argn++; } if (argc > argn && streq (argv [argn], "-h")) { puts ("Usage: malamute [ -v ] [ -f ] [ -h | config-file ]"); puts (" Default config-file is 'malamute.cfg'"); return 0; } // Collect configuration file name const char *config_file = "malamute.cfg"; if (argc > argn) { config_file = argv [argn]; argn++; } // Send logging to system facility as well as stdout zsys_init (); zsys_set_logsystem (true); zsys_set_pipehwm (0); zsys_set_sndhwm (0); zsys_set_rcvhwm (0); // Load config file for our own use here zsys_info ("starting Malamute using config in '%s'", config_file); zconfig_t *config = zconfig_load (config_file); if (config) { // Do we want to run broker in the background? int as_daemon = !force_foreground && atoi (zconfig_resolve (config, "server/background", "0")); const char *workdir = zconfig_resolve (config, "server/workdir", "."); if (as_daemon) { zsys_info ("switching Malamute to background..."); if (zsys_daemonize (workdir)) return -1; } // Switch to user/group to run process under, if any if (zsys_run_as ( zconfig_resolve (config, "server/lockfile", NULL), zconfig_resolve (config, "server/group", NULL), zconfig_resolve (config, "server/user", NULL))) return -1; } else { zsys_error ("cannot load config file '%s'\n", config_file); return 1; } // Install authenticator (NULL or PLAIN) zactor_t *auth = zactor_new (zauth, NULL); assert (auth); if (verbose || atoi (zconfig_resolve (config, "server/auth/verbose", "0"))) { zstr_sendx (auth, "VERBOSE", NULL); zsock_wait (auth); } // Do PLAIN password authentication if requested const char *passwords = zconfig_resolve (config, "server/auth/plain", NULL); if (passwords) { zstr_sendx (auth, "PLAIN", passwords, NULL); zsock_wait (auth); } // Start Malamute server instance zactor_t *server = zactor_new (mlm_server, "Malamute"); if (verbose) zstr_send (server, "VERBOSE"); zstr_sendx (server, "LOAD", config_file, NULL); // Accept and print any message back from server while (true) { char *message = zstr_recv (server); if (message) { puts (message); free (message); } else { puts ("interrupted"); break; } } // Shutdown all services zactor_destroy (&server); zactor_destroy (&auth); // Destroy config tree zconfig_destroy (&config); return 0; }
static int server_join_cluster (server_t *self) { self->zyre = zyre_new (zconfig_resolve (self->config, "zyre/name", NULL)); // Get Zyre configuration properties char *value = zconfig_resolve (self->config, "zyre/discovery", "beacon"); if (streq (value, "beacon")) { // Set-up UDP beacon discovery zsys_info ("using UDP beacon discovery service"); value = zconfig_resolve (self->config, "zyre/beacon/interface", "auto"); if (strneq (value, "auto")) { zsys_info ("forcing cluster interface to %s", value); zyre_set_interface (self->zyre, value); } value = zconfig_resolve (self->config, "zyre/beacon/interval", NULL); if (value) zyre_set_interval (self->zyre, atoi (value)); value = zconfig_resolve (self->config, "zyre/beacon/port", NULL); if (value) { zsys_info ("UDP beaconing on port %s", value); zyre_set_port (self->zyre, atoi (value)); } } else if (streq (value, "gossip")) { // Set-up TCP gossip discovery zsys_info ("using TCP gossip discovery service"); zconfig_t *section = zconfig_locate (self->config, "zyre/gossip"); if (!section) { zsys_warning ("please configure zyre/gossip section"); return -1; } zconfig_t *entry = zconfig_child (section); while (entry) { char *name = zconfig_name (entry); char *value = zconfig_value (entry); if (streq (name, "endpoint")) { zsys_info ("Zyre node endpoint=%s", value); zyre_set_endpoint (self->zyre, "%s", value); } else if (streq (name, "bind")) { zsys_info ("gossip service bind to %s", value); zyre_gossip_bind (self->zyre, "%s", value); } else if (streq (name, "connect")) { zsys_info ("gossip service connect to %s", value); zyre_gossip_connect (self->zyre, "%s", value); } else zsys_warning ("unknown zyre/gossip entry '%s' ignored", name); entry = zconfig_next (entry); } } else { zsys_error ("bad zyre/discovery=%s (use beacon|gossip)", value); assert (0); } if (zyre_start (self->zyre)) { zsys_warning ("clustering not working"); return -1; // Can't join cluster } zyre_join (self->zyre, "ZPIPES"); // Get Zyre public name for logging self->name = strdup (zyre_name (self->zyre)); zsys_info ("joining cluster as %s", self->name); // Set-up reader for Zyre events engine_handle_socket (self, zyre_socket (self->zyre), zyre_handler); return 0; }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; bool force_foreground = false; if (argc > argn && streq (argv [argn], "-v")) { verbose = true; argn++; } if (argc > argn && streq (argv [argn], "-f")) { force_foreground = true; argn++; } if (argc > argn && streq (argv [argn], "-h")) { puts ("Usage: malamute [ -v ] [ -f ] [ -h | config-file ]"); puts (" Default config-file is 'malamute.cfg'"); return 0; } // Collect configuration file name const char *config_file = "malamute.cfg"; if (argc > argn) { config_file = argv [argn]; argn++; } zsys_init (); // Keep old behavior unless specified otherwise. if (!getenv ("ZSYS_LOGSYSTEM")) { zsys_set_logsystem(true); } zsys_set_pipehwm (0); zsys_set_sndhwm (0); zsys_set_rcvhwm (0); // Load config file for our own use here zsys_info ("loading configuration from '%s'...", config_file); zconfig_t *config = zconfig_load (config_file); if (!config) { zsys_info ("'%s' is missing, creating with defaults:", config_file); config = zconfig_new ("root", NULL); zconfig_put (config, "server/timeout", "5000"); zconfig_put (config, "server/background", "0"); zconfig_put (config, "server/workdir", "."); zconfig_put (config, "server/verbose", "0"); zconfig_put (config, "mlm_server/security/mechanism", "null"); zconfig_put (config, "mlm_server/bind/endpoint", MLM_DEFAULT_ENDPOINT); zconfig_print (config); zconfig_save (config, config_file); } // Do we want to run broker in the background? int as_daemon = !force_foreground && atoi (zconfig_resolve (config, "server/background", "0")); const char *workdir = zconfig_resolve (config, "server/workdir", "."); if (as_daemon) { zsys_info ("switching Malamute to background..."); if (zsys_daemonize (workdir)) return -1; } // Switch to user/group to run process under, if any if (zsys_run_as ( zconfig_resolve (config, "server/lockfile", NULL), zconfig_resolve (config, "server/group", NULL), zconfig_resolve (config, "server/user", NULL))) return -1; // Install authenticator (NULL or PLAIN) zactor_t *auth = zactor_new (zauth, NULL); assert (auth); if (verbose || atoi (zconfig_resolve (config, "server/auth/verbose", "0"))) { zstr_sendx (auth, "VERBOSE", NULL); zsock_wait (auth); } // Do PLAIN password authentication if requested const char *passwords = zconfig_resolve (config, "server/auth/plain", NULL); if (passwords) { zstr_sendx (auth, "PLAIN", passwords, NULL); zsock_wait (auth); } // Start Malamute server instance zactor_t *server = zactor_new (mlm_server, "Malamute"); if (verbose) zstr_send (server, "VERBOSE"); zstr_sendx (server, "LOAD", config_file, NULL); // Accept and print any message back from server while (true) { char *message = zstr_recv (server); if (message) { puts (message); free (message); } else { puts ("interrupted"); break; } } // Shutdown all services zactor_destroy (&server); zactor_destroy (&auth); // Destroy config tree zconfig_destroy (&config); #if defined (__WINDOWS__) zsys_shutdown (); #endif return 0; }
bool GlobalServerStartupInfo_init ( GlobalServerStartupInfo *self, char *confFilePath ) { memset (self, 0, sizeof (GlobalServerStartupInfo)); bool result = true; zconfig_t *conf = NULL; char *portsArray = NULL; // =================================== // Read Global configuration // =================================== // Open the configuration file if (!(conf = zconfig_load (confFilePath))) { error ("Cannot read the global configuration file (%s).", confFilePath); result = false; goto cleanup; } // Read the CLI serverIP if (!(self->ip = strdup (zconfig_resolve (conf, "globalServer/serverIP", NULL))) ) { warning ("Cannot read correctly the CLI serverIP in the configuration file (%s). ", confFilePath); warning ("The default serverIP = %s has been used.", GLOBAL_SERVER_CLI_IP_DEFAULT); self->ip = GLOBAL_SERVER_CLI_IP_DEFAULT; } // Read the CLI port if (!(self->cliPort = atoi (zconfig_resolve (conf, "globalServer/port", NULL))) ) { warning ("Cannot read correctly the CLI port in the configuration file (%s). ", confFilePath); warning ("The default port = %d has been used.", GLOBAL_SERVER_CLI_PORT_DEFAULT); self->cliPort = GLOBAL_SERVER_CLI_PORT_DEFAULT; } // =================================== // Read Zone configuration // =================================== // Read the zone ports array if (!(portsArray = zconfig_resolve (conf, "zoneServer/portsArray", NULL))) { warning ("Public Zone ports cannot be read for Global Server. Defaults ports have been used : %s", ZONE_SERVER_PORTS_DEFAULT); portsArray = ZONE_SERVER_PORTS_DEFAULT; } // Tokenize the ports array char *port = strtok (portsArray, " "); while (port != NULL) { self->zoneServersCount++; port = strtok (NULL, " "); } if (self->zoneServersCount == 0) { error ("Cannot read correctly the zone ports array."); result = false; goto cleanup; } // Fill the server ports array self->zoneServersPorts = calloc (self->zoneServersCount, sizeof (int)); for (int portIndex = 0; portIndex < self->zoneServersCount; portIndex++) { self->zoneServersPorts[portIndex] = strtoul (portsArray, &portsArray, 10); portsArray++; } // Read the number of zone workers if (!(self->zoneWorkersCount = atoi (zconfig_resolve (conf, "zoneServer/workersCount", NULL)))) { warning ("Cannot read correctly the zone workers count in the configuration file (%s). ", confFilePath); warning ("The default worker count = %d has been used.", ZONE_SERVER_WORKERS_COUNT_DEFAULT); self->zoneWorkersCount = ZONE_SERVER_WORKERS_COUNT_DEFAULT; } char *zoneServersIp; // Read the zone server interfaces IP if (!(zoneServersIp = zconfig_resolve (conf, "zoneServer/serversIP", NULL))) { error ("Cannot read correctly the zone servers interface IP in the configuration file (%s). ", confFilePath); result = false; goto cleanup; } int nbZoneServersIp = 0; char *routerIp = strtok (zoneServersIp, " "); while (routerIp != NULL) { routerIp = strtok (NULL, " "); nbZoneServersIp++; } if (nbZoneServersIp != self->zoneServersCount) { error ("Number of zone ports different from the number of zone interfaces IP. (%d / %d)", nbZoneServersIp, self->zoneServersCount ); result = false; goto cleanup; } // Fill the zone server IPs array self->zoneServersIp = calloc (self->zoneServersCount, sizeof (char *)); for (int ipIndex = 0; ipIndex < self->zoneServersCount; ipIndex++) { self->zoneServersIp[ipIndex] = strdup (zoneServersIp); zoneServersIp += strlen (zoneServersIp) + 1; } // =================================== // Read Social configuration // =================================== // Read the social ports array if (!(portsArray = zconfig_resolve (conf, "socialServer/portsArray", NULL))) { warning ("Public Social ports cannot be read for Global Server. Defaults ports have been used : %s", SOCIAL_SERVER_PORTS_DEFAULT); portsArray = SOCIAL_SERVER_PORTS_DEFAULT; } // Tokenize the ports array port = strtok (portsArray, " "); while (port != NULL) { self->socialServersCount++; port = strtok (NULL, " "); } if (self->socialServersCount == 0) { error ("Cannot read correctly the social ports array."); result = false; goto cleanup; } // Fill the server ports array self->socialServersPorts = calloc (self->socialServersCount, sizeof (int)); for (int portIndex = 0; portIndex < self->socialServersCount; portIndex++) { self->socialServersPorts[portIndex] = strtoul (portsArray, &portsArray, 10); portsArray++; } // Read the number of social workers if (!(self->socialWorkersCount = atoi (zconfig_resolve (conf, "socialServer/workersCount", NULL)))) { warning ("Cannot read correctly the social workers count in the configuration file (%s). ", confFilePath); warning ("The default worker count = %d has been used.", SOCIAL_SERVER_WORKERS_COUNT_DEFAULT); self->socialWorkersCount = SOCIAL_SERVER_WORKERS_COUNT_DEFAULT; } char *socialServersIp; // Read the social server interfaces IP if (!(socialServersIp = zconfig_resolve (conf, "socialServer/serversIP", NULL))) { error ("Cannot read correctly the social servers interface IP in the configuration file (%s). ", confFilePath); result = false; goto cleanup; } int nbSocialServersIp = 0; routerIp = strtok (socialServersIp, " "); while (routerIp != NULL) { routerIp = strtok (NULL, " "); nbSocialServersIp++; } if (nbSocialServersIp != self->socialServersCount) { error ("Number of social ports different from the number of social interfaces IP. (%d / %d)", nbSocialServersIp, self->socialServersCount ); result = false; goto cleanup; } // Fill the social server IPs array self->socialServersIp = calloc (self->socialServersCount, sizeof (char *)); for (int ipIndex = 0; ipIndex < self->socialServersCount; ipIndex++) { self->socialServersIp[ipIndex] = strdup (socialServersIp); socialServersIp += strlen (socialServersIp) + 1; } // =================================== // Read Barrack configuration // =================================== // Read the ports array if (!(portsArray = zconfig_resolve (conf, "barrackServer/portsArray", NULL))) { warning ("Ports cannot be read for Barrack Server. Defaults ports have been used : %s", BARRACK_SERVER_PORTS_DEFAULT); portsArray = BARRACK_SERVER_PORTS_DEFAULT; } // Tokenize the ports array port = strtok (portsArray, " "); while (port != NULL) { self->barrackServerPortCount++; port = strtok (NULL, " "); } // Fill the server ports array self->barrackServerPort = calloc (self->barrackServerPortCount, sizeof (int)); for (int portIndex = 0; portIndex < self->barrackServerPortCount; portIndex++) { self->barrackServerPort[portIndex] = strtoul (portsArray, &portsArray, 10); portsArray++; } // Read the number of barrack server workers if (!(self->barrackWorkersCount = atoi (zconfig_resolve (conf, "barrackServer/workersCount", NULL)))) { warning ("Cannot read correctly the barrack workers count in the configuration file (%s). ", confFilePath); warning ("The default worker count = %d has been used.", BARRACK_SERVER_WORKERS_COUNT_DEFAULT); self->barrackWorkersCount = BARRACK_SERVER_WORKERS_COUNT_DEFAULT; } // Read the server interface IP if (!(self->barrackServerIp = strdup (zconfig_resolve (conf, "barrackServer/serverIP", NULL)))) { warning ("Cannot read correctly the barrack interface IP in the configuration file (%s). ", confFilePath); warning ("The default IP = %s has been used.", BARRACK_SERVER_FRONTEND_IP_DEFAULT); self->barrackServerIp = BARRACK_SERVER_FRONTEND_IP_DEFAULT; } // =================================== // Read MySQL configuration // =================================== if (!(self->sqlInfo.hostname = strdup (zconfig_resolve (conf, "database/mysql_host", NULL))) ) { warning ("Cannot read correctly the MySQL host in the configuration file (%s). ", confFilePath); warning ("The default hostname = %s has been used.", MYSQL_HOSTNAME_DEFAULT); self->sqlInfo.hostname = MYSQL_HOSTNAME_DEFAULT; } if (!(self->sqlInfo.login = strdup (zconfig_resolve (conf, "database/mysql_user", NULL))) ) { warning ("Cannot read correctly the MySQL user in the configuration file (%s). ", confFilePath); warning ("The default hostname = %s has been used.", MYSQL_LOGIN_DEFAULT); self->sqlInfo.login = MYSQL_LOGIN_DEFAULT; } if (!(self->sqlInfo.password = strdup (zconfig_resolve (conf, "database/mysql_password", NULL))) ) { warning ("Cannot read correctly the MySQL password in the configuration file (%s). ", confFilePath); warning ("The default hostname = %s has been used.", MYSQL_PASSWORD_DEFAULT); self->sqlInfo.password = MYSQL_PASSWORD_DEFAULT; } if (!(self->sqlInfo.database = strdup (zconfig_resolve (conf, "database/mysql_database", NULL))) ) { warning ("Cannot read correctly the MySQL database in the configuration file (%s). ", confFilePath); warning ("The default hostname = %s has been used.", MYSQL_DATABASE_DEFAULT); self->sqlInfo.database = MYSQL_DATABASE_DEFAULT; } // =================================== // Read Redis configuration // =================================== if (!(self->redisInfo.hostname = strdup (zconfig_resolve (conf, "redisServer/redis_host", NULL))) ) { warning ("Cannot read correctly the Redis host in the configuration file (%s). ", confFilePath); warning ("The default hostname = %s has been used.", REDIS_HOSTNAME_DEFAULT); self->redisInfo.hostname = REDIS_HOSTNAME_DEFAULT; } if (!(self->redisInfo.port = atoi (zconfig_resolve (conf, "redisServer/redis_port", NULL))) ) { warning ("Cannot read correctly the Redis port in the configuration file (%s). ", confFilePath); warning ("The default hostname = %d has been used.", REDIS_PORT_DEFAULT); self->redisInfo.port = REDIS_PORT_DEFAULT; } cleanup: // Close the configuration file zconfig_destroy (&conf); return result; }