summaryrefslogtreecommitdiff
path: root/support/dktools/dk3sf.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3sf.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk3sf.ctr')
-rw-r--r--support/dktools/dk3sf.ctr4689
1 files changed, 4689 insertions, 0 deletions
diff --git a/support/dktools/dk3sf.ctr b/support/dktools/dk3sf.ctr
new file mode 100644
index 0000000000..b12b4621cd
--- /dev/null
+++ b/support/dktools/dk3sf.ctr
@@ -0,0 +1,4689 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if DK3_ON_WINDOWS
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ The size must not exceed INT_MAX/2.
+ Practically this is not a limitation
+ as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app);
+
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed INT_MAX. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app);
+
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app);;
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name);
+
+#else
+
+
+#endif
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of characters).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest.
+ On some platforms the size is converted to int, so it
+ should not exceed 32767. Practically this is not a limitation
+ as the userful buffer size is DK3_MAX_PATH.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ @param fi Input file.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi);
+
+/** Read input line.
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 32767 as it is converted to int on some
+ systems.
+ @param fi Input file.
+ @param fn Input file name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+);
+
+/** Write string to file.
+ @param st String to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs(dkChar const *st, FILE *fi);
+
+/** Write string to file, report errors if any.
+ @param st String to write.
+ @param fi Output file to write to.
+ @param fn File name for error messages, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app);
+
+/** Write array of line strings to file.
+ @param txt Pointer to array of lines.
+ @param fi Output file to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc(dkChar ch, FILE *fi);
+
+/** Write one character to file.
+ @param ch Character to write.
+ @param fi File to write to.
+ @param fn File name of output file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app);
+
+/** Write byte order marker 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout(void);
+
+/** Only set stdout mode, do not write byte order marker
+ 0xFEFF to standard output.
+*/
+void
+dk3sf_initialize_stdout_no_bom(void);
+
+/** Write byte order marker 0xFEFF to standard error output.
+*/
+void
+dk3sf_initialize_stderr(void);
+
+/** Write byte order marker 0xFEFF to file.
+ @param fipo File to set up.
+*/
+void
+dk3sf_initialize_file(FILE *fipo);
+
+/** Prepare standard output and standard error output for multibyte
+ characters (write byte order marker 0xFEFF).
+*/
+void
+dk3sf_initialize_output(void);
+
+/** Get current timestamp.
+ @param timer Pointer to result variable.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time(dk3_time_t *timer);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ The size should not exceed 2^32-1 as it is converted to
+ a DWORD. Practically this is not a restriction as DK3_MAX_PATH
+ is the useful buffer size.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app);
+
+/** Get current users login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of characters).
+ @param app Application structure for diagnostics, may be NULL.
+*/
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app);
+
+/** Get current process ID.
+ @return Process ID.
+*/
+dk3_um_t
+dk3sf_getpid(void);
+
+/** Check whether we must expand a file name.
+ @param fn File name to check.
+ @return 1 for "must expand", 0 for "no need to expand".
+*/
+int
+dk3sf_must_expand(dkChar const *fn);
+
+/** Retrieve host name (short name).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of characters).
+ The size must not exceed 2^32-1. Practically this is not a
+ limitation as the useful buffer size for host name is below 256.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app);
+
+/** Print 8-bit character to file, convert to 16 bit if necessary.
+ @param c Character to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputc(char c, FILE *f);
+
+/** Print 8-bit character string to file, convert to 16 bit if necessary.
+ @param s String to print.
+ @param f File to write to.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_c8_fputs(char const *s, FILE *f);
+
+/** Read bytes from file descriptor into buffer.
+ @param fd File descriptor.
+ @param buf Buffer.
+ @param s Size of \a buf.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of bytes read.
+*/
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app);
+
+/** Write bytes to file descriptor.
+ @param fd File descriptor.
+ @param buf Buffer to write.
+ @param s Size of \a buf in bytes.
+ The size must not exceed 65535 as it is converted to unsigned int
+ on some systems.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for success (all bytes written), 0 on error.
+*/
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app);
+
+/** Read from file.
+ @param db Destination buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to read from.
+ @param app Application structure for diagnostics, may be NULL.
+ @return Number of elements read.
+*/
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app);
+
+/** Write to file.
+ @param sb Source buffer.
+ @param sz Size of one element.
+ @param ne Number of elements.
+ @param fi File to write to.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (all elements written), 0 on error.
+*/
+int
+dk3sf_fwrite_app(void const *sb,size_t sz,size_t ne,FILE *fi,dk3_app_t *app);
+
+/** Inspect file, search for byte order marker.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app);
+
+/** Inspect file, search for byte order marker. If byte order marker
+ is found save number of bytes to skip at beginning of file
+ to variable.
+ The function inspects the first 4 bytes from file and attempts
+ to find the file encoding (DK3_FILE_ENCODING_xxx).
+ If there is no BOM at the beginning of the file the default
+ value \a dv is returned. A value for \a dv can be obtained
+ from dk3app_get_output_encoding() or by inspecting the DK3_CHAR_SIZE
+ value and the language setting (ending on "UTF-8" or "utf8"?).
+ @param fn File name.
+ @param dv Default value for file encoding.
+ @param skb Pointer to size_t variable for number of bytes
+ to skip at the beginning of the file.
+ @param app Application structure for diagnostics, may be NULL.
+ @return File encoding if BOM found, default value \a dv otherwise.
+*/
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+);
+
+/** Attempt to apply an encoding found from BOM to an input FILE.
+ This function has an effect on Windows systems only.
+ For \a enc we can handle DK3_FILE_ENCODING_ASCII (mapped to
+ _O_TEXT), DK3_FILE_ENCODING_UTF8 (mapped to _O_U8TEXT) and
+ DK3_FILE_ENCODING_UTF16_LSB (mapped to _O_U16TEXT).
+ @param fipo File pointer.
+ @param enc Encoding found from dk3sf_inspect_bom_app().
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+char *
+dk3sf_c8_getenv(char const *name);
+
+/** Check whether or not the given file name is a directory.
+ @param n File name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success (is directory), 0 on error.
+*/
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Change into directory.
+ * @param dn Directory name.
+ * @param app Application structure for diagnostics, may be NULL.
+ * @return 1 on success, 0 on error.
+ */
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app);
+
+/** Check whether we need to re-build a destination file from a source.
+ * @param dn Destination file name.
+ * @param sn Source file name.
+ * @return 1 for rebuild necessary, 0 for not necessary.
+ */
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn);
+
+/** Create 8-bit file name from dkChar file name.
+ @param fnb File name buffer for result.
+ @param szfnb Size of @a fnb (number of bytes).
+ @param src Source file name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+);
+
+/** Retrieve a double value in POSIX notation from a string.
+ The sscanf() function depends on the current locale setting.
+ This function retrieves and saves the current locale setting,
+ establishes C locale temporarily for the the sscanf() call and
+ restores the original setting before exiting.
+ @param txt Text to inspect.
+ @param v Pointer to result variable.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app);
+
+/** Convert timestamp to human readable date and time.
+ @param dest Destination structure.
+ @param timer Source timestamp.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_localtime_app(dk3_tm_t *dest, dk3_time_t *timer, dk3_app_t *app);
+
+/** Retrieve maximum number of open files.
+ @return Maximum number of open files.
+*/
+int
+dk3sf_get_max_files(void);
+
+/** Report error detailes.
+ @param app Application structure for diagnostics.
+ @param err Error code from errno.
+ @param fctn Function name.
+*/
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param fn File name, may be NULL.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app);
+
+/** Close a file.
+ @param fipo FILE to close.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app);
+
+/** Retrieve information about a file.
+ @param st File information buffer.
+ @param fn File name.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app);
+
+/** Open a file.
+ @param fn File name.
+ @param mo Mode.
+ @param app Application structure, used for diagnostics.
+ @return FILE pointer on success, NULL on error.
+*/
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app);
+
+/** Convert timestamp to text.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ @param timer Timestamp to convert.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+);
+
+/** Get current working directory.
+ @param dest Destination buffer.
+ @param sz Size of \a dest (number of dkChar).
+ The size must not exceed INT_MAX/2. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param app Application structure, used for diagnostics.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app);
+
+/** Find executable file.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as the useful buffer size is DK3_MAX_PATH elements.
+ @param w Current working directory.
+ @param c Command as typed in the command line.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+);
+
+/** Get login name.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Find users home directory.
+ @param d Destination buffer.
+ @param s Size of \a d (number of dkChar).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app);
+
+/** Create directory if it does not yet exist.
+ @param p Path name.
+ @param mo Creation mode.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app);
+
+/** Remove (unlink) path.
+ @param n Path name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app);
+
+/** Remove directory.
+ @param n Directory name.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app);
+
+/** Retrieve host name (short name, without DNS domain).
+ @param db Destination buffer.
+ @param sz Size of \a db (number of dkChar).
+ The size must not exceed 2^31-1. Practically this is not a
+ limitation as I have never seen host names longer than 80 characters.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app);
+
+/** Get environment variable.
+ @param name Environment variable name.
+ @return Value on success, NULL on error.
+*/
+dkChar *
+dk3sf_getenv(dkChar const *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "No functions to support large characters!"
+#else
+#if DK3_ON_WINDOWS
+
+/** Macro to choose correct character size for sscanf()/swscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) swscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf()/swprintf().
+ NOTE: The first argument must be a *buffer*, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) swprintf(s,(sizeof(s)/sizeof(wchar_t)),f,d)
+#else
+#error "16 bit characters are supported on Windows platforms only!"
+#endif
+#endif
+#else
+
+
+/** Macro to choose correct character size for sscanf().
+*/
+#define dk3sf_sscanf3(s,f,d) sscanf(s,f,d)
+
+/** Macro to choose correct character size for sprintf().
+ NOTE: The first argument *must* be a buffer, *not* a pointer.
+*/
+#define dk3sf_sprintf3(s,f,d) sprintf(s,f,d)
+
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+
+
+$(trace-include)
+
+
+
+#if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '\\'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '/'
+
+#else
+
+/** File path component separator.
+*/
+#define DK3_C8_SEP '/'
+
+/** Not a file path component separator.
+*/
+#define DK3_C8_NOSEP '\\'
+
+#endif
+
+
+
+/** Add bit to set after testing another bit.
+*/
+#define DK3SF_ADDIF(a,b) if(m & a) { back |= b; }
+
+
+
+/** Function names used in error messages.
+*/
+dkChar const * const dk3sf_function_names[] = {
+$!string-table macro=dkT
+#
+# 0
+#
+
+#
+# 1
+#
+fclose:
+#
+# 2
+#
+rmdir:
+#
+# 3
+#
+unlink:
+#
+# 4
+#
+getpwuid:
+#
+# 5
+#
+lstat64:
+#
+# 6
+#
+stat64:
+#
+# 7
+#
+stat:
+#
+# 8
+#
+lstat:
+#
+# 9
+#
+fopen:
+#
+# 10
+#
+localtime_r:
+#
+# 11
+#
+getcwd:
+#
+# 12
+#
+mkdir:
+#
+# 13
+#
+gethostname:
+#
+# 14
+#
+read:
+#
+# 15
+#
+_read:
+#
+# 16
+#
+write:
+#
+# 17
+#
+_write:
+#
+# 18
+#
+fread:
+#
+# 19
+#
+_fread:
+#
+# 20
+#
+fwrite:
+#
+# 21
+#
+_fwrite:
+#
+# 22
+#
+chdir:
+#
+# 23
+#
+fputs:
+#
+# 24
+#
+fputc:
+#
+# 25
+#
+fgets:
+$!end
+};
+
+
+
+void
+dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn)
+{
+#if (DK3_CHAR_SIZE == 1) && DK3_HAVE_STRERROR && (!DK3_ON_WINDOWS)
+ dkChar const *msgarray[2];
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ char const *oldlocale = NULL;
+ char const *langptr = NULL;
+#endif
+ if((app) && (fctn)) {
+ msgarray[0] = fctn;
+ errno = 0;
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ langptr = getenv("LANG");
+ if(langptr) {
+ oldlocale = setlocale(LC_MESSAGES, langptr);
+ }
+#endif
+ msgarray[1] = strerror(err);
+ if(0 == errno) {
+ dk3app_log_3(app, DK3_LL_ERROR, msgarray, 0, 1, dk3sf_function_names[0]);
+ }
+#if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
+ if(langptr) {
+ if(oldlocale) { setlocale(LC_MESSAGES, oldlocale); }
+ }
+#endif
+ }
+#endif
+}
+
+
+
+
+#if DK3_ON_WINDOWS
+/* +++ Windows +++ */
+
+
+
+/** Unlocalized 8-bit character keywords used by module.
+*/
+static char const * const dk3sf_kw_win_c8[] = {
+/* 0 */ "HOMEDRIVE",
+/* 1 */ "HOMEPATH",
+/* 2 */ "USERPROFILE",
+/* 3 */ "LOCALAPPDATA",
+/* 4 */ "\\AppData\\Local",
+/* 5 */ "APPDATA",
+/* 6 */ "\\AppData\\Roaming",
+/* 7 */ "TEMP",
+/* 8 */ "TMP",
+/* 9 */ "\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+/** Unlocalized 16-bit character keywords used by module.
+*/
+static wchar_t const * const dk3sf_kw_win_c16[] = {
+/* 0 */ L"HOMEDRIVE",
+/* 1 */ L"HOMEPATH",
+/* 2 */ L"USERPROFILE",
+/* 3 */ L"LOCALAPPDATA",
+/* 4 */ L"\\AppData\\Local",
+/* 5 */ L"APPDATA",
+/* 6 */ L"\\AppData\\Roaming",
+/* 7 */ L"TEMP",
+/* 8 */ L"TMP",
+/* 9 */ L"\\AppData\\Local\\Temp",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back;
+ back = (dk3_um_t)_getpid();
+ return back;
+}
+
+
+
+dk3_c16_t *
+dk3sf_c16_getenv(dk3_c16_t const *name)
+{
+ dk3_c16_t *back = NULL;
+ if(name) {
+ back = _wgetenv(name);
+ }
+ return back;
+}
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wrmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_wunlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove file! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+ if(_unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to remove file! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_attempt_home(
+ char *d, size_t sz, char const *n1, char const *n2, char const *n3
+)
+{
+ int back = 0;
+ char *p1 = NULL; /* Value of first environment variable. */
+ char *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing part to remove. */
+ p2 = NULL;
+ $? "+ dk3sf_c8_attempt_home \"%!8s\" \"%!8s\" \"%!8s\"", TR_8STR(n1), TR_8STR(n2), TR_8STR(n3)
+ p1 = getenv(n1);
+ if(p1) {
+ if(n2) { p2 = getenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c8_len(p1);
+ if(p2) { s += dk3str_c8_len(p2); }
+ if(s < sz) {
+ dk3str_c8_cpy_not_overlapped(d, p1);
+ if(p2) { dk3str_c8_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c8_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c8_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = '\0';
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%!8s\"", d
+ $!trace-code }
+ } $? "- dk3sf_c8_attempt_home %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[0], dk3sf_kw_win_c8[1], NULL);
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, dk3sf_kw_win_c8[4]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, dk3sf_kw_win_c8[6]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, dk3sf_kw_win_c8[9]);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, NULL);
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%!8s\"", d
+ $!trace-code }
+ }
+ return back;
+}
+
+
+
+/** Attempt to retrieve home directory name.
+ @param d Destination buffer.
+ @param sz Size of \a d (number of characters).
+ @param n1 Name of first environment variable to check.
+ @param n2 Name of second environment variable to check.
+ @param n3 Trailing string to remove if found.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c16_attempt_home(
+ dk3_c16_t *d, size_t sz,
+ dk3_c16_t const *n1, dk3_c16_t const *n2, dk3_c16_t const *n3
+)
+{
+ int back = 0;
+ dk3_c16_t *p1 = NULL; /* Value of first environment variable. */
+ dk3_c16_t *p2 = NULL; /* Value of second environment variable. */
+ size_t s = 0; /* Buffer size needed. */
+ size_t s2 = 0; /* Size of trailing text to remove. */
+ p2 = NULL;
+ $? "+ dk3sf_c8_attempt_home \"%ls\" \"%ls\" \"%ls\"", TR_LSTR(n1), TR_LSTR(n2), TR_LSTR(n3)
+ p1 = _wgetenv(n1);
+ if(p1) {
+ if(n2) { p2 = _wgetenv(n2); }
+ if((p2) || (!(n2))) {
+ s = dk3str_c16_len(p1);
+ if(p2) { s += dk3str_c16_len(p2); }
+ if(s < sz) {
+ dk3str_c16_cpy(d, p1);
+ if(p2) { dk3str_c16_cat(d, p2); }
+ if(n3) {
+ s2 = dk3str_c16_len(n3);
+ if(s2 < 2) {
+ if(dk3str_c16_casecmp(&(d[s - s2]), n3) == 0) {
+ d[s - s2] = 0x0000U;
+ back = 1;
+ }
+ }
+ } else {
+ back = 1;
+ }
+ }
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%ls\"", d
+ $!trace-code }
+ } $? "- dk3sf_c8_attempt_home %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((d) && (s)) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[0], dk3sf_kw_win_c16[1], NULL);
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[2], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, dk3sf_kw_win_c16[4]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, dk3sf_kw_win_c16[6]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, dk3sf_kw_win_c16[9]);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, NULL);
+ }
+ if(!back) {
+ back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, NULL);
+ }
+ $!trace-code if(back) {
+ $? ". home = \"%ls\"", d
+ $!trace-code }
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / Result length. */
+ sz = (DWORD)s;
+ if((d) && (s)) {
+ if(GetUserNameA(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = '\0';
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD sz = 0; /* Buffer size / result length. */
+ if((d) && (s)) {
+ sz = (DWORD)s;
+ if(GetUserNameW(d, &sz)) {
+ if(sz) {
+ d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = 0U;
+ back = 1;
+ }
+ } else {
+ if(app) {
+ /* Failed to find current user name */
+ dk3app_log_i1(app, DK3_LL_ERROR, 43);
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ _time64(timer);
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_type(int m)
+{
+ int back = 0;
+ switch(m & _S_IFMT) {
+#ifdef _S_IFIFO
+ case _S_IFIFO: back = DK3_FT_FIFO; break;
+#endif
+#ifdef _S_IFCHR
+ case _S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+#endif
+#ifdef _S_IFDIR
+ case _S_IFDIR: back = DK3_FT_DIRECTORY; break;
+#endif
+#ifdef _S_IFBLK
+ case _S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+#endif
+#ifdef _S_IFREG
+ case _S_IFREG: back = DK3_FT_REGULAR; break;
+#endif
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_convert_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(_S_IREAD,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(_S_IWRITE,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(_S_IEXEC,DK3_FPERM_U_EXEC)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+int
+dk3sf_convert_back_file_permissions(int m)
+{
+ int back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IREAD)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWRITE)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IEXEC)
+ return back;
+}
+
+
+
+static
+void
+dk3sf_convert_filetime(dk3_time_t *pd, FILETIME *ps)
+{
+ __int64 i1;
+ __int64 i2;
+ i1 = (__int64)(ps->dwHighDateTime);
+ i2 = (__int64)(ps->dwLowDateTime);
+ i1 = ((i1 << 32) & 0xFFFFFFFF00000000UL) | (i2 & 0x00000000FFFFFFFFUL);
+ *pd = (dk3_time_t)i1;
+}
+
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAA wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Internal buffer for _stat64(). */
+ $? "+ dk3sf_c8_stat_app \"%!8s\"", fn
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_stat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAA wfdFileDetails;
+ HANDLE hFileSearch;
+ $? ". check directory"
+ hFileSearch = FindFirstFileA(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) {
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesA(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileA(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_stat_app %d", back
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Internal buffer for checks. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* ERROR: Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Check mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ $? "+ dk3sf_c8_fopen_app \"%!8s\"", TR_8STR(fn)
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+ back = fopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ } $? "- dk3sf_c8_fopen_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+
+
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res;
+ if((dest) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ back = 1;
+ dest->Y = 1900 + res.tm_year;
+ dest->M = 1 + res.tm_mon;
+ dest->D = res.tm_mday;
+ dest->h = res.tm_hour;
+ dest->m = res.tm_min;
+ dest->s = res.tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_time_convert_app(
+ char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer for sprintf() result. */
+ struct tm res; /* Result from localtime(). */
+ if((dest) && (sz) && (timer)) {
+ if(0 == _localtime64_s(&res, timer)) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + res.tm_year),
+ (1 + res.tm_mon),
+ res.tm_mday,
+ res.tm_hour,
+ res.tm_min,
+ res.tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* _localtime64_s failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_getcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameA(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c8_is_drive(char const *p)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_is_drive \"%!8s\"", TR_8STR(p)
+ if(dk3str_c8_len(p) == 2) {
+ if((*p >= 'a') && (*p <= 'z')) {
+ back = 1;
+ }
+ if((*p >= 'A') && (*p <= 'Z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == ':') { back = 1; }
+ }
+ } $? "- dk3sf_c8_is_drive %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* Path name for parent directories. */
+ char *ptr = NULL; /* Slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* File permissions. */
+ dk3_stat_t stb;
+ $? "+ dk3sf_c8_mkdir_app \"%!8s\"", TR_8STR(p)
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) { $? ". loop ptr=\"%!8s\"", TR_8STR(ptr)
+ ptr = dk3str_c8_chr(ptr, '\\');
+ if(ptr) {
+ *ptr = '\0'; $? ". directory=\"%!8s\"", buffer
+ if((dk3str_c8_len(buffer) > 0) && (!dk3sf_c8_is_drive(buffer))) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0; $? ". path \"%!8s\" no directory", buffer
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create directory \"%!8s\"", buffer
+ if(_mkdir(buffer) != 0) { $? "! failed to create \"%!8s\"", buffer
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = '\\';
+ ptr++;
+ }
+ }
+ if(cc) { $? ". all parents ok"
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". \"%!8s\" exists", buffer
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1; $? ". is directory"
+ } else { $? ". \"%!8s\" is not a directory", buffer
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create \"%!8s\"", buffer
+ if(_mkdir(buffer) == 0) {
+ back = 1;
+ } else { $? "! failed to create \"%!8s\"", buffer
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else { $? "! directory name too long"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_mkdir_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app)
+{
+ WIN32_FIND_DATAW wfd;
+ DWORD dwFileAttributes;
+ HANDLE hFFF;
+ int ec = 0;
+ int back = 0;
+ struct __stat64 stb; /* Result from _wstat64(). */
+ $? "+ dk3sf_c16_stat_app \"%ls\"", fn
+ if((st) && (fn)) {
+ dk3mem_res((void *)st, sizeof(dk3_stat_t));
+ st->cReparse = 0x00;
+ st->dwReparse = (DWORD)0;
+ if(_wstat64(fn, &stb) == 0) {
+ back = 1;
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+ dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
+ dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
+ st->lu = st->u;
+ st->lg = st->g;
+ st->ldevice = st->device;
+ st->lrdev = st->rdev;
+ st->linode = st->inode;
+ st->lnlink = st->nlink;
+ st->lft = st->ft;
+ st->lperm = st->perm;
+ st->lsz = st->sz;
+#if VERSION_BEFORE_2012_04_14
+ if(DK3_FT_DIRECTORY == st->ft) {
+ WIN32_FIND_DATAW wfdFileDetails;
+ HANDLE hFileSearch;
+ $? ". directory special check"
+ hFileSearch = FindFirstFileW(fn, &wfdFileDetails);
+ if(INVALID_HANDLE_VALUE != hFileSearch) { $? ". handle ok"
+ if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
+ $? ". reparse point"
+ if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
+ $? ". mount point"
+ /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
+ } else {
+ if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
+ $? ". symbolic link"
+ /* Symbolic link */
+ st->lsz = dk3ma_um_add_ok(
+ dk3ma_um_mul_ok(
+ (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
+ dk3ma_um_add_ok(
+ (dk3_um_t)(MAXDWORD),
+ DK3_UM_1,
+ &ec
+ ),
+ &ec
+ ),
+ (dk3_um_t)(wfdFileDetails.nFileSizeLow),
+ &ec
+ );
+ dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
+ dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
+ dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
+ st->ft |= DK3_FT_SYMLINK;
+ } else {
+ }
+ }
+ }
+ FindClose(hFileSearch);
+ }
+ }
+#else
+ dwFileAttributes = GetFileAttributesW(fn);
+ if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
+ if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->cReparse = 'r';
+ hFFF = FindFirstFileW(fn, &wfd);
+ if(INVALID_HANDLE_VALUE != hFFF) {
+ if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
+ st->dwReparse = wfd.dwReserved0;
+ switch(wfd.dwReserved0) {
+ case IO_REPARSE_TAG_MOUNT_POINT: {
+ st->cReparse = 'm';
+ } break;
+ case IO_REPARSE_TAG_SYMLINK: {
+ st->cReparse = 'l';
+ } break;
+ }
+ }
+ FindClose(hFFF);
+ }
+ }
+ }
+#endif
+ } else {
+ if(app) {
+ /* _wstat64() failed! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 163, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 73);
+#endif
+ }
+ }
+ } $? "- dk3sf_c16_stat_app %d", back
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_check_open_file(dk3_c16_t const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c16_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ /* Place for additional checks to write files here. */
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ dk3_c16_t const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case L'w': case L'a': case L'+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c16_check_open_file(fn, want_to_write, app)) {
+ back = _wfopen(fn, mo);
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_time_convert_app(
+ dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64];
+ if(dk3sf_c8_time_convert_app(buffer, sizeof(buffer), timer, app)) {
+ back = dk3str_cnv_c8p_to_c16_app(dest, sz, buffer, app);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+ if(_wgetcwd(dest, (int)sz)) {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ /* Failed to find current working directory! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_find_exec_app(
+ dk3_c16_t *d, size_t s, dk3_c16_t const *w, dk3_c16_t const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((d) && (s)) {
+ if(GetModuleFileNameW(GetModuleHandle(NULL),d,(DWORD)s)) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to find name of executable! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 40);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+static
+int
+dk3sf_c16_is_drive(dk3_c16_t const *p)
+{
+ int back = 0;
+ if(dk3str_c16_len(p) == 2) {
+ if((*p >= L'A') && (*p <= L'Z')) {
+ back = 1;
+ }
+ if((*p >= L'a') && (*p <= L'z')) {
+ back = 1;
+ }
+ if(back) {
+ back = 0;
+ if(p[1] == L':') { back = 1; }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_mkdir_app(dk3_c16_t const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_c16_t buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ dk3_c16_t *ptr = NULL; /* Current slash/backslash position. */
+ int cc = 1; /* Flag: Can continue. */
+ int m = 0; /* Permissions. */
+ dk3_stat_t stb; /* Test whether file/dir exists. */
+ if(p) {
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c16_len(p) < sizeof(buffer)) {
+ dk3str_c16_cpy(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) {
+ ptr = dk3str_c16_chr(ptr, 0x005CU);
+ if(ptr) {
+ *ptr = 0U;
+ if((dk3str_c16_len(buffer) > 0) && (!dk3sf_c16_is_drive(buffer))) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0;
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) != 0) {
+ cc = 0;
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ }
+ *ptr = 0x005CU;
+ ptr++;
+ }
+ }
+ if(cc) {
+ if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else {
+ if(_wmkdir(buffer) == 0) {
+ back = 1;
+ } else {
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 2
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExW(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = L'\0';
+ } else {
+ db[sz - 1] = L'\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ DWORD s = 0; /* Buffer size / result length. */
+ if((db) && (sz)) {
+ s = (DWORD)sz;
+ if(GetComputerNameExA(ComputerNameNetBIOS, db, &s)) {
+ if((size_t)s < sz) {
+ db[(size_t)s] = '\0';
+ } else {
+ db[sz - 1] = '\0';
+ }
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to find NetBIOS name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "dkChar must be 8 or 16 bit!"
+#else
+/* +++ Windows, dkChar 16 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ $? "+ dk3sf_fgets"
+ if((db) && (sz) && (fi)) {
+ if(fgetws(db, (int)sz, fi)) {
+ if(db[0] == DK3_CHAR_BOM) { $? ". BOM at start of line"
+ dk3str_c16_cpy(db, &(db[1]));
+ }
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ } $? "- dk3sf_fgets %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputwc(ch, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputws(st, fi) != WEOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ if(!_isatty(_fileno(stdout))) {
+ fputwc(0xFEFF, stdout);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_stdout_no_bom(void)
+{
+ static int not_bom_written_to_stdout = 1;
+ if(not_bom_written_to_stdout) {
+ not_bom_written_to_stdout = 0;
+ (void)_setmode(_fileno(stdout), _O_U16TEXT);
+ }
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+ static int not_bom_written_to_stderr = 1;
+ if(not_bom_written_to_stderr) {
+ not_bom_written_to_stderr = 0;
+ (void)_setmode(_fileno(stderr), _O_U16TEXT);
+ if(!_isatty(_fileno(stderr))) {
+ fputwc(0xFEFF, stderr);
+ }
+ }
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+ (void)_setmode(_fileno(fipo), _O_U16TEXT);
+ fputwc(0xFEFF, fipo);
+}
+
+
+
+/* --- Windows, dkChar 16 bit --- */
+#endif
+#else
+/* +++ Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+/* --- Windows, dkChar 8 bit --- */
+#endif
+
+/* --- Windows --- */
+#else
+/* +++ non-Windows +++ */
+
+
+
+/** 8-bit character keywords for use on non-Windows systems.
+*/
+static char const * const kw_c8_no_win[] = {
+/* 0 */ "/",
+/* 1 */ "PATH",
+NULL
+};
+
+
+
+dk3_um_t
+dk3sf_getpid(void)
+{
+ dk3_um_t back = DK3_UM_0;
+#if DK3_HAVE_GETPID
+ back = (dk3_um_t)getpid();
+#else
+#if DK3_HAVE__GETPID
+ back = (dk3_um_t)_getpid();
+#else
+#error "No getpid() function!"
+#endif
+#endif
+ return back;
+}
+
+
+
+dk3_c8_t *
+dk3sf_c8_getenv(char const *name)
+{
+ char *back = NULL;
+ if(name) {
+ back = getenv(name);
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_RMDIR
+ if(rmdir(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* Failed to remove directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 68);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[2]);
+ }
+ }
+#else
+#error "No rmdir() function!"
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
+{
+ int back = 0;
+ if(n) {
+#if DK3_HAVE_UNLINK
+ if(unlink(n) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Failed to unlink file */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 90);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[3]);
+ }
+ }
+#else
+#error "No support for unlink"
+#endif
+ }
+ return back;
+}
+
+
+/** Copy logname of user record to buffer.
+ @param d Destination buffer.
+ @param s Size of \a d.
+ @param p User record.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3sf_c8_copy_logname(char *d, size_t s, struct passwd *p, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_copy_logname"
+ if(p) { $? ". p ok"
+ if(p->pw_name) { $? ". name ok"
+ if(dk3str_c8_len(p->pw_name) < s) { $? ". name length ok"
+ dk3str_c8_cpy_not_overlapped(d, p->pw_name);
+ back = 1;
+ } else { $? "! name too long"
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* No name entry in record! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 91);
+ }
+ }
+ } $? "- dk3sf_c8_copy_logname %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+ $? "+ dk3sf_c8_get_logname_app"
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u); $? ". getpwuid()"
+ if(p) { $? ". entry found"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ } else { $? "! entry not found"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ {
+ int cc;
+ int found; $? ". getpwent()"
+ cc = 1; found = 0;
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0;
+ found = 1; $? ". entry found"
+ back = dk3sf_c8_copy_logname(d, s, p, app);
+ }
+ } else { cc = 0; }
+ }
+ if(!found) { $? "! entry not found"
+ if(app) {
+ /* No passwd record for UID! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+#endif
+ } $? "- dk3sf_c8_get_logname_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ uid_t u = 0; /* Current user ID to process. */
+ struct passwd *p = NULL; /* Current user to process. */
+ char uidbuffer[128]; /* Text buffer to store UID. */
+ if((d) && (s)) {
+ u = getuid();
+#if DK3_HAVE_GETPWUID
+ p = getpwuid(u);
+ if(p) {
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ } else {
+ if(app) {
+ /* No passwd record for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
+ }
+ }
+#else
+ {
+ int cc;
+ int found;
+ cc = 1; found = 0;
+#if DK3_HAVE_SETPWENT
+ setpwent();
+#endif
+ while(cc) {
+ p = getpwent();
+ if(p) {
+ if(p->pw_uid == u) {
+ cc = 0; found = 1;
+ if(p->pw_dir) {
+ if(dk3str_c8_len(p->pw_dir) < s) {
+ dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
+ back = 1;
+ } else {
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* Home directory entry empty! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 95);
+ }
+ }
+ }
+ } else { cc = 0; }
+ }
+#if DK3_HAVE_SETPWENT
+ endpwent();
+#endif
+ if(!found) {
+ if(app) {
+ /* No entry for uid! */
+#if DK3_CHAR_SIZE == 1
+ dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
+ dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 94);
+#endif
+ }
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+int
+dk3sf_time(dk3_time_t *timer)
+{
+ int back = 1;
+ time(timer);
+ return back;
+}
+
+
+
+/** Convert file type from system representation to DK3_FT_xxx.
+ @param m File type as found by stat().
+ @return DK3_FT_xxx.
+*/
+static
+int
+dk3sf_convert_file_type(mode_t m)
+{
+ int back = 0;
+ switch(m & S_IFMT) {
+ case S_IFIFO: back = DK3_FT_FIFO; break;
+ case S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
+ case S_IFDIR: back = DK3_FT_DIRECTORY; break;
+ case S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
+ case S_IFREG: back = DK3_FT_REGULAR; break;
+ case S_IFSOCK: back = DK3_FT_SOCKET; break;
+#ifdef S_IFMPC
+ case S_IFMPC: back = DK3_FT_MUX_CHAR; break;
+#endif
+#ifdef S_IFNAM
+ case S_IFNAM: back = DK3_FT_XENIX_SPECIAL; break;
+#endif
+#ifdef S_INSEM
+ case S_INSEM: back = DK3_FT_XENIX_SEMAPHORE; break;
+#endif
+#ifdef S_INSHD
+ case S_INSHD: back = DK3_FT_XENIX_SHARED_DATA; break;
+#endif
+#ifdef S_IFMPB
+ case S_IFMPB: back = DK3_FT_MUX_BLOCK; break;
+#endif
+#ifdef S_IFCMP
+ case S_IFCMP: back = DK3_FT_VXFS_COMPRESSED; break;
+#endif
+#ifdef S_IFNWK
+ case S_IFNWK: back = DK3_FT_NETWORK_SPECIAL; break;
+#endif
+#ifdef S_IFSHAD
+ case S_IFSHAD: back = DK3_FT_ACL_SHADOW; break;
+#endif
+#ifdef S_IFDOOR
+ case S_IFDOOR: back = DK3_FT_DOOR; break;
+#endif
+#ifdef S_IFWHT
+ case S_IFWHT: back = DK3_FT_WHITEOUT; break;
+#endif
+ }
+ return back;
+}
+
+
+
+/** Convert file permissions from system representation to
+ DK3_PERM_xxx
+ @param m File mode as obtained from stat().
+ @return DK3_PERM_xxx value or combination.
+*/
+static
+int
+dk3sf_convert_file_permissions(mode_t m)
+{
+ int back = 0;
+ DK3SF_ADDIF(S_IRUSR,DK3_FPERM_U_READ)
+ DK3SF_ADDIF(S_IWUSR,DK3_FPERM_U_WRITE)
+ DK3SF_ADDIF(S_IXUSR,DK3_FPERM_U_EXEC)
+ DK3SF_ADDIF(S_IRGRP,DK3_FPERM_G_READ)
+ DK3SF_ADDIF(S_IWGRP,DK3_FPERM_G_WRITE)
+ DK3SF_ADDIF(S_IXGRP,DK3_FPERM_G_EXEC)
+ DK3SF_ADDIF(S_IROTH,DK3_FPERM_O_READ)
+ DK3SF_ADDIF(S_IWOTH,DK3_FPERM_O_WRITE)
+ DK3SF_ADDIF(S_IXOTH,DK3_FPERM_O_EXEC)
+ DK3SF_ADDIF(S_ISUID,DK3_FPERM_SUID)
+ DK3SF_ADDIF(S_ISGID,DK3_FPERM_SGID)
+ DK3SF_ADDIF(S_ISVTX,DK3_FPERM_VTX)
+ return back;
+}
+
+
+
+/** Convert file permissions back from dktools to system values.
+ @param m File permissions in dktools notation.
+ @return File permissions in system notation.
+*/
+static
+mode_t
+dk3sf_convert_back_file_permissions(int m)
+{
+ mode_t back = 0;
+ DK3SF_ADDIF(DK3_FPERM_U_READ,S_IRUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWUSR)
+ DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IXUSR)
+ DK3SF_ADDIF(DK3_FPERM_G_READ,S_IRGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_WRITE,S_IWGRP)
+ DK3SF_ADDIF(DK3_FPERM_G_EXEC,S_IXGRP)
+ DK3SF_ADDIF(DK3_FPERM_O_READ,S_IROTH)
+ DK3SF_ADDIF(DK3_FPERM_O_WRITE,S_IWOTH)
+ DK3SF_ADDIF(DK3_FPERM_O_EXEC,S_IXOTH)
+ DK3SF_ADDIF(DK3_FPERM_SUID,S_ISUID)
+ DK3SF_ADDIF(DK3_FPERM_SGID,S_ISGID)
+ DK3SF_ADDIF(DK3_FPERM_VTX,S_ISVTX)
+ return back;
+}
+
+
+int
+dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_c8_stat_app \"%!8s\"", fn
+ if((st) && (fn)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_STAT64
+ struct stat64 stb; /* Result from stat64(). */
+#if DK3_HAVE_LSTAT64
+ struct stat64 lstb; /* Result from lstat64(). */
+#endif
+ $? ". use stat64() / lstat64()"
+ if(stat64(fn, &stb) == 0) { $? ". stat64 ok"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ st->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ } $? ". ft = %d", st->ft
+ } else { $? "! lstat64() failed"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else { $? "! stat64() failed for \"%!8s\"", fn
+#if DK3_HAVE_LSTAT64
+ if(lstat64(fn, &lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[5]);
+ }
+ }
+#else
+ if(app) {
+ /* stat failed */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[6]);
+ }
+#endif
+ }
+#else
+#if DK3_HAVE_STAT
+ struct stat stb;
+#if DK3_HAVE_LSTAT
+ struct stat lstb;
+#endif
+ $? ". used stat() / lstat()"
+ if(stat(fn, &stb) == 0) { $? ". stat() ok"
+ st->u = (dk3_um_t)(stb.st_uid);
+ st->g = (dk3_um_t)(stb.st_gid);
+ st->device = (dk3_um_t)(stb.st_dev);
+ st->rdev = (dk3_um_t)(stb.st_rdev);
+ st->inode = (dk3_um_t)(stb.st_ino);
+ st->nlink = (dk3_um_t)(stb.st_nlink);
+ st->cre = (dk3_time_t)(stb.st_ctime);
+ st->mod = (dk3_time_t)(stb.st_mtime);
+ st->acc = (dk3_time_t)(stb.st_atime);
+ st->ft = dk3sf_convert_file_type(stb.st_mode);
+ st->perm = dk3sf_convert_file_permissions(stb.st_mode);
+ st->sz = (dk3_um_t)(stb.st_size);
+ sz->lsz = st->sz;
+ st->ai = 0x00;
+#if DK3_HAVE_LSTAT
+ if(lstat(fn, &lstb) == 0) {
+ back = 1;
+ if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
+ st->ft |= DK3_FT_SYMLINK;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ sz->lsz = (dk3_um_t)(lstb.st_size);
+ if(lstb.st_uid != stb.st_uid) {
+ st->ai |= DK3_STAT_AI_USER_DIFFERS;
+ }
+ if(lstb.st_gid != stb.st_gid) {
+ st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
+ }
+ if(lstb.st_dev != stb.st_dev) {
+ st->ai |= DK3_STAT_AI_FAR_LINK;
+ }
+ } $? ". ft = %d", st->ft
+ } else { $? "! lstat() failed"
+ if(app) {
+ /* lstat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 98);
+#endif
+ }
+ }
+#else
+ back = 1;
+#endif
+ } else { $? "! stat() failed"
+#if DK3_HAVE_LSTAT
+ if(lstat(fn,&lstb) == 0) {
+ back = 1;
+ st->u = DK3_UM_0;
+ st->g = DK3_UM_0;
+ st->device = DK3_UM_0;
+ st->rdev = DK3_UM_0;
+ st->inode = DK3_UM_0;
+ st->nlink = DK3_UM_0;
+ st->cre = (dk3_time_t)0UL;
+ st->mod = (dk3_time_t)0UL;
+ st->acc = (dk3_time_t)0UL;
+ st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
+ st->perm = 0;
+ st->sz = DK3_UM_0;
+ st->ai = 0x00;
+ st->lu = (dk3_um_t)(lstb.st_uid);
+ st->lg = (dk3_um_t)(lstb.st_gid);
+ st->ldevice = (dk3_um_t)(lstb.st_dev);
+ st->lrdev = (dk3_um_t)(lstb.st_rdev);
+ st->linode = (dk3_um_t)(lstb.st_ino);
+ st->lnlink = (dk3_um_t)(lstb.st_nlink);
+ st->lcre = (dk3_time_t)(lstb.st_ctime);
+ st->lmod = (dk3_time_t)(lstb.st_mtime);
+ st->lacc = (dk3_time_t)(lstb.st_atime);
+ st->lft = dk3sf_convert_file_type(lstb.st_mode);
+ st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
+ st->lsz = (dk3_um_t)(lstb.st_size);
+ } else {
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[8]);
+ }
+ }
+#else
+ if(app) {
+ /* stat() failed! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 99);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[7]);
+ }
+#endif
+ }
+#else
+#error "Not stat() function available!"
+#endif
+#endif
+ } $? "- dk3sf_c8_stat_app %d", back
+ return back;
+}
+
+
+
+/** Check whether opening a file is allowed.
+ @param fn File name.
+ @param want_to_write Flag: Write access is wanted.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 for write allowed, 0 for write denied.
+*/
+static
+int
+dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
+{
+ int back = 1;
+ dk3_stat_t stb; /* Check for existing file. */
+ if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ if(app) {
+ back = 0;
+ /* Name refers a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 76);
+#endif
+ }
+ }
+ if(want_to_write) {
+ if((stb.ft) & DK3_FT_SYMLINK) {
+ if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
+ back = 0;
+ /* Symlink owner is not file owner! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 100, 101, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 102);
+#endif
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+FILE *
+dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
+{
+ FILE *back = NULL;
+ char const *moptr = NULL; /* Traverse mode string. */
+ int want_to_write = 0; /* Flag: Write access wanted. */
+ $? "+ dk3sf_c8_fopen_app \"%!8s\" \"%!8s\"", TR_8STR(fn), TR_8STR(mo)
+ if((fn) && (mo)) {
+ moptr = mo;
+ while(*moptr) {
+ switch(*moptr) {
+ case 'w': case 'a': case '+': { want_to_write = 1; } break;
+ }
+ moptr++;
+ }
+ if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
+#if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_FOPEN64
+ back = fopen64(fn, mo); $? ". attempt fopen64"
+#else
+ back = fopen(fn, mo); $? ". attempt fopen"
+#endif
+ if(!(back)) {
+ if(app) {
+ /* Failed to open file for writing! */
+ if(want_to_write) {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 79);
+#endif
+ } else {
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 145);
+#endif
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[9]);
+ }
+ }
+ }
+ } $? "- dk3sf_c8_fopen_app %!8s", TR_8PTR(back)
+ return back;
+}
+
+
+#if DK3_HAVE_LOCALTIME_R
+int
+dk3sf_localtime_app(
+ dk3_tm_t *dest,
+ dk3_time_t *timer,
+ dk3_app_t *app
+)
+{
+ int back = 0;
+ struct tm res, *rp;
+ if((dest) && (timer)) {
+ if((rp = localtime_r(timer, &res)) != NULL) {
+ back = 1;
+ dest->Y = 1900 + rp->tm_year;
+ dest->M = 1 + rp->tm_mon;
+ dest->D = rp->tm_mday;
+ dest->h = rp->tm_hour;
+ dest->m = rp->tm_min;
+ dest->s = rp->tm_sec;
+ } else {
+ if(app) {
+ /* ERROR: localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 268);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+
+int
+dk3sf_c8_time_convert_app(
+ dkChar *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
+)
+{
+ int back = 0;
+ char buffer[64]; /* Buffer. */
+ struct tm res, *rp; /* Conversion result. */
+ if((dest) && (sz) && (timer)) {
+ rp = localtime_r(timer, &res);
+ if(rp) {
+ sprintf(
+ buffer,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ (1900 + rp->tm_year),
+ (1 + rp->tm_mon),
+ rp->tm_mday,
+ rp->tm_hour,
+ rp->tm_min,
+ rp->tm_sec
+ );
+ if(sz > dk3str_c8_len(buffer)) {
+ dk3str_c8_cpy_not_overlapped(dest, buffer);
+ back = 1;
+ } else {
+ if(app) {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* localtime_r failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 80);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Function localtime_r() not available!"
+#endif
+
+
+
+#if DK3_HAVE_GETCWD || DK3_HAVE__GETCWD
+int
+dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ if((dest) && (sz)) {
+#if DK3_HAVE_GETCWD
+ if(getcwd(dest, sz))
+#else
+ if(_getcwd(dest, sz))
+#endif
+ {
+ back = 1;
+ } else {
+ if(app) {
+ switch(errno) {
+#ifdef ERANGE
+ case ERANGE: {
+ /* Buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ } break;
+#endif
+ default: {
+ dk3app_log_i1(app, DK3_LL_ERROR, 53);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[11]);
+ } break;
+ }
+ }
+ }
+ }
+ return back;
+}
+#else
+#error "Neither getcwd() or _getcwd() available!"
+#endif
+
+
+
+/** Check whether or not a file is executable.
+ @param f File name.
+ @return 1 for exectuable, 0 for not executable.
+*/
+static
+int
+dk3sf_c8_check_exec(char const *f)
+{
+ int back = 0;
+ int testperm; /* Permissions of file. */
+ dk3_stat_t stb; /* stat() result to check for file. */
+ $? "+ dk3sf_c8_check_exec \"%!8s\"", f
+ if(dk3sf_c8_stat_app(&stb, f, NULL)) { $? ". file name ok"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) { $? ". type ok"
+ testperm = (DK3_FPERM_U_EXEC | DK3_FPERM_G_EXEC | DK3_FPERM_O_EXEC);
+ if((stb.perm) & testperm) { $? ". permissions ok"
+ back = 1;
+ } else { $? "! wrong permissions"
+ }
+ } else { $? "! wrong file type"
+ }
+ } else { $? "! file does not exist"
+ } $? "- dk3sf_c8_check_exec %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_find_exec_app(
+ char *d, size_t s, char const *w, char const *c, dk3_app_t *app
+)
+{
+ int back = 0;
+ int cc = 0; /* Flag: Can continue. */
+ char *pathcopy = NULL; /* Copy of parent directory. */
+ char *p = NULL;
+ char *pn = NULL;
+ size_t tsl = 0; /* Needed buffer length. */
+ $? "+ dk3sf_c8_find_exec_app"
+ if((d) && (s) && (w) && (c)) { $? ". args ok"
+ if(dk3str_c8_chr(c, DK3_C8_SEP)) { $? ". combine w and c"
+ if(dk3str_c8_is_abs_path(c)) { $? ". c is absolute path"
+ if(dk3str_c8_len(c) < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, c);
+ back = 1; $? ". result \"%!8s\"", d
+ } else { $? "! buffer too short"
+ if(app) {
+ /* c too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 103, 104, c);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 105);
+#endif
+ }
+ }
+ } else { $? ". c is relative path"
+ if(dk3str_c8_len(w) < s) {
+ dk3str_c8_cpy_not_overlapped(d, w);
+ back = dk3str_c8_append_path_app(d, s, c, app);
+ if(back) { $? ". result \"%!8s\"", d
+ }
+ } else { $? "! buffer too short"
+ if(app) {
+ /* w too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, w);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ }
+ } else { $? ". search PATH"
+ p = getenv(kw_c8_no_win[1]);
+ if(p) { $? ". PATH ok"
+ pathcopy = dk3str_dup_app(p, app);
+ if(pathcopy) { $? ". copy ok"
+ p = pathcopy; cc = 1;
+ while((p) && (cc) && (back == 0)) {
+ pn = dk3str_c8_chr(p, ':');
+ if(pn) { *(pn++) = '\0'; }
+ if(dk3str_c8_len(p)) { $? ". one directory"
+ tsl = dk3str_c8_len(p);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, p);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else { $? "! buffer too short"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else { $? ". current directory"
+ tsl = dk3str_c8_len(w);
+ tsl += dk3str_c8_len(kw_c8_no_win[0]);
+ tsl += dk3str_c8_len(c);
+ if(tsl < s) { $? ". buffer length ok"
+ dk3str_c8_cpy_not_overlapped(d, w);
+ dk3str_c8_cat(d, kw_c8_no_win[0]);
+ dk3str_c8_cat(d, c);
+ back = dk3sf_c8_check_exec(d);
+ } else { $? "! buffer too short"
+ cc = 0;
+ if(app) {
+ /* Destination buffer too small! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ }
+ p = pn;
+ }
+ dk3_delete(pathcopy);
+ } else { $? "! memory"
+ }
+ } else { $? "! No PATH"
+ if(app) {
+ /* PATH environment variable not defined. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 106);
+ }
+ }
+ }
+ } $? "- dk3sf_c8_find_exec_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
+{
+ int back = 0;
+ char buffer[DK3_MAX_PATH]; /* File names of parent directories. */
+ char *ptr = NULL; /* Current path separator. */
+ int cc = 0; /* Flag: Can continue. */
+ mode_t m = 0; /* File creation mode. */
+ dk3_stat_t stb; /* Check for existance of file or directory. */
+ $? "+ dk3sf_c8_mkdir_app \"%!8s\"", TR_8STR(p)
+ if(p) { $? ". name ok"
+ m = dk3sf_convert_back_file_permissions(mo);
+ if(dk3str_c8_len(p) < sizeof(buffer)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(buffer, p);
+ ptr = buffer; cc = 1;
+ while((cc) && (ptr)) { $? ". loop \"%!8s\"", ptr
+ ptr = dk3str_c8_chr(ptr, DK3_C8_SEP);
+ if(ptr) {
+ *ptr = '\0'; $? ". directory \"%!8s\"", buffer
+ if(dk3str_c8_len(buffer) > 0) {
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
+ cc = 0; $? "! path is not a directory"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create dir \"%!8s\"", buffer
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m); $? ". mode %o", m
+#endif
+ } else {
+ cc = 0; $? "! failed to create directory"
+ if(app) {
+ /* Failed to create directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+ }
+#else
+ cc = 0;
+ if(app) { $? "! no mkdir) function"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ *ptr = DK3_C8_SEP;
+ ptr++;
+ }
+ }
+ if(cc) { $? ". all parents ok path now \"%!8s\"", buffer
+ if(dk3sf_c8_stat_app(&stb, buffer, NULL)) { $? ". path exists"
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1; $? ". path is a directory"
+ } else { $? "! path is not a directory"
+ if(app) {
+ /* Not a directory! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 83);
+#endif
+ }
+ }
+ } else { $? ". must create \"%!8s\"", buffer
+#if DK3_HAVE_MKDIR
+#if DK3_HAVE_MKDIR2
+ if(mkdir(buffer, m) == 0)
+#else
+ if(mkdir(buffer) == 0)
+#endif
+ {
+ back = 1; $? ". \"%!8s\" created successfully", buffer
+#if DK3_HAVE_CHMOD
+ (void)chmod(buffer, m); $? ". mode %o", m
+#endif
+ } else { $? "! failed to create \"%!8s\"", buffer
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 86);
+#endif
+ dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
+ }
+#else
+ if(app) { $? "! no mkdir() function"
+ /* No mkdir() function available! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 107);
+ }
+#endif
+ }
+ }
+ } else { $? "! directory name too long"
+ if(app) {
+ /* Path too long! */
+#if DK3_CHAR_SIZE == 1
+ dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
+#else
+ dk3app_log_i1(app, DK3_LL_ERROR, 87);
+#endif
+ }
+ }
+ } $? "- dk3sf_c8_mkdir_app %d", back
+ return back;
+}
+
+
+int
+dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
+{
+ int back = 0;
+ char *ptr = NULL; /* Begin of DNS domain name. */
+ if((db) && (sz)) {
+ if(gethostname(db, sz) == 0) {
+ back = 1;
+ ptr = dk3str_c8_chr(db, '.');
+ if(ptr) {
+ *ptr = '\0';
+ }
+ } else {
+ if(app) {
+ /* ERROR: Failed to find host name! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 131);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[13]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+#if DK3_CHAR_SIZE > 1
+#error "dkChar must be 8 bit on non-Windows systems!"
+#else
+/* +++ non-Windows, dkChar 8 bit +++ */
+
+
+
+int
+dk3sf_fgets_fn_app(
+ dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((db) && (sz) && (fi)) {
+ if(fgets(db, sz, fi)) {
+ back = 1;
+ } else {
+ if(!feof(fi)) {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 345);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[25]);
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
+{
+ int back = 0;
+ if((st) && (fi)) {
+ if(fputs(st, fi) >= 0) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[23]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ if(fi) {
+ if(fputc(ch, fi) != EOF) {
+ back = 1;
+ } else {
+ if(app) {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 120);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[24]);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+void
+dk3sf_initialize_stdout(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_stderr(void)
+{
+}
+
+
+
+void
+dk3sf_initialize_file(FILE *fipo)
+{
+}
+
+
+
+/* --- non-Windows, dkChar 8 bit --- */
+#endif
+
+/* --- non-Windows --- */
+#endif
+
+
+
+int
+dk3sf_must_expand(dkChar const *fn)
+{
+ int back = 0;
+ $? "+ dk3sf_must_expand"
+ if(fn) {
+#if DK3_ON_WINDOWS
+ dkChar const *ptr;
+ ptr = fn;
+ while((*ptr) && (back == 0)) {
+ switch(*ptr) {
+ case dkT('?'):
+ case dkT('*'):
+ {
+ back = 1;
+ }
+ break;
+ }
+ ptr++;
+ }
+#endif
+ } $? "- dk3sf_must_expand %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputc(char c, FILE *f)
+{
+ int back = 0;
+ if(f) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+ if(fputwc((((wchar_t)c) & 0x000000FFUL), f) != WEOF) {
+ back = 1;
+ }
+#else
+ if(fputwc((((wchar_t)c) & 0x00FFU), f) != WEOF) {
+ back = 1;
+ }
+#endif
+#else
+ if(fputc(c, f) != EOF) {
+ back = 1;
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_c8_fputs(char const *s, FILE *f)
+{
+ int back = 0;
+ char const *ptr = NULL;
+ if((s) && (f)) {
+ back = 1;
+ ptr = s;
+ while(*ptr) {
+ if(!dk3sf_c8_fputc(*(ptr++), f)) {
+ back = 0;
+ }
+ }
+ }
+ return back;
+}
+
+
+
+size_t
+dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app)
+{
+ size_t back = 0;
+ $? "+ dk3sf_read_app buf=%!8s s=%u", TR_8PTR(buf), (unsigned)s
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int rb;
+ $? ". Windows +"
+ rb = _read(fd, buf, (unsigned int)s);
+ if(rb >= 0) {
+ back = (size_t)rb;
+ } else {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+ $? ". Windows -"
+#else
+ $? ". non-Windows +"
+#if DK3_HAVE_READ
+ ssize_t rb = 0; /* Number of bytes read. */
+ $? ". read() +"
+ rb = read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[14]);
+ }
+ } $? ". read() -"
+#else
+#if DK3_HAVE__READ
+ ssize_t rb = 0; /* Number of bytes read. */
+ $? ". _read() +"
+ rb = _read(fd, buf, s);
+ if(rb >= (ssize_t)0) {
+ back = (size_t)rb;
+ } else {
+ if(app) {
+ /* ERROR: Read failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[15]);
+ }
+ } $? ". _read() -"
+#else
+#error "No read() function available!"
+#endif
+#endif
+ $? ". non-Windows -"
+#endif
+ } $? "- dk3sf_read_app %u", (unsigned)back
+ return back;
+}
+
+
+
+int
+dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app)
+{
+ int back = 0;
+ if((buf) && (s)) {
+#if DK3_ON_WINDOWS
+ int wb;
+ wb = _write(fd, buf, (unsigned int)s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1( app, DK3_LL_ERROR, 173);
+ }
+ }
+#else
+#if DK3_HAVE_WRITE
+ ssize_t wb;
+ wb = write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[16]);
+ }
+ }
+#else
+#if DK3_HAVE__WRITE
+ ssize_t wb;
+ wb = _write(fd, buf, s);
+ if(wb >= 0) {
+ if((size_t)wb == s) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: Not all bytes written! */
+ dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Write failed! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 173);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[17]);
+ }
+ }
+#else
+#error "No write() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+size_t
+dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ size_t back = 0;
+ if((db) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ }
+ }
+ clearerr(fi);
+ }
+#else
+#if DK3_HAVE_FREAD
+ back = fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[18]);
+ }
+ } clearerr(fi);
+ }
+#else
+#if DK3_HAVE__FREAD
+ back = _fread(db, sz, ne, fi);
+ if(back < ne) {
+ if(ferror(fi)) {
+ if(app) {
+ dk3app_log_i1(app, DK3_LL_ERROR, 124);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[19]);
+ }
+ } clearerr(fi);
+ }
+#else
+#error "No fread() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fwrite_app(void const *sb, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
+{
+ int back = 0;
+ if((sb) && (sz) && (ne) && (fi)) {
+#if DK3_ON_WINDOWS
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ }
+ }
+#else
+#if DK3_HAVE_FWRITE
+ size_t wb;
+ wb = fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[20]);
+ }
+ }
+#else
+#if DK3_HAVE__FWRITE
+ size_t wb;
+ wb = _fwrite(sb, sz, ne, fi);
+ if(wb == ne) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[21]);
+ }
+ }
+#else
+#error "No fwrite() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_skip_app(
+ dkChar const *fn,
+ int dv,
+ size_t *skb,
+ dk3_app_t *app
+)
+{
+ int back = -1;
+ int found = 0; /* Flag: Any form of BOM found .*/
+ FILE *fipo = NULL; /* Input file. */
+ unsigned char bb[4]; /* Buffer for BOM. */
+ size_t rb = 0; /* Number of bytes read. */
+ $? "+ dk3sf_inspect_bom_app %d", dv
+ if(skb) { *skb = 0; }
+ back = dv;
+ if(fn) {
+ fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
+ if(fipo) {
+ rb = dk3sf_fread_app(bb, 1, 4, fipo, app);
+ /* Check UTF-8 */
+ if(rb >= 3) {
+ if((bb[0] == 0xEF) && (bb[1] == 0xBB) && (bb[2] == 0xBF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF8; $? ". UTF-8"
+ if(skb) { *skb = 3; }
+ }
+ }
+ if(!found) {
+ if(rb >= 2) {
+ if((bb[0] == 0xFE) && (bb[1] == 0xFF)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; $? ". U16 M"
+ if(skb) { *skb = 2; }
+ } else {
+ if((bb[0] == 0xFF) && (bb[1] == 0xFE)) {
+ found = 1; back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; $? ". U16 L"
+ if(skb) { *skb = 2; }
+ if(rb >= 4) {
+ if((bb[2] == 0x00) && (bb[3] == 0x00)) {
+ back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; $? ". U32 L"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(!found) {
+ if(rb >= 4) {
+ if((bb[0] == 0x00) && (bb[1] == 0x00)
+ && (bb[2] == 0xFE) && (bb[3] == 0xFF)
+ )
+ {
+ found = 1; back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; $? ". U32 M"
+ if(skb) { *skb = 4; }
+ }
+ }
+ }
+ if(!found) {
+ /* No BOM found */
+ back = dv;
+ }
+ fclose(fipo);
+ }
+ } $? "- dk3sf_inspect_bom_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app)
+{
+ int back;
+ back = dk3sf_inspect_bom_skip_app(fn, dv, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_apply_bom_to_file_app"
+#if DK3_ON_WINDOWS
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: {
+ back = 1; $? ". keep default"
+ } break;
+ case DK3_FILE_ENCODING_UTF8: {
+ back = 1;
+ _setmode(_fileno(fipo), _O_U8TEXT); $? ". 8"
+ } break;
+ case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
+ _setmode(_fileno(fipo), _O_U16TEXT); $? ". 16 L"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled directly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#else
+ if(fipo) {
+ switch(enc) {
+ case DK3_FILE_ENCODING_ASCII: case DK3_FILE_ENCODING_UTF8: {
+ back = 1; $? ". 8-bit, ok"
+ } break;
+ default: {
+ /* ERROR: Encoding can not be handled direcly by file! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 204);
+ } break;
+ }
+ }
+#endif
+ $? "- dk3sf_apply_bom_to_file_app %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = 0;
+ dk3_stat_t stb;
+ if(dk3sf_stat_app(&stb, n, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
+ back = 1;
+ } else {
+ if(app) {
+ /* ERROR: n is not a directory! */
+ dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, n);
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app)
+{
+ int back = 0;
+ if(dn) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_ON_WINDOWS
+ if(_wchdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#error "No chdir() function (16-bit) on non-Windows systems!"
+#endif
+#else
+#if DK3_ON_WINDOWS
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ }
+ }
+#else
+#if DK3_HAVE_CHDIR
+ if(chdir(dn) == 0) {
+ back = 1;
+ } else {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
+ dk3sf_report_errno(app, errno, dk3sf_function_names[22]);
+ }
+ }
+#else
+#error "No chdir() function available!"
+#endif
+#endif
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn)
+{
+ int back = 1;
+ dk3_stat_t stbs;
+ dk3_stat_t stbd;
+ if((dn) && (sn)) {
+ if(dk3sf_stat_app(&stbd, dn, NULL)) {
+ if(dk3sf_stat_app(&stbs, sn, NULL)) {
+ if(stbd.mod > stbs.mod) {
+ back = 0;
+ }
+ }
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_filename_to_c8(
+ char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
+)
+{
+ int back = 0;
+ if((fnb) && (szfnb) && (src)) {
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "Only 1- or 2-byte character support available!"
+#else
+#if DK3_ON_WINDOWS
+ back = dk3str_cnv_c16_to_c8p_app(fnb, szfnb, src, app);
+#else
+#error "2-byte character support is available on Windows platforms only!"
+#endif
+#endif
+#else
+ if(dk3str_len(src) < szfnb) {
+ dk3str_cpy_not_overlapped(fnb, src);
+ back = 1;
+ } else {
+ /* ERROR: File name too long! */
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, src);
+ }
+ }
+#endif
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app)
+{
+ int back = 0;
+ $? "+ dk3sf_scan_double"
+ if((txt) && (v)) { $? ". args ok"
+#if DK3_HAVE_SETLOCALE
+ char oldlocale[64];
+ char *lcptr;
+
+ lcptr = setlocale(LC_NUMERIC, NULL); $? ". have setlocale"
+ if(lcptr) { $? ". setlocale (1) ok"
+ if(dk3str_c8_len(lcptr) < sizeof(oldlocale)) { $? ". length ok"
+ dk3str_c8_cpy_not_overlapped(oldlocale, lcptr);
+ setlocale(LC_NUMERIC, "C");
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ setlocale(LC_NUMERIC, oldlocale);
+ } else { $? "! too long"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to save current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 254);
+ }
+ }
+ } else { $? "! setlocale (1)"
+#if VERSION_BEFORE_20140716
+ dk3sf_sscanf3(txt,dkT("%lf"),v);
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+ if(app) {
+ /* ERROR: Failed to obtain current locale! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 253);
+ }
+ }
+#else
+#if VERSION_BEFORE_20140716
+ back = dk3sf_sscanf3(txt,dkT("%lf"),v); $? ". no setlocale"
+#else
+ back = dk3ma_d_from_string(v, txt, NULL);
+#endif
+#endif
+ } $? "- dk3sf_scan_double %d", back
+ return back;
+}
+
+
+
+int
+dk3sf_get_max_files(void)
+{
+ int back = 1024;
+#if DK3_HAVE_SYS_RESOURCE_H
+#if DK3_HAVE_GETRLIMIT
+ struct rlimit rl;
+ if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
+ if(rl.rlim_max != RLIM_INFINITY) {
+ back = rl.rlim_max;
+ }
+ }
+#endif
+#endif
+ return back;
+}
+
+
+
+
+int
+dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app)
+{
+ int back = 0;
+ int res;
+ if(fipo) {
+ res = fclose(fipo);
+ if(0 == res) {
+ back = 1;
+ } else {
+ if(fn) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 341, 342, fn);
+ } else {
+ dk3app_log_i1(app, DK3_LL_ERROR, 340);
+ }
+ dk3sf_report_errno(app, errno, dk3sf_function_names[1]);
+ }
+ }
+ return back;
+}
+
+
+
+int
+dk3sf_fclose_app(FILE *fipo, dk3_app_t *app)
+{
+ int back = 0;
+ back = dk3sf_fclose_fn_app(fipo, NULL, app);
+ return back;
+}
+
+
+
+int
+dk3sf_fgets(dkChar *db, size_t sz, FILE *fi)
+{
+ int back;
+ back = dk3sf_fgets_fn_app(db, sz, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputs(dkChar const *st, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputs_fn_app(st, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_fputt(dkChar const * const *txt, FILE *fi)
+{
+ dkChar const * const *ptr;
+ int back = 0;
+ if((txt) && (fi)) {
+ back = 1;
+ ptr = txt;
+ while(*ptr) {
+ if(!(dk3sf_fputs(*(ptr++), fi))) {
+ back = 0;
+ }
+ dk3sf_fputc(dkT('\n'), fi);
+ }
+ }
+ return back;
+}
+
+
+int
+dk3sf_fputc(dkChar c, FILE *fi)
+{
+ int back;
+ back = dk3sf_fputc_fn_app(c, fi, NULL, NULL);
+ return back;
+}
+
+
+
+int
+dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_stat_app(st, fn, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_stat_app(st, fn, app));
+#endif
+}
+
+
+
+FILE *
+dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_fopen_app(fn, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_fopen_app(fn, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_time_convert_app(
+ dkChar *dest,
+ size_t sz,
+ dk3_time_t const *timer,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_time_convert_app(dest, sz, timer, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_time_convert_app(dest, sz, timer, app));
+#endif
+}
+
+
+
+int
+dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getcwd_app(dest, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getcwd_app(dest, sz, app));
+#endif
+}
+
+
+
+int
+dk3sf_find_exec_app(
+ dkChar *d,
+ size_t s,
+ dkChar const *w,
+ dkChar const *c,
+ dk3_app_t *app
+)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_find_exec_app(d, s, w, c, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_find_exec_app(d, s, w, c, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_logname_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_logname_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_home_app(d, s, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_home_app(d, s, app));
+#endif
+}
+
+
+
+int
+dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_mkdir_app(p, mo, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_mkdir_app(p, mo, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_file_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_file_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_remove_dir_app(n, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_remove_dir_app(n, app));
+#endif
+}
+
+
+
+int
+dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_get_hostname_app(db, sz, app));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_get_hostname_app(db, sz, app));
+#endif
+}
+
+
+
+dkChar *
+dk3sf_getenv(dkChar const *name)
+{
+#if DK3_CHAR_SIZE > 1
+#if DK3_CHAR_SIZE > 2
+#error "System function for b-byte character strings not available!"
+#else
+#if DK3_ON_WINDOWS
+ return(dk3sf_c16_getenv(name));
+#else
+#error "Wide character functions not defined on non-Windows systems!"
+#endif
+#endif
+#else
+ return(dk3sf_c8_getenv(name));
+#endif
+}
+
+
+
+
+/* vim: set ai sw=2 : */
+