summaryrefslogtreecommitdiff
path: root/support/dktools/dk3dir.ctr
diff options
context:
space:
mode:
Diffstat (limited to 'support/dktools/dk3dir.ctr')
-rw-r--r--support/dktools/dk3dir.ctr1397
1 files changed, 0 insertions, 1397 deletions
diff --git a/support/dktools/dk3dir.ctr b/support/dktools/dk3dir.ctr
deleted file mode 100644
index f50e8c90d8..0000000000
--- a/support/dktools/dk3dir.ctr
+++ /dev/null
@@ -1,1397 +0,0 @@
-%% options
-
-copyright owner = Dirk Krause
-copyright year = 2011-xxxx
-SPDX-License-Identifier: BSD-3-Clause
-
-
-
-%% header
-
-#include "dk3conf.h"
-#include "dk3types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/** Open a directory.
- @param dn Directory name.
- @param app Application structure for diagnostics, may be NULL.
- @return Pointer to directory structure on success, NULL on error.
-*/
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app);
-
-/** Open directory structure to expand a file name.
- @param fn File name.
- @param app Application structure for diagnostics, may be NULL.
- @return Pointer to directory structure on success, NULL on errror.
-*/
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app);
-
-/** Close directory.
- @param dp Directory to close.
-*/
-void
-dk3dir_close(dk3_dir_t *dp);
-
-/** Get number of subdirectories.
- @param d Directory structure.
- @return Number of subdirectories.
-*/
-dk3_um_t
-dk3dir_get_number_of_directories(dk3_dir_t const *d);
-
-/** Get number of files.
- @param d Directory structure.
- @return Number of non-directory entries in directory.
-*/
-dk3_um_t
-dk3dir_get_number_of_files(dk3_dir_t const *d);
-
-/** Attempt to retrieve information about the next sub-directory.
- @param d Directory structure.
- @return 1 on success, 0 on error.
-*/
-int
-dk3dir_get_next_directory(dk3_dir_t *d);
-
-/** Attempt to retrieve information about the next non-sub-directory entry.
- @param d Directory structure.
- @return 1 on success, 0 on error.
-*/
-int
-dk3dir_get_next_file(dk3_dir_t *d);
-
-/** Retrieve short file name of entry found.
- May be used after a successful call to dk3dir_get_next_directory() or
- dk3dir_get_next_file() only.
- @param d Directory structure.
- @return Pointer to file name on success, NULL on error.
-*/
-dkChar const *
-dk3dir_get_shortname(dk3_dir_t const *d);
-
-/** Retrieve full file name of entry found.
- May be used after a successful call to dk3dir_get_next_directory() or
- dk3dir_get_next_file() only.
- @param d Directory structure.
- @return Pointer to file name on success, NULL on error.
-*/
-dkChar const *
-dk3dir_get_fullname(dk3_dir_t const *d);
-
-/** Retrieve file status information.
- May be used after a successful call to dk3dir_get_next_directory() or
- dk3dir_get_next_file() only.
- @param d Directory structure.
- @return Pointer to file name on success, NULL on error.
-*/
-dk3_stat_t const *
-dk3dir_get_stat(dk3_dir_t *d);
-
-/** Reset directory for new traversal.
- @param d Directory structure.
-*/
-void
-dk3dir_reset(dk3_dir_t *d);
-
-/** Retrieve directory name.
- @param dir Directory structure.
- @return Directory path name.
-*/
-dkChar const *
-dk3dir_get_directory_name(dk3_dir_t const *dir);
-
-/** Remove directory recursively, including all contents.
- @param dn Directory name.
- @param app Application structure for diagnostics, may be NULL.
- @return 1 on success, 0 on error.
-*/
-int
-dk3dir_remove_app(dkChar const *dn, dk3_app_t *app);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-%% module
-
-#include "dk3all.h"
-#include "dk3unused.h"
-
-
-
-$!trace-include
-
-
-
-/* Error flags used in ec:
- 1 Failed to allocate memory for name to save.
- 2 Failed to save name to storage.
- 4 Directory name too long.
- 8 stat() failed for full name.
- 16 Failed to list directory contents.
-*/
-
-/** Keywords and texts used in this module.
-*/
-static dkChar const * const kw[] = {
-/* 0 */ dkT("."),
-/* 1 */ dkT(".."),
-#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
-/* 2 */ dkT("\\"),
-/* 3 */ dkT("\\*"),
-#else
-/* 2 */ dkT("/"),
-/* 3 */ dkT("/*"),
-#endif
-/* 4 */ dkT("*"),
-NULL
-};
-
-
-
-/** Compare two directory entries by name.
- @param l Left name.
- @param r Right name.
- @param cr Comparison criteria (ignored).
- @return Comparison result.
-*/
-static
-int
-dk3dir_compare_by_name(void const *l, void const *r, int DK3_ARG_UNUSED(cr) )
-{
- int back = 0;
-
- DK3_UNUSED_ARG(cr)
- if(l) {
- if(r) {
-#if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS
- back = dk3str_casecmp((dkChar const *)l,(dkChar const *)r);
-#else
- back = dk3str_cmp((dkChar const *)l,(dkChar const *)r);
-#endif
- } else { back = 1; }
- } else {
- if(r) { back = -1; }
- }
- return back;
-}
-
-
-
-/** Release all directory entries in a storage.
- @param s Storage to clean up.
- @param i Iterator for \a s.
-*/
-static
-void
-dk3dir_release_entries(dk3_sto_t *s, dk3_sto_it_t *i)
-{
- dkChar *p = NULL; /* Current name to release. */
- $? "+ dk3dir_release_entries"
- if(s) {
- if(i) {
- dk3sto_it_reset(i);
- while((p = (dkChar *)dk3sto_it_next(i)) != NULL) {
- $? ". release entry %!ds", p
- dk3_delete(p);
- }
- dk3sto_it_close(i);
- }
- dk3sto_close(s);
- } $? "- dk3dir_release_entries"
-}
-
-
-
-/** Close directory.
- @param dp Directory to close.
-*/
-void
-dk3dir_close(dk3_dir_t *dp)
-{
- $? "+ dk3dir_close"
- if(dp) {
- dk3dir_release_entries(dp->sdi, dp->idi);
- dk3dir_release_entries(dp->sfi, dp->ifi);
- dp->sdi = NULL; dp->sfi = NULL; dp->idi = NULL; dp->ifi = NULL;
- dk3_release(dp->dirname);
- dk3_release(dp->fullname);
- dp->app = NULL;
- dp->ndir = dp->nfi = DK3_UM_0;
- dk3_delete(dp);
- } $? "- dk3dir_close"
-}
-
-
-
-/** Create new dir structure.
- @param dn Directory name.
- @param app Application structure for diagnostics, may be NULL.
- @return Pointer to new structure on success, NULL on error.
-*/
-static
-dk3_dir_t *
-dk3dir_new(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ok = 0; /* Flag: Success. */
- $? "+ dk3dir_new \"%!ds\"", TR_STR(dn)
- back = dk3_new_app(dk3_dir_t,1,app);
- if(back) {
- back->sdi = NULL; back->sfi = NULL; back->idi = NULL; back->ifi = NULL;
- back->dirname = NULL; back->fullname = NULL; back->app = app;
- back->ndir = back->nfi = DK3_UM_0;
- back->sdi = dk3sto_open_app(app);
- if(back->sdi) {
- back->idi = dk3sto_it_open(back->sdi);
- if(back->idi) {
- back->sfi = dk3sto_open_app(app);
- if(back->sfi) {
- back->ifi = dk3sto_it_open(back->sfi);
- if(back->ifi) {
- dk3sto_set_comp(back->sdi,dk3dir_compare_by_name,0);
- dk3sto_set_comp(back->sfi,dk3dir_compare_by_name,0);
- back->dirname = dk3str_dup_app(dn, NULL);
- if(back->dirname) {
- back->fullname = dk3_new_app(dkChar,DK3_MAX_PATH,app);
- if(back->fullname) {
- ok = 1;
- }
- }
- }
- }
- }
- }
- if(!ok) {
- dk3dir_close(back); back = NULL;
- }
- } $? "- dk3dir_new %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-dkChar const *
-dk3dir_get_directory_name(dk3_dir_t const *dir)
-{
- dkChar const *back = NULL;
- $? "+ dk3dir_get_directory_name"
- if(dir) {
- back = dir->dirname;
- } $? "- dk3dir_get_directory_name \"%!ds\"", TR_STR(back)
- return back;
-}
-
-
-
-void
-dk3dir_reset(dk3_dir_t *d)
-{
- $? "+ dk3dir_reset"
- if(d) {
- dk3sto_it_reset(d->idi);
- dk3sto_it_reset(d->ifi);
- d->shortname = NULL;
- } $? "- dk3dir_reset"
-}
-
-
-
-dk3_um_t
-dk3dir_get_number_of_directories(dk3_dir_t const *d)
-{
- dk3_um_t back = DK3_UM_0;
- if(d) {
- back = d->ndir;
- } $? "= dk3dir_get_number_of_directories %lu", (unsigned long)back
- return back;
-}
-
-
-
-dk3_um_t
-dk3dir_get_number_of_files(dk3_dir_t const *d)
-{
- dk3_um_t back = DK3_UM_0;
- if(d) {
- back = d->nfi;
- } $? "= dk3dir_get_number_of_files %lu", (unsigned long)back
- return back;
-}
-
-
-
-dkChar const *
-dk3dir_get_fullname(dk3_dir_t const *d)
-{
- dkChar const *back = NULL;
- $? "+ dk3dir_get_fullname"
- if(d) {
- back = (dkChar const *)(d->fullname);
- } $? "- dk3dir_get_fullname \"%!ds\"", TR_STR(back)
- return back;
-}
-
-
-
-dk3_stat_t const *
-dk3dir_get_stat(dk3_dir_t *d)
-{
- dk3_stat_t *back = NULL;
- $? "+ dk3dir_get_stat"
- if(d) {
- back = &(d->stb);
- } $? "- dk3dir_get_stat %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-dkChar const *
-dk3dir_get_shortname(dk3_dir_t const *d)
-{
- dkChar const *back = NULL;
- $? "+ dk3dir_get_shortname"
- if(d) {
- back = (dkChar const *)(d->shortname);
- } $? "- dk3dir_get_shortname \"%!ds\"", TR_STR(back)
- return back;
-}
-
-
-
-/** Get next entry.
- @param d Directory structure.
- @param s Iterator for the storage.
- @param isdir Flag: Current entry is a directory.
- @return 1 on success, 0 on error.
-*/
-static
-int
-dk3dir_get_next_entry(dk3_dir_t *d, dk3_sto_it_t *s, int isdir)
-{
- int back = 0;
- int cc = 1; /* Flag: Can continue. */
- size_t sz = 0; /* Directory name length. */
- $? "+ dk3dir_get_next_entry dir=%d", isdir
- do {
- cc = 0;
- d->shortname = (dkChar *)dk3sto_it_next(s);
- if(d->shortname) { $? ". shortname = \"%!ds\"", d->shortname
- cc = 1;
- if(d->dirname) {
- if(dk3str_len(d->dirname)) {
- dk3str_cpy_not_overlapped(d->fullname, d->dirname);
- sz = dk3str_len(d->dirname);
- if(sz > 0) {
- if((d->dirname)[sz - 1] != DK3_CHAR_SEP) {
- dk3str_cat(d->fullname, kw[2]);
- }
- } else {
- dk3str_cat(d->fullname, kw[2]);
- }
- dk3str_cat(d->fullname, d->shortname);
- } else {
- dk3str_cpy_not_overlapped(d->fullname, d->shortname);
- }
- } else {
- dk3str_cpy_not_overlapped(d->fullname, d->shortname);
- }
- if(dk3sf_stat_app(&(d->stb), d->fullname, (dk3_app_t *)(d->app))) {
- switch(((d->stb).ft) & (~(DK3_FT_SYMLINK))) {
- case DK3_FT_DIRECTORY: {
- if(isdir) {
- back = 1; cc = 0;
- }
- } break;
- default: {
- if(!isdir) {
- back = 1; cc = 0;
- }
- } break;
- }
- }
- } $? ". cc = %d shortname=\"%!ds\"", cc, TR_STR(d->shortname)
- } while(cc); $? "- dk3dir_get_next_entry %d", back
- return back;
-}
-
-
-
-int
-dk3dir_get_next_directory(dk3_dir_t *d)
-{
- int back = 0;
- $? "+ dk3dir_get_next_directory"
- if(d) {
- back = dk3dir_get_next_entry(d, d->idi, 1);
- } $? "- dk3dir_get_next_directory %d", back
- return back;
-}
-
-
-
-int
-dk3dir_get_next_file(dk3_dir_t *d)
-{
- int back = 0;
- $? "+ dk3dir_get_next_file"
- if(d) {
- back = dk3dir_get_next_entry(d, d->ifi, 0);
- } $? "- dk3dir_get_next_file %d", back
- return back;
-}
-
-
-
-/** Add a found item to a storage.
- @param s Storage to add item to.
- @param n Item name.
- @param c Pointer to variable to increase to.
- @param ec Pointer to error code variable.
- @param app Application structure for diagnostics.
-*/
-static
-void
-dk3dir_add(dk3_sto_t *s, dkChar const *n, dk3_um_t *c, int *ec, dk3_app_t *app)
-{
- dkChar *newname = NULL; /* New copy of name. */
- dk3_um_t mu = DK3_UM_0; /* Number of entries. */
- $? "+ dk3dir_add \"%!ds\"", TR_STR(n)
- newname = dk3str_dup_app(n,(((*ec) & 1) ? NULL : app));
- if(newname) {
- if(dk3sto_add(s, newname)) {
- mu = *c;
- mu++;
- *c = mu;
- } else {
- dk3_delete(newname);
- *ec |= 2; $? "! failed to store name"
- }
- } else {
- *ec |= 1; $? "! failed to allocate name"
- } $? "- dk3dir_add"
-}
-
-
-
-#if DK3_ON_WINDOWS
-/* +++ Windows +++ */
-#if DK3_CHAR_SIZE > 1
-/* +++ Windows > 8 bit +++ */
-
-
-#if VERSION_BEFORE_2012_04_13
-
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
- intptr_t ffres; /* Result of findfirst(). */
- dkChar *namecopy = NULL; /* New copy of name. */
- struct _wfinddata64_t ffdata; /* Find data. */
- if(dn) {
- if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
- dk3str_cpy_not_overlapped(buffer, dn);
- dk3str_cat(buffer, kw[3]);
- back = dk3dir_new(dn, app);
- if(back) {
- ffres = _wfindfirst64(buffer, &ffdata);
- if(ffres != -1) {
- do {
- if(dk3str_cmp(ffdata.name, kw[0])) {
- if(dk3str_cmp(ffdata.name, kw[1])) {
- if((ffdata.attrib) & _A_SUBDIR) {
- dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
- } else {
- dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
- }
- }
- }
- } while(_wfindnext64(ffres, &ffdata) == 0);
- _findclose(ffres);
- } else {
- ec |= 16;
- if(app) {
- /* ERROR: Failed to open directory! */
- dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else {
- if(app) {
- /* ERROR: Directory name too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
- }
- }
- }
- return back;
-}
-
-
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry names. */
- dkChar myb2[2]; /* Search pattern. */
- dkChar *ptr = NULL; /* Last separator. */
- dkChar *namecopy = NULL; /* New copy of entry name. */
- intptr_t ffres; /* Result from findfirst(). */
- struct _wfinddata64_t ffdata; /* Find data. */
- $? "+ dk3dir_fne_open_app \"%ls\"", fn
- if(fn) {
- if(dk3str_len(fn) < DK3_MAX_PATH) {
- dk3str_cpy_not_overlapped(mybuffer, fn);
- ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
- if(ptr) {
- *ptr = DK3_CHAR_0;
- back = dk3dir_new(mybuffer, app);
- *ptr = DK3_CHAR_SEP;
- } else {
- myb2[0] = DK3_CHAR_0;
- back = dk3dir_new(myb2, app);
- }
- if(back) { $? ". mybuffer = \"%ls\"", mybuffer
- ffres = _wfindfirst64(mybuffer, &ffdata);
- if(ffres != -1) {
- do { $? ". entry \"%ls\"", ffdata.name
- if(dk3str_cmp(ffdata.name, kw[0])) { $? ". comparison ok"
- if(dk3str_cmp(ffdata.name, kw[1])) { $? ". comparison ok"
- if((ffdata.attrib) & _A_SUBDIR) { $? ". sub directory"
- dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
- } else { $? ". regular file"
- dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
- }
- }
- }
- } while(_wfindnext64(ffres, &ffdata) == 0);
- _findclose(ffres);
- } else {
- ec |= 16;
- if(app) {
- /* ERROR: Failed to open directory! */
- dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else {
- /* ERROR: Pattern too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
- }
- } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-#else
-
-
-static
-dk3_dir_t *
-dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
-{
- WIN32_FIND_DATAW wfd; /* Details for file. */
- dkChar b1[DK3_MAX_PATH]; /* Directory base. */
- dkChar b2[DK3_MAX_PATH]; /* Pattern. */
- dkChar *p1; /* Separator. */
- dk3_dir_t *back = NULL;
- HANDLE hSearch; /* File search handle. */
- size_t sz; /* String length. */
- int ok; /* Flag: No error yet. */
- int ec; /* Error code. */
- int isDir; /* Flag: Entry is dir. */
- $? "+ dk3dir_my_open_app \"%!ds\"", dn
- ec = 0;
- if(dn) {
- ok = 0;
- if(usefne) {
- if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
- ok = 1; $? ". ok"
- dk3str_cpy_not_overlapped(b1, dn);
- dk3str_cpy_not_overlapped(b2, dn);
- p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
- if(p1) {
- *p1 = dkT('\0');
- } else {
- b1[0] = dkT('\0');
- }
- } else { $? "! name too long"
- /* ERROR: Name too long! */
- if(app) {
- dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
- }
- }
- } else {
- sz = dk3str_len(dn) + dk3str_len(kw[3]);
- if(sz < DK3_SIZEOF(b1,dkChar)) {
- ok = 1; $? ". ok"
- dk3str_cpy_not_overlapped(b1, dn);
- dk3str_cpy_not_overlapped(b2, dn);
- sz = dk3str_len(b2);
- if(sz > 1) {
- dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
- } else {
- dk3str_cat(b2, kw[3]);
- }
- } else { $? "! name too long"
- /* Name too long! */
- if(app) {
- dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
- }
- }
- }
- if(ok) { $? ". b1=\"%!ds\" b2=\"%!ds\"", b1, b2
- back = dk3dir_new(b1, app);
- if(back) { $? ". alloc ok"
- hSearch = FindFirstFileW(b2, &wfd);
- if(INVALID_HANDLE_VALUE != hSearch) { $? ". FindFirstFile"
- do {
- isDir = 0; $? ". name=\"%ls\"", wfd.cFileName
- if(dk3str_cmp(wfd.cFileName, kw[0])) {
- if(dk3str_cmp(wfd.cFileName, kw[1])) { $? ". name ok"
- if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
- isDir = 1;
-#if 0
- if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
- switch(wfd.dwReserved0) {
- case IO_REPARSE_TAG_MOUNT_POINT: {
- isDir = 0;
- } break;
- }
- }
-#endif
- }
- if(isDir) { $? ". dir"
- dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
- } else { $? ". no dir"
- dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
- }
- }
- }
- } while(FindNextFileW(hSearch, &wfd));
- FindClose(hSearch);
- } else { $? "! FindFirstFileW"
- /* ERROR: Failed to search for pattern! */
- ec |= 16;
- if(app) {
- if(usefne) {
- dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
- } else {
- dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else { $? "! alloc"
- }
- }
- } else { $? "! no dn"
- } $? "- dk3dir_my_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back;
- $? "+ dk3dir_open_app \"%!ds\"", dn
- back = dk3dir_my_open_app(dn, 0, app);
- $? "- dk3dir_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
-{
- dk3_dir_t *back;
- $? "+ dk3dir_fne_open_app \"%!ds\"", fn
- back = dk3dir_my_open_app(fn, 1, app);
- $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-#endif
-
-
-/* --- Windows > 8 bit --- */
-#else
-/* +++ Windows, 8 bit +++ */
-
-
-
-#if VERSION_BEFORE_2012_04_13
-
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- dkChar buffer[DK3_MAX_PATH]; /* Buffer for entry names. */
- intptr_t ffres; /* Result from findfirst(). */
- dkChar *namecopy = NULL; /* New copy of entry name. */
- struct __finddata64_t ffdata; /* Find data. */
- if(dn) {
- if((dk3str_len(kw[3]) + dk3str_len(dn)) < DK3_SIZEOF(buffer,dkChar)) {
- dk3str_cpy_not_overlapped(buffer, dn);
- dk3str_cat(buffer, kw[3]);
- back = dk3dir_new(dn, app);
- if(back) {
- ffres = _findfirst64(buffer, &ffdata);
- if(ffres != -1) {
- do {
- if(dk3str_cmp(ffdata.name, kw[0])) {
- if(dk3str_cmp(ffdata.name, kw[1])) {
- if((ffdata.attrib) & _A_SUBDIR) {
- dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
- } else {
- dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
- }
- }
- }
- } while(_findnext64(ffres, &ffdata) == 0);
- _findclose(ffres);
- } else {
- ec |= 16; /* Findfirst failed */
- if(app) {
- /* ERROR: Findfirst failed! */
- dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else {
- if(app) {
- /* ERROR: Directory name too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
- }
- }
- }
- return back;
-}
-
-
-
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entry name. */
- dkChar myb2[2]; /* Buffer for pattern. */
- dkChar *ptr = NULL; /* Last separator. */
- dkChar *namecopy = NULL; /* New copy of entry name. */
- intptr_t ffres; /* Result from findfirst(). */
- struct __finddata64_t ffdata; /* Find data. */
- $? "+ dk3dir_fne_open_app \"%!ds\"", fn
- if(fn) {
- if(dk3str_len(fn) < DK3_MAX_PATH) {
- dk3str_cpy_not_overlapped(mybuffer, fn);
- ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
- if(ptr) {
- *ptr = DK3_CHAR_0;
- back = dk3dir_new(mybuffer, app);
- *ptr = DK3_CHAR_SEP;
- } else {
- myb2[0] = DK3_CHAR_0;
- back = dk3dir_new(myb2, app);
- }
- if(back) {
- ffres = _findfirst64(mybuffer, &ffdata);
- if(ffres != -1) {
- do {
- if(dk3str_cmp(ffdata.name, kw[0])) {
- if(dk3str_cmp(ffdata.name, kw[1])) {
- if((ffdata.attrib) & _A_SUBDIR) {
- dk3dir_add(back->sdi, ffdata.name, &(back->ndir), &ec, app);
- } else {
- dk3dir_add(back->sfi, ffdata.name, &(back->nfi), &ec, app);
- }
- }
- }
- } while(_findnext64(ffres, &ffdata) == 0);
- _findclose(ffres);
- } else {
- ec |= 16;
- if(app) {
- /* ERROR: Failed to open directory! */
- dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, mybuffer);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else {
- if(app) {
- /* ERROR: Pattern too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
- }
- }
- } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-#else
-
-
-
-static
-dk3_dir_t *
-dk3dir_my_open_app(dkChar const *dn, int usefne, dk3_app_t *app)
-{
- WIN32_FIND_DATAA wfd; /* Details for file. */
- dkChar b1[DK3_MAX_PATH]; /* Directory base. */
- dkChar b2[DK3_MAX_PATH]; /* Pattern. */
- dkChar *p1; /* Separator. */
- dk3_dir_t *back = NULL;
- HANDLE hSearch; /* File search handle. */
- size_t sz; /* String length. */
- int ok; /* Flag: No error yet. */
- int ec; /* Error code. */
- int isDir; /* Flag: Entry is dir. */
- $? "+ dk3dir_my_open_app \"%!ds\"", dn
- ec = 0;
- if(dn) {
- ok = 0;
- if(usefne) {
- if(dk3str_len(dn) < DK3_SIZEOF(b1,dkChar)) {
- ok = 1; $? ". ok"
- dk3str_cpy_not_overlapped(b1, dn);
- dk3str_cpy_not_overlapped(b2, dn);
- p1 = dk3str_rchr(b1, DK3_CHAR_SEP);
- if(p1) {
- *p1 = dkT('\0');
- } else {
- b1[0] = dkT('\0');
- }
- } else { $? "! name too long"
- /* ERROR: Name too long! */
- if(app) {
- dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, dn);
- }
- }
- } else {
- sz = dk3str_len(dn) + dk3str_len(kw[3]);
- if(sz < DK3_SIZEOF(b1,dkChar)) {
- ok = 1; $? ". ok"
- dk3str_cpy_not_overlapped(b1, dn);
- dk3str_cpy_not_overlapped(b2, dn);
- sz = dk3str_len(b2);
- if(sz > 1) {
- dk3str_cat(b2, kw[(DK3_CHAR_SEP == b2[sz - 1]) ? 4 : 3]);
- } else {
- dk3str_cat(b2, kw[3]);
- }
- } else { $? "! name too long"
- /* ERROR: Name too long! */
- if(app) {
- dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
- }
- }
- }
- if(ok) { $? ". b1=\"%!ds\" b2=\"%!ds\"", b1, b2
- back = dk3dir_new(b1, app);
- if(back) { $? ". alloc ok"
- hSearch = FindFirstFileA(b2, &wfd);
- if(INVALID_HANDLE_VALUE != hSearch) { $? ". FIndFirstFile"
- do {
- isDir = 0; $? ". name=\"%!8s\"", wfd.cFileName
- if(dk3str_cmp(wfd.cFileName, kw[0])) {
- if(dk3str_cmp(wfd.cFileName, kw[1])) { $? ". name ok"
- if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_DIRECTORY) {
- isDir = 1;
-#if 0
- if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
- switch(wfd.dwReserved0) {
- case IO_REPARSE_TAG_MOUNT_POINT: {
- isDir = 0;
- } break;
- }
- }
-#endif
- }
- if(isDir) { $? ". dir"
- dk3dir_add(back->sdi, wfd.cFileName, &(back->ndir), &ec, app);
- } else { $? ". no dir"
- dk3dir_add(back->sfi, wfd.cFileName, &(back->nfi), &ec, app);
- }
- }
- }
- } while(FindNextFileA(hSearch, &wfd));
- FindClose(hSearch);
- } else { $? "! FindFirstFileW"
- /* ERROR: Failed to search for pattern! */
- ec |= 16;
- if(app) {
- if(usefne) {
- dk3app_log_i3(app, DK3_LL_ERROR, 215, 216, dn);
- } else {
- dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
- }
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- } else { $? "! alloc"
- }
- }
- } else { $? "! no dn"
- } $? "- dk3dir_my_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back;
- $? "+ dk3dir_open_app \"%!ds\"", dn
- back = dk3dir_my_open_app(dn, 0, app);
- $? "- dk3dir_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
-{
- dk3_dir_t *back;
- $? "+ dk3dir_fne_open_app \"%!ds\"", fn
- back = dk3dir_my_open_app(fn, 1, app);
- $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-#endif
-
-/* --- Windows, 8 bit --- */
-#endif
-/* --- Windows --- */
-#else
-/* +++ non-Windows +++ */
-#if DK3_CHAR_SIZE > 1
-/* +++ non-Windows > 8 bit +++ */
-#error "16/32-bit file names only available on Windows!"
-/* --- non-Windows > 8 bit --- */
-#else
-/* +++ non-Windows, 8 bit +++ */
-
-
-
-/** Function names used in error messages.
-*/
-static dkChar const * const dk3dir_function_names[] = {
-$!string-table macro=dkT
-#
-# 0
-#
-opendir:
-$!end
-};
-
-
-
-#if DK3_HAVE_OPENDIR && DK3_HAVE_READDIR && DK3_HAVE_CLOSEDIR
-
-
-
-dk3_dir_t *
-dk3dir_open_app(dkChar const *dn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- struct dirent *de = NULL; /* Directory entry from readdir(). */
- DIR *d = NULL; /* Directory structure from opendir(). */
- size_t sz = 0; /* Length of entire file name. */
- size_t dns = 0; /* Directory name length. */
- size_t kw2l = 0; /* Length of separator string. */
- dk3_stat_t stb; /* Buffer for stat() result. */
- $? "+ dk3dir_open_app"
- if(dn) {
- back = dk3dir_new(dn, app);
- if(back) {
- d = opendir(dn);
- if(d) {
- dns = dk3str_len(dn); kw2l = dk3str_len(kw[2]);
- while((de = readdir(d)) != NULL) {
- if(dk3str_cmp(de->d_name, kw[0])) {
- if(dk3str_cmp(de->d_name, kw[1])) {
- sz = dns + kw2l + dk3str_len(de->d_name);
- if(sz < DK3_MAX_PATH) {
- dk3str_cpy_not_overlapped(back->fullname, dn);
- dk3str_cat(back->fullname, kw[2]);
- dk3str_cat(back->fullname, de->d_name);
- if(dk3sf_stat_app(&stb, back->fullname, NULL)) {
- switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
- case DK3_FT_DIRECTORY: {
- dk3dir_add(back->sdi,de->d_name,&(back->ndir),&ec,app);
- } break;
- default: {
- dk3dir_add(back->sfi,de->d_name,&(back->nfi),&ec,app);
- } break;
- }
- } else {
- if(!(ec & 8)) {
- if(app) {
- /* Stat failed! */
- dk3app_log_i3(app,DK3_LL_ERROR,61,62,back->fullname);
- }
- } ec |= 8;
- }
- } else {
- if(!(ec & 4)) {
- if(app) {
- /* Directory name too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, dn);
- }
- } ec |= 4;
- }
- }
- }
- }
- closedir(d);
- } else {
- ec |= 16;
- if(app) {
- /* Failed to open directory! */
- dk3app_log_i3(app, DK3_LL_ERROR, 63, 64, dn);
- dk3sf_report_errno(app, errno, dk3dir_function_names[0]);
- }
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- }
- } $? "- dk3dir_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-dk3_dir_t *
-dk3dir_fne_open_app(dkChar const *fn, dk3_app_t *app)
-{
- dk3_dir_t *back = NULL;
- int ec = 0; /* Error code. */
- dk3_stat_t stb; /* Stat buffer. */
- dkChar mybuffer[DK3_MAX_PATH]; /* Buffer for entire file name. */
- dkChar myb2[2]; /* Pattern buffer. */
- dkChar *ptr; /* Last separator in pattern. */
- $? "+ dk3dir_fne_open_app \"%!ds\"", fn
- if(fn) {
- if(dk3str_len(fn) < DK3_MAX_PATH) {
- dk3str_cpy_not_overlapped(mybuffer, fn);
- if(dk3sf_stat_app(&stb, fn, app)) {
- ptr = dk3str_rchr(mybuffer, DK3_CHAR_SEP);
- if(ptr) {
- *(ptr++) = DK3_CHAR_0;
- back = dk3dir_new(mybuffer, app);
- } else {
- myb2[0] = DK3_CHAR_0;
- back = dk3dir_new(myb2, app);
- ptr = mybuffer;
- }
- if(back) {
- switch((stb.ft) & (~(DK3_FT_SYMLINK))) {
- case DK3_FT_DIRECTORY: {
- dk3dir_add(back->sdi, ptr, &(back->ndir), &ec, app);
- } break;
- default: {
- dk3dir_add(back->sfi, ptr, &(back->nfi), &ec, app);
- } break;
- }
- if(ec) {
- if(3 & ec) {
- if(app) {
- dk3app_log_i1(app, DK3_LL_ERROR, 9);
- }
- }
- dk3dir_close(back); back = NULL;
- }
- }
- }
- } else {
- if(app) {
- /* Name too long! */
- dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, fn);
- }
- }
- } $? "- dk3dir_fne_open_app %!8s", TR_8PTR(back)
- return back;
-}
-
-
-
-#else
-#error "No opendir()/readdir()/closedir() function set!"
-#endif
-
-/* --- non-Windows, 8 bit --- */
-#endif
-/* --- non-Windows --- */
-#endif
-
-
-/** Directory chain cell.
-*/
-struct _dk3_dir_cell_t_ {
- struct _dk3_dir_cell_t_ *parent; /**< Parent cell. */
- dk3_dir_t *dir; /**< Directory structure. */
-};
-/** Directory chain cell.
-*/
-typedef struct _dk3_dir_cell_t_ DK3_DIR_CELL;
-
-
-
-/** Destroy chain cell, release memory.
- @param c Cell to destroy.
-*/
-static
-void
-dk3dir_cell_delete(DK3_DIR_CELL *c)
-{
- if(c) {
- if(c->dir) {
- dk3dir_close(c->dir);
- }
- c->dir = NULL;
- c->parent = NULL;
- dk3_delete(c);
- }
-}
-
-
-
-/** Create directory cell, allocate memory.
- @param n Directory name.
- @param p Parent cell in chain.
- @param app Application structure for diagnostics.
- @return Pointer to new cell on success, NULL on error.
-*/
-static
-DK3_DIR_CELL *
-dk3dir_cell_new(dkChar const *n, DK3_DIR_CELL *p, dk3_app_t *app)
-{
- DK3_DIR_CELL *back = NULL;
- back = dk3_new_app(DK3_DIR_CELL,1,app);
- if(back) {
- back->parent = p;
- back->dir = dk3dir_open_app(n, app);
- if(!(back->dir)) {
- dk3dir_cell_delete(back); back = NULL;
- }
- }
- return back;
-}
-
-
-
-#if DK3_ON_WINDOWS
-/** Remove a directory reparse point.
- @param dn Directory to remove.
- @param app Application structure for diagnostics, may be NULL.
- @return 1 on success, 0 on error.
-*/
-static
-int
-dk3dir_remove_reparse_point(dkChar const *dn, dk3_app_t *app)
-{
- int back = 0;
- if(dk3sf_remove_dir_app(dn, app)) {
- back = 1;
- } else {
- if(dk3sf_remove_file_app(dn, app)) {
- back = 1;
- }
- }
- return back;
-}
-#endif
-
-
-
-int
-dk3dir_remove_app(dkChar const *dn, dk3_app_t *app)
-{
- int back = 0;
- dk3_stat_t stb; /* Stat buffer. */
- dkChar const *en = NULL; /* Entry name. */
- dkChar const *xdn; /* Current dir to delete. */
- dk3_stat_t const *es = NULL; /* Entry stat buffer. */
- DK3_DIR_CELL *ccell = NULL; /* Current cell. */
- DK3_DIR_CELL *ncell = NULL; /* New cell or next cell. */
-#if VERSION_BEFORE_20150821
- int ft; /* File type. */
-#endif
-
- if(dn) {
- if(dk3sf_stat_app(&stb, dn, app)) {
- if((stb.ft) & DK3_FT_SYMLINK) { /* symbolic link */
- /* Removing symbolic link only, not target! */
- back = dk3sf_remove_file_app(dn, app);
- } else {
- if(stb.ft == DK3_FT_DIRECTORY) {
-
-#if DK3_ON_WINDOWS
- if(0x00 == stb.cReparse) {
-#endif
- ccell = dk3dir_cell_new(dn, NULL, app);
- if(ccell) {
- back = 1;
- while(ccell) {
- if(dk3dir_get_next_directory(ccell->dir)) {
- en = dk3dir_get_fullname(ccell->dir);
- if(en) {
- es = dk3dir_get_stat(ccell->dir);
- if(es) {
- if((es->ft) & DK3_FT_SYMLINK) {
- if(!dk3sf_remove_file_app(en, app)) {
- back = 0;
- }
- } else {
-#if DK3_ON_WINDOWS
- if(0x00 == es->cReparse) {
-#endif
- ncell = dk3dir_cell_new(en, ccell, app);
- if(ncell) {
- ccell = ncell;
- } else {
- back = 0;
- }
-#if DK3_ON_WINDOWS
- } else {
- if(!dk3dir_remove_reparse_point(en, app)) {
- back = 0;
- }
- }
-#endif
- }
- } else {
- back = 0;
- /* BUG: Internal error. */
- }
- } else {
- back = 0;
- /* BUG: Internal error. */
- }
- } else {
- while(dk3dir_get_next_file(ccell->dir)) {
-#if VERSION_BEFORE_20150821
- ft = DK3_FT_REGULAR;
-#endif
- en = dk3dir_get_fullname(ccell->dir);
-#if VERSION_BEFORE_20150821
- es = dk3dir_get_stat(ccell->dir);
- if(es) { ft = es->ft; }
-#endif
- if(en) {
- if(!dk3sf_remove_file_app(en, app)) {
- back = 0;
- }
- } else {
- back = 0;
- /* BUG: Internal error. */
- }
- }
- ncell = ccell->parent;
- if(ccell->dir) {
- xdn = dk3dir_get_directory_name(ccell->dir);
- if(xdn) {
- if(!dk3sf_remove_dir_app(xdn, app)) {
- back = 0;
- }
- }
- }
- dk3dir_cell_delete(ccell);
- ccell = ncell;
- }
- }
- }
-#if DK3_ON_WINDOWS
- } else {
- if(!dk3dir_remove_reparse_point(dn, app)) {
- back = 0;
- }
- }
-#endif
- } else {
- /* ERROR: Not a directory! */
- dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, dn);
- }
- }
- }
- }
- return back;
-}
-
-
-
-/* vim: set ai sw=2 : */
-