void zrex_test (bool verbose) { printf (" * zrex: "); // @selftest // This shows the pattern of matching many lines to a single pattern zrex_t *rex = zrex_new ("\\d+-\\d+-\\d+"); assert (rex); assert (zrex_valid (rex)); bool matches = zrex_matches (rex, "123-456-789"); assert (matches); assert (zrex_hits (rex) == 1); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (zrex_hit (rex, 1) == NULL); zrex_destroy (&rex); // Here we pick out hits using capture groups rex = zrex_new ("(\\d+)-(\\d+)-(\\d+)"); assert (rex); assert (zrex_valid (rex)); matches = zrex_matches (rex, "123-456-ABC"); assert (!matches); matches = zrex_matches (rex, "123-456-789"); assert (matches); assert (zrex_hits (rex) == 4); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (streq (zrex_hit (rex, 1), "123")); assert (streq (zrex_hit (rex, 2), "456")); assert (streq (zrex_hit (rex, 3), "789")); zrex_destroy (&rex); // This shows the pattern of matching one line against many // patterns and then handling the case when it hits rex = zrex_new (NULL); // No initial pattern assert (rex); char *input = "Mechanism: CURVE"; matches = zrex_eq (rex, input, "Version: (.+)"); assert (!matches); assert (zrex_hits (rex) == 0); matches = zrex_eq (rex, input, "Mechanism: (.+)"); assert (matches); assert (zrex_hits (rex) == 2); const char *mechanism; zrex_fetch (rex, &mechanism, NULL); assert (streq (zrex_hit (rex, 1), "CURVE")); assert (streq (mechanism, "CURVE")); zrex_destroy (&rex); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
int zrex_test (bool verbose) { printf (" * zrex: "); zrex_t *rex = zrex_new (""); assert (rex); assert (!zrex_valid (rex)); if (verbose) puts (zrex_strerror (rex)); zrex_destroy (&rex); // This shows the pattern of matching many lines to a single pattern rex = zrex_new ("[0-9]+\\-[0-9]+\\-[0-9]+"); assert (rex); int hits = zrex_hits (rex, "123-456-789"); assert (hits == 1); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (zrex_hit (rex, 1) == NULL); zrex_destroy (&rex); // Here we pick out hits using capture groups rex = zrex_new ("([0-9]+)\\-([0-9]+)\\-([0-9]+)"); assert (rex); assert (zrex_valid (rex)); hits = zrex_hits (rex, "123-456-ABC"); assert (hits == 0); hits = zrex_hits (rex, "123-456-789"); assert (hits == 4); assert (streq (zrex_hit (rex, 0), "123-456-789")); assert (streq (zrex_hit (rex, 1), "123")); assert (streq (zrex_hit (rex, 2), "456")); assert (streq (zrex_hit (rex, 3), "789")); zrex_destroy (&rex); // This shows the pattern of matching one line against many // patterns and then handling the case when it hits rex = zrex_new (NULL); // No initial pattern char *input = "Mechanism: CURVE"; if (zrex_eq (rex, input, "Version: (.+)")) assert (false); else if (zrex_eq (rex, input, "Mechanism: (.+)")) assert (streq (zrex_hit (rex, 1), "CURVE")); zrex_destroy (&rex); printf ("OK\n"); return 0; }
static void s_load_certs_from_disk (zcertstore_t *self) { zhashx_purge (self->certs); zdir_t *dir = zdir_new (self->location, NULL); if (dir) { // Load all certificates including those in subdirectories zfile_t **filelist = zdir_flatten (dir); assert (filelist); zrex_t *rex = zrex_new ("_secret$"); assert (rex); uint index; for (index = 0;; index++) { zfile_t *file = filelist [index]; if (!file) break; // End of list if (zfile_is_regular (file) && !zrex_matches (rex, zfile_filename (file, NULL))) { zcert_t *cert = zcert_load (zfile_filename (file, NULL)); if (cert) zcertstore_insert (self, &cert); } } zdir_flatten_free (&filelist); self->modified = zdir_modified (dir); self->count = zdir_count (dir); self->cursize = zdir_cursize (dir); zrex_destroy (&rex); zdir_destroy (&dir); } }
static void s_ztrie_node_destroy (ztrie_node_t **self_p) { assert (self_p); if (*self_p) { ztrie_node_t *self = *self_p; // Free class properties zstr_free (&self->token); zstr_free (&self->asterisk_match); if (self->parameter_count > 0) { int index; for (index = 0; index < self->parameter_count; index++) { free (self->parameter_names [index]); if (self->parameter_values [index]) free (self->parameter_values [index]); } free (self->parameter_names); free (self->parameter_values); } if (self->token_type == NODE_TYPE_REGEX || self->token_type == NODE_TYPE_PARAM) zrex_destroy (&self->regex); zlistx_destroy (&self->children); if (self->data && self->destroy_data_fn) (self->destroy_data_fn) (&self->data); // Free object itself free (self); *self_p = NULL; } }
static void s_offer_destroy (offer_t **self_p) { assert (self_p); if (*self_p) { offer_t *self = *self_p; zrex_destroy (&self->rex); free (self->pattern); free (self); *self_p = NULL; } }
static void s_selector_destroy (selector_t **self_p) { assert (self_p); if (*self_p) { selector_t *self = *self_p; zrex_destroy (&self->rex); zlistx_destroy (&self->clients); free (self->pattern); free (self); *self_p = NULL; } }
int zyre_peer_connect (zyre_peer_t *self, zuuid_t *from, const char *endpoint, uint64_t expired_timeout) { assert (self); assert (!self->connected); // Create new outgoing socket (drop any messages in transit) self->mailbox = zsock_new (ZMQ_DEALER); if (!self->mailbox) return -1; // Null when we're shutting down // Set our own identity on the socket so that receiving node // knows who each message came from. Note that we cannot use // the UUID directly as the identity since it may contain a // zero byte at the start, which libzmq does not like for // historical and arguably bogus reasons that it nonetheless // enforces. byte routing_id [ZUUID_LEN + 1] = { 1 }; memcpy (routing_id + 1, zuuid_data (from), ZUUID_LEN); int rc = zmq_setsockopt (zsock_resolve (self->mailbox), ZMQ_IDENTITY, routing_id, ZUUID_LEN + 1); assert (rc == 0); // Set a high-water mark that allows for reasonable activity zsock_set_sndhwm (self->mailbox, expired_timeout * 100); // Send messages immediately or return EAGAIN zsock_set_sndtimeo (self->mailbox, 0); // If the peer is a link-local IPv6 address but the interface is not set, // use ZSYS_INTERFACE_ADDRESS if provided zrex_t *rex = zrex_new (NULL); char endpoint_iface [NI_MAXHOST] = {0}; if (zsys_ipv6 () && zsys_interface () && strlen(zsys_interface ()) && !streq (zsys_interface (), "*") && zrex_eq (rex, endpoint, "^tcp://(fe80[^%]+)(:\\d+)$")) { const char *hostname, *port; zrex_fetch (rex, &hostname, &port, NULL); strcat (endpoint_iface, "tcp://"); strcat (endpoint_iface, hostname); strcat (endpoint_iface, "%"); strcat (endpoint_iface, zsys_interface ()); strcat (endpoint_iface, port); } else strcat (endpoint_iface, endpoint); zrex_destroy (&rex); // Connect through to peer node rc = zsock_connect (self->mailbox, "%s", endpoint_iface); if (rc != 0) { zsys_debug ("(%s) cannot connect to endpoint=%s", self->origin, endpoint_iface); zsock_destroy (&self->mailbox); return -1; } if (self->verbose) zsys_info ("(%s) connect to peer: endpoint=%s", self->origin, endpoint_iface); self->endpoint = strdup (endpoint_iface); self->connected = true; self->ready = false; return 0; }
int zsock_bind (zsock_t *self, const char *format, ...) { assert (self); assert (zsock_is (self)); // Expand format to get full endpoint va_list argptr; va_start (argptr, format); char *endpoint = zsys_vprintf (format, argptr); va_end (argptr); int rc; // If tcp:// endpoint, parse to get or make port number zrex_t *rex = zrex_new (NULL); if (zrex_eq (rex, endpoint, "^tcp://.*:(\\d+)$")) { assert (zrex_hits (rex) == 2); if (zmq_bind (self->handle, endpoint) == 0) rc = atoi (zrex_hit (rex, 1)); else rc = -1; } else if (zrex_eq (rex, endpoint, "^(tcp://.*):([*!])(\\[(\\d+)?-(\\d+)?\\])?$")) { assert (zrex_hits (rex) == 6); const char *hostname, *opcode, *group, *first_str, *last_str; zrex_fetch (rex, &hostname, &opcode, &group, &first_str, &last_str, NULL); int first = *first_str? atoi (first_str): DYNAMIC_FIRST; int last = *last_str? atoi (last_str): DYNAMIC_LAST; // This is how many times we'll try before giving up int attempts = last - first + 1; // If operator is '*', take first available port. // If operator is '!', take a random leap into our port space; we'll // still scan sequentially to make sure we find a free slot rapidly. int port = first; if (streq (opcode, "!")) port += randof (attempts); rc = -1; // Assume we don't succeed while (rc == -1 && attempts--) { free (endpoint); endpoint = zsys_sprintf ("%s:%d", hostname, port); if (zmq_bind (self->handle, endpoint) == 0) rc = port; if (++port > last) port = first; } } else rc = zmq_bind (self->handle, endpoint); // Store successful endpoint for later reference if (rc >= 0) { free (self->endpoint); self->endpoint = endpoint; } else free (endpoint); zrex_destroy (&rex); return rc; }