char * zfile_digest (zfile_t *self) { if (!self->digest) { if (zfile_input (self) == -1) return NULL; // Problem reading file // Now calculate hash for file data, chunk by chunk size_t blocksz = 65535; off_t offset = 0; self->digest = zdigest_new (); zchunk_t *chunk = zfile_read (self, blocksz, offset); while (zchunk_size (chunk)) { zdigest_update (self->digest, zchunk_data (chunk), zchunk_size (chunk)); zchunk_destroy (&chunk); offset += blocksz; chunk = zfile_read (self, blocksz, offset); } zchunk_destroy (&chunk); zfile_close (self); } return zdigest_string (self->digest); }
const char * zfile_digest (zfile_t *self) { assert (self); if (!self->digest) { if (zfile_input (self) == -1) return NULL; // Problem reading file // Now calculate hash for file data, chunk by chunk size_t blocksz = 65535; off_t offset = 0; self->digest = zdigest_new (); if (!self->digest) return NULL; zchunk_t *chunk = zfile_read (self, blocksz, offset); while (zchunk_size (chunk)) { zdigest_update (self->digest, zchunk_data (chunk), zchunk_size (chunk)); zchunk_destroy (&chunk); // off_t is defined as long (32 bit on Windows, 64 bit otherwise) // This guards against overflow in both contexts. if (blocksz > LONG_MAX - offset) return NULL; offset += (off_t) blocksz; chunk = zfile_read (self, blocksz, offset); } zchunk_destroy (&chunk); fclose (self->handle); self->handle = 0; } return zdigest_string (self->digest); }
static void server_process_cluster_command ( server_t *self, const char *peer_id, const char *peer_name, zmsg_t *msg, bool unicast) { char *request = zmsg_popstr (msg); char *pipename = zmsg_popstr (msg); zsys_info ("peer=%s command=%s pipe=%s unicast=%d", peer_name, request, pipename? pipename: "-", unicast); // Lookup or create pipe // TODO: remote pipes need cleaning up with some timeout pipe_t *pipe = NULL; if (pipename) { pipe = (pipe_t *) zhash_lookup (self->pipes, pipename); if (!pipe) pipe = pipe_new (self, pipename); } if (pipe && streq (request, "HAVE WRITER")) pipe_attach_remote_writer (pipe, peer_id, unicast); else if (pipe && streq (request, "HAVE READER")) pipe_attach_remote_reader (pipe, peer_id, unicast); else if (pipe && streq (request, "DATA")) { // TODO encode these commands as proper protocol zframe_t *frame = zmsg_pop (msg); zchunk_t *chunk = zchunk_new (zframe_data (frame), zframe_size (frame)); if (pipe->writer == REMOTE_NODE && pipe->reader) { zsys_info ("send %d bytes to pipe", (int) zchunk_size (chunk)); pipe_send_data (pipe, &chunk); } else zsys_info ("discard %d bytes, unroutable", (int) zchunk_size (chunk)); zframe_destroy (&frame); zchunk_destroy (&chunk); } else if (pipe && streq (request, "DROP READER")) pipe_drop_remote_reader (&pipe, peer_id); else if (pipe && streq (request, "DROP WRITER")) pipe_drop_remote_writer (&pipe, peer_id); else if (streq (request, "DUMP")) zyre_dump (self->zyre); else zsys_warning ("bad request %s from %s", request, peer_name); zstr_free (&pipename); zstr_free (&request); }
void zchunk_test (bool verbose) { printf (" * zchunk: "); // @selftest zchunk_t *chunk = zchunk_new ("1234567890", 10); assert (chunk); assert (zchunk_size (chunk) == 10); assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0); zchunk_destroy (&chunk); chunk = zchunk_new (NULL, 10); zchunk_append (chunk, "12345678", 8); zchunk_append (chunk, "90ABCDEF", 8); zchunk_append (chunk, "GHIJKLMN", 8); assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0); assert (zchunk_size (chunk) == 10); zframe_t *frame = zchunk_pack (chunk); assert(frame); zchunk_t *chunk2 = zchunk_unpack (frame); assert (memcmp (zchunk_data (chunk2), "1234567890", 10) == 0); zframe_destroy(&frame); zchunk_destroy(&chunk2); zchunk_t *copy = zchunk_dup (chunk); assert (memcmp (zchunk_data (copy), "1234567890", 10) == 0); assert (zchunk_size (copy) == 10); zchunk_destroy (©); zchunk_destroy (&chunk); copy = zchunk_new ("1234567890abcdefghij", 20); chunk = zchunk_new (NULL, 8); zchunk_consume (chunk, copy); assert (!zchunk_exhausted (copy)); assert (memcmp (zchunk_data (chunk), "12345678", 8) == 0); zchunk_set (chunk, NULL, 0); zchunk_consume (chunk, copy); assert (!zchunk_exhausted (copy)); assert (memcmp (zchunk_data (chunk), "90abcdef", 8) == 0); zchunk_set (chunk, NULL, 0); zchunk_consume (chunk, copy); assert (zchunk_exhausted (copy)); assert (zchunk_size (chunk) == 4); assert (memcmp (zchunk_data (chunk), "ghij", 4) == 0); zchunk_destroy (©); zchunk_destroy (&chunk); // @end printf ("OK\n"); }
static void s_check_directory (s_agent_t *self) { // Get latest snapshot and build a patches list for any changes // All patches are built using a virtual path starting at "/" zdir_t *dir = zdir_new (self->path, NULL); zlist_t *patches = zdir_diff (self->dir, dir, "/"); // Drop old directory and replace with latest version zdir_destroy (&self->dir); self->dir = dir; while (zlist_size (patches)) { zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); if (zdir_patch_op (patch) == patch_create) { // Shout new files to DROPS group // Stupidest possible approach: send whole file as one frame // Truncate file at arbitrary limit of 10MB zfile_t *file = zdir_patch_file (patch); if (zfile_input (file) == 0) { zchunk_t *chunk = zfile_read (file, 10 * 1024 * 1024, 0); assert (chunk); zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "CREATE"); zmsg_addstr (msg, zdir_patch_vpath (patch)); zmsg_add (msg, zframe_new (zchunk_data (chunk), zchunk_size (chunk))); zchunk_destroy (&chunk); zyre_shout (self->zyre, "DROPS", &msg); } } zdir_patch_destroy (&patch); } zlist_destroy (&patches); }
static void pass_data_to_reader (client_t *self) { assert (self->pipe); zchunk_t *chunk = zpipes_msg_get_chunk (self->request); zsys_info ("write %d bytes", (int) zchunk_size (chunk)); pipe_send_data (self->pipe, &chunk); }
static void client_store_chunk (client_t *self, zchunk_t **chunk_p) { zchunk_t *chunk = *chunk_p; assert (chunk); zlist_append (self->queue, chunk); self->pending += zchunk_size (chunk); *chunk_p = NULL; }
JNIEXPORT jbyteArray JNICALL Java_org_zeromq_czmq_Zchunk__1_1data (JNIEnv *env, jclass c, jlong self) { jbyte *data_ = (jbyte *) zchunk_data ((zchunk_t *) (intptr_t) self); jint return_size_ = (jint) zchunk_size ((zchunk_t *) (intptr_t) self); jbyteArray return_data_ = (*env)->NewByteArray (env, return_size_); (*env)->SetByteArrayRegion (env, return_data_, 0, return_size_, (jbyte *) data_); return return_data_; }
void hydra_post_set_data (hydra_post_t *self, const void *data, size_t size) { assert (self); zstr_free (&self->location); zchunk_destroy (&self->content); self->content = zchunk_new (data, size); strcpy (self->digest, zchunk_digest (self->content)); self->content_size = zchunk_size (self->content); }
static zsync_node_t * zsync_node_new () { int rc; zsync_node_t *self = (zsync_node_t *) zmalloc (sizeof (zsync_node_t)); self->ctx = zctx_new (); assert (self->ctx); self->zyre = zyre_new (self->ctx); assert (self->zyre); // Obtain permanent UUID self->own_uuid = zuuid_new (); if (zsys_file_exists (UUID_FILE)) { // Read uuid from file zfile_t *uuid_file = zfile_new (".", UUID_FILE); int rc = zfile_input (uuid_file); // open file for reading assert (rc == 0); zchunk_t *uuid_chunk = zfile_read (uuid_file, 16, 0); assert (zchunk_size (uuid_chunk) == 16); // make sure read succeeded zuuid_set (self->own_uuid, zchunk_data (uuid_chunk)); zfile_destroy (&uuid_file); } else { // Write uuid to file zfile_t *uuid_file = zfile_new (".", UUID_FILE); rc = zfile_output (uuid_file); // open file for writing assert (rc == 0); zchunk_t *uuid_bin = zchunk_new ( zuuid_data (self->own_uuid), 16); rc = zfile_write (uuid_file, uuid_bin, 0); assert (rc == 0); zfile_destroy (&uuid_file); } // Obtain peers and states self->peers = zlist_new (); if (zsys_file_exists (PEER_STATES_FILE)) { zhash_t *peer_states = zhash_new (); int rc = zhash_load (peer_states, PEER_STATES_FILE); assert (rc == 0); zlist_t *uuids = zhash_keys (peer_states); char *uuid = zlist_first (uuids); while (uuid) { char * state_str = zhash_lookup (peer_states, uuid); uint64_t state; sscanf (state_str, "%"SCNd64, &state); zlist_append (self->peers, zsync_peer_new (uuid, state)); uuid = zlist_next (uuids); } } self->zyre_peers = zhash_new (); self->terminated = false; return self; }
void hydra_post_test (bool verbose) { printf (" * hydra_post: "); if (verbose) printf ("\n"); // @selftest // Simple create/destroy test zsys_dir_create (".hydra_test"); zsys_dir_change (".hydra_test"); hydra_post_t *post = hydra_post_new ("Test post"); assert (post); hydra_post_set_content (post, "Hello, World"); assert (streq (hydra_post_mime_type (post), "text/plain")); char *content = hydra_post_content (post); assert (content); assert (streq (content, "Hello, World")); zstr_free (&content); int rc = hydra_post_save (post, "testpost"); assert (rc == 0); hydra_post_destroy (&post); post = hydra_post_load ("testpost"); assert (post); assert (hydra_post_content_size (post) == 12); if (verbose) hydra_post_print (post); content = hydra_post_content (post); assert (content); assert (streq (content, "Hello, World")); zstr_free (&content); zchunk_t *chunk = hydra_post_fetch ( post, hydra_post_content_size (post), 0); assert (chunk); assert (zchunk_size (chunk) == 12); zchunk_destroy (&chunk); hydra_post_t *copy = hydra_post_dup (post); assert (streq (hydra_post_ident (copy), hydra_post_ident (post))); hydra_post_destroy (&post); hydra_post_destroy (©); // Delete the test directory zsys_dir_change (".."); zdir_t *dir = zdir_new (".hydra_test", NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); // @end printf ("OK\n"); }
void pass_chunk (zchunk_t *chunk, char *path, uint64_t sequence, uint64_t offset) { // save chunk printf ("[ST] PASS_CHUNK %s, %"PRId64", %"PRId64", %"PRId64"\n", path, sequence, zchunk_size (chunk), offset); zfile_t *file = zfile_new("./syncfolder", path); zfile_output(file); zfile_write(file, chunk, offset); zfile_close(file); zfile_destroy(&file); }
int zfile_test (bool verbose) { printf (" * zfile: "); // @selftest zfile_t *file = zfile_new (".", "bilbo"); assert (streq (zfile_filename (file, "."), "bilbo")); assert (zfile_is_readable (file) == false); zfile_destroy (&file); // Create a test file in some random subdirectory file = zfile_new ("./this/is/a/test", "bilbo"); int rc = zfile_output (file); assert (rc == 0); zchunk_t *chunk = zchunk_new (NULL, 100); zchunk_fill (chunk, 0, 100); // Write 100 bytes at position 1,000,000 in the file rc = zfile_write (file, chunk, 1000000); assert (rc == 0); zfile_close (file); assert (zfile_is_readable (file)); assert (zfile_cursize (file) == 1000100); assert (!zfile_is_stable (file)); zchunk_destroy (&chunk); zclock_sleep (1001); assert (zfile_is_stable (file)); // Check we can read from file rc = zfile_input (file); assert (rc == 0); chunk = zfile_read (file, 1000100, 0); assert (chunk); assert (zchunk_size (chunk) == 1000100); zchunk_destroy (&chunk); // Remove file and directory zdir_t *dir = zdir_new ("./this", NULL); assert (zdir_cursize (dir) == 1000100); zdir_remove (dir, true); assert (zdir_cursize (dir) == 0); zdir_destroy (&dir); // Check we can no longer read from file assert (!zfile_is_readable (file)); rc = zfile_input (file); assert (rc == -1); zfile_destroy (&file); // @end printf ("OK\n"); return 0; }
static void collect_data_to_send (client_t *self) { zsys_info ("read %d bytes", (int) zpipes_msg_size (self->request)); // Do we have enough data to satisfy the read request? size_t required = zpipes_msg_size (self->request); // If pipe was closed, we'll do a short read with as much // data as we have pending if (required > self->pending && self->pipe == NULL) required = self->pending; if (self->pipe == NULL && self->pending == 0) engine_set_exception (self, pipe_shut_event); else if (self->pending >= required) { // Create a bucket chunk with the required max size zchunk_t *bucket = zchunk_new (NULL, required); // Now fill the bucket with chunks from our queue while (zchunk_size (bucket) < required) { // Get next chunk and consume as much of it as possible zchunk_t *chunk = (zchunk_t *) zlist_pop (self->queue); assert (chunk); zchunk_consume (bucket, chunk); // If chunk is exhausted, destroy it if (zchunk_exhausted (chunk)) zchunk_destroy (&chunk); else { // Push chunk back for next time zlist_push (self->queue, chunk); assert (zchunk_size (bucket) == required); } } zpipes_msg_set_chunk (self->reply, &bucket); self->pending -= required; } else engine_set_exception (self, not_enough_data_event); }
zchunk_t * zconfig_chunk_save (zconfig_t *self) { assert (self); int size = s_config_execute (self, s_config_save, NULL, 0); // Allow an extra byte so we can null-terminate the data zchunk_t *chunk = zchunk_new (NULL, size + 1); if (chunk) { s_config_execute (self, s_config_save, chunk, 0); // This lets us treat the chunk data as a string zchunk_data (chunk) [zchunk_size (chunk)] = 0; } return chunk; }
ssize_t zpipes_client_read (zpipes_client_t *self, void *data, size_t size, int timeout) { assert (self); zpipes_msg_send_read (self->dealer, size, timeout); zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); if (!reply) { self->error = EINTR; return -1; // Interrupted } ssize_t rc = 0; if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_OK) { zchunk_t *chunk = zpipes_msg_chunk (reply); ssize_t bytes = zchunk_size (chunk); assert (bytes <= size); memcpy (data, zchunk_data (chunk), bytes); rc = bytes; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_END) rc = 0; else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_TIMEOUT) { self->error = EAGAIN; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_FAILED) { // TODO: better error code? // This happens if we close a pipe while there's a pending read self->error = EINTR; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_INVALID) { self->error = EBADF; rc = -1; } zpipes_msg_destroy (&reply); return rc; }
zchunk_t * zfile_read (zfile_t *self, size_t bytes, off_t offset) { assert (self); assert (self->handle); // Calculate real number of bytes to read if (offset > self->cursize) bytes = 0; else if (bytes > (size_t) (self->cursize - offset)) bytes = (size_t) (self->cursize - offset); if (fseek (self->handle, (long) offset, SEEK_SET) == -1) return NULL; self->eof = false; zchunk_t *chunk = zchunk_read (self->handle, bytes); if (chunk) self->eof = zchunk_size (chunk) < bytes; return chunk; }
static void pipe_send_data (pipe_t *self, zchunk_t **chunk_p) { assert (self); assert (self->reader); zchunk_t *chunk = *chunk_p; assert (chunk); if (self->reader == REMOTE_NODE) { // Send chunk to remote node reader zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "DATA"); zmsg_addstr (msg, self->name); zmsg_addmem (msg, zchunk_data (chunk), zchunk_size (chunk)); zyre_whisper (self->server->zyre, self->remote, &msg); zchunk_destroy (chunk_p); } else { client_store_chunk (self->reader, chunk_p); engine_send_event (self->reader, have_data_event); } }
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 zfile_test (bool verbose) { printf (" * zfile: "); // @selftest zfile_t *file = zfile_new (NULL, "bilbo"); assert (streq (zfile_filename (file, "."), "bilbo")); assert (zfile_is_readable (file) == false); zfile_destroy (&file); // Create a test file in some random subdirectory file = zfile_new ("./this/is/a/test", "bilbo"); int rc = zfile_output (file); assert (rc == 0); zchunk_t *chunk = zchunk_new (NULL, 100); zchunk_fill (chunk, 0, 100); // Write 100 bytes at position 1,000,000 in the file rc = zfile_write (file, chunk, 1000000); assert (rc == 0); zchunk_destroy (&chunk); zfile_close (file); assert (zfile_is_readable (file)); assert (zfile_cursize (file) == 1000100); assert (!zfile_is_stable (file)); // Now append one byte to file from outside int handle = open ("./this/is/a/test/bilbo", O_WRONLY | O_TRUNC | O_BINARY, 0); assert (handle >= 0); rc = write (handle, "Hello, World\n", 13); assert (rc == 13); close (handle); assert (zfile_has_changed (file)); zclock_sleep (1001); assert (zfile_has_changed (file)); assert (!zfile_is_stable (file)); zfile_restat (file); assert (zfile_is_stable (file)); assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54")); // Check we can read from file rc = zfile_input (file); assert (rc == 0); chunk = zfile_read (file, 1000100, 0); assert (chunk); assert (zchunk_size (chunk) == 13); zchunk_destroy (&chunk); zfile_close (file); // Try some fun with symbolic links zfile_t *link = zfile_new ("./this/is/a/test", "bilbo.ln"); rc = zfile_output (link); assert (rc == 0); fprintf (zfile_handle (link), "./this/is/a/test/bilbo\n"); zfile_destroy (&link); link = zfile_new ("./this/is/a/test", "bilbo.ln"); rc = zfile_input (link); assert (rc == 0); chunk = zfile_read (link, 1000100, 0); assert (chunk); assert (zchunk_size (chunk) == 13); zchunk_destroy (&chunk); zfile_destroy (&link); // Remove file and directory zdir_t *dir = zdir_new ("./this", NULL); assert (zdir_cursize (dir) == 26); zdir_remove (dir, true); assert (zdir_cursize (dir) == 0); zdir_destroy (&dir); // Check we can no longer read from file assert (zfile_is_readable (file)); zfile_restat (file); assert (!zfile_is_readable (file)); rc = zfile_input (file); assert (rc == -1); zfile_destroy (&file); // @end printf ("OK\n"); }
static void zhttp_client_actor (zsock_t *pipe, void *args) { curl_global_init (CURL_GLOBAL_ALL); CURLM *multi = curl_multi_init (); CURLSH *share = curl_share_init (); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); long verbose = (*(bool *) args) ? 1L : 0L; CURLMcode code; SOCKET pipefd = zsock_fd (pipe); struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN}; // List to hold pending curl handles, in case we are destroy the client // while request are inprogress zlistx_t *pending_handles = zlistx_new (); zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor); zsock_signal (pipe, 0); bool terminated = false; while (!terminated) { if (!zsock_has_in (pipe)) { code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL); assert (code == CURLM_OK); } if (zsock_has_in (pipe)) { char *command = zstr_recv (pipe); if (!command) break; // Interrupted // All actors must handle $TERM in this way if (streq (command, "$TERM")) terminated = true; else if (streq (command, "GET")) { char *url; zlistx_t *headers; int timeout; void *handler; void *arg; int rc = zsock_recv (pipe, "slipp", &url, &headers, &timeout, &handler, &arg); assert (rc == 0); zchunk_t *response = zchunk_new (NULL, 100); assert (response); struct curl_slist *curl_headers = zlistx_to_slist (headers); CURL *curl = curl_easy_init (); zlistx_add_end (pending_handles, curl); http_request *request = (http_request *) zmalloc (sizeof (http_request)); assert (request); request->handler = handler; request->arg = arg; request->curl = curl; request->response = response; request->headers = curl_headers; request->body = NULL; curl_easy_setopt (curl, CURLOPT_SHARE, share); curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long)timeout); curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose); curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt (curl, CURLOPT_WRITEDATA, response); curl_easy_setopt (curl, CURLOPT_PRIVATE, request); code = curl_multi_add_handle (multi, curl); assert (code == CURLM_OK); zlistx_destroy (&headers); zstr_free (&url); } else if (streq (command, "POST")) { char *url; zlistx_t *headers; zchunk_t *body; int timeout; void *handler; void *arg; int rc = zsock_recv (pipe, "slcipp", &url, &headers, &body, &timeout, &handler, &arg); assert (rc == 0); zchunk_t *response = zchunk_new (NULL, 100); assert (response); struct curl_slist *curl_headers = zlistx_to_slist (headers); CURL *curl = curl_easy_init (); zlistx_add_end (pending_handles, curl); http_request *request = (http_request *) zmalloc (sizeof (http_request)); assert (request); request->handler = handler; request->arg = arg; request->curl = curl; request->response = response; request->headers = curl_headers; request->body = body; curl_easy_setopt (curl, CURLOPT_SHARE, share); curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long)timeout); curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose); curl_easy_setopt (curl, CURLOPT_POSTFIELDS, zchunk_data (body)); curl_easy_setopt (curl, CURLOPT_POSTFIELDSIZE, zchunk_size (body)); curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt (curl, CURLOPT_WRITEDATA, response); curl_easy_setopt (curl, CURLOPT_PRIVATE, request); code = curl_multi_add_handle (multi, curl); assert (code == CURLM_OK); zlistx_destroy (&headers); zstr_free (&url); } else { puts ("E: invalid message to actor"); assert (false); } zstr_free (&command); } int still_running; code = curl_multi_perform (multi, &still_running); assert (code == CURLM_OK); int msgq = 0; struct CURLMsg *msg = curl_multi_info_read (multi, &msgq); while (msg) { if (msg->msg == CURLMSG_DONE) { CURL *curl = msg->easy_handle; http_request *request; curl_easy_getinfo (curl, CURLINFO_PRIVATE, &request); long response_code_long; curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long); int response_code = (int) response_code_long; if (response_code == 0 && msg->data.result == CURLE_OPERATION_TIMEDOUT) response_code = -1; int rc = zsock_send (pipe, "icpp", response_code, request->response, request->handler, request->arg); assert (rc == 0); curl_multi_remove_handle (multi, curl); // Remove curl from the pending handles and delete it void *handle = zlistx_find (pending_handles, curl); assert (handle); rc = zlistx_delete (pending_handles, handle); assert (rc == 0); } msg = curl_multi_info_read (multi, &msgq); } } zlistx_destroy (&pending_handles); curl_share_cleanup (share); curl_multi_cleanup (multi); curl_global_cleanup (); }
/// // Return chunk cur size size_t QZchunk::size () { size_t rv = zchunk_size (self); return rv; }
static void get_next_patch_for_client (server_t *self, client_t *client) { // Get next patch for client if we're not doing one already if (client->patch == NULL) client->patch = (zdir_patch_t *) zlist_pop (client->patches); if (client->patch == NULL) { client->next_event = finished_event; return; } // Get virtual path from patch fmq_msg_set_filename (client->reply, zdir_patch_vpath (client->patch)); // We can process a delete patch right away if (zdir_patch_op (client->patch) == patch_delete) { fmq_msg_set_sequence (client->reply, client->sequence++); fmq_msg_set_operation (client->reply, FMQ_MSG_FILE_DELETE); client->next_event = send_delete_event; // No reliability in this version, assume patch delivered safely zdir_patch_destroy (&client->patch); } else if (zdir_patch_op (client->patch) == patch_create) { // Create patch refers to file, open that for input if needed if (client->file == NULL) { client->file = zfile_dup (zdir_patch_file (client->patch)); if (zfile_input (client->file)) { // File no longer available, skip it zdir_patch_destroy (&client->patch); zfile_destroy (&client->file); client->next_event = next_patch_event; return; } client->offset = 0; } // Get next chunk for file zchunk_t *chunk = zfile_read (client->file, CHUNK_SIZE, client->offset); assert (chunk); // Check if we have the credit to send chunk if (zchunk_size (chunk) <= client->credit) { fmq_msg_set_sequence (client->reply, client->sequence++); fmq_msg_set_operation (client->reply, FMQ_MSG_FILE_CREATE); fmq_msg_set_offset (client->reply, client->offset); fmq_msg_set_chunk (client->reply, zframe_new ( zchunk_data (chunk), zchunk_size (chunk))); client->offset += zchunk_size (chunk); client->credit -= zchunk_size (chunk); client->next_event = send_chunk_event; // Zero-sized chunk means end of file if (zchunk_size (chunk) == 0) { zfile_destroy (&client->file); zdir_patch_destroy (&client->patch); } } else client->next_event = no_credit_event; zchunk_destroy (&chunk); } }
int zproto_example_send (zproto_example_t *self, zsock_t *output) { assert (self); assert (output); if (zsock_type (output) == ZMQ_ROUTER) zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZPROTO_EXAMPLE_LOG: frame_size += 2; // sequence frame_size += 2; // version frame_size += 1; // level frame_size += 1; // event frame_size += 2; // node frame_size += 2; // peer frame_size += 8; // time frame_size += 1 + strlen (self->host); frame_size += 4; if (self->data) frame_size += strlen (self->data); break; case ZPROTO_EXAMPLE_STRUCTURES: frame_size += 2; // sequence frame_size += 4; // Size is 4 octets if (self->aliases) { char *aliases = (char *) zlist_first (self->aliases); while (aliases) { frame_size += 4 + strlen (aliases); aliases = (char *) zlist_next (self->aliases); } } frame_size += 4; // Size is 4 octets if (self->headers) { self->headers_bytes = 0; char *item = (char *) zhash_first (self->headers); while (item) { self->headers_bytes += 1 + strlen (zhash_cursor (self->headers)); self->headers_bytes += 4 + strlen (item); item = (char *) zhash_next (self->headers); } } frame_size += self->headers_bytes; break; case ZPROTO_EXAMPLE_BINARY: frame_size += 2; // sequence frame_size += 4; // flags frame_size += 4; // Size is 4 octets if (self->public_key) frame_size += zchunk_size (self->public_key); frame_size += ZUUID_LEN; // identifier break; case ZPROTO_EXAMPLE_TYPES: frame_size += 2; // sequence frame_size += 1 + strlen (self->client_forename); frame_size += 1 + strlen (self->client_surname); frame_size += 1 + strlen (self->client_mobile); frame_size += 1 + strlen (self->client_email); frame_size += 1 + strlen (self->supplier_forename); frame_size += 1 + strlen (self->supplier_surname); frame_size += 1 + strlen (self->supplier_mobile); frame_size += 1 + strlen (self->supplier_email); break; } // Now serialize message into the frame zmq_msg_t frame; zmq_msg_init_size (&frame, frame_size); self->needle = (byte *) zmq_msg_data (&frame); PUT_NUMBER2 (0xAAA0 | 0); PUT_NUMBER1 (self->id); bool have_content = false; size_t nbr_frames = 1; // Total number of frames to send switch (self->id) { case ZPROTO_EXAMPLE_LOG: PUT_NUMBER2 (self->sequence); PUT_NUMBER2 (3); PUT_NUMBER1 (self->level); PUT_NUMBER1 (self->event); PUT_NUMBER2 (self->node); PUT_NUMBER2 (self->peer); PUT_NUMBER8 (self->time); PUT_STRING (self->host); if (self->data) { PUT_LONGSTR (self->data); } else PUT_NUMBER4 (0); // Empty string break; case ZPROTO_EXAMPLE_STRUCTURES: PUT_NUMBER2 (self->sequence); if (self->aliases) { PUT_NUMBER4 (zlist_size (self->aliases)); char *aliases = (char *) zlist_first (self->aliases); while (aliases) { PUT_LONGSTR (aliases); aliases = (char *) zlist_next (self->aliases); } } else PUT_NUMBER4 (0); // Empty string array if (self->headers) { PUT_NUMBER4 (zhash_size (self->headers)); char *item = (char *) zhash_first (self->headers); while (item) { PUT_STRING (zhash_cursor (self->headers)); PUT_LONGSTR (item); item = (char *) zhash_next (self->headers); } } else PUT_NUMBER4 (0); // Empty hash break; case ZPROTO_EXAMPLE_BINARY: PUT_NUMBER2 (self->sequence); PUT_OCTETS (self->flags, 4); if (self->public_key) { PUT_NUMBER4 (zchunk_size (self->public_key)); memcpy (self->needle, zchunk_data (self->public_key), zchunk_size (self->public_key)); self->needle += zchunk_size (self->public_key); } else PUT_NUMBER4 (0); // Empty chunk if (self->identifier) zuuid_export (self->identifier, self->needle); else memset (self->needle, 0, ZUUID_LEN); self->needle += ZUUID_LEN; nbr_frames++; nbr_frames += self->content? zmsg_size (self->content): 1; have_content = true; break; case ZPROTO_EXAMPLE_TYPES: PUT_NUMBER2 (self->sequence); PUT_STRING (self->client_forename); PUT_STRING (self->client_surname); PUT_STRING (self->client_mobile); PUT_STRING (self->client_email); PUT_STRING (self->supplier_forename); PUT_STRING (self->supplier_surname); PUT_STRING (self->supplier_mobile); PUT_STRING (self->supplier_email); break; } // Now send the data frame zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0); // Now send any frame fields, in order if (self->id == ZPROTO_EXAMPLE_BINARY) { // If address isn't set, send an empty frame if (self->address) zframe_send (&self->address, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); else zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0)); } // Now send the content if necessary if (have_content) { if (self->content) { zframe_t *frame = zmsg_first (self->content); while (frame) { zframe_send (&frame, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0)); frame = zmsg_next (self->content); } } else zmq_send (zsock_resolve (output), NULL, 0, 0); } return 0; }
void zfile_test (bool verbose) { printf (" * zfile: "); // @selftest const char *SELFTEST_DIR_RW = "src/selftest-rw"; const char *testbasedir = "this"; const char *testsubdir = "is/a/test"; const char *testfile = "bilbo"; const char *testlink = "bilbo.ln"; char *basedirpath = NULL; // subdir in a test, under SELFTEST_DIR_RW char *dirpath = NULL; // subdir in a test, under basedirpath char *filepath = NULL; // pathname to testfile in a test, in dirpath char *linkpath = NULL; // pathname to testlink in a test, in dirpath basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir); assert (basedirpath); dirpath = zsys_sprintf ("%s/%s", basedirpath, testsubdir); assert (dirpath); filepath = zsys_sprintf ("%s/%s", dirpath, testfile); assert (filepath); linkpath = zsys_sprintf ("%s/%s", dirpath, testlink); assert (linkpath); // This subtest is specifically for NULL as current directory, so // no SELFTEST_DIR_RW here; testfile should have no slashes inside. // Normally tests clean up in zfile_destroy(), but if a selftest run // dies e.g. on assert(), workspace remains dirty. Better clean it up. if (zfile_exists (testfile) ) { if (verbose) zsys_debug ("zfile_test() has to remove ./%s that should not have been here", testfile); zfile_delete (testfile); } zfile_t *file = zfile_new (NULL, testfile); assert (file); assert (streq (zfile_filename (file, "."), testfile)); assert (zfile_is_readable (file) == false); zfile_destroy (&file); // Create a test file in some random subdirectory if (verbose) zsys_debug ("zfile_test() at timestamp %" PRIi64 ": " "Creating new zfile %s", zclock_time(), filepath ); if (zfile_exists (filepath) ) { if (verbose) zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath); zfile_delete (filepath); } file = zfile_new (dirpath, testfile); assert (file); int rc = zfile_output (file); assert (rc == 0); zchunk_t *chunk = zchunk_new (NULL, 100); assert (chunk); zchunk_fill (chunk, 0, 100); // Write 100 bytes at position 1,000,000 in the file if (verbose) zsys_debug ("zfile_test() at timestamp %" PRIi64 ": " "Writing 100 bytes at position 1,000,000 in the file", zclock_time() ); rc = zfile_write (file, chunk, 1000000); if (verbose) zsys_debug ("zfile_test() at timestamp %" PRIi64 ": " "Wrote 100 bytes at position 1,000,000 in the file, result code %d", zclock_time(), rc ); assert (rc == 0); zchunk_destroy (&chunk); zfile_close (file); assert (zfile_is_readable (file)); assert (zfile_cursize (file) == 1000100); if (verbose) zsys_debug ("zfile_test() at timestamp %" PRIi64 ": " "Testing if file is NOT stable (is younger than 1 sec)", zclock_time() ); assert (!zfile_is_stable (file)); if (verbose) zsys_debug ("zfile_test() at timestamp %" PRIi64 ": " "Passed the lag-dependent tests", zclock_time() ); assert (zfile_digest (file)); // Now truncate file from outside int handle = open (filepath, O_WRONLY | O_TRUNC | O_BINARY, 0); assert (handle >= 0); rc = write (handle, "Hello, World\n", 13); assert (rc == 13); close (handle); assert (zfile_has_changed (file)); #ifdef CZMQ_BUILD_DRAFT_API zclock_sleep ((int)zsys_file_stable_age_msec() + 50); #else zclock_sleep (5050); #endif assert (zfile_has_changed (file)); assert (!zfile_is_stable (file)); zfile_restat (file); assert (zfile_is_stable (file)); assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54")); // Check we can read from file rc = zfile_input (file); assert (rc == 0); chunk = zfile_read (file, 1000100, 0); assert (chunk); assert (zchunk_size (chunk) == 13); zchunk_destroy (&chunk); zfile_close (file); // Check we can read lines from file rc = zfile_input (file); assert (rc == 0); const char *line = zfile_readln (file); assert (streq (line, "Hello, World")); line = zfile_readln (file); assert (line == NULL); zfile_close (file); // Try some fun with symbolic links zfile_t *link = zfile_new (dirpath, testlink); assert (link); rc = zfile_output (link); assert (rc == 0); fprintf (zfile_handle (link), "%s\n", filepath); zfile_destroy (&link); link = zfile_new (dirpath, testlink); assert (link); rc = zfile_input (link); assert (rc == 0); chunk = zfile_read (link, 1000100, 0); assert (chunk); assert (zchunk_size (chunk) == 13); zchunk_destroy (&chunk); zfile_destroy (&link); // Remove file and directory zdir_t *dir = zdir_new (basedirpath, NULL); assert (dir); assert (zdir_cursize (dir) == 26); zdir_remove (dir, true); assert (zdir_cursize (dir) == 0); zdir_destroy (&dir); // Check we can no longer read from file assert (zfile_is_readable (file)); zfile_restat (file); assert (!zfile_is_readable (file)); rc = zfile_input (file); assert (rc == -1); zfile_destroy (&file); // This set of tests is done, free the strings for reuse zstr_free (&basedirpath); zstr_free (&dirpath); zstr_free (&filepath); zstr_free (&linkpath); const char *eof_checkfile = "eof_checkfile"; filepath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, eof_checkfile); assert (filepath); if (zfile_exists (filepath) ) { if (verbose) zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath); zfile_delete (filepath); } zstr_free (&filepath); file = zfile_new (SELFTEST_DIR_RW, eof_checkfile); assert (file); // 1. Write something first rc = zfile_output (file); assert (rc == 0); chunk = zchunk_new ("123456789", 9); assert (chunk); rc = zfile_write (file, chunk, 0); assert (rc == 0); zchunk_destroy (&chunk); zfile_close (file); assert (zfile_cursize (file) == 9); // 2. Read the written something rc = zfile_input (file); assert (rc != -1); // try to read more bytes than there is in the file chunk = zfile_read (file, 1000, 0); assert (zfile_eof(file)); assert (zchunk_streq (chunk, "123456789")); zchunk_destroy (&chunk); // reading is ok chunk = zfile_read (file, 5, 0); assert (!zfile_eof(file)); assert (zchunk_streq (chunk, "12345")); zchunk_destroy (&chunk); // read from non zero offset until the end chunk = zfile_read (file, 5, 5); assert (zfile_eof(file)); assert (zchunk_streq (chunk, "6789")); zchunk_destroy (&chunk); zfile_remove (file); zfile_close (file); zfile_destroy (&file); #ifdef CZMQ_BUILD_DRAFT_API zfile_t *tempfile = zfile_tmp (); assert (tempfile); assert (zfile_filename (tempfile, NULL)); assert (zsys_file_exists (zfile_filename (tempfile, NULL))); zchunk_t *tchunk = zchunk_new ("HELLO", 6); assert (zfile_write (tempfile, tchunk, 0) == 0); zchunk_destroy (&tchunk); char *filename = strdup (zfile_filename (tempfile, NULL)); zfile_destroy (&tempfile); assert (!zsys_file_exists (filename)); zstr_free (&filename); #endif // CZMQ_BUILD_DRAFT_API #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
int fmq_msg_send (fmq_msg_t *self, zsock_t *output) { assert (self); assert (output); if (zsock_type (output) == ZMQ_ROUTER) zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE); size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case FMQ_MSG_OHAI: frame_size += 1 + strlen ("FILEMQ"); frame_size += 2; // version break; case FMQ_MSG_ICANHAZ: frame_size += 4; if (self->path) frame_size += strlen (self->path); frame_size += 4; // Size is 4 octets if (self->options) { self->options_bytes = 0; char *item = (char *) zhash_first (self->options); while (item) { self->options_bytes += 1 + strlen (zhash_cursor (self->options)); self->options_bytes += 4 + strlen (item); item = (char *) zhash_next (self->options); } } frame_size += self->options_bytes; frame_size += 4; // Size is 4 octets if (self->cache) { self->cache_bytes = 0; char *item = (char *) zhash_first (self->cache); while (item) { self->cache_bytes += 1 + strlen (zhash_cursor (self->cache)); self->cache_bytes += 4 + strlen (item); item = (char *) zhash_next (self->cache); } } frame_size += self->cache_bytes; break; case FMQ_MSG_NOM: frame_size += 8; // credit frame_size += 8; // sequence break; case FMQ_MSG_CHEEZBURGER: frame_size += 8; // sequence frame_size += 1; // operation frame_size += 4; if (self->filename) frame_size += strlen (self->filename); frame_size += 8; // offset frame_size += 1; // eof frame_size += 4; // Size is 4 octets if (self->headers) { self->headers_bytes = 0; char *item = (char *) zhash_first (self->headers); while (item) { self->headers_bytes += 1 + strlen (zhash_cursor (self->headers)); self->headers_bytes += 4 + strlen (item); item = (char *) zhash_next (self->headers); } } frame_size += self->headers_bytes; frame_size += 4; // Size is 4 octets if (self->chunk) frame_size += zchunk_size (self->chunk); break; case FMQ_MSG_SRSLY: frame_size += 1 + strlen (self->reason); break; case FMQ_MSG_RTFM: frame_size += 1 + strlen (self->reason); break; } // Now serialize message into the frame zmq_msg_t frame; zmq_msg_init_size (&frame, frame_size); self->needle = (byte *) zmq_msg_data (&frame); PUT_NUMBER2 (0xAAA0 | 3); PUT_NUMBER1 (self->id); size_t nbr_frames = 1; // Total number of frames to send switch (self->id) { case FMQ_MSG_OHAI: PUT_STRING ("FILEMQ"); PUT_NUMBER2 (FMQ_MSG_VERSION); break; case FMQ_MSG_ICANHAZ: if (self->path) { PUT_LONGSTR (self->path); } else PUT_NUMBER4 (0); // Empty string if (self->options) { PUT_NUMBER4 (zhash_size (self->options)); char *item = (char *) zhash_first (self->options); while (item) { PUT_STRING (zhash_cursor (self->options)); PUT_LONGSTR (item); item = (char *) zhash_next (self->options); } } else PUT_NUMBER4 (0); // Empty hash if (self->cache) { PUT_NUMBER4 (zhash_size (self->cache)); char *item = (char *) zhash_first (self->cache); while (item) { PUT_STRING (zhash_cursor (self->cache)); PUT_LONGSTR (item); item = (char *) zhash_next (self->cache); } } else PUT_NUMBER4 (0); // Empty hash break; case FMQ_MSG_NOM: PUT_NUMBER8 (self->credit); PUT_NUMBER8 (self->sequence); break; case FMQ_MSG_CHEEZBURGER: PUT_NUMBER8 (self->sequence); PUT_NUMBER1 (self->operation); if (self->filename) { PUT_LONGSTR (self->filename); } else PUT_NUMBER4 (0); // Empty string PUT_NUMBER8 (self->offset); PUT_NUMBER1 (self->eof); if (self->headers) { PUT_NUMBER4 (zhash_size (self->headers)); char *item = (char *) zhash_first (self->headers); while (item) { PUT_STRING (zhash_cursor (self->headers)); PUT_LONGSTR (item); item = (char *) zhash_next (self->headers); } } else PUT_NUMBER4 (0); // Empty hash if (self->chunk) { PUT_NUMBER4 (zchunk_size (self->chunk)); memcpy (self->needle, zchunk_data (self->chunk), zchunk_size (self->chunk)); self->needle += zchunk_size (self->chunk); } else PUT_NUMBER4 (0); // Empty chunk break; case FMQ_MSG_SRSLY: PUT_STRING (self->reason); break; case FMQ_MSG_RTFM: PUT_STRING (self->reason); break; } // Now send the data frame zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0); return 0; }
void zsync_node_engine (void *args, zctx_t *ctx, void *pipe) { int rc; zsync_node_t *self = zsync_node_new (); self->ctx = ctx; self->zyre = zyre_new (ctx); self->zsync_pipe = pipe; // Join group rc = zyre_join (self->zyre, "ZSYNC"); assert (rc == 0); // Give time to interconnect zclock_sleep (250); zpoller_t *poller = zpoller_new (zyre_socket (self->zyre), self->zsync_pipe, NULL); // Create thread for file management self->file_pipe = zthread_fork (self->ctx, zsync_ftmanager_engine, NULL); zpoller_add (poller, self->file_pipe); // Create thread for credit management self->credit_pipe = zthread_fork (self->ctx, zsync_credit_manager_engine, NULL); zpoller_add (poller, self->credit_pipe); // Start receiving messages printf("[ND] started\n"); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (self->zyre)) { zsync_node_recv_from_zyre (self); } else if (which == self->zsync_pipe) { printf("[ND] Recv Agent\n"); zsync_node_recv_from_agent (self); } else if (which == self->file_pipe) { printf("[ND] Recv FT Manager\n"); zsync_ftm_msg_t *msg = zsync_ftm_msg_recv (self->file_pipe); char *receiver = zsync_ftm_msg_receiver (msg); char *zyre_uuid = zsync_node_zyre_uuid (self, receiver); if (zyre_uuid) { char *path = zsync_ftm_msg_path (msg); uint64_t sequence = zsync_ftm_msg_sequence (msg); uint64_t chunk_size = zsync_ftm_msg_chunk_size (msg); uint64_t offset = zsync_ftm_msg_offset (msg); zsync_msg_send_req_chunk (pipe, path, chunk_size, offset); zsync_msg_t *zsmsg = zsync_msg_recv (pipe); zchunk_t *chunk = zsync_msg_chunk (zsmsg); zframe_t *frame = zframe_new (zchunk_data (chunk), zchunk_size (chunk)); zmsg_t *zmsg = zmsg_new (); zs_msg_pack_chunk (zmsg, sequence, path, offset, frame); zyre_whisper (self->zyre, zyre_uuid, &zmsg); zsync_ftm_msg_destroy (&msg); zsync_msg_destroy (&zsmsg); } } else if (which == self->credit_pipe) { printf("[ND] Recv Credit Manager\n"); zsync_credit_msg_t *cmsg = zsync_credit_msg_recv (self->credit_pipe); char *receiver = zsync_credit_msg_receiver (cmsg); char *zyre_uuid = zsync_node_zyre_uuid (self, receiver); if (zyre_uuid) { zmsg_t *credit_msg = zsync_credit_msg_credit (cmsg); assert (rc == 0); zyre_whisper (self->zyre, zyre_uuid, &credit_msg); } zsync_credit_msg_destroy (&cmsg); } if (self->terminated) { break; } } zpoller_destroy (&poller); zsync_node_destroy (&self); printf("[ND] stopped\n"); }
JNIEXPORT jlong JNICALL Java_org_zeromq_czmq_Zchunk__1_1size (JNIEnv *env, jclass c, jlong self) { jlong size_ = (jlong) zchunk_size ((zchunk_t *) (intptr_t) self); return size_; }