/** * Load configuration file. * @param[in] path Configuration file location. * @param[in,out] zconf Parsed configuration storage. * @return True on success. */ bool zconfig_load(const char *path, zconfig_t *zconf) { if (NULL == path) { ZLOG(LOG_ERR, "config: configuration file not specified"); return false; } bool loaded = false; config_t config; config_init(&config); if (!config_read_file(&config, path)) { ZLOG(LOG_ERR, "config: failed to parse %s (error: %s at %d line)", path, config_error_text(&config), config_error_line(&config)); goto end; } const config_setting_t *root = config_root_setting(&config); if (!zconfig_load_sections(root, zconf)) { zconfig_destroy(zconf); } else { loaded = true; } end: config_destroy(&config); return loaded; }
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; }
int curvezmq_keypair_save (curvezmq_keypair_t *self) { assert (self); // Get printable key strings char *public_key = s_key_to_hex (self->public_key); char *secret_key = s_key_to_hex (self->secret_key); // Set process file create mask to owner access only zfile_mode_private (); // The public key file contains just the public key zconfig_t *root = zconfig_new ("root", NULL); zconfig_t *key = zconfig_new ("public-key", root); zconfig_set_value (key, public_key); zconfig_save (root, "public.key"); // The secret key file contains both secret and public keys key = zconfig_new ("secret-key", root); zconfig_set_value (key, secret_key); zconfig_save (root, "secret.key"); zconfig_destroy (&root); // Reset process file create mask zfile_mode_default (); free (public_key); free (secret_key); return 0; }
int hydra_post_save (hydra_post_t *self, const char *filename) { assert (self); assert (filename); // Creeate subdirectories if necessary zsys_dir_create ("posts"); zsys_dir_create ("posts/blobs"); // If post content hasn't yet been serialised, write it to disk in the // blobs directory and set the location property to point to it. if (self->content) { assert (!self->location); self->location = zsys_sprintf ("posts/blobs/%s", self->digest); FILE *output = fopen (self->location, "wb"); zchunk_write (self->content, output); zchunk_destroy (&self->content); fclose (output); } zconfig_t *root = zconfig_new ("root", NULL); zconfig_put (root, "/post/ident", hydra_post_ident (self)); zconfig_put (root, "/post/subject", self->subject); zconfig_put (root, "/post/timestamp", self->timestamp); zconfig_put (root, "/post/parent-id", self->parent_id); zconfig_put (root, "/post/mime-type", self->mime_type); zconfig_put (root, "/post/digest", self->digest); zconfig_put (root, "/post/location", self->location); zconfig_putf (root, "/post/content-size", "%ld", self->content_size); zconfig_savef (root, "posts/%s", filename); zconfig_destroy (&root); return 0; }
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; }
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"); }
// Process message from pipe static void server_control_message (server_t *self) { zmsg_t *msg = zmsg_recv (self->pipe); char *method = zmsg_popstr (msg); if (streq (method, "BIND")) { char *endpoint = zmsg_popstr (msg); self->port = zsocket_bind (self->router, endpoint); zstr_sendf (self->pipe, "%d", self->port); free (endpoint); } else if (streq (method, "PUBLISH")) { char *location = zmsg_popstr (msg); char *alias = zmsg_popstr (msg); mount_t *mount = mount_new (location, alias); zlist_append (self->mounts, mount); free (location); free (alias); } else if (streq (method, "SET ANONYMOUS")) { char *enabled_string = zmsg_popstr (msg); long enabled = atoi (enabled_string); free (enabled_string); // Enable anonymous access without a config file zconfig_put (self->config, "security/anonymous", enabled? "1" :"0"); } else if (streq (method, "CONFIG")) { char *config_file = zmsg_popstr (msg); zconfig_destroy (&self->config); self->config = zconfig_load (config_file); if (self->config) server_apply_config (self); else { printf ("E: cannot load config file '%s'\n", config_file); self->config = zconfig_new ("root", NULL); } free (config_file); } else if (streq (method, "SETOPTION")) { char *path = zmsg_popstr (msg); char *value = zmsg_popstr (msg); zconfig_put (self->config, path, value); server_config_self (self); free (path); free (value); } else if (streq (method, "STOP")) { zstr_send (self->pipe, "OK"); self->stopped = true; } free (method); zmsg_destroy (&msg); }
void zconfig_remove (zconfig_t *self) { assert (self); // Destroy all children and siblings recursively zconfig_destroy (&self->child); self->child = NULL; }
void zconfig_destroy (zconfig_t **self_p) { assert (self_p); if (*self_p) { zconfig_t *self = *self_p; // Destroy all children and siblings recursively if (self->child) zconfig_destroy (&self->child); if (self->next) zconfig_destroy (&self->next); zlist_destroy (&self->comments); free (self->name); free (self->value); free (self); *self_p = NULL; } }
void zconfig_destroy (zconfig_t **self_p) { assert (self_p); if (*self_p) { zconfig_t *self = *self_p; // Destroy all children and siblings recursively zconfig_destroy (&self->child); zconfig_destroy (&self->next); // Destroy other properties and then self zlist_destroy (&self->comments); zfile_destroy (&self->file); free (self->name); free (self->value); free (self); *self_p = NULL; } }
void zcert_destroy (zcert_t **self_p) { assert (self_p); if (*self_p) { zcert_t *self = *self_p; zhash_destroy (&self->metadata); zconfig_destroy (&self->config); free (self); *self_p = NULL; } }
static void s_save_metadata_all (zcert_t *self) { zconfig_destroy (&self->config); self->config = zconfig_new ("root", NULL); zconfig_t *section = zconfig_new ("metadata", self->config); zhash_foreach (self->metadata, s_save_metadata, section); char *timestr = zclock_timestr (); zconfig_comment (self->config, " **** Generated on %s by CZMQ ****", timestr); zstr_free (×tr); }
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 }
int zconfig_reload (zconfig_t **self_p) { assert (self_p); zconfig_t *self = *self_p; if (self->file) { zconfig_t *copy = zconfig_load (zfile_filename (self->file, NULL)); if (copy) { // Destroy old tree and install new one zconfig_destroy (self_p); *self_p = copy; return 0; } } return -1; // Not successful }
static void s_save_metadata_all (zcert_t *self) { zconfig_destroy (&self->config); self->config = zconfig_new ("root", NULL); zconfig_t *section = zconfig_new ("metadata", self->config); char *value = (char *) zhash_first (self->metadata); while (value) { zconfig_t *item = zconfig_new (zhash_cursor (self->metadata), section); zconfig_set_value (item, "%s", value); value = (char *) zhash_next (self->metadata); } char *timestr = zclock_timestr (); zconfig_set_comment (self->config, " **** Generated on %s by CZMQ ****", timestr); zstr_free (×tr); }
static void server_destroy (server_t **self_p) { assert (self_p); if (*self_p) { server_t *self = *self_p; zsocket_destroy (self->ctx, self->router); zconfig_destroy (&self->config); zhash_destroy (&self->clients); // Destroy mount points while (zlist_size (self->mounts)) { mount_t *mount = (mount_t *) zlist_pop (self->mounts); mount_destroy (&mount); } zlist_destroy (&self->mounts); free (self); *self_p = NULL; } }
int shelf_test (bool verbose) { printf (" * shelf: "); zconfig_t* config = zconfig_load(".testdir/test.cfg"); assert(config); zpgutil_datasource_t *datasource = zpgutil_datasource_new (config); assert (datasource); zpgutil_session_t *session = zpgutil_session_new (datasource); assert (session); // @selftest // Simple create/destroy test shelf_t *self = shelf_new (session); assert (self); book_t *mybook = shelf_add_book (self,"William Shakespeare","Macbeth"); assert (mybook); book_destroy (&mybook); int c = shelf_count_books (self); assert (c>0); shelf_load_books (self); book_t *loaded; while ( (loaded = shelf_next_book (self)) != NULL) { book_print (loaded); book_destroy (&loaded); } shelf_destroy (&self); // @end zpgutil_session_destroy (&session); zpgutil_datasource_destroy (&datasource); zconfig_destroy (&config); printf ("OK\n"); return 0; }
JNIEXPORT void JNICALL Java_org_zeromq_czmq_Zconfig__1_1destroy (JNIEnv *env, jclass c, jlong self) { zconfig_destroy ((zconfig_t **) &self); }
zconfig_t * zconfig_load (char *filename) { FILE *file = fopen (filename, "r"); if (!file) return NULL; // File not found, or unreadable // Parse the file line by line zconfig_t *self = zconfig_new ("root", NULL); char cur_line [1024]; bool valid = true; int lineno = 0; while (fgets (cur_line, 1024, file)) { // Trim line int length = strlen (cur_line); while (length && isspace ((byte) cur_line [length - 1])) cur_line [--length] = 0; // Collect indentation level and name, if any lineno++; // Handle whole-line comment if present if (cur_line [0] == '#') { if (!self->comments) { self->comments = zlist_new (); zlist_autofree (self->comments); } zlist_append (self->comments, cur_line + 1); } char *scanner = cur_line; int level = s_collect_level (&scanner, lineno); if (level == -1) { valid = false; break; } char *name = s_collect_name (&scanner, lineno); if (name == NULL) { valid = false; break; } // If name is not empty, collect property value if (*name) { char *value = s_collect_value (&scanner, lineno); if (value == NULL) valid = false; else { // Navigate to parent for this element zconfig_t *parent = zconfig_at_depth (self, level); if (parent) { zconfig_t *item = zconfig_new (name, parent); item->value = value; } else { fprintf (stderr, "E: (%d) indentation error\n", lineno); free (value); valid = false; } } } else if (s_verify_eoln (scanner, lineno)) valid = false; free (name); if (!valid) break; } // Either the whole ZPL file is valid or none of it is if (!valid) zconfig_destroy (&self); fclose (file); return self; }
void zconfig_test (bool verbose) { printf (" * zconfig: "); // @selftest const char *SELFTEST_DIR_RW = "src/selftest-rw"; const char *testbasedir = ".test_zconfig"; const char *testfile = "test.cfg"; char *basedirpath = NULL; // subdir in a test, under SELFTEST_DIR_RW char *filepath = NULL; // pathname to testfile in a test, in dirpath basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir); assert (basedirpath); filepath = zsys_sprintf ("%s/%s", basedirpath, testfile); assert (filepath); // Make sure old aborted tests do not hinder us zdir_t *dir = zdir_new (basedirpath, NULL); if (dir) { zdir_remove (dir, true); zdir_destroy (&dir); } zsys_file_delete (filepath); zsys_dir_delete (basedirpath); // Create temporary directory for test files zsys_dir_create (basedirpath); zconfig_t *root = zconfig_new ("root", NULL); assert (root); zconfig_t *section, *item; section = zconfig_new ("headers", root); assert (section); item = zconfig_new ("email", section); assert (item); zconfig_set_value (item, "*****@*****.**"); item = zconfig_new ("name", section); assert (item); zconfig_set_value (item, "Justin Kayce"); zconfig_putf (root, "/curve/secret-key", "%s", "Top Secret"); zconfig_set_comment (root, " CURVE certificate"); zconfig_set_comment (root, " -----------------"); assert (zconfig_comments (root)); zconfig_save (root, filepath); zconfig_destroy (&root); root = zconfig_load (filepath); if (verbose) zconfig_save (root, "-"); assert (streq (zconfig_filename (root), filepath)); char *email = zconfig_get (root, "/headers/email", NULL); assert (email); assert (streq (email, "*****@*****.**")); char *passwd = zconfig_get (root, "/curve/secret-key", NULL); assert (passwd); assert (streq (passwd, "Top Secret")); zconfig_savef (root, "%s/%s", basedirpath, testfile); assert (!zconfig_has_changed (root)); int rc = zconfig_reload (&root); assert (rc == 0); assert (!zconfig_has_changed (root)); zconfig_destroy (&root); // Test chunk load/save root = zconfig_new ("root", NULL); assert (root); section = zconfig_new ("section", root); assert (section); item = zconfig_new ("value", section); assert (item); zconfig_set_value (item, "somevalue"); zconfig_t *search = zconfig_locate (root, "section/value"); assert (search == item); zchunk_t *chunk = zconfig_chunk_save (root); assert (strlen ((char *) zchunk_data (chunk)) == 32); char *string = zconfig_str_save (root); assert (string); assert (streq (string, (char *) zchunk_data (chunk))); freen (string); assert (chunk); zconfig_destroy (&root); root = zconfig_chunk_load (chunk); assert (root); char *value = zconfig_get (root, "/section/value", NULL); assert (value); assert (streq (value, "somevalue")); // Test config can't be saved to a file in a path that doesn't // exist or isn't writable rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", basedirpath, testfile); assert (rc == -1); zconfig_destroy (&root); zchunk_destroy (&chunk); // Test subtree removal { zconfig_t *root = zconfig_str_load ( "context\n" " iothreads = 1\n" " verbose = 1 # Ask for a trace\n" "main\n" " type = zqueue # ZMQ_DEVICE type\n" " frontend\n" " option\n" " hwm = 1000\n" " swap = 25000000 # 25MB\n" " bind = 'inproc://addr1'\n" " bind = 'ipc://addr2'\n" " backend\n" " bind = inproc://addr3\n" ); zconfig_t *to_delete = zconfig_locate (root, "main/frontend"); assert (to_delete); zconfig_remove (to_delete); char *value = zconfig_get (root, "/main/type", NULL); assert (value); assert (streq (value, "zqueue")); value = zconfig_get (root, "/main/backend/bind", NULL); assert (value); assert (streq (value, "inproc://addr3")); value = zconfig_get (root, "/main/frontend", NULL); assert (value); value = zconfig_get (root, "/main/frontend/option", NULL); assert (value == NULL); value = zconfig_get (root, "/main/frontend/option/swap", NULL); assert (value == NULL); zconfig_destroy (&root); } // Test str_load zconfig_t *config = zconfig_str_load ( "malamute\n" " endpoint = ipc://@/malamute\n" " producer = STREAM\n" " consumer\n" " STREAM2 = .*\n" " STREAM3 = HAM\n" "server\n" " verbose = true\n" ); assert (config); assert (streq (zconfig_get (config, "malamute/endpoint", NULL), "ipc://@/malamute")); assert (streq (zconfig_get (config, "malamute/producer", NULL), "STREAM")); assert (zconfig_locate (config, "malamute/consumer")); zconfig_t *c = zconfig_child (zconfig_locate (config, "malamute/consumer")); assert (c); assert (streq (zconfig_name (c), "STREAM2")); assert (streq (zconfig_value (c), ".*")); c = zconfig_next (c); assert (c); assert (streq (zconfig_name (c), "STREAM3")); assert (streq (zconfig_value (c), "HAM")); c = zconfig_next (c); assert (!c); assert (streq (zconfig_get (config, "server/verbose", NULL), "true")); zconfig_destroy (&config); // Delete all test files dir = zdir_new (basedirpath, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); zstr_free (&basedirpath); zstr_free (&filepath); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
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; }
/// // Destroy a config item and all its children void QmlZconfigAttached::destruct (QmlZconfig *qmlSelf) { zconfig_destroy (&qmlSelf->self); };
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); assert (root); zconfig_t *section, *item; section = zconfig_new ("headers", root); assert (section); item = zconfig_new ("email", section); assert (item); zconfig_set_value (item, "*****@*****.**"); item = zconfig_new ("name", section); assert (item); zconfig_set_value (item, "Justin Kayce"); zconfig_putf (root, "/curve/secret-key", "%s", "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, "-"); assert (streq (zconfig_filename (root), TESTDIR "/test.cfg")); char *email = zconfig_get (root, "/headers/email", NULL); assert (email); assert (streq (email, "*****@*****.**")); char *passwd = zconfig_get (root, "/curve/secret-key", NULL); assert (passwd); assert (streq (passwd, "Top Secret")); zconfig_savef (root, "%s/%s", TESTDIR, "test.cfg"); assert (!zconfig_has_changed (root)); int rc = zconfig_reload (&root); assert (rc == 0); assert (!zconfig_has_changed (root)); zconfig_destroy (&root); // Test chunk load/save root = zconfig_new ("root", NULL); assert (root); section = zconfig_new ("section", root); assert (section); item = zconfig_new ("value", section); assert (item); zconfig_set_value (item, "somevalue"); zconfig_t *search = zconfig_locate (root, "section/value"); assert (search == item); zchunk_t *chunk = zconfig_chunk_save (root); assert (strlen ((char *) zchunk_data (chunk)) == 32); char *string = zconfig_str_save (root); assert (string); assert (streq (string, (char *) zchunk_data (chunk))); free (string); assert (chunk); zconfig_destroy (&root); root = zconfig_chunk_load (chunk); assert (root); char *value = zconfig_get (root, "/section/value", NULL); assert (value); assert (streq (value, "somevalue")); // Test config can't be saved to a file in a path that doesn't // exist or isn't writable rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", TESTDIR, "test.cfg"); assert (rc == -1); zconfig_destroy (&root); zchunk_destroy (&chunk); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); // @end printf ("OK\n"); }
JNIEXPORT void JNICALL Java_zconfig__1_1destroy (JNIEnv *env, jclass c, jlong self_p) { zconfig_destroy ((zconfig_t **) &self_p); }
zconfig_t * zconfig_chunk_load (zchunk_t *chunk) { // Parse the chunk line by line zconfig_t *self = zconfig_new ("root", NULL); if (!self) return NULL; bool valid = true; int lineno = 0; char *data_ptr = (char *) zchunk_data (chunk); size_t remaining = zchunk_size (chunk); while (remaining) { // Copy stuff into cur_line; not fastest but safest option // since chunk may not be null terminated, etc. char *eoln = (char *) memchr (data_ptr, '\n', remaining); size_t cur_size; if (eoln) cur_size = eoln - data_ptr; else cur_size = remaining; if (cur_size > 1024) cur_size = 1024; char cur_line [1024 + 1]; memcpy (cur_line, data_ptr, cur_size); cur_line [cur_size] = '\0'; data_ptr = eoln? eoln + 1: NULL; remaining -= cur_size + (eoln? 1: 0); // Trim line size_t length = strlen (cur_line); while (length && isspace ((byte) cur_line [length - 1])) cur_line [--length] = 0; // Collect indentation level and name, if any lineno++; // Handle whole-line comment if present if (cur_line [0] == '#') { if (!self->comments) { self->comments = zlist_new (); assert (self->comments); zlist_autofree (self->comments); } zlist_append (self->comments, cur_line + 1); } char *scanner = cur_line; int level = s_collect_level (&scanner, lineno); if (level == -1) { valid = false; break; } char *name = s_collect_name (&scanner, lineno); if (name == NULL) { valid = false; break; } // If name is not empty, collect property value if (*name) { char *value = s_collect_value (&scanner, lineno); if (value == NULL) valid = false; else { // Navigate to parent for this element zconfig_t *parent = zconfig_at_depth (self, level); if (parent) { zconfig_t *item = zconfig_new (name, parent); assert (item); item->value = value; } else { zclock_log ("E (zconfig): (%d) indentation error", lineno); free (value); valid = false; } } } else if (s_verify_eoln (scanner, lineno)) valid = false; free (name); if (!valid) break; } // Either the whole ZPL stream is valid or none of it is if (!valid) zconfig_destroy (&self); return self; }
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; }
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; }