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 int s_file_compare (void *item1, void *item2) { assert (item1); assert (item2); return strcmp (zfile_filename ((zfile_t *) item1, NULL), zfile_filename ((zfile_t *) item2, NULL)); }
void zdir_patch_test (bool verbose) { printf (" * zdir_patch: "); // @selftest zfile_t *file = zfile_new (".", "bilbo"); assert (file); zdir_patch_t *patch = zdir_patch_new (".", file, patch_create, "/"); assert (patch); zfile_destroy (&file); file = zdir_patch_file (patch); assert (file); assert (streq (zfile_filename (file, "."), "bilbo")); assert (streq (zdir_patch_vpath (patch), "/bilbo")); zdir_patch_destroy (&patch); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
zdir_patch_t * zdir_patch_new (const char *path, zfile_t *file, zdir_patch_op_t op, const char *alias) { zdir_patch_t *self = (zdir_patch_t *) zmalloc (sizeof (zdir_patch_t)); if (!self) return NULL; self->path = strdup (path); if (self->path) self->file = zfile_dup (file); if (!self->file) { zdir_patch_destroy (&self); return NULL; } self->op = op; // Calculate virtual path for patch (remove path, prefix alias) char *filename = zfile_filename (file, path); if (!filename) { zdir_patch_destroy (&self); return NULL; } assert (*filename != '/'); self->vpath = (char *) zmalloc (strlen (alias) + strlen (filename) + 2); if (alias [strlen (alias) - 1] == '/') sprintf (self->vpath, "%s%s", alias, filename); else sprintf (self->vpath, "%s/%s", alias, filename); return self; }
const char * zconfig_filename (zconfig_t *self) { assert (self); if (self->file) return (zfile_filename (self->file, NULL)); else return NULL; }
JNIEXPORT jstring JNICALL Java_org_zeromq_czmq_Zfile__1_1filename (JNIEnv *env, jclass c, jlong self, jstring path) { char *path_ = (char *) (*env)->GetStringUTFChars (env, path, NULL); char *filename_ = (char *) zfile_filename ((zfile_t *) (intptr_t) self, path_); jstring return_string_ = (*env)->NewStringUTF (env, filename_); (*env)->ReleaseStringUTFChars (env, path, path_); return return_string_; }
static int s_on_read_timer (zloop_t *loop, int timer_id, void *arg) { zdir_watch_t *watch = (zdir_watch_t *) arg; void *data; for (data = zhash_first (watch->subs); data != NULL; data = zhash_next (watch->subs)) { zdir_watch_sub_t *sub = (zdir_watch_sub_t *) data; zdir_t *new_dir = zdir_new (zdir_path (sub->dir), NULL); if (!new_dir) { if (watch->verbose) zsys_error ("zdir_watch: Unable to create new zdir for path %s", zdir_path (sub->dir)); continue; } // Determine if anything has changed. zlist_t *diff = zdir_diff (sub->dir, new_dir, ""); // Do memory management before error handling... zdir_destroy (&sub->dir); sub->dir = new_dir; if (!diff) { if (watch->verbose) zsys_error ("zdir_watch: Unable to create diff for path %s", zdir_path (sub->dir)); continue; } if (zlist_size (diff) > 0) { if (watch->verbose) { zdir_patch_t *patch = (zdir_patch_t *) zlist_first (diff); zsys_info ("zdir_watch: Found %d changes in %s:", zlist_size (diff), zdir_path (sub->dir)); while (patch) { zsys_info ("zdir_watch: %s %s", zfile_filename (zdir_patch_file (patch), NULL), zdir_patch_op (patch) == ZDIR_PATCH_CREATE? "created": "deleted"); patch = (zdir_patch_t *) zlist_next (diff); } } if (zsock_send (watch->pipe, "sp", zdir_path (sub->dir), diff) != 0) { if (watch->verbose) zsys_error ("zdir_watch: Unable to send patch list for path %s", zdir_path (sub->dir)); zlist_destroy (&diff); } // Successfully sent `diff` list - now owned by receiver } else { zlist_destroy (&diff); } } return 0; }
zhash_t * zdir_cache (zdir_t *self) { assert (self); // Load any previous cache from disk zhash_t *cache = zhash_new (); if (!cache) return NULL; zhash_autofree (cache); char *cache_file = (char *) zmalloc (strlen (self->path) + strlen ("/.cache") + 1); if (!cache_file) { zhash_destroy (&cache); return NULL; } sprintf (cache_file, "%s/.cache", self->path); zhash_load (cache, cache_file); // Recalculate digest for any new files zfile_t **files = zdir_flatten (self); uint index; for (index = 0;; index++) { zfile_t *file = files [index]; if (!file) break; const char *filename = zfile_filename (file, self->path); if (zhash_lookup (cache, zfile_filename (file, self->path)) == NULL) { int rc = zhash_insert (cache, filename, (void *) zfile_digest (file)); if (rc != 0) { zhash_destroy (&cache); break; } } } freen (files); // Save cache to disk for future reference if (cache) zhash_save (cache, cache_file); freen (cache_file); return cache; }
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; }
void zdir_fprint (zdir_t *self, FILE *stream, int indent) { assert (self); zfile_t **files = zdir_flatten (self); uint index; for (index = 0;; index++) { zfile_t *file = files [index]; if (!file) break; fprintf (stream, "%s\n", zfile_filename (file, NULL)); } zdir_flatten_free (&files); }
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 }
// -------------------------------------------------------------------------- // Self test of this class int zdir_patch_test (bool verbose) { printf (" * zdir_patch: "); // @selftest zfile_t *file = zfile_new (".", "bilbo"); zdir_patch_t *patch = zdir_patch_new (".", file, patch_create, "/"); zfile_destroy (&file); file = zdir_patch_file (patch); assert (streq (zfile_filename (file, "."), "bilbo")); assert (streq (zdir_patch_vpath (patch), "/bilbo")); zdir_patch_destroy (&patch); // @end printf ("OK\n"); return 0; }
/// // Return file name, remove path if provided const QString QZfile::filename (const QString &path) { const QString rv = QString (zfile_filename (self, path.toUtf8().data())); return rv; }
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"); }
zlist_t * zdir_diff (zdir_t *older, zdir_t *newer, const char *alias) { zlist_t *patches = zlist_new (); if (!patches) return NULL; zfile_t **old_files = zdir_flatten (older); zfile_t **new_files = zdir_flatten (newer); int old_index = 0; int new_index = 0; // Note that both lists are sorted, so detecting differences // is rather trivial while (old_files [old_index] || new_files [new_index]) { zfile_t *old_file = old_files [old_index]; zfile_t *new_file = new_files [new_index]; int cmp; if (!old_file) cmp = 1; // Old file was deleted at end of list else if (!new_file) cmp = -1; // New file was added at end of list else cmp = strcmp (zfile_filename (old_file, NULL), zfile_filename (new_file, NULL)); if (cmp > 0) { // New file was created if (zfile_is_stable (new_file)) { int rc = zlist_append (patches, zdir_patch_new (newer->path, new_file, patch_create, alias)); if (rc != 0) { zlist_destroy (&patches); break; } } old_index--; } else if (cmp < 0) { // Old file was deleted if (zfile_is_stable (old_file)) { int rc = zlist_append (patches, zdir_patch_new (older->path, old_file, patch_delete, alias)); if (rc != 0) { zlist_destroy (&patches); break; } } new_index--; } else if (cmp == 0 && zfile_is_stable (new_file)) { if (zfile_is_stable (old_file)) { // Old file was modified or replaced // Since we don't check file contents, treat as created // Could better do SHA check on file here if (zfile_modified (new_file) != zfile_modified (old_file) || zfile_cursize (new_file) != zfile_cursize (old_file)) { int rc = zlist_append (patches, zdir_patch_new (newer->path, new_file, patch_create, alias)); if (rc != 0) { zlist_destroy (&patches); break; } } } else { // File was created over some period of time int rc = zlist_append (patches, zdir_patch_new (newer->path, new_file, patch_create, alias)); if (rc != 0) { zlist_destroy (&patches); break; } } } old_index++; new_index++; } freen (old_files); freen (new_files); return patches; }
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"); }
/// // Return file name, remove path if provided const QString QmlZfile::filename (const QString &path) { return QString (zfile_filename (self, path.toUtf8().data())); };
void zdir_test (bool verbose) { printf (" * zdir: "); // @selftest // need to create a file in the test directory we're watching // in order to ensure the directory exists zfile_t *initfile = zfile_new ("./zdir-test-dir", "initial_file"); assert (initfile); zfile_output (initfile); fprintf (zfile_handle (initfile), "initial file\n"); zfile_close (initfile); zfile_destroy (&initfile); zdir_t *older = zdir_new ("zdir-test-dir", NULL); assert (older); if (verbose) { printf ("\n"); zdir_dump (older, 0); } zdir_t *newer = zdir_new (".", NULL); assert (newer); zlist_t *patches = zdir_diff (older, newer, "/"); assert (patches); while (zlist_size (patches)) { zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); zdir_patch_destroy (&patch); } zlist_destroy (&patches); zdir_destroy (&older); zdir_destroy (&newer); zdir_t *nosuch = zdir_new ("does-not-exist", NULL); assert (nosuch == NULL); // zdir_watch test: zactor_t *watch = zactor_new (zdir_watch, NULL); assert (watch); int synced; if (verbose) { zsock_send (watch, "s", "VERBOSE"); synced = zsock_wait(watch); assert ( synced == 0); } zclock_sleep (1001); // wait for initial file to become 'stable' zsock_send (watch, "si", "TIMEOUT", 100); synced = zsock_wait(watch); assert (synced == 0); zsock_send (watch, "ss", "SUBSCRIBE", "zdir-test-dir"); synced = zsock_wait(watch); assert(synced == 0); zsock_send (watch, "ss", "UNSUBSCRIBE", "zdir-test-dir"); synced = zsock_wait(watch); assert(synced == 0); zsock_send (watch, "ss", "SUBSCRIBE", "zdir-test-dir"); synced = zsock_wait(watch); assert(synced == 0); zfile_t *newfile = zfile_new ("zdir-test-dir", "test_abc"); zfile_output (newfile); fprintf (zfile_handle (newfile), "test file\n"); zfile_close (newfile); zpoller_t *watch_poll = zpoller_new (watch, NULL); // poll for a certain timeout before giving up and failing the test. void* polled = zpoller_wait(watch_poll, 1001); assert (polled == watch); // wait for notification of the file being added char *path; int rc = zsock_recv (watch, "sp", &path, &patches); assert (rc == 0); assert (streq (path, "zdir-test-dir")); freen (path); assert (zlist_size (patches) == 1); zdir_patch_t *patch = (zdir_patch_t *) zlist_pop (patches); assert (streq (zdir_patch_path (patch), "zdir-test-dir")); zfile_t *patch_file = zdir_patch_file (patch); assert (streq (zfile_filename (patch_file, ""), "zdir-test-dir/test_abc")); zdir_patch_destroy (&patch); zlist_destroy (&patches); // remove the file zfile_remove (newfile); zfile_destroy (&newfile); // poll for a certain timeout before giving up and failing the test. polled = zpoller_wait(watch_poll, 1001); assert (polled == watch); // wait for notification of the file being removed rc = zsock_recv (watch, "sp", &path, &patches); assert (rc == 0); assert (streq (path, "zdir-test-dir")); freen (path); assert (zlist_size (patches) == 1); patch = (zdir_patch_t *) zlist_pop (patches); assert (streq (zdir_patch_path (patch), "zdir-test-dir")); patch_file = zdir_patch_file (patch); assert (streq (zfile_filename (patch_file, ""), "zdir-test-dir/test_abc")); zdir_patch_destroy (&patch); zlist_destroy (&patches); zpoller_destroy (&watch_poll); zactor_destroy (&watch); // clean up by removing the test directory. zdir_t *testdir = zdir_new ("zdir-test-dir", NULL); zdir_remove (testdir, true); zdir_destroy (&testdir); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }