/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3app.ctr */ /* Copyright (C) 2011-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk3app.c The dk3app module. */ #line 701 "dk3app.ctr" #include "dk3all.h" #if DK3_HAVE_OPENSSL_RAND_H #include #endif #line 710 "dk3app.ctr" /** Names of preference scope attributes. */ static dkChar const * const dk3app_scope_attributes[] = { /* 0 */ dkT("user"), /* 1 */ dkT("application"), /* 2 */ dkT("application-group"), /* 3 */ dkT("host"), /* 4 */ dkT("language"), /* 5 */ dkT("region"), NULL }; /** Text strings, not localized. */ static dkChar const * const dk3app_no_loc[] = { /* 0 */ dkT("bin"), /* Used to build bindir. */ /* 1 */ dkT("etc"), /* Used to build etcdir. */ /* 2 */ dkT("share"), /* Used to build sharedir. */ /* 3 */ dkT("var"), /* Used to build vardir. */ #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /* 4 */ dkT("\\log"), /* Used to build log directory. */ #else /* 4 */ dkT("/log"), /* Used to build log directory. */ #endif /* 5 */ dkT("-"), /* Used to build log file name. */ /* 6 */ dkT(".log"), /* Used to build log file name. */ /* 7 */ dkT("/"), /* Used to build log directory. */ /* 8 */ dkT("a"), /* Open mode for log file. */ #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /* 9 */ dkT("\\tmp"), /* Subdirectory for temporary files. */ #else /* 9 */ dkT("/tmp"), /* Subdirectory for temporary files. */ #endif #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /* 10 */ dkT("\\run"), /* Subdirectory for temporary files. */ #else /* 10 */ dkT("/run"), /* Subdirectory for temporary files. */ #endif /* 11 */ dkT("LANG"), /* Environment variable for language. */ /* 12 */ dkT("Control Panel\\International"), /* Reg key for language. */ /* 13 */ dkT("LocaleName"), /* Reg entry name for language. */ /* 14 */ dkT("sLanguage"), /* Alternative reg entry name for language. */ /* 15 */ dkT("utf8"), /* Encoding UTF-8 (modern variant). */ /* 16 */ dkT("UTF-8"), /* Encoding UTF-8 (older variant). */ /* 17 */ dkT("dk3app"), /* Subdirectory in system configuration. */ /* 18 */ dkT(".dk3app"), /* Subdirectory in home directory. */ /* 19 */ dkT("."), /* Current directory. */ #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH /* 20 */ dkT("\\"), /* File name separator. */ #else /* 20 */ dkT("/"), /* File name separator. */ #endif /* 21 */ dkT("dk3pref.conf"), /* Configuration file name. */ /* 22 */ dkT("r"), /* File open mode for reading. */ /* 23 */ dkT("dk3app.str"), /* String table name. */ /* 24 */ dkT("w"), /* File open mode. */ /* 25 */ dkT("="), /* Used when writing preferences. */ /* 26 */ dkT("\n"), /* Used when writing preferences. */ /* 27 */ dkT("/ui/lang"), /* User interface, language. */ /* 28 */ dkT("/log/file/level"), /* Required log level for file. */ /* 29 */ dkT("/log/file/keep"), /* Required level to keep file. */ /* 30 */ dkT("/log/stderr/level"), /* Required log level for stderr. */ /* 31 */ dkT("/temp/dir/keep"), /* Required to keep temp dir. */ /* 32 */ dkT("-site"), /* Check for site-specific config files. */ /* 33 */ dkT("*"), /* Wildcard for all users ... */ /* 34 */ dkT("dk3conf.conf"), /* Configuration file name. */ /* 35 */ dkT("%lu"), /* scanf/printf format. */ /* 36 */ dkT("rb"), /* File open mode: Read binary. */ /* 37 */ dkT("/rand/types"), /* Preference name for allowed PRNG types. */ /* 38 */ dkT(".rnd-simple"), /* Preference name for simple seed file. */ /* 39 */ dkT(".rnd-lrand48"), /* Preference name for lrand48() seed file. */ /* 40 */ dkT(".rnd-random"), /* Preference name for random() seed file. */ /* 41 */ dkT(".rnd-openssl"), /* Preference name for OpenSSL seed file. */ /* 42 */ dkT("/rand/egd/name"), /* Preference name for EGD socket. */ /* 43 */ dkT("EGDSOCKET"), /* Environment variable name for EGD socket. */ /* 44 */ dkT("/dev/urandom"), /* Device name for seed data. */ /* 45 */ dkT("/dev/random"), /* Device name for seed data. */ /* 46 */ dkT("/rand/file/allowed"), /* Preference name. */ /* 47 */ dkT("en"), /* Default language name. */ #if 0 /* 48 */ dkT("/dir/uc2lat-t"), /* Preference name for LaTeX encoding. */ #else /* 48 */ dkT("/dir/charmap"), /* Preference name for LaTeX encoding. */ #endif /* 49 */ #if 0 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH dkT("\\uc2lat-t"), #else dkT("/uc2lat-t"), #endif #else #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH dkT("\\dktools\\charmap"), /* Character map subdirectory of share. */ #else dkT("/dktools/charmap"), /* Character map subdirectory of share. */ #endif #endif /* 50 */ dkT("/silent"), /* Preference name for silent work. */ /* 51 */ dkT("/input/encoding/file"), /* Preference name. */ /* 52 */ dkT("/input/encoding/stdin"), /* Preference name. */ /* 53 */ dkT("wb"), /* File open mode: Read binary. */ /* 54 */ dkT(".dir"), /* Suffix for uc2lat *.dir files. */ /* 55 */ dkT(".lat"), /* Suffix for uc2lat *.lat files. */ /* 56 */ dkT("sbin"), /* sbin dirctory. */ }; /** Directories where binary executable can reside. */ static dkChar const * const dk3app_bindir_candidates[] = { /* 0 */ dkT("bin"), /* 1 */ dkT("sbin"), /* 2 */ dkT("lib"), /* 3 */ dkT("libexec"), NULL #line 833 "dk3app.ctr" }; /** Keywords for users configuration files. These keywords can be used in the $HOME/.dk3app/dk3conf.conf file. */ dkChar const * const dk3app_conf_file[] = { /* 0 */ dkT("use-system-config-files"), /* 1 */ dkT("ignore-system-config-files"), NULL }; /** Log level names. */ static dkChar const * const dk3app_log_levels[] = { dkT("n$one"), dkT("pa$nic"), dkT("f$atal"), dkT("e$rror"), dkT("w$arning"), dkT("in$fo"), dkT("pr$ogress"), dkT("d$ebug"), dkT("ig$nore"), NULL }; #if 0 static dkChar const * const dk3app_prng_type_names[] = { /* 0 */ dkT("openssl"), /* OpenSSL PRNG. */ /* 1 */ dkT("random"), /* initstate()/setstate()/random() */ /* 2 */ dkT("rand48"), /* lrand48(). */ /* 3 */ dkT("simple"), /* srand()/rand(). */ NULL }; #endif /** Text strings, localization needed. The texts strings are used as parts of diagnostic messages. */ static dkChar const * const dk3app_kw[] = { /* 0 */ dkT("\n"), /* 1 */ dkT("PANIC"), /* 2 */ dkT("FATAL"), /* 3 */ dkT("ERROR"), /* 4 */ dkT("Warning"), /* 5 */ dkT("Information"), /* 6 */ dkT("Progress"), /* 7 */ dkT("Debug"), /* 8 */ dkT(" "), /* 9 */ dkT("Not enough memory (RAM/swap space)!"), /* 10 */ dkT("# "), /* 11 */ dkT(":"), /* 12 */ dkT("Memory allocation ("), /* 13 */ dkT(" bytes) failed!"), /* 14 */ dkT("Memory allocation failed!"), /* 15 */ dkT("Numeric overflow in size calculation!"), /* 16 */ dkT("Numeric overflow in size calculation ("), /* 17 */ dkT(" x "), /* 18 */ dkT(" bytes)!"), /* 19 */ dkT("Application \""), /* 20 */ dkT("\" started."), /* 21 */ dkT("Application \""), /* 22 */ dkT("\" finished."), /* 23 */ dkT("Application name: "), /* 24 */ dkT("Application group: "), /* 25 */ dkT("Executable file: "), /* 26 */ dkT("Directory \"bin\": "), /* 27 */ dkT("Directory \"etc\": "), /* 28 */ dkT("Directory \"share\": "), /* 29 */ dkT("Directory \"var\": "), /* 30 */ dkT("Directory \"home\": "), /* 31 */ dkT("Directory \"temp\": "), /* 32 */ dkT("User: "), /* 33 */ dkT("Log file: "), /* 34 */ dkT("Language: "), /* 35 */ dkT("Region: "), /* 36 */ dkT(""), /* 37 */ dkT("The name of the temporary directory is too long!"), /* 38 */ dkT("Destination buffer too small!"), /* 39 */ dkT("The LANG environment variable is too long!"), /* 40 */ dkT("Failed to find name of executable file!"), /* 41 */ dkT("Too few directories in hierarchy!\nExecutable files should not reside in the root directory!"), /* 42 */ dkT("File name of executable file too long!"), /* 43 */ dkT("Failed to obtain the users login name!"), /* 44 */ dkT("Failed to find the users home directory!"), /* 45 */ dkT("File name for log file gets too long!"), /* 46 */ dkT("Failed to create directory for log file!"), /* 47 */ dkT("Failed to convert process ID to text!"), /* 48 */ dkT("Failed to find application name!"), /* 49 */ dkT("The name of the temporary directory is too long!"), /* 50 */ dkT("Failed to find local state (var) directory!"), /* 51 */ dkT("Preference name too long!"), /* 52 */ dkT("Malformed preference entry on command line!"), /* 53 */ dkT("Failed to find current working directory!"), /* 54 */ dkT("Too many requests for temporary file names!"), /* 55 */ dkT("Internal error (bug): Missing a file or directory name!"), /* 56 */ dkT("Failed to save preference entry \""), /* 57 */ dkT("\"=\""), /* 58 */ dkT("\"!"), /* 59 */ dkT("Directory name \""), /* 60 */ dkT("\" too long!"), /* 61 */ dkT("Failed to obtain information about \""), /* 62 */ dkT("\"!\nThe stat() function failed!"), /* 63 */ dkT("Failed to read directory \""), /* 64 */ dkT("\"!"), /* 65 */ dkT("File name \""), /* 66 */ dkT("\" too long!"), /* 67 */ dkT("Illegal characters in source string, conversion failed!"), /* 68 */ dkT("Failed to remove directory!"), /* 69 */ dkT("Failed to remove directory \""), /* 70 */ dkT("\"!"), /* 71 */ dkT("The HOMEDRIVE environment variable is not set!"), /* 72 */ dkT("The HOMEPATH environment variable is not set!"), /* 73 */ dkT("Failed to obtain information about a file!"), /* 74 */ dkT("\""), /* 75 */ dkT("\" is a directory!"), /* 76 */ dkT("Can not open file, name refers to a directory!"), /* 77 */ dkT("Failed to open file \""), /* 78 */ dkT("\" for write access!"), /* 79 */ dkT("Failed to open file for write access!"), /* 80 */ dkT("Failed to obtain current time!"), /* 81 */ dkT("File \""), /* 82 */ dkT("\" exists but is not a directory!"), /* 83 */ dkT("File exists but is not a directory!"), /* 84 */ dkT("Failed to create directory \""), /* 85 */ dkT("\"!"), /* 86 */ dkT("Failed to create directory!"), /* 87 */ dkT("Directory name too long!"), /* 88 */ dkT("Failed to remove file \""), /* 89 */ dkT("\"!"), /* 90 */ dkT("Failed to remove file!"), /* 91 */ dkT("No user name entry in user record!"), /* 92 */ dkT("No user record for \""), /* 93 */ dkT("\"!"), /* 94 */ dkT("No matching user record found!"), /* 95 */ dkT("No home directory entry in user record!"), /* 96 */ dkT("Failed to obtain information about \""), /* 97 */ dkT("\"!\nThe lstat() function failed!"), /* 98 */ dkT("No information about a file, lstat() failed!"), /* 99 */ dkT("No information about a file, lstat() failed!"), /* 100 */ dkT("Owner of symlink \""), /* 101 */ dkT("\" is not owner of file!"), /* 102 */ dkT("Symlink owner is not file owner!"), /* 103 */ dkT("Command \""), /* 104 */ dkT("\" is too long!"), /* 105 */ dkT("Command is too long!"), /* 106 */ dkT("The PATH environment variable is not defined!"), /* 107 */ dkT("No mkdir() function available!"), /* 108 */ dkT("String too long!"), /* 109 */ dkT("Command name too long!"), /* 110 */ dkT("Too many \"..\" entries in file name \""), /* 111 */ dkT("\"!"), /* 112 */ dkT("Illegal character(s) in source string!"), /* 113 */ dkT("Illegal character(s) in source buffer!"), /* 114 */ dkT("Illegal destination encoding!"), /* 115 */ dkT("Conversion to UTF-8 failed!"), /* 116 */ dkT("Conversion to UTF-16 failed!"), /* 117 */ dkT("Result character(s) not available for destination encoding!"), /* 118 */ dkT("UTF-8 decoding failed!"), /* 119 */ dkT("UTF-16 decoding failed!"), /* 120 */ dkT("Failed to write data!"), /* 121 */ dkT("Failed to flush output!"), /* 122 */ dkT("Failed to close data stream object!"), /* 123 */ dkT("Stream not opened for write operations!"), /* 124 */ dkT("Failed to read data!"), /* 125 */ dkT("Mismatch between encoding and character size!"), /* 126 */ dkT("Too many \"..\" entries in file name!"), /* 127 */ dkT("Unknown message digest type: \""), /* 128 */ dkT("\"!"), /* 129 */ dkT("Unknown encoding: \""), /* 130 */ dkT("\"!"), /* 131 */ dkT("Failed to find current host name!"), /* 132 */ dkT("Host: "), /* 133 */ dkT("Option \""), /* 134 */ dkT("\" requires an argument!"), /* 135 */ dkT("Option \""), /* 136 */ dkT("\" too long for processing"), /* 137 */ dkT("Ignoring irrelevant argument in \""), /* 138 */ dkT("\"!"), /* 139 */ dkT("Unknown option \""), /* 140 */ dkT("\"!"), /* 141 */ dkT("Not a numeric value: \""), /* 142 */ dkT("\"!"), /* 143 */ dkT("Failed to open file \""), /* 144 */ dkT("\"!"), /* 145 */ dkT("Failed to open file!"), /* 146 */ dkT("Not a boolean value: \""), /* 147 */ dkT("\"!"), /* 148 */ dkT("Resource file \""), /* 149 */ dkT("\" found."), /* 150 */ dkT("Resource file \""), /* 151 */ dkT("\" not found."), /* 152 */ dkT("Configuration file \""), /* 153 */ dkT("\" found."), /* 154 */ dkT("Configuration file \""), /* 155 */ dkT("\" not found."), /* 156 */ dkT("No support for message digest \""), /* 157 */ dkT("\"!"), /* 158 */ dkT("Illegal message digest or encoding number!"), /* 159 */ dkT("Checksumming is available for regular files only!"), /* 160 */ dkT("Option name missing in long option: \""), /* 161 */ dkT("\"!"), /* 162 */ dkT("Failed to convert a numeric value to text!"), /* 163 */ dkT("\"!"), /* 164 */ dkT("Too many command line arguments! Ignoring \""), /* 165 */ dkT("\"...!"), /* 166 */ dkT("Internal error (bug) "), /* 167 */ dkT("."), /* 168 */ dkT("Too many file names match pattern \""), /* 169 */ dkT("\", just one allowed!"), /* 170 */ dkT("Write operation failed, "), /* 171 */ dkT(" of "), /* 172 */ dkT(" bytes written!"), /* 173 */ dkT("Write operation failed!"), /* 174 */ dkT("Write operation failed, "), /* 175 */ dkT(" of "), /* 176 */ dkT(" elements written!"), /* 177 */ dkT("Failed to create random data!"), /* 178 */ dkT("No usable PRNG found!"), /* 179 */ dkT("Failed to seed simple PRNG!"), /* 180 */ dkT("Failed to seed lrand48() PRNG!"), /* 181 */ dkT("Failed to seed random() PRNG!"), /* 182 */ dkT("Failed to seed OpenSSL PRNG!"), /* 183 */ dkT("Seed file \""), /* 184 */ dkT("\" not used (permissions)!"), /* 185 */ dkT("Seed file \""), /* 186 */ dkT("\" not used (symlink owner)!"), /* 187 */ dkT("Unknown PRNG type: \""), /* 188 */ dkT("\"!"), /* 189 */ dkT("The srand()/rand() PRNG is not available!"), /* 190 */ dkT("The srand48()/lrand48() PRNG is not available!"), /* 191 */ dkT("The random() PRNG is not available!"), /* 192 */ dkT("The OpenSSL PRNG is not available!"), /* 193 */ dkT("Failed to save random seed data!"), /* 194 */ dkT("HOME directory name too long!"), /* 195 */ dkT("System configuration files skipped by user."), /* 196 */ dkT("Attempt to obtain seed data from \""), /* 197 */ dkT("\"."), /* 198 */ dkT("Seed data: "), /* 199 */ dkT(" bytes found."), /* 200 */ dkT("Index out of range!"), /* 201 */ dkT("Matrix expansion requires a square matrix!"), /* 202 */ dkT("Not a directory: \""), /* 203 */ dkT("\"!"), /* 204 */ dkT("Encoding not supported by C runtime library!"), /* 205 */ dkT("No directory containing LaTeX encoding tables found!"), /* 206 */ dkT("Redefinition,\noverwriting \""), /* 207 */ dkT("\" by \""), /* 208 */ dkT("\"."), /* 209 */ dkT("Syntax error,\nindex "), /* 210 */ dkT(" is out of range 0...255."), /* 211 */ dkT("Syntax error\nnear \""), /* 212 */ dkT("\"!"), /* 213 */ dkT("Syntax error,\nmissing LaTeX encoding!"), /* 214 */ dkT("Syntax error,\nmissing index!"), /* 215 */ dkT("No file name matches pattern \""), /* 216 */ dkT("\"!"), /* 217 */ dkT("Missing name of long option!"), /* 218 */ dkT("Incomplete input sequence."), /* 219 */ dkT("String contains non-ISO-LATIN-1 characters!"), /* 220 */ dkT("Misconfigured start/end for range!"), /* 221 */ dkT("New range conflicts with existing one!"), /* 222 */ dkT("Not a hex number!"), /* 223 */ dkT("Syntax error!"), /* 224 */ dkT("Character redefinition!"), /* 225 */ dkT("Range not declared in character directory!"), /* 226 */ dkT("Package name conflicts with previous definition!"), /* 227 */ dkT("Attempt to obtain seed data from CryptoAPI."), /* 228 */ dkT("Attempt to obtain seed data from screen."), /* 229 */ dkT("OpenSSL PRNG seeded successfully."), /* 230 */ dkT("Attempt to read preferences file \""), /* 231 */ dkT("\"."), /* 232 */ dkT("LaTeX table directory: \""), /* 233 */ dkT("\"."), /* 234 */ dkT("Attempting LaTeX table directory: \""), /* 235 */ dkT("\"."), /* 236 */ dkT("Reading LaTeX table dir: \""), /* 237 */ dkT("\"."), /* 238 */ dkT("Registering LaTeX conversion range "), /* 239 */ dkT("."), /* 240 */ dkT("Loading LaTeX conversion data file \""), /* 241 */ dkT("\"."), /* 242 */ dkT("Failed to change into directory: \""), /* 243 */ dkT("\"!"), /* 244 */ dkT("Failed to enumerate printers!"), /* 245 */ dkT("Record too large!"), /* 246 */ dkT("File damaged or not a database file!"), /* 247 */ dkT("No support for database type \""), /* 248 */ dkT("\" available!"), /* 249 */ dkT("Key not found in database!"), /* 250 */ dkT("DB entry probably damaged - not a multibyte char string!"), /* 251 */ dkT("Database opened for read access only!"), /* 252 */ dkT("Error(s) occured while processing command line options!"), /* 253 */ dkT("Failed to retrieve current locale!"), /* 254 */ dkT("Current locale too long!"), /* 255 */ dkT("Not a regular file: \""), /* 256 */ dkT("\"!"), /* 257 */ dkT("Image file type unknown or not supported!"), /* 258 */ dkT("Bits per component restricted to 16!"), /* 259 */ dkT("Incorrect page setup, no usable space between borders!"), /* 260 */ dkT("Mathematical error in graphics calculations!"), /* 261 */ dkT("Failed to set bitmap image frame!"), /* 262 */ dkT("Flate compression not supported!"), /* 263 */ dkT("Illegal compression cell type used!"), /* 264 */ dkT("Error during previous compression operations!"), /* 265 */ dkT("Failed to retrieve console settings!"), /* 266 */ dkT("Failed to restore console settings!"), /* 267 */ dkT("Failed to modify console settings!"), /* 268 */ dkT("Failed to convert timestamp to local time!"), /* 269 */ dkT("No file name available for database!"), /* 270 */ dkT("Failed to change ownership for file:\n\""), /* 271 */ dkT("\"!"), /* 272 */ dkT("Failed to change permissions for file:\n\""), /* 273 */ dkT("\"!"), /* 274 */ dkT("Insufficient permissions to open network connection!"), /* 275 */ dkT("Unknown or illegal address family!"), /* 276 */ dkT("Process table overflow!"), /* 277 */ dkT("Too many open files!"), /* 278 */ dkT("Protocol not supported!"), /* 279 */ dkT("Failed to open network socket!"), /* 280 */ dkT("Failed to close socket!"), /* 281 */ dkT("Interrupted by signal or explicitly cancelled!"), /* 282 */ dkT("Failed to connect!"), /* 283 */ dkT("Failed to listen for incoming requests!"), /* 284 */ dkT("Failed to find IP address for:\n\""), /* 285 */ dkT("\"!"), /* 286 */ dkT("Host not found!"), /* 287 */ dkT("Host exists, but no IP address assigned!"), /* 288 */ dkT("Problem on DNS server!"), /* 289 */ dkT("Temporary problem on DNS server, try again later!"), /* 290 */ dkT("No gethostbyname() function available!"), /* 291 */ dkT("Can not connect to remote port 0!"), /* 292 */ dkT("Access denied by firewall or due to insufficient permissions!"), /* 293 */ dkT("Local address already in use!"), /* 294 */ dkT("Resources shortage, network operation failed!"), /* 295 */ dkT("Previous connection attempt not yet completed!"), /* 296 */ dkT("Connection refused, port not open on peer!"), /* 297 */ dkT("Socket already connected!"), /* 298 */ dkT("Network unreachable!"), /* 299 */ dkT("Timeout occured."), /* 300 */ dkT("No select() function available, timeout settings ignored!"), /* 301 */ dkT("Failed to retrieve socket state!"), /* 302 */ dkT("Failed to bind local address!"), /* 303 */ dkT(""), /* 304 */ dkT("Socket already bound to local address!"), /* 305 */ dkT("Failed to write data to socket!"), /* 306 */ dkT("Operation would block!"), /* 307 */ dkT("Connection reset by peer!"), /* 308 */ dkT("Peer address is required to send data via connectionless socket!"), /* 309 */ dkT("Peer address specification is not allowed for connected sockets!"), /* 310 */ dkT("Message too large to be sent atomically!"), /* 311 */ dkT("Sending queue full for socket!"), /* 312 */ dkT("Writing to a pipe without a reader!"), /* 313 */ dkT("Less bytes were written than required!"), /* 314 */ dkT("Failed to read data from socket!"), /* 315 */ dkT("Failed to shut down socket!"), /* 316 */ dkT("Socket not connected!"), /* 317 */ dkT("Failed to accept incoming connection request!"), /* 318 */ dkT("Connection aborted!"), /* 319 */ dkT("Network protocol error!"), /* 320 */ dkT("Network subsystem not available!"), /* 321 */ dkT("Windows sockets not initialized!"), /* 322 */ dkT("A blocking Winsock 1.1 operation is in progress!"), /* 323 */ dkT("Socket type doesn't correspond to address family!"), /* 324 */ dkT("Socket not configured for broadcasts!"), /* 325 */ dkT("Requested address is not available!"), /* 326 */ dkT("Host unreachable!"), /* 327 */ dkT("Windows sockets version not available!"), /* 328 */ dkT("Too many processes use Windows sockets at this time!"), /* 329 */ dkT("I/O error occured!"), /* 330 */ dkT("Too many symbolic links in path!"), /* 331 */ dkT("Illegal pathname (missing a parent directory)!"), /* 332 */ dkT("File system is mounted read-only!"), /* 333 */ dkT("Stale NFS file handle!"), /* 334 */ dkT("Server for remote file not available!"), /* 335 */ dkT("No space left on device!"), /* 336 */ dkT("Failed to wait for sockets to become ready!"), /* 337 */ dkT("Failed to convert text address to address!"), /* 338 */ dkT("Failed to find address for host!"), /* 339 */ dkT("Failed to set socket options!"), /* 340 */ dkT("Error while closing file!"), /* 341 */ dkT("Error while closing file\n\""), /* 342 */ dkT("\"!"), /* 343 */ dkT("Failed to write data to file:\n\""), /* 344 */ dkT("\"!"), /* 345 */ dkT("Failed to read data from file!"), /* 346 */ dkT("Failed to read data from file:\n\""), /* 347 */ dkT("\"!"), /* 348 */ dkT("Not an IP address: \""), /* 349 */ dkT("\"!"), /* 350 */ dkT("Not an IP address!"), /* 351 */ dkT("Failed to connect to: \""), /* 352 */ dkT("\"!"), /* 353 */ dkT("No function available to check blocking/non-blocking state!"), /* 354 */ dkT("Netmask is not a dotted IP address!"), /* 355 */ dkT("Netmask is not a bit number!"), /* 356 */ dkT("Netmask is not an IPv6 address!"), /* 357 */ dkT("No name resolution available, please specify IP address!"), /* 358 */ dkT("No select() function available!"), /* 359 */ dkT("No valid socket found in set!"), /* 360 */ dkT("Socket "), /* 361 */ dkT(" connected to client: "), /* 362 */ dkT("Connection from \""), /* 363 */ dkT("\" rejected!"), /* 364 */ dkT("Failed to create any listener socket for socket set!"), /* 365 */ dkT("Preference value of /threads/max higher than number of cores!"), /* 366 */ dkT("Failed to find unique file identifier for file\n\""), /* 367 */ dkT("\"!"), /* 368 */ dkT("Failed to find unique file identifier for a file!"), /* 369 */ dkT("Preference \""), /* 370 */ dkT("\" does not point to a directory!"), /* 371 */ dkT(""), /* 372 */ dkT("Socket "), /* 373 */ dkT(" listening: "), /* 374 */ dkT(""), /* 375 */ dkT("Socket "), /* 376 */ dkT(" connected:"), /* 377 */ dkT(""), /* 378 */ dkT("Multiple different font encodings required!"), /* 379 */ dkT("Font encoding both required and denied: `"), /* 380 */ dkT("'!"), /* 381 */ dkT("Font encoding can be used: `"), /* 382 */ dkT("'!"), /* 383 */ dkT("The following font encoding can not be used: `"), /* 384 */ dkT("'."), /* 385 */ dkT("All font encodings denied!"), /* 386 */ dkT("Too many entries on position "), /* 387 */ dkT(" in text line:\n\""), /* 388 */ dkT("\""), /* 389 */ dkT("Unexpected end of text after backslash in text:\n\""), /* 390 */ dkT("\""), /* 391 */ dkT("UTF-8 decoding failed for string:\n\""), /* 392 */ dkT("UTF-16 decoding failed for string:\n\""), /* 393 */ dkT("Non-ANSI characters in string:\n\""), /* 394 */ dkT("Non-URL characters in string:\n\""), /* 395 */ dkT("Character 0x"), /* 396 */ dkT("already defined!"), /* 397 */ dkT("Character redefinition!"), /* 398 */ dkT("First word is not a hexadecimal number!"), /* 399 */ dkT("_UNUSED_"), /* 400 */ dkT("No configuration data found for character!"), /* 401 */ dkT("No support for zlib compression!"), /* 402 */ dkT("No support for bzip2 compression!"), /* 403 */ dkT("No data files found to process!"), /* 404 */ dkT("Syntax error, unknown encoding!"), /* 405 */ dkT("Syntax error, no package names found!"), /* 406 */ dkT("Syntax error, missing value for attribute!"), /* 407 */ dkT("Missing \"share\" directory!"), /* 408 */ dkT("No data found for character!"), /* 409 */ dkT("No data found for character 0x"), /* 410 */ dkT("!"), /* 411 */ dkT("Conflicting font encoding requirements!"), /* 412 */ dkT("Failed to set buffer for file\n\""), /* 413 */ dkT("\"!"), NULL #line 2444 "dk3app.ctr" }; /** Preferences entry. */ typedef struct _dk3app_pref_t { dkChar const *k; /**< Key (name). */ dkChar const *v; /**< Value. */ } dk3app_pref_t; /** Message catalog. */ typedef struct _dk3app_mc_t_ { dkChar const *n; /**< Name (always dynamically allocated). */ dkChar const **msg; /**< Message texts. */ int f; /**< Flag: Messages dynamically allocated. */ size_t nmsg; /**< Number of messages. */ } dk3app_mc_t; /** Delete preferences entry, release memory. @param p Preference entry to delete. */ static void dk3app_pref_delete(dk3app_pref_t *p) { if(p) { #line 2476 "dk3app.ctr" dk3_release(p->k); dk3_release(p->v); dk3_delete(p); } } /** Create new preferences entry, allocate memory. @param k Key (preference name). @param v Value. @return Pointer to new entry on success, NULL on error. */ static dk3app_pref_t * dk3app_pref_new(dkChar const *k, dkChar const *v) { dk3app_pref_t *back = NULL; #line 2495 "dk3app.ctr" if((k) && (v)) { back = dk3_new(dk3app_pref_t,1); if(back) { back->k = dk3str_dup_app(k, NULL); back->v = dk3str_dup_app(v, NULL); if(!((back->k) && (back->v))) { dk3app_pref_delete(back); back = NULL; } } } #line 2505 "dk3app.ctr" return back; } /** Compare two preference entries by name. @param l Left entry. @param r Right entry. @param crit Comparison criteria (ignored). @return Comparison result l <=> r. */ static int dk3app_compare_pref(void const *l, void const *r, int crit) { int back = 0; dk3app_pref_t const *pl = NULL; /* Left object. */ dk3app_pref_t const *pr = NULL; /* Right object. */ if(l) { if(r) { pl = (dk3app_pref_t const *)l; pr = (dk3app_pref_t const *)r; if(pl->k) { if(pr->k) { back = dk3str_cmp(pl->k, pr->k); } else { back = 1; } } else { if(pr->k) { back = -1; } } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Delete string table. @param ta Table to delete. @param n Number of entries in the table. */ static void dk3app_mc_table_delete(dkChar const **ta, size_t n) { dkChar const **ptr = NULL; /* Start of string table. */ size_t i = 0; /* Index of current element to process. */ #line 2553 "dk3app.ctr" ptr = ta; for(i = 0; i < n; i++) { #line 2555 "dk3app.ctr" if(*ptr) { #line 2556 "dk3app.ctr" dk3_delete(*ptr); } *(ptr++) = NULL; } dk3_delete(ta); #line 2561 "dk3app.ctr" } /** Delete message catalog entry. @param mc Message catalog entry to delete. */ static void dk3app_mc_delete(dk3app_mc_t *mc) { #line 2573 "dk3app.ctr" if(mc) { #line 2574 "dk3app.ctr" dk3_release(mc->n); if(mc->f) { if(mc->msg) { dk3app_mc_table_delete(mc->msg, mc->nmsg); } } mc->f = 0; mc->msg = NULL; dk3_delete(mc); } #line 2582 "dk3app.ctr" } /** Create message catalog entry. @param n Short file name of string table file. @param msg String table. @param nmsg Number of entries in \a msg. @param f Flag: The memory for \a msg was dynamically allocated. @param app Application structure for diagnostics, may be NULL. @return Pointer to message catalog entry on success, NULL on error. */ static dk3app_mc_t * dk3app_mc_new( dkChar const *n, dkChar const **msg, size_t nmsg, int f, dk3_app_t *app ) { dk3app_mc_t *back = NULL; #line 2602 "dk3app.ctr" back = dk3_new_app(dk3app_mc_t,1,app); if(back) { back->n = NULL; back->msg = NULL; back->f = f; back->nmsg = nmsg; back->n = dk3str_dup_app(n, app); if(back->n) { back->msg = msg; } else { dk3app_mc_delete(back); back = NULL; } } #line 2612 "dk3app.ctr" return back; } /** Compare two message catalog entries. @param l Left entry. @param r Right entry. @param cr Comparison criteria (ignored). @return Comparison result. */ static int dk3app_mc_compare(void const *l, void const *r, int cr) { int back = 0; dk3app_mc_t const *pl = NULL; /* Left message catalog. */ dk3app_mc_t const *pr = NULL; /* Right message catalog. */ if(l) { if(r) { pl = (dk3app_mc_t const *)l; pr = (dk3app_mc_t const *)r; if(pl->n) { if(pr->n) { back = dk3str_cmp(pl->n, pr->n); } else { back = 1; } } else { if(pr->n) { back = -1; } } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Write log message to a file. If the time has changed since the last message written to that file we write a new timestamp before writing the message. @param app Application structure. @param ll Log level, DK3_LL_xxx. @param msg Array of message parts. @param nmsg Number of elements in \a msg. @param fipo File to write to. @param last_time Timestamp of last message written to that file. */ static void dk3app_log_to_file( dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg, FILE *fipo, dk3_time_t *last_time ) { dk3_time_t time_now; /* Current time. */ dkChar tb[64]; /* Buffer to store current time as text. */ char ulb[64]; /* Buffer for current time as char text. */ char *sp = NULL; /* Source pointer used in conversion. */ size_t i = 0; /* Index of current string to process. */ #line 2672 "dk3app.ctr" if(dk3sf_time(&time_now)) { if(time_now != *last_time) { if(dk3sf_time_convert_app(tb, DK3_SIZEOF(tb,dkChar), &time_now, NULL)) { *last_time = time_now; dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[10], fipo); dk3sf_fputs(tb, fipo); dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo); } } } if(app->n_sourcefile) { dk3sf_fputs(app->n_sourcefile, fipo); dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo); if(app->sourceline) { sprintf(ulb, "%lu", app->sourceline); sp = ulb; while(*sp) { dk3sf_fputc( (dkChar)(*(sp++)), fipo); } dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo); } dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo); } if((ll >= DK3_LL_PANIC) && (ll <= DK3_LL_WARNING)) { dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[ll], fipo); dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[11], fipo); dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[8], fipo); } for(i = 0; i < nmsg; i++) { if(msg[i]) { dk3sf_fputs(msg[i], fipo); } } dk3sf_fputs(((app->msg) ? app->msg : dk3app_kw)[0], fipo); #line 2704 "dk3app.ctr" } static void dk3app_create_parent_directory(const dkChar *fn) { dkChar fnb[DK3_MAX_PATH]; dkChar *ptr; dkChar *lptr; if (dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, fn); ptr= fnb; lptr = NULL; while (dkT('\0') != *ptr) { #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH if (dkT('\\') == *ptr) { lptr = ptr; } #else if (dkT('/') == *ptr) { lptr = ptr; } #endif ptr++; } if (NULL != lptr) { *lptr = dkT('\0'); (void)dk3sf_mkdir_app(fnb, 0700, NULL); } } } /** Create ${HOME}/log directory for known log file name. @param app Application structure containing log file name in n_logfilename. */ static void dk3app_create_log_directory(dk3_app_t *app) { dk3app_create_parent_directory(app->n_logfilename); } /** Create ${HOME}/tmp directory for known log file name. @param app Application structure containing log file name in n_logfilename. */ static void dk3app_create_tmp_directory(dk3_app_t *app) { dk3app_create_parent_directory(app->n_tmpdir); } /** Write log message to log file. If the time has changed since the last message written to that file we write a new timestamp before writing the message. @param app Application structure. @param ll Log level, DK3_LL_xxx. @param msg Array of message parts. @param nmsg Number of elements in \a msg. */ static void dk3app_log_file(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg) { FILE *fipo; /* Output file. */ dk3_stat_t stb; /* File stat buffer. */ #line 2777 "dk3app.ctr" if(app->n_logfilename) { #line 2778 "dk3app.ctr" if (0 == app->cr_log) { /* Create ${HOME}/log directory if not yet done. */ dk3app_create_log_directory(app); app->cr_log = 1; } if(app->f_first_file_log) { /* Daemons always attempt to append after existing log. */ if(app->app_type == DK3_APP_TYPE_DAEMON) { app->f_first_file_log = 0; if(!dk3sf_stat_app(&stb, app->n_logfilename, NULL)) { app->f_first_file_log = 1; } } } fipo = dk3sf_fopen_app(app->n_logfilename, dk3app_no_loc[8], NULL); /* WRITE */ if(fipo) { #line 2799 "dk3app.ctr" #if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1) /* Switch to 16 bit characters. */ (void)_setmode(_fileno(fipo), _O_U16TEXT); /* Write byte order marker. */ if(app->f_first_file_log) { fputwc(0xFEFF, fipo); } #endif app->f_first_file_log = 0; dk3app_log_to_file( app, ll, msg, nmsg, fipo, &(app->t_last_log_file) ); fclose(fipo); } else { #line 2813 "dk3app.ctr" } } #line 2815 "dk3app.ctr" } int dk3app_max_log_level(dk3_app_t const *app) { int back = 0; if(app) { if(app->app_type != DK3_APP_TYPE_SILENT) { back = app->ll_file; if(app->app_type == DK3_APP_TYPE_COMMAND) { if(app->ll_stderr > back) { back = app->ll_stderr; } } } } return back; } void dk3app_log_msg(dk3_app_t *app, int ll, dkChar const * const * msg, size_t nmsg) { #line 2840 "dk3app.ctr" if((app) && (msg) && (nmsg)) { #line 2841 "dk3app.ctr" if(app->f_readytolog) { #line 2842 "dk3app.ctr" if(ll < app->ll_highest) { #line 2843 "dk3app.ctr" app->ll_highest = ll; } switch(app->app_type) { case DK3_APP_TYPE_COMMAND: { #line 2847 "dk3app.ctr" if(app->ll_file >= ll) { #line 2848 "dk3app.ctr" dk3app_log_file(app, ll, msg, nmsg); } else { #line 2850 "dk3app.ctr" } if(app->ll_stderr >= ll) { #line 2852 "dk3app.ctr" dk3sf_initialize_stderr(); dk3app_log_to_file( app, ll, msg, nmsg, stderr, &(app->t_last_log_stderr) ); } else { #line 2857 "dk3app.ctr" } } break; case DK3_APP_TYPE_GUI: case DK3_APP_TYPE_DAEMON: #line 2861 "dk3app.ctr" { #line 2862 "dk3app.ctr" if(app->ll_file >= ll) { #line 2863 "dk3app.ctr" dk3app_log_file(app, ll, msg, nmsg); } } break; } } else { #line 2868 "dk3app.ctr" } } else { #line 2870 "dk3app.ctr" } #line 2871 "dk3app.ctr" } void dk3app_log_1(dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1) { dkChar const *m[2]; /* Message parts. */ #line 2880 "dk3app.ctr" if((app) && (msg)) { m[0] = msg[i1]; m[1] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)m, 1); } #line 2885 "dk3app.ctr" } void dk3app_log_2( dk3_app_t *app, int ll, dkChar const * const * msg, size_t i, dkChar const *st ) { dkChar const *m[3]; if((app) && (msg)) { m[0] = msg[i]; m[1] = st; m[2] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)m, 2); } } void dk3app_log_3( dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1, size_t i2, dkChar const *st ) { dkChar const *m[4]; /* Message parts. */ #line 2913 "dk3app.ctr" if((app) && (msg)) { m[0] = msg[i1]; m[1] = st; m[2] = msg[i2]; m[3] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)m, 3); } #line 2920 "dk3app.ctr" } void dk3app_log_5( dk3_app_t *app, int ll, dkChar const * const * msg, size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2 ) { dkChar const *m[6]; /* Message parts. */ #line 2932 "dk3app.ctr" if((app) && (msg)) { m[0] = msg[i1]; m[1] = st1; m[2] = msg[i2]; m[3] = st2; m[4] = msg[i3]; m[5] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)m, 5); } #line 2941 "dk3app.ctr" } void dk3app_log_i1(dk3_app_t *app, int ll, size_t i1) { #line 2949 "dk3app.ctr" if(app) { dk3app_log_1(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1); } #line 2952 "dk3app.ctr" } void dk3app_log_i2(dk3_app_t *app, int ll, size_t i, dkChar const * st) { dkChar const *msg[3]; /* Message parts. */ if((app) && (i) && (st)) { if(i < DK3_SIZEOF(dk3app_kw,DK3_PCDKCHAR)) { msg[0] = ((app->msg) ? app->msg : dk3app_kw)[i]; msg[1] = st; msg[2] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)msg, 2); } } } void dk3app_log_i3( dk3_app_t *app, int ll, size_t i1, size_t i2, dkChar const *st ) { #line 2980 "dk3app.ctr" if(app) { dk3app_log_3(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, st); } #line 2983 "dk3app.ctr" } void dk3app_log_i5( dk3_app_t *app, int ll, size_t i1, size_t i2, size_t i3, dkChar const *st1, dkChar const *st2 ) { #line 2994 "dk3app.ctr" if(app) { dk3app_log_5( app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, i3, st1, st2 ); } #line 2999 "dk3app.ctr" } void dk3app_set_source_file(dk3_app_t *app, dkChar const *fn) { if(app) { #line 3007 "dk3app.ctr" app->n_sourcefile = fn; } } void dk3app_set_source_line(dk3_app_t *app, unsigned long li) { if(app) { #line 3017 "dk3app.ctr" app->sourceline = li; } } dkChar const * dk3app_get_source_file(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_sourcefile; } #line 3030 "dk3app.ctr" return back; } unsigned long dk3app_get_source_line(dk3_app_t const *app) { unsigned long back = 0UL; if(app) { back = app->sourceline; } #line 3042 "dk3app.ctr" return back; } /** Find data (resource) file. String tables are resources too, so we check language and region subdirectories too. @param app Application structure. @param fn File name. @param db Destination buffer. @param sz Size of \a db (number of characters). @param verb Flag: Diagnostic messages enabled. @return 1 on success, 0 on error. */ static int dk3app_my_find_data_file( dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int verb ) { int back = 0; dkChar const *p1 = NULL; /* dk3app, group or application name. */ dkChar const *p2 = NULL; /* Language. */ dkChar const *p3 = NULL; /* Region. */ int cc = 1; /* Flag: Can go. */ size_t mysz = 0; /* Size for calculation. */ size_t sz1 = 0; /* Length of /xxx/share directory name. */ size_t sz2 = 0; /* Length of short file name. */ dk3_stat_t stb; /* Stat buffer to test existance of files. */ int i = 0; /* Pass: 0=lang+region, 1=language, 0=share. */ int j = 0; /* Pass: 0=app, 1=appgroup, 2=dk3app, 3=base. */ #line 3075 "dk3app.ctr" if((app) && (fn) && (db) && (sz)) { if(app->n_sharedir) { sz1 = dk3str_len(app->n_sharedir); sz2 = dk3str_len(fn); for(i = 0; ((back == 0) && (i < 4)); i++) { for(j = 0; ((back == 0) && (j < 4)); j++) { #line 3081 "dk3app.ctr" p1 = NULL; p2 = NULL; p3 = NULL; cc = 0; switch(i) { case 1: { if(app->n_language) { p2 = app->n_language; cc = 1; } } break; case 2: { p2 = dk3app_no_loc[47]; cc = 1; } break; case 3: { cc = 1; } break; default: { if(app->n_language) { p2 = app->n_language; if(app->n_region) { p3 = app->n_region; cc = 1; } } } break; } switch(j) { case 1: { if(app->n_appgroup) { p1 = app->n_appgroup; } else { cc = 0; } } break; case 2: { p1 = dk3app_no_loc[17]; } break; case 3: { p1 = NULL; } break; default: { if(app->n_app) { p1 = app->n_app; } else { cc = 0; } } break; } if(cc) { mysz = sz1 + sz2 + 1; if(p1) { mysz += dk3str_len(p1); mysz++; } if(p2) { mysz += dk3str_len(p2); mysz++; } if(p3) { mysz += dk3str_len(p3); mysz++; } if(mysz < sz) { dk3str_cpy_not_overlapped(db, app->n_sharedir); if(p1) { dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p1); } if(p2) { dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p2); } if(p3) { dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, p3); } dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, fn); #line 3143 "dk3app.ctr" if(dk3sf_stat_app(&stb, db, NULL)) { switch((stb.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { back = 1; #line 3147 "dk3app.ctr" } break; } } if(back) { /* DEBUG: Resource file ... found. */ dk3app_log_i3(app, DK3_LL_DEBUG, 148, 149, db); } else { /* DEBUG: Resource file ... not found. */ dk3app_log_i3(app, DK3_LL_DEBUG, 150, 151, db); } } } } } } else { if(verb) { /* Internal error, no /xxx/share directory! */ dk3app_log_i1(app, DK3_LL_ERROR, 55); } } } #line 3168 "dk3app.ctr" return back; } /** Remove a file. The difference to dk3sf_remove_file_app() is that this function does not complain if the file does not exist. @param n File name. @param app Application structure for diagnostics, may be NULL. @return 1 on success, 0 on error. */ static int dk3app_remove_file_app(dkChar *n, dk3_app_t *app) { int back = 0; dk3_stat_t stb; /* Stat buffer to test existance of file. */ #line 3187 "dk3app.ctr" if(dk3sf_stat_app(&stb,n,app)) { #line 3188 "dk3app.ctr" back = dk3sf_remove_file_app(n, app); } else { #line 3190 "dk3app.ctr" back = 1; /* File does not exist. */ } #line 3192 "dk3app.ctr" return back; } /** Delete one temporaray file. @param app Application structure. @param n Number to build the file name. @param s Number to build the file suffix. @param f Pointer to error code variable. */ static void dk3app_delete_one_temp_file(dk3_app_t *app, unsigned long n, unsigned s, int *f) { dkChar buffer[DK3_MAX_PATH]; /* Buffer to construct complete file name. */ dkChar fnb2[16]; /* Buffer for short file name. */ char fnb[16]; /* Buffer for numeric conversion. */ dk3_app_t *ra = NULL; /* Application to use for diagnostics. */ size_t sz = 0; /* Length needed for complete file name. */ #line 3213 "dk3app.ctr" sprintf(fnb, "/%08lx.%03x", n, s); ra = app; if((*f) & 1) { ra = NULL; } if(dk3str_cnv_c8_to_str_app(fnb2, 15, fnb, ra)) { sz = dk3str_len(app->n_tmpdir) + dk3str_len(fnb2); if(sz < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, app->n_tmpdir); dk3str_cat(buffer, fnb2); dk3str_correct_filename(buffer); #if VERSION_BEFORE_20150821 ra = app; if((*f) & 4) { ra = NULL; } #endif if(!dk3app_remove_file_app(buffer, NULL)) { *f = ((*f) | 4); } } else { if(!((*f) & 2)) { dk3app_log_i1(app, DK3_LL_ERROR, 37); *f = ((*f) | 2); } } } else { *f = ((*f) | 1); } #line 3238 "dk3app.ctr" } /** Delete all temporary files of an application for a core name. @param app Application structure. @param n Number to build core file name. @param f Pointer to error code variable. */ static void dk3app_delete_all_temp_files_for(dk3_app_t *app, unsigned long n, int *f) { unsigned u; /* Used for file name suffix. */ #line 3253 "dk3app.ctr" for(u = 0; u < 0x1000U; u++) { dk3app_delete_one_temp_file(app, n, u, f); } #line 3256 "dk3app.ctr" } /** Delete all temporary files of an application. @param app Application structure. */ static void dk3app_remove_temporary_files(dk3_app_t *app) { unsigned long ul = 0UL; /* Used for base file name. */ unsigned u = 0; /* Used for suffixes of final base. */ int f = 0; /* Error checking variable. */ #line 3271 "dk3app.ctr" if(app->n_tmpdir) { f = 0; if(app->i_tmpcarry) { for(ul = 0UL; ul < 0xFFFFFFFFUL; ul++) { dk3app_delete_all_temp_files_for(app, ul, &f); } dk3app_delete_all_temp_files_for(app, 0xFFFFFFFFUL, &f); } else { for(ul = 0UL; ul < app->ul_tmpname; ul++) { dk3app_delete_all_temp_files_for(app, ul, &f); } for(u = 0; u < app->u_tmpsuffix; u++) { dk3app_delete_one_temp_file(app, app->ul_tmpname, u, &f); } dk3app_delete_one_temp_file(app, app->ul_tmpname, app->u_tmpsuffix, &f); } dk3sf_remove_dir_app(app->n_tmpdir, NULL); } #line 3289 "dk3app.ctr" } /** Construct configuration file name candidate. When searching for files (configuration or resource files) we specify the sort file name without leading directory. During the search process we do several tests prepending directory names before the short file name. This function is used to construct a file name. @param app Application structure. @param fn File name. @param db Result buffer. @param sz Size of \a db (number of characters). @param passno Pass number (0-15). @param verb Flag: Diagnostic messages enabled. @return 1 on success, 0 on error. */ static int dk3app_config_name( dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb ) { int back = 0; dkChar const *ptr1 = NULL; /* Base directory (etc or share). */ dkChar const *ptr2 = NULL; /* Subdirectory (app, group, dk3app or none). */ dkChar const *ptr3 = NULL; /* Application or group name. */ size_t mysz = 0; /* Buffer size needed for all components. */ #line 3319 "dk3app.ctr" ptr1 = NULL; ptr2 = NULL; ptr3 = NULL; switch(passno) { #if VERSION_BEFORE_20110219 case 0: { ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17]; } break; case 2: { ptr1 = app->n_sharedir; ptr2 = app->n_appgroup; } break; case 3: { ptr1 = app->n_etcdir; ptr2 = app->n_appgroup; } break; case 4: { ptr1 = app->n_sharedir; ptr2 = app->n_app; } break; case 5: { ptr1 = app->n_etcdir; ptr2 = app->n_app; } break; case 6: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; } break; case 7: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup; } break; case 8: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app; } break; case 9: { ptr1 = dk3app_no_loc[19]; } break; default: { /* 1 */ ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17]; } break; #else case 0: { ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17]; } break; case 1: { ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17]; } break; case 2: { ptr1 = app->n_sharedir; ptr2 = dk3app_no_loc[17]; } break; case 3: { ptr1 = app->n_etcdir; ptr2 = dk3app_no_loc[17]; } break; case 4: { ptr1 = app->n_sharedir; ptr2 = app->n_appgroup; } break; case 5: { ptr1 = app->n_etcdir; ptr2 = app->n_appgroup; } break; case 6: { ptr1 = app->n_sharedir; ptr2 = app->n_appgroup; } break; case 7: { ptr1 = app->n_etcdir; ptr2 = app->n_appgroup; } break; case 8: { ptr1 = app->n_sharedir; ptr2 = app->n_app; } break; case 9: { ptr1 = app->n_etcdir; ptr2 = app->n_app; } break; case 10: { ptr1 = app->n_sharedir; ptr2 = app->n_app; } break; case 11: { ptr1 = app->n_etcdir; ptr2 = app->n_app; } break; case 12: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; } break; case 13: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_appgroup; } break; case 14: { ptr1 = app->n_homedir; ptr2 = dk3app_no_loc[18]; ptr3 = app->n_app; } break; case 15: { ptr1 = dk3app_no_loc[19]; } break; #endif } mysz = dk3str_len(fn); if(ptr1) { mysz += dk3str_len(ptr1); mysz++; } if(ptr2) { mysz += dk3str_len(ptr2); mysz++; } if(ptr3) { mysz += dk3str_len(ptr3); mysz++; } switch(passno) { case 2: case 3: case 6: case 7: case 10: case 11: { mysz += dk3str_len(dk3app_no_loc[32]); } break; } if(mysz < sz) { if(ptr1) { dk3str_cpy_not_overlapped(db, ptr1); if(ptr2) { dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, ptr2); } if(ptr3) { dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, ptr3); } switch(passno) { case 2: case 3: case 6: case 7: case 10: case 11: { dk3str_cat(db, dk3app_no_loc[32]); } break; } dk3str_cat(db, dk3app_no_loc[20]); dk3str_cat(db, fn); back = 1; #line 3429 "dk3app.ctr" } else { if(verb) { /* Internal error, some directory not set! */ } } } else { if(verb) { dk3app_log_i1(app, DK3_LL_ERROR, 38); } } #line 3439 "dk3app.ctr" return back; } /** Unconfigure application (delete registry key or config file). @param app Application to unconfigure. */ static void dk3app_do_unconfigure(dk3_app_t *app) { dkChar fnb[DK3_MAX_PATH]; /* File name buffer for config file. */ if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) { (void)dk3sf_remove_file_app(fnb, app); } } /** Save self-set preferences to registry or file. @param app Application structure. */ static void dk3app_do_save_config(dk3_app_t *app) { dkChar fnb[DK3_MAX_PATH]; /* File name buffer for conf file. */ dkChar *ptr = NULL; /* Slash/backslash correction. */ FILE *fipo = NULL; /* Used to write file. */ dk3app_pref_t *p1 = NULL; /* Preference entry to process. */ dk3app_pref_t *p2 = NULL; /* Check in higher priorized storage. */ #line 3473 "dk3app.ctr" if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) { #line 3475 "dk3app.ctr" ptr = dk3str_rchr(fnb, DK3_CHAR_SEP); if(ptr) { *ptr = dkT('\0'); #line 3479 "dk3app.ctr" dk3sf_mkdir_app(fnb, 0700, NULL); *ptr = DK3_CHAR_SEP; } fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[24], app); /* WRITE */ if(fipo) { #line 3484 "dk3app.ctr" #if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1) /* Switch to 16 bit characters. */ (void)_setmode(_fileno(fipo), _O_U16TEXT); /* Write byte order marker. */ fputwc(0xFEFF, fipo); #endif if((app->s_varprefs) && (app->i_varprefs)) { dk3sto_it_reset(app->i_varprefs); while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL) { p2 = NULL; if((app->s_selfprefs) && (app->i_selfprefs)) { p2 = (dk3app_pref_t *)dk3sto_it_find_like(app->i_selfprefs, p1, 0); } if(!(p2)) { dk3sf_fputs(p1->k, fipo); dk3sf_fputs(dk3app_no_loc[25], fipo); dk3sf_fputs(p1->v, fipo); dk3sf_fputs(dk3app_no_loc[26], fipo); } } } if((app->s_selfprefs) && (app->i_selfprefs)) { dk3sto_it_reset(app->i_selfprefs); while((p1 = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) { dk3sf_fputs(p1->k, fipo); dk3sf_fputs(dk3app_no_loc[25], fipo); dk3sf_fputs(p1->v, fipo); dk3sf_fputs(dk3app_no_loc[26], fipo); } } fclose(fipo); } else { #line 3516 "dk3app.ctr" } } else { #line 3518 "dk3app.ctr" } #line 3519 "dk3app.ctr" } void dk3app_close(dk3_app_t *app) { int i = 0; /* Used to release argv memory. */ dk3app_pref_t *pref = NULL; /* Used to delete preference entries. */ dk3app_mc_t *mcptr = NULL; /* Used to delete message catalogs. */ #line 3532 "dk3app.ctr" if(app) { if(app->f_unconfigure) { #line 3535 "dk3app.ctr" dk3app_do_unconfigure(app); } else { if(app->f_prefschanged) { #line 3538 "dk3app.ctr" dk3app_do_save_config(app); } } /* Clean up preferences system. */ #line 3542 "dk3app.ctr" if(app->s_selfprefs) { if(app->i_selfprefs) { dk3sto_it_reset(app->i_selfprefs); while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_selfprefs)) != NULL) { dk3app_pref_delete(pref); } dk3sto_it_close(app->i_selfprefs); } dk3sto_close(app->s_selfprefs); } app->s_selfprefs = NULL; app->i_selfprefs = NULL; if(app->s_cmdprefs) { if(app->i_cmdprefs) { dk3sto_it_reset(app->i_cmdprefs); while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_cmdprefs)) != NULL) { dk3app_pref_delete(pref); } dk3sto_it_close(app->i_cmdprefs); } dk3sto_close(app->s_cmdprefs); } app->s_cmdprefs = NULL; app->i_cmdprefs = NULL; if(app->s_sysprefs) { if(app->i_sysprefs) { dk3sto_it_reset(app->i_sysprefs); while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_sysprefs)) != NULL) { dk3app_pref_delete(pref); } dk3sto_it_close(app->i_sysprefs); } dk3sto_close(app->s_sysprefs); } app->s_sysprefs = NULL; app->i_sysprefs = NULL; if(app->s_constprefs) { if(app->i_constprefs) { dk3sto_it_reset(app->i_constprefs); while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_constprefs)) != NULL) { dk3app_pref_delete(pref); } dk3sto_it_close(app->i_constprefs); } dk3sto_close(app->s_constprefs); } app->s_constprefs = NULL; app->i_constprefs = NULL; if(app->s_varprefs) { if(app->i_varprefs) { dk3sto_it_reset(app->i_varprefs); while((pref = (dk3app_pref_t *)dk3sto_it_next(app->i_varprefs)) != NULL) { dk3app_pref_delete(pref); } dk3sto_it_close(app->i_varprefs); } dk3sto_close(app->s_varprefs); } app->s_varprefs = NULL; app->i_varprefs = NULL; /* Clean up temporary directory. */ #line 3596 "dk3app.ctr" if(app->ll_highest > app->ll_tmp_keep) { dk3app_remove_temporary_files(app); } /* Remove log file if no longer needed. */ #line 3600 "dk3app.ctr" if(DK3_APP_TYPE_DAEMON != app->app_type) { dk3app_log_i3(app, DK3_LL_DEBUG, 21, 22, app->n_app); if(app->ll_highest > app->ll_file_keep) { dk3sf_remove_file_app(app->n_logfilename, NULL); } } /* Unset resources, release resources. */ app->ll_file = app->ll_stderr = app->ll_file_keep = app->ll_highest = 0; app->app_type = 0; app->msg = NULL; app->n_sourcefile = NULL; app->sourceline = 0UL; #line 3612 "dk3app.ctr" if(app->s_mc) { if(app->i_mc) { dk3sto_it_reset(app->i_mc); while((mcptr = (dk3app_mc_t *)dk3sto_it_next(app->i_mc)) != NULL) { dk3app_mc_delete(mcptr); } dk3sto_it_close(app->i_mc); } dk3sto_close(app->s_mc); } app->s_mc = NULL; app->i_mc = NULL; #line 3623 "dk3app.ctr" if(app->argv) { dkChar const **ptr; ptr = (dkChar const **)(app->argv); for(i = 0; i < app->argc; i++) { dk3_release(*ptr); ptr++; } } #line 3631 "dk3app.ctr" dk3_release(app->n_app); dk3_release(app->n_execfile); dk3_release(app->n_bindir); dk3_release(app->n_etcdir); dk3_release(app->n_sharedir); dk3_release(app->n_vardir); dk3_release(app->n_logname); dk3_release(app->n_homedir); dk3_release(app->n_appgroup); dk3_release(app->n_logfilename); dk3_release(app->n_tmpdir); dk3_release(app->n_language); dk3_release(app->n_region); dk3_release(app->n_langstr); dk3_release(app->n_hostname); dk3_delete(app); } #line 3648 "dk3app.ctr" } int dk3app_get_default_stdin_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_output_encoding; #if DK3_CHAR_SIZE > 1 #if DK3_ON_WINDOWS back = DK3_FILE_ENCODING_ASCII; #endif #endif } return back; } int dk3app_get_default_file_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_output_encoding; #if DK3_CHAR_SIZE > 1 #if DK3_ON_WINDOWS back = DK3_FILE_ENCODING_ASCII; #endif #endif } return back; } /** Initialize application structure. @param app Application to initialize. */ static void dk3app_init(dk3_app_t *app) { #line 3695 "dk3app.ctr" app->app_type = 0; app->msg = NULL; app->n_sourcefile = NULL; app->sourceline = 0UL; app->ll_file = DK3_LL_NONE; app->ll_stderr = DK3_LL_INFO; app->ll_file_keep = DK3_LL_NONE; app->ll_tmp_keep = DK3_LL_NONE; app->ll_highest = DK3_LL_IGNORE; app->argv = NULL; app->argc = 0; app->n_app = NULL; app->n_execfile = NULL; app->n_bindir = NULL; app->n_etcdir = NULL; app->n_sharedir = NULL; app->n_vardir = NULL; app->n_logname = NULL; app->n_homedir = NULL; app->n_appgroup = NULL; app->n_logfilename = NULL; app->n_tmpdir = NULL; app->n_language = NULL; app->n_region = NULL; app->n_langstr = NULL; app->ul_tmpname = 0UL; app->u_tmpsuffix = 0U; app->i_tmpcarry = 0; app->n_hostname = NULL; #if DK3_CHAR_SIZE > 1 app->i_encoding = DK3_ENCODING_UTF16; #if DK3_BIGENDIAN app->i_output_encoding = DK3_FILE_ENCODING_UTF16_MSB_FIRST; #else app->i_output_encoding = DK3_FILE_ENCODING_UTF16_LSB_FIRST; #endif #else app->i_encoding = DK3_ENCODING_PLAIN; app->i_output_encoding = DK3_FILE_ENCODING_ASCII; #endif app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app); #line 3737 "dk3app.ctr" app->i_file_input_encoding = dk3app_get_default_file_encoding(app); app->de = 0; /* No error found yet. */ #line 3739 "dk3app.ctr" app->s_mc = NULL; app->i_mc = NULL; app->s_cmdprefs = NULL; app->i_cmdprefs = NULL; app->s_selfprefs = NULL; app->i_selfprefs = NULL; app->f_unconfigure = 0; app->f_prefschanged = 0; app->f_readytolog = 0; app->s_sysprefs = NULL; app->i_sysprefs = NULL; app->s_constprefs = NULL; app->i_constprefs = NULL; app->s_varprefs = NULL; app->i_varprefs = NULL; app->f_first_file_log = 1; app->f_rand_initialized = 0; app->f_rand_success = 0; app->rand_type = 0; app->cr_log = 0; app->cr_tmp = 0; app->t_last_log_stderr = (dk3_time_t)0UL; app->t_last_log_file = (dk3_time_t)0UL; } /** Copy binary directory name to other directory names. @param app Application structure. */ static void dk3app_copy_bin_to_others(dk3_app_t *app) { #line 3774 "dk3app.ctr" app->n_etcdir = dk3str_dup_app(app->n_bindir, NULL); if(app->n_etcdir) { app->n_sharedir = dk3str_dup_app(app->n_bindir, NULL); if(app->n_sharedir) { app->n_vardir = dk3str_dup_app(app->n_bindir, NULL); if(!(app->n_vardir)) { app->de = 9; } } else { app->de = 8; } } else { app->de = 7; } #line 3788 "dk3app.ctr" } #if DK3_ON_WINDOWS #if VERSION_BEFORE_20131022 /** Open a registry key. @param k Parent key (HKLM or HKCU). @param n Key name. @param p Permissions needed. @param kp Pointer to result key variable. @return ERROR_SUCCESS on success, other values indicate an error. */ static long dk3app_reg_open_key(HKEY k, dkChar const *n, int p, HKEY *kp) { long back = 0L; #if DK3_CHAR_SIZE > 1 back = RegOpenKeyExW(k, n, (DWORD)0, p, kp); #else back = RegOpenKeyExA(k, n, (DWORD)0, p, kp); #endif return back; } /** Retrieve a value from the registry. @param k Registry key. @param n Entry name. @param tp Entry type. @param b Result buffer address. @param len In: size of buffer, out: number of bytes used. @return ERROR_SUCCESS on success, any other value indicates an error. */ static long dk3app_reg_query(HKEY k, dkChar const *n, DWORD *tp, LPBYTE b, DWORD *len) { long back = 0L; #if DK3_CHAR_SIZE > 1 back = RegQueryValueExW(k, n, NULL, tp, b, len); #else back = RegQueryValueExA(k, n, NULL, tp, b, len); #endif return back; } /** Retrieve string value from registry. @param k Key. @param n Entry name. @param b Result buffer. @param sz Size of \a b (number of characters). @return 1 on success, 0 on error. */ static int dk3app_reg_query_str(HKEY k, dkChar const *n, dkChar *b, size_t sz) { int back = 0; DWORD tp = REG_SZ; /* Registry entry type. */ DWORD len = 0L; /* Length of arguments and results. */ LONG res = 0L; /* Registry operation result. */ tp = REG_SZ; len = (DWORD)(sz * DK3_CHAR_SIZE); res = dk3app_reg_query(k, n, &tp, (LPBYTE)b, &len); if(ERROR_SUCCESS == res) { if((REG_SZ == tp) || (REG_EXPAND_SZ == tp)) { if(len > 0) { #if DK3_CHAR_SIZE > 1 len = len / DK3_CHAR_SIZE; #endif b[(((size_t)len) < sz) ? len : (sz - 1)] = dkT('\0'); back = 1; } } } return back; } #endif #endif /** Get users language/region/encoding setting. @param app Application structure. @param db Result buffer. @param sz Size of \a db (number of characters). @return 1 on success, 0 on error. */ static int dk3app_get_language_string(dk3_app_t *app, dkChar *db, size_t sz) { int back = 0; #line 3890 "dk3app.ctr" #if DK3_ON_WINDOWS #if VERSION_BEFORE_20131022 { LONG res = 0L; /* Registry operation result. */ HKEY key; /* Registry key. */ res = dk3app_reg_open_key( HKEY_CURRENT_USER, dk3app_no_loc[12], KEY_READ, &key ); if(ERROR_SUCCESS == res) { back = dk3app_reg_query_str(key, dk3app_no_loc[13], db, sz); if(back == 0) { back = dk3app_reg_query_str(key, dk3app_no_loc[14], db, sz); if(back) { db[2] = dkT('\0'); } } RegCloseKey(key); } } #else { HKEY hk; /* Registry key. */ if(dk3wreg_key_open_read(HKEY_CURRENT_USER, dk3app_no_loc[12], &hk, NULL)) { if(dk3wreg_get_sz(hk, dk3app_no_loc[13],db,sz,NULL)) { back = 1; } else { if(dk3wreg_get_sz(hk, dk3app_no_loc[14],db,sz,NULL)) { back = 1; db[2] = dkT('\0'); } } dk3wreg_key_close(hk, dk3app_no_loc[12], NULL); } } #endif #else #if DK3_CHAR_SIZE == 1 { char *ptr; /* Pointer to environment variable contents. */ ptr = getenv(dk3app_no_loc[11]); if(ptr) { if(dk3str_c8_len(ptr) < sz) { dk3str_c8_cpy_not_overlapped(db, ptr); back = 1; } else { dk3app_log_i1(app, DK3_LL_ERROR, 39); } } } #endif #endif #line 3947 "dk3app.ctr" return back; } /** Find language, region and encoding. @param app Application structure. @param argc Number of command line arguments. @param argv Command line arguments array. */ static void dk3app_language_and_region(dk3_app_t *app, int argc, dkChar const * const *argv) { dkChar buffer[DK3_MAX_PATH]; /* Buffer to store language/region name. */ dkChar *ptr; /* Used to find region. */ dkChar *p2; /* Used to convert to lower characters. */ #line 3965 "dk3app.ctr" if(dk3app_get_language_string(app, buffer, DK3_SIZEOF(buffer,dkChar))) { app->n_langstr = dk3str_dup_app(buffer, NULL); #line 3967 "dk3app.ctr" if(app->n_langstr) { ptr = dk3str_chr(buffer, dkT('.')); if(ptr) { *(ptr++) = dkT('\0'); #line 3971 "dk3app.ctr" #if DK3_CHAR_SIZE == 1 if(dk3str_casecmp(ptr, dk3app_no_loc[15]) == 0) { app->i_encoding = DK3_ENCODING_UTF8; app->i_output_encoding = DK3_FILE_ENCODING_UTF8; } if(dk3str_casecmp(ptr, dk3app_no_loc[16]) == 0) { app->i_encoding = DK3_ENCODING_UTF8; app->i_output_encoding = DK3_FILE_ENCODING_UTF8; } #endif } ptr = dk3str_chr(buffer, dkT('_')); #if DK3_ON_WINDOWS if(!(ptr)) { ptr = dk3str_chr(buffer, dkT('-')); } #endif if(ptr) { #line 3987 "dk3app.ctr" *(ptr++) = dkT('\0'); #line 3988 "dk3app.ctr" p2 = ptr; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; } app->n_region = dk3str_dup_app(ptr, NULL); if(!(app->n_region)) { #line 3991 "dk3app.ctr" app->de = 29; } } if(!(app->de)) { #line 3995 "dk3app.ctr" p2 = buffer; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; } app->n_language = dk3str_dup_app(buffer, NULL); if(!(app->n_language)) { #line 3998 "dk3app.ctr" app->de = 30; } } } else { #line 4002 "dk3app.ctr" app->de = 28; } } #line 4005 "dk3app.ctr" } /** Check whether a directory name is a root directory. @param dirname Directory name to check. @return 1 for root directory, 0 for others. */ static int dk3app_is_root_directory(dkChar const *dirname) { int back = 0; #if DK3_ON_WINDOWS size_t sz; sz = dk3str_len(dirname); if(1 == sz) { if(dkT('\\') == dirname[0]) { back = 1; } } else { if(3 == sz) { if((dkT('a') <= dirname[0]) && (dkT('z') >= dirname[0])) { back = 1; } else { if((dkT('A') <= dirname[0]) && (dkT('Z') >= dirname[0])) { back = 1; } } if(back) { back = 0; if(dkT(':') == dirname[1]) { if(dkT('\\') == dirname[2]) { back = 1; } } } } } #else if(dk3str_len(dirname) == 1) { if(dkT('/') == dirname[0]) { back = 1; } } #endif return back; } /** Reduce a directory name referring to a bin (or sbin or libexec/xxx directory. @param dirname Directory name to modify. @return 1 on success, 0 on error. */ static int dk3app_reduce_bindir_name(dkChar *dirname) { dkChar buffer[DK3_MAX_PATH]; dkChar *pCurrent; /* Current path component. */ dkChar *pPrevious; /* Previous path component. */ size_t sz; int ai; /* Array index. */ int cc; /* Flag: Can continue. */ int back = 0; #line 4073 "dk3app.ctr" if(dk3str_len(dirname) < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, dirname); pCurrent = NULL; pPrevious = NULL; cc = 1; while(cc) { #line 4078 "dk3app.ctr" cc = 0; if(dk3str_len(buffer) > 1) { #line 4080 "dk3app.ctr" if(!dk3app_is_root_directory(buffer)) { #line 4081 "dk3app.ctr" pCurrent = dk3str_rchr(buffer, DK3_CHAR_SEP); if(pCurrent) { #line 4083 "dk3app.ctr" cc = 1; #line 4084 "dk3app.ctr" #if DK3_ON_WINDOWS ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),0); #else ai = dk3str_array_index(dk3app_bindir_candidates,&(pCurrent[1]),1); #endif if(-1 < ai) { #line 4090 "dk3app.ctr" cc = 0; sz = dk3str_len(buffer); dirname[sz] = dkT('\0'); back = 1; } else { #line 4095 "dk3app.ctr" if(pPrevious) { *pPrevious = DK3_CHAR_SEP; } pPrevious = pCurrent; *pCurrent = dkT('\0'); } } } } } } #line 4104 "dk3app.ctr" return back; } /** Find all the names. Set app->de on errors, don't report directly. @param app Application to configure. @param wd Current working directory. @param argc Number of command line arguments. @param argv Command line arguments array. */ static void dk3app_find_names( dk3_app_t *app, dkChar const *wd, int argc, dkChar const * const *argv ) { int must_relocate = 0; /* Flag: Must relocate. */ int redres; /* Result from reduce directory. */ #if DK3_HAVE_UMASK mode_t oldumask; /* Umask before mkdir. */ #endif dkChar *n_app = NULL; /* Application name. */ dkChar *p = NULL; /* Modify application name. */ dkChar const *q = NULL; /* Installation bin directory. */ dkChar *x = NULL; /* Deal with executable name. */ dkChar buffer[DK3_MAX_PATH]; /* Used to construct file names. */ char pidbuffer[128]; /* Buffer for PID number (8-bit). */ dkChar dkpidbuffer[128]; /* Buffer for PID number. */ size_t tsl = 0; /* Buffer size needed. */ #line 4136 "dk3app.ctr" p = dk3str_rchr(argv[0], DK3_CHAR_SEP); if(p) { p++; } else { p = (dkChar *)(argv[0]); } n_app = dk3str_dup_app(p, NULL); #line 4139 "dk3app.ctr" if(n_app) { #line 4140 "dk3app.ctr" app->n_app = (dkChar const *)n_app; #line 4141 "dk3app.ctr" p = dk3str_chr(n_app, DK3_CHAR_DOT); if(p) { *p = DK3_CHAR_0; } if(dk3sf_find_exec_app(buffer,DK3_SIZEOF(buffer,dkChar),wd,argv[0], NULL)) { x = dk3str_dup_app(buffer, NULL); app->n_execfile = x; if(app->n_execfile) { p = dk3str_rchr(buffer, DK3_CHAR_SEP); if(p) { *p = DK3_CHAR_0; app->n_bindir = dk3str_dup_app(buffer, NULL); if(app->n_bindir) { redres = dk3app_reduce_bindir_name(buffer); q = dk3inst_get_directory(DK3_INST_BIN); if(dk3str_fncmp(buffer, q)) { q = dk3inst_get_directory(DK3_INST_SBIN); if(dk3str_fncmp(buffer, q)) { q = dk3inst_get_directory(DK3_INST_LIB); if(dk3str_fncmp(buffer, q)) { q = dk3inst_get_directory(DK3_INST_LIBEXEC); if(dk3str_fncmp(buffer, q)) { must_relocate = 1; } } } } if(must_relocate) { p = dk3str_rchr(buffer, DK3_CHAR_SEP); if(p) { p++; if(redres) { *p = DK3_CHAR_0; tsl = dk3str_len(buffer); tsl += dk3str_len(dk3app_no_loc[1]); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(p, dk3app_no_loc[1]); app->n_etcdir = dk3str_dup_app(buffer, NULL); if(app->n_etcdir) { *p = DK3_CHAR_0; tsl = dk3str_len(buffer); tsl += dk3str_len(dk3app_no_loc[2]); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(p, dk3app_no_loc[2]); app->n_sharedir = dk3str_dup_app(buffer, NULL); if(app->n_sharedir) { *p = DK3_CHAR_0; tsl = dk3str_len(buffer); tsl += dk3str_len(dk3app_no_loc[3]); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(p, dk3app_no_loc[3]); app->n_vardir = dk3str_dup_app(buffer, NULL); if(!(app->n_vardir)) { app->de = 9; } } else { app->de = 13; } } else { app->de = 8; } } else { app->de = 12; } } else { app->de = 7; } } else { app->de = 11; } } else { dk3app_copy_bin_to_others(app); } } else { dk3app_copy_bin_to_others(app); } } else { q = dk3inst_get_directory(DK3_INST_SYSCONF); app->n_etcdir = dk3str_dup_app(q, NULL); if(app->n_etcdir) { q = dk3inst_get_directory(DK3_INST_DATAROOT); app->n_sharedir = dk3str_dup_app(q, NULL); if(app->n_sharedir) { q = dk3inst_get_directory(DK3_INST_LOCALSTATE); app->n_vardir = dk3str_dup_app(q, NULL); if(!(app->n_vardir)) { app->de = 9; } } else { app->de = 8; } } else { app->de = 7; } } if(!(app->de)) { if(dk3sf_get_logname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL)) { app->n_logname = dk3str_dup_app(buffer,NULL); if(!(app->n_logname)) { app->de = 15; } } else { app->de = 14; } } if(!(app->de)) { if(dk3sf_get_hostname_app(buffer,DK3_SIZEOF(buffer,dkChar),NULL)) { app->n_hostname = dk3str_dup_app(buffer, NULL); if(!(app->n_hostname)) { app->de = 37; } } else { app->de = 38; } } if(!(app->de)) { if(dk3sf_get_home_app(buffer,DK3_SIZEOF(buffer,dkChar), NULL)) { app->n_homedir = dk3str_dup_app(buffer,NULL); if(!(app->n_homedir)) { app->de = 17; } } else { app->de = 16; } } if(!(app->de)) { switch(app->app_type) { case DK3_APP_TYPE_COMMAND: case DK3_APP_TYPE_GUI: { tsl = dk3str_len(app->n_homedir); tsl += dk3str_len(dk3app_no_loc[4]); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(app->n_app); tsl += dk3str_len(dk3app_no_loc[5]); (void)dk3ma_um_to_c8_string( pidbuffer, sizeof(pidbuffer), dk3sf_getpid() ); if(dk3str_cnv_c8_to_str_app( dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar), pidbuffer, NULL ) ) { tsl += dk3str_len(dkpidbuffer); tsl += dk3str_len(dk3app_no_loc[6]); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, app->n_homedir); dk3str_cat(buffer, dk3app_no_loc[4]); dk3str_correct_filename(buffer); #line 4290 "dk3app.ctr" #if VERSION_BEFORE_20160128 if(dk3sf_mkdir_app(buffer, 0700, NULL)) { dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_cat(buffer, dk3app_no_loc[5]); dk3str_cat(buffer, dkpidbuffer); dk3str_cat(buffer, dk3app_no_loc[6]); dk3str_correct_filename(buffer); app->n_logfilename = dk3str_dup_app(buffer,NULL); if(!(app->n_logfilename)) { app->de = 21; } } else { app->de = 20; } #else /* 2016-01-28 Do not immediately create the log directory for non-daemon programs. */ dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_cat(buffer, dk3app_no_loc[5]); dk3str_cat(buffer, dkpidbuffer); dk3str_cat(buffer, dk3app_no_loc[6]); dk3str_correct_filename(buffer); app->n_logfilename = dk3str_dup_app(buffer,NULL); if(!(app->n_logfilename)) { app->de = 21; } #endif } else { app->de = 19; } } else { app->de = 22; } } break; case DK3_APP_TYPE_DAEMON: { tsl = dk3str_len(app->n_vardir); tsl += dk3str_len(dk3app_no_loc[4]); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(app->n_app); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(app->n_app); tsl += dk3str_len(dk3app_no_loc[6]); #if DK3_HAVE_UMASK oldumask = umask(0); #endif if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, app->n_vardir); dk3str_cat(buffer, dk3app_no_loc[4]); #line 4343 "dk3app.ctr" if(dk3sf_mkdir_app(buffer, 0755, NULL)) { dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); #line 4347 "dk3app.ctr" if(dk3sf_mkdir_app(buffer, 0755, NULL)) { app->cr_log = 1; dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_cat(buffer, dk3app_no_loc[6]); app->n_logfilename = dk3str_dup_app(buffer, NULL); if(!(app->n_logfilename)) { app->de = 21; } } else { #line 4357 "dk3app.ctr" app->de = 20; } } else { #line 4360 "dk3app.ctr" app->de = 20; } } else { app->de = 19; } #if DK3_HAVE_UMASK umask(oldumask); #endif } break; } } if(!(app->de)) { #line 4372 "dk3app.ctr" switch(app->app_type) { case DK3_APP_TYPE_DAEMON: { if(app->n_vardir) { if(app->n_app) { (void)dk3ma_um_to_c8_string( pidbuffer, sizeof(pidbuffer), dk3sf_getpid() ); if(dk3str_cnv_c8_to_str_app( dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar), pidbuffer, NULL ) ) { tsl = dk3str_len(app->n_vardir); tsl += dk3str_len(dk3app_no_loc[10]); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(app->n_app); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(dkpidbuffer); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, app->n_vardir); dk3str_cat(buffer, dk3app_no_loc[10]); dk3str_correct_filename(buffer); #line 4397 "dk3app.ctr" (void)dk3sf_mkdir_app(buffer,0700,NULL); dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_correct_filename(buffer); #line 4402 "dk3app.ctr" (void)dk3sf_mkdir_app(buffer,0700,NULL); dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, dkpidbuffer); #line 4406 "dk3app.ctr" #line 4407 "dk3app.ctr" if(dk3sf_mkdir_app(buffer,0700,NULL)) { app->cr_tmp = 1; app->n_tmpdir = dk3str_dup_app(buffer, NULL); if(!(app->n_tmpdir)) { app->de = 25; dk3sf_remove_dir_app(buffer, NULL); } } else { app->de = 26; } } else { app->de = 19; } } else { app->de = 22; } } else { app->de = 24; } } else { app->de = 27; } } break; default: { if(app->n_homedir) { if(app->n_app) { (void)dk3ma_um_to_c8_string( pidbuffer, sizeof(pidbuffer), dk3sf_getpid() ); if(dk3str_cnv_c8_to_str_app( dkpidbuffer, DK3_SIZEOF(dkpidbuffer,dkChar), pidbuffer, NULL ) ) { tsl = dk3str_len(app->n_homedir); tsl += dk3str_len(dk3app_no_loc[9]); tsl += dk3str_len(dk3app_no_loc[20]); tsl += dk3str_len(app->n_app); tsl += dk3str_len(dk3app_no_loc[5]); tsl += dk3str_len(dkpidbuffer); if(tsl < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, app->n_homedir); dk3str_cat(buffer, dk3app_no_loc[9]); dk3str_correct_filename(buffer); #if VERSION_BEFORE_20160128 #line 4454 "dk3app.ctr" if(dk3sf_mkdir_app(buffer,0700,NULL)) { dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_cat(buffer, dk3app_no_loc[5]); dk3str_cat(buffer, dkpidbuffer); dk3str_correct_filename(buffer); #if VERSION_BEFORE_20150318 #line 4462 "dk3app.ctr" if(dk3sf_mkdir_app(buffer,0700,NULL)) { app->n_tmpdir = dk3str_dup_app(buffer, NULL); if(!(app->n_tmpdir)) { app->de = 25; dk3sf_remove_dir_app(buffer, NULL); } } else { app->de = 26; } #else app->n_tmpdir = dk3str_dup_app(buffer, NULL); if(!(app->n_tmpdir)) { app->de = 25; } #endif } else { app->de = 26; } #else /* if VERSION_BEFORE_20160128 */ dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); dk3str_cat(buffer, dk3app_no_loc[5]); dk3str_cat(buffer, dkpidbuffer); dk3str_correct_filename(buffer); app->n_tmpdir = dk3str_dup_app(buffer, NULL); if(!(app->n_tmpdir)) { app->de = 25; } #endif /* if VERSION_BEFORE_20160128 */ } else { app->de = 19; } } else { app->de = 22; } } else { app->de = 24; } } else { app->de = 23; } } break; } } } else { app->de = 6; } } else { app->de = 5; } } else { app->de = 4; } } else { app->de = 3; } } else { app->de = 2; } #line 4523 "dk3app.ctr" } /** Test whether a configuration file name candidate is valid. @param app Application structure. @param fn File name. @param db Destination buffer. @param sz Size of \a db (number of characters). @param passno Pass number. @param verb Flag: Diagnostic messages enabled. @return 1 on success, 0 on error. */ static int dk3app_check_config_file( dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz, int passno, int verb ) { int back = 0; dk3_stat_t stb; /* Stat buffer used to check existance of files. */ #line 4545 "dk3app.ctr" if(dk3app_config_name(app, fn, db, sz, passno, verb)) { if(dk3sf_stat_app(&stb, db, NULL)) { switch((stb.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { back = 1; } break; } } if(back) { /* DEBUG Config file ... found. */ dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, db); } else { /* DEBUG Config file ... not found. */ dk3app_log_i3(app, DK3_LL_DEBUG, 154, 155, db); } } #line 4559 "dk3app.ctr" return back; } /** Add preference key/value entry to storage. Check whether an entry for the key already exists. @param app Application structure for diagnostics, may be NULL. @param s Storage. @param i Storage iterator. @param k Preference key. @param v Preference value. */ static int dk3app_add_pref( dk3_app_t *app, dk3_sto_t *s, dk3_sto_it_t *i, dkChar const *k, dkChar const *v ) { int back = 0; dk3app_pref_t p; /* Preference search. */ dk3app_pref_t *pref = NULL; /* Existing preference for name. */ dkChar *nv = NULL; /* New value string for preference. */ #line 4584 "dk3app.ctr" p.k = k; p.v = v; pref = (dk3app_pref_t *)dk3sto_it_find_like(i, &p, 0); if(pref) { nv = dk3str_dup_app(v, NULL); if(nv) { dk3_delete(pref->v); pref->v = nv; back = 1; } else { if(app) { dk3app_log_i1(app, DK3_LL_ERROR, 9); } } } else { pref = dk3app_pref_new(k, v); if(pref) { if(dk3sto_add(s, pref)) { back = 1; } else { if(app) { dk3app_log_i1(app, DK3_LL_ERROR, 9); } dk3app_pref_delete(pref); pref = NULL; } } else { if(app) { dk3app_log_i1(app, DK3_LL_ERROR, 9); } } } #line 4614 "dk3app.ctr" return back; } /** Save one preference entry. Do not report problems directly, set app->de instead. @param app Application structure. @param pt Preference text. */ static void dk3app_save_one_preference(dk3_app_t *app, dkChar const *pt) { dkChar b[DK3_MAX_PATH]; /* Buffer for input line. */ dkChar *p1 = NULL; /* Value position. */ #line 4631 "dk3app.ctr" if(dk3str_len(pt) < DK3_SIZEOF(b,dkChar)) { dk3str_cpy_not_overlapped(b, pt); p1 = dk3str_chr(b, dkT('=')); if(p1) { *(p1++) = dkT('\0'); p1 = dk3str_start(p1, NULL); if(p1) { dk3str_chomp(b, NULL); dk3str_chomp(p1, NULL); if(!(app->s_cmdprefs)) { app->s_cmdprefs = dk3sto_open_app(NULL); if(app->s_cmdprefs) { dk3sto_set_comp(app->s_cmdprefs, dk3app_compare_pref, 0); } else { app->de = 36; #line 4646 "dk3app.ctr" } } if(!(app->i_cmdprefs)) { if(app->s_cmdprefs) { app->i_cmdprefs = dk3sto_it_open(app->s_cmdprefs); } else { app->de = 35; #line 4653 "dk3app.ctr" } } if((app->s_cmdprefs) && (app->i_cmdprefs)) { if(!dk3app_add_pref(NULL,app->s_cmdprefs,app->i_cmdprefs,b,p1)) { app->de = 33; #line 4658 "dk3app.ctr" } } } else { app->de = 32; #line 4662 "dk3app.ctr" } } else { app->de = 32; #line 4665 "dk3app.ctr" } } else { app->de = 31; #line 4668 "dk3app.ctr" } #line 4669 "dk3app.ctr" } /** Set application to silent mode if --/silent=yes was provided as command line argument. @param app Application structure. */ static void dk3app_first_set_silent(dk3_app_t *app) { app->ll_stderr = DK3_LL_NONE; switch(app->app_type) { case DK3_APP_TYPE_COMMAND: { app->app_type = DK3_APP_TYPE_SILENT; } break; } } int dk3app_first_silence_check(dk3_app_t *app, int argc, dkChar const * const *argv) { int back = 0; int i; /* Index of current argument. */ dkChar const * const *lfdptr; /* Pointer to traverse arguments. */ dkChar const *ptr; /* Current argument. */ dkChar buffer[2 * DK3_MAX_PATH]; /* Local copy. */ dkChar *p1; /* Option keyword. */ dkChar *p2; /* Option argument. */ lfdptr = argv; lfdptr++; i = 1; while(i < argc) { ptr = *lfdptr; if(*ptr == dkT('-')) { ptr++; if(*ptr == dkT('-')) { ptr++; if(dk3str_len(ptr) < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, ptr); p1 = dk3str_start(buffer, NULL); if(p1) { p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); } if(dk3str_cmp(dk3app_no_loc[50], p1) == 0) { if(p2) { if(dk3str_is_on(p2)) { back = 1; if(app) { dk3app_first_set_silent(app); } } } else { back = 1; if(app) { dk3app_first_set_silent(app); } } } } } else { /* ERROR: Too long! */ } } } lfdptr++; i++; } return back; } /** Save command line arguments for later use. Don't report errors directly, set app->de instead. @param app Application structure. @param argc Number of command line arguments. @param argv Command line arguments array. */ static void dk3app_save_arguments(dk3_app_t *app, int argc, dkChar const * const *argv) { int myargc = 0; /* Number of options used. */ dkChar const **myargv = NULL; /* Private copy of options. */ dkChar const **ptr = NULL; /* Traverse myargv. */ dkChar const * const *sptr = NULL; /* Traverse original argv. */ dkChar const *tptr = NULL; /* String tests in sptr. */ int ispref = 0; /* Flag: Is a preference. */ int i = 0; /* Index of current argv. */ #line 4760 "dk3app.ctr" myargv = dk3_new_app(DK3_PCDKCHAR,(argc+1),app); if(myargv) { ptr = myargv; for(i = 0; i < (argc + 1); i++) { *(ptr++) = NULL; } ptr = myargv; myargc = 0; sptr = argv; for(i = 0; i < argc; i++) { tptr = *(sptr++); #line 4767 "dk3app.ctr" ispref = 0; if(*tptr == DK3_CHAR_MINUS) { if(tptr[1] == DK3_CHAR_MINUS) { if(tptr[2] == DK3_CHAR_SLASH) { ispref = 1; #line 4772 "dk3app.ctr" } } } if(ispref) { dk3app_save_one_preference(app, &(tptr[2])); } else { *ptr = dk3str_dup_app(tptr, NULL); if(*ptr) { myargc++; ptr++; } else { app->de = 1; } } } app->argc = myargc; app->argv = myargv; } #line 4789 "dk3app.ctr" } /** Save application group name. @param app Application structure. @param gn Group name to save. */ static void dk3app_save_group_name(dk3_app_t *app, dkChar const *gn) { #line 4802 "dk3app.ctr" app->n_appgroup = dk3str_dup_app(gn,NULL); if(!(app->n_appgroup)) { app->de = 18; } #line 4806 "dk3app.ctr" } /** Retrieve preferences from a storage. @param app Application structure for diagnostics, may be NULL. @param p Storage iterator. @param k Key (preference name). @param d Destination buffer. @param s Size of \a d (number of characters). @return 1 on success, 0 on error. */ static int dk3app_sto_pref( dk3_app_t *app, dk3_sto_it_t *p, dkChar const *k, dkChar *d, size_t s) { int back = 0; dk3app_pref_t pr; /* Used for comparisons in search. */ dk3app_pref_t *pref = NULL; /* Entry found. */ #line 4827 "dk3app.ctr" if(p) { pr.k = k; pr.v = NULL; pref = (dk3app_pref_t *)dk3sto_it_find_like(p, &pr, 0); if(pref) { if(pref->v) { if(dk3str_len(pref->v) < s) { dk3str_cpy_not_overlapped(d, pref->v); back = 1; } else { if(app) { /* Destination buffer too short! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } } #line 4844 "dk3app.ctr" return back; } /** Find number of entries for a string table file. @param dv String table value array. @return Number of entries in array, including final NULL entry. */ static size_t dk3app_mc_array_size(dkChar const * const *dv) { size_t back = 0; dkChar const * const *ptr = NULL; /* Traverse the dv array. */ #line 4860 "dk3app.ctr" if(dv) { ptr = dv; while(*(ptr++)) { back++; } back++; } #line 4865 "dk3app.ctr" return back; } void dk3app_squeeze_line(char *lb) { char *pd = NULL; /* Destination in copy operations. */ char *ps = NULL; /* Source in copy operations. */ char *px = NULL; /* Position to continue. */ ps = lb; #line 4878 "dk3app.ctr" /* Remove trailing newline. */ while(*ps) { if((*ps == '\r') || (*ps == '\n')) { *ps = '\0'; } else { ps++; } } /* Correct escape sequences */ ps = lb; while(*ps) { if(*ps == '\\') { px = pd = ps; ps++; if(*ps) { switch(*ps) { case 't': { *(pd++) = '\t'; ps++; dk3str_c8_cpy(pd, ps); } break; case 'n': { *(pd++) = '\n'; ps++; dk3str_c8_cpy(pd, ps); } break; case 'r': { *(pd++) = '\r'; ps++; dk3str_c8_cpy(pd, ps); } break; default: { dk3str_c8_cpy(pd, ps); } break; } ps = px; ps++; } } else { ps++; } } #line 4915 "dk3app.ctr" } /** Get message catalog contents. @param app Application structure. @param fn File name for message catalog. @param dv Default values. @param verb Flag: Diagnostics enabled. @return Pointer to message array. */ static dkChar const * const * dk3app_my_messages( dk3_app_t *app, dkChar const *fn, dkChar const * const *dv, int verb ) { dkChar const * const *back = NULL; dkChar const *source_file = NULL; /* File name for source file. */ dk3app_mc_t mc; /* Used for comparisons. */ dk3app_mc_t *mcptr = NULL; /* Message catalog. */ int errors_occured = 0; /* Flag: We had errors. */ unsigned long source_line = 0UL; /* Number of source line. */ unsigned long line_number = 0UL; /* NUmber of current line. */ size_t sz_defaults = 0; /* Number entries in default table. */ size_t i = 0; /* Walk through table. */ size_t current_index = 0; /* Index of current entry to process. */ dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ char lb[4096]; /* Input line (8-bit characters). */ dkChar const **rb = NULL; /* Array of strings to return. */ FILE *fipo; /* Input file. */ #line 4947 "dk3app.ctr" if((app) && (fn) && (dv)) { #line 4948 "dk3app.ctr" /* Find array size. */ sz_defaults = dk3app_mc_array_size(dv); if(sz_defaults) { #line 4951 "dk3app.ctr" if((app->s_mc) && (app->i_mc)) { #line 4952 "dk3app.ctr" mc.n = fn; mc.msg = NULL; mc.f = 0; mc.nmsg = sz_defaults; mcptr = (dk3app_mc_t *)dk3sto_it_find_like(app->i_mc, &mc, 0); if(mcptr) { #line 4955 "dk3app.ctr" if(mcptr->nmsg >= sz_defaults) { back = mcptr->msg; #line 4957 "dk3app.ctr" } else { #line 4958 "dk3app.ctr" errors_occured = 1; /* Too short */ } } else { #line 4961 "dk3app.ctr" } } else { #line 4963 "dk3app.ctr" } if((!(back)) && (errors_occured == 0)) { #line 4965 "dk3app.ctr" if(dk3app_my_find_data_file(app, fn, fnb, DK3_MAX_PATH, verb)) { source_file = dk3app_get_source_file(app); #line 4967 "dk3app.ctr" source_line = dk3app_get_source_line(app); dk3app_set_source_file(app, fnb); dk3app_set_source_line(app, 0UL); /* UTF8 */ fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], (verb ? app : NULL)); if(fipo) { #line 4972 "dk3app.ctr" rb = dk3_new_app(DK3_PCDKCHAR,sz_defaults,(verb ? app : NULL)); if(rb) { #line 4974 "dk3app.ctr" for(i = 0; i < sz_defaults; i++) { rb[i] = NULL; } current_index = 0; /* We explicitly used 8-bit characters, the file is UTF-8 */ while(fgets(lb, sizeof(lb), fipo)) { line_number++; dk3app_set_source_line(app, line_number); if(lb[0] != '#') { dk3app_squeeze_line(lb); if(current_index < (sz_defaults - 1)) { #if DK3_CHAR_SIZE > 1 #if DK3_CHAR_SIZE > 2 #error "Can not handle 4-byte characters here!" #else rb[current_index] = (dkChar const *)dk3str_cnvnew_c8u_to_c16_app( lb, (verb ? app : NULL) ); if(rb[current_index]) { current_index++; } else { errors_occured = 2; } #endif #else switch(app->i_encoding) { case DK3_ENCODING_PLAIN: { rb[current_index] = dk3str_cnvnew_c8u_to_c8p_app(lb, (verb ? app : NULL)); if(rb[current_index]) { current_index++; } else { errors_occured = 2; } } break; default: { rb[current_index] = dk3str_dup_app(lb, (verb ? app : NULL)); if(rb[current_index]) { current_index++; } else { errors_occured = 2; } } break; } #endif } /* current_index++; */ } } #line 5024 "dk3app.ctr" dk3app_set_source_line(app, 0UL); if((current_index >= (sz_defaults - 1)) && (!(errors_occured))) { if(!(app->s_mc)) { #line 5027 "dk3app.ctr" app->s_mc = dk3sto_open_app(verb ? app : NULL); if(app->s_mc) { #line 5029 "dk3app.ctr" dk3sto_set_comp(app->s_mc, dk3app_mc_compare, 0); } else { #line 5031 "dk3app.ctr" } } if(!(app->i_mc)) { #line 5034 "dk3app.ctr" if(app->s_mc) { #line 5035 "dk3app.ctr" app->i_mc = dk3sto_it_open(app->s_mc); } else { #line 5037 "dk3app.ctr" } } if((app->s_mc) && (app->i_mc)) { #line 5040 "dk3app.ctr" mcptr = dk3app_mc_new(fn, rb, sz_defaults, 1, (verb ? app: NULL)); if(mcptr) { #line 5043 "dk3app.ctr" if(dk3sto_add(app->s_mc, mcptr)) { #line 5044 "dk3app.ctr" back = rb; } else { dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5049 "dk3app.ctr" dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5052 "dk3app.ctr" dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { /* Error occured or not enough strings. */ if(errors_occured) { #line 5056 "dk3app.ctr" if(verb) { /* Errors while reading file! */ } } else { #line 5060 "dk3app.ctr" if(verb) { /* Too few entries in file! */ } } dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5068 "dk3app.ctr" } fclose(fipo); } else { #line 5071 "dk3app.ctr" } dk3app_set_source_file(app, source_file); dk3app_set_source_line(app, source_line); } else { #line 5075 "dk3app.ctr" } } else { #line 5077 "dk3app.ctr" } } else { #line 5079 "dk3app.ctr" } if(!(back)) { #line 5081 "dk3app.ctr" back = dv; } } else { #line 5084 "dk3app.ctr" } #line 5085 "dk3app.ctr" return back; } /** Read one preferences file. @param app Application structure. @param fn File name to process. @param s Storage to save preference entries. @param i Iterator through storage. */ static void dk3app_rd_pref_file( dk3_app_t *app, dkChar const *fn, dk3_sto_t *s, dk3_sto_it_t *i ) { dkChar buffer[4096]; char bombuf[4]; dkChar *p1 = NULL; /* Preference key (name). */ dkChar *p2 = NULL; /* Preference value. */ dkChar *p3 = NULL; /* Scope attribute value. */ dkChar const *oldsourcename; /* Old source file name. */ FILE *fipo = NULL; /* Input file. */ unsigned long lineno = 0UL; /* Current line number. */ unsigned long oldsourceline; /* Old source line number. */ size_t skb; /* Bytes to skip at start. */ int scope_valid = 1; /* Flag: In a valid scope. */ int last_was_scope = 0; /* Flag: Previous line was scope. */ int scope_action = 0; /* 0=yes, 1=no */ int conditions_ok; /* Flag: All conditions ok. */ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding. */ skb = 0; ie = dk3sf_inspect_bom_skip_app(fn, DK3_FILE_ENCODING_ASCII, &skb, NULL); dk3app_log_i3(app, DK3_LL_DEBUG, 230, 231, fn); fipo = dk3sf_fopen_app(fn, dk3app_no_loc[22], NULL); /* READ */ if(fipo) { oldsourcename = dk3app_get_source_file(app); oldsourceline = dk3app_get_source_line(app); dk3app_set_source_file(app, fn); dk3app_set_source_line(app, 0UL); (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL); lineno = 0UL; if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, NULL); } while(dk3sf_fgets(buffer, DK3_SIZEOF(buffer,dkChar), fipo)) { lineno++; dk3app_set_source_line(app, lineno); #line 5133 "dk3app.ctr" p1 = dk3str_start(buffer, NULL); if(p1) { if(*p1 != dkT('#')) { if(*p1 == dkT('[')) { if(!last_was_scope) { scope_valid = 0; } scope_action = 0; p2 = dk3str_chr(p1, dkT(']')); if(p2) { *p2 = dkT('\0'); } p1++; dk3str_chomp(p1, NULL); if(*p1 == dkT('-')) { scope_action = 1; p1++; } p1 = dk3str_start(p1, NULL); conditions_ok = 1; while(p1) { p2 = dk3str_chr(p1, dkT(',')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); } p3 = dk3str_chr(p1, dkT('=')); if(p3) { *(p3++) = dkT('\0'); p3 = dk3str_start(p3, NULL); if(p3) { dk3str_chomp(p1, NULL); dk3str_chomp(p3, NULL); #line 5159 "dk3app.ctr" switch(dk3str_array_index(dk3app_scope_attributes, p1, 0)) { case 0: { /* user */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_logname) { #if DK3_ON_WINDOWS || DK3_HAVE_USER_NAMES_CASE_INSENSITIVE if(dk3str_casecmp(p3, app->n_logname)) { conditions_ok = 0; } #else if(dk3str_cmp(p3, app->n_logname)) { conditions_ok = 0; } #endif } else { conditions_ok = 0; } } } break; case 1: { /* application */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_app) { #if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS if(dk3str_casecmp(p3, app->n_app)) { conditions_ok = 0; } #else if(dk3str_cmp(p3, app->n_app)) { conditions_ok = 0; } #endif } else { conditions_ok = 0; } } } break; case 2: { /* application-group */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_appgroup) { #if DK3_ON_WINDOWS || DK3_HAVE_FNCASEINS if(dk3str_casecmp(p3, app->n_appgroup)) { conditions_ok = 0; } #else if(dk3str_cmp(p3, app->n_appgroup)) { conditions_ok = 0; } #endif } else { conditions_ok = 0; } } } break; case 3: { /* host */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_hostname) { if(dk3str_casecmp(p3, app->n_hostname)) { conditions_ok = 0; } } else { conditions_ok = 0; } } } break; case 4: { /* language */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_language) { if(dk3str_cmp(p3, app->n_language)) { conditions_ok = 0; } } else { conditions_ok = 0; } } } break; case 5: { /* region */ if(dk3str_cmp(p3, dk3app_no_loc[33])) { if(app->n_region) { if(dk3str_cmp(p3, app->n_region)) { conditions_ok = 0; } } else { conditions_ok = 0; } } } break; } } } p1 = p2; } last_was_scope = 1; if(conditions_ok) { if(scope_action) { scope_valid = 0; } else { scope_valid = 1; } } } else { last_was_scope = 0; if(scope_valid) { dk3str_chomp(p1, NULL); p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_chomp(p1, NULL); dk3str_chomp(p2, NULL); if(!dk3app_add_pref(NULL, s, i, p1, p2)) { app->de = 33; } } } } } } } } fclose(fipo); dk3app_set_source_file(app, oldsourcename); dk3app_set_source_line(app, oldsourceline); } else { dk3app_log_i3(app, DK3_LL_DEBUG, 152, 153, fn); } } /** Read all preference files for an application. @param app Application structure. */ static void dk3app_read_preference_files(dk3_app_t *app) { dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ int i = 0; /* Pass. */ #line 5288 "dk3app.ctr" for(i = 0; i < 16; i++) { if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, i, 0)) { switch(i) { case 14: { #line 5292 "dk3app.ctr" if(!(app->s_varprefs)) { app->s_varprefs = dk3sto_open_app(NULL); if(app->s_varprefs) { dk3sto_set_comp(app->s_varprefs, dk3app_compare_pref, 0); } else { app->de = 36; } } if(!(app->i_varprefs)) { if(app->s_varprefs) { app->i_varprefs = dk3sto_it_open(app->s_varprefs); if(!(app->i_varprefs)) { app->de = 36; } } } if((app->s_varprefs) && (app->i_varprefs)) { dk3app_rd_pref_file(app, fnb, app->s_varprefs, app->i_varprefs); } } break; case 12: case 13: case 15: { #line 5311 "dk3app.ctr" if(!(app->s_constprefs)) { app->s_constprefs = dk3sto_open_app(NULL); if(app->s_constprefs) { dk3sto_set_comp(app->s_constprefs, dk3app_compare_pref, 0); } else { app->de = 36; } } if(!(app->i_constprefs)) { if(app->s_constprefs) { app->i_constprefs = dk3sto_it_open(app->s_constprefs); if(!(app->i_constprefs)) { app->de = 36; } } } if((app->s_constprefs) && (app->i_constprefs)) { dk3app_rd_pref_file(app,fnb,app->s_constprefs,app->i_constprefs); } } break; default: { #line 5330 "dk3app.ctr" if(!(app->s_sysprefs)) { app->s_sysprefs = dk3sto_open_app(NULL); if(app->s_sysprefs) { dk3sto_set_comp(app->s_sysprefs, dk3app_compare_pref, 0); } else { app->de = 36; } } if(!(app->i_sysprefs)) { if(app->s_sysprefs) { app->i_sysprefs = dk3sto_it_open(app->s_sysprefs); if(!(app->i_sysprefs)) { app->de = 36; } } } if((app->s_sysprefs) && (app->i_sysprefs)) { dk3app_rd_pref_file(app, fnb, app->s_sysprefs, app->i_sysprefs); } } break; } } } #line 5349 "dk3app.ctr" } /** Find log level. @param app Application structure. @param ind Index of preference name in \a dk3app_no_loc. @param buffer Buffer for preference value. @param sz Size of \a buffer (number of characters). @param dv Default value to use if preference is not set. @return Log level found in preference or default value. */ static int dk3app_find_ll(dk3_app_t *app, int ind, dkChar *buffer, size_t sz, int dv) { int back = 0; dkChar *p1 = NULL; /* Value string. */ int i = 0; /* Index search result. */ back = dv; #line 5370 "dk3app.ctr" if(dk3app_get_pref(app, dk3app_no_loc[ind], buffer, sz)) { #line 5371 "dk3app.ctr" p1 = dk3str_start(buffer, NULL); if(p1) { #line 5374 "dk3app.ctr" dk3str_chomp(p1, NULL); #line 5376 "dk3app.ctr" i = dk3str_array_abbr(dk3app_log_levels, p1, dkT('$'), 0); if(i >= 0) { #line 5378 "dk3app.ctr" if(i <= DK3_LL_IGNORE) { back = i; #line 5380 "dk3app.ctr" } } else { #line 5382 "dk3app.ctr" } } else { #line 5384 "dk3app.ctr" } } else { #line 5386 "dk3app.ctr" } #line 5387 "dk3app.ctr" return back; } /** Preferences processing at application startup. @param app Application structure. */ static void dk3app_process_preferences(dk3_app_t *app) { dkChar buffer[4096]; dkChar *p1 = NULL; /* Start of language/region/encoding string. */ dkChar *p2 = NULL; /* Encoding, later region. */ dkChar *p3 = NULL; /* Used to convert to lower case. */ dkChar *p4 = NULL; /* New string for region. */ int i; /* Input encoding. */ if(dk3app_get_pref(app,dk3app_no_loc[27],buffer,DK3_SIZEOF(buffer,dkChar))) { p1 = dk3str_start(buffer, NULL); if(p1) { p2 = dk3str_chr(buffer, dkT('.')); if(p2) { *p2 = dkT('\0'); } p2 = dk3str_chr(buffer, dkT('_')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_chomp(p2, NULL); p3 = p2; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; } } } p3 = p1; while(*p3) { *p3 = dk3str_tolower(*p3); p3++; } dk3str_chomp(p1, NULL); p3 = dk3str_dup_app(p1, NULL); p4 = NULL; if(p2) { p4 = dk3str_dup_app(p2, NULL); } if(p3) { dk3_delete(app->n_language); app->n_language = p3; } if(p4) { dk3_delete(app->n_region); app->n_region = p4; } } } app->ll_file = dk3app_find_ll( app, 28, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file ); app->ll_file_keep = dk3app_find_ll( app, 29, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_file_keep ); app->ll_stderr = dk3app_find_ll( app, 30, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_stderr ); app->ll_tmp_keep = dk3app_find_ll( app, 31, buffer, DK3_SIZEOF(buffer,dkChar), app->ll_tmp_keep ); app->i_stdin_input_encoding = dk3app_get_default_stdin_encoding(app); #line 5449 "dk3app.ctr" app->i_file_input_encoding = dk3app_get_default_file_encoding(app); if(dk3app_get_pref(app,dk3app_no_loc[51],buffer,DK3_SIZEOF(buffer,dkChar))) { p1 = dk3str_start(buffer, NULL); if(p1) { dk3str_chomp(p1, NULL); i = dk3enc_get_text_encoding_app(buffer, NULL); if(i >= 0) { app->i_file_input_encoding = i; } } } if(dk3app_get_pref(app,dk3app_no_loc[52],buffer,DK3_SIZEOF(buffer,dkChar))) { p1 = dk3str_start(buffer, NULL); if(p1) { dk3str_chomp(p1, NULL); i = dk3enc_get_text_encoding_app(buffer, NULL); if(i >= 0) { app->i_stdin_input_encoding = i; #line 5470 "dk3app.ctr" } } } } /** Create new application. @param wd Current working directory. @param argc Number of command line arguments. @param argv Command line arguments array. @param gn Application group name. @param tp Application type. @return Pointer to new application on success, NULL on error. */ static dk3_app_t * dk3app_open( dkChar const * wd, int argc, dkChar const * const * argv, dkChar const *gn, int tp ) { dk3_app_t *back = NULL; #line 5497 "dk3app.ctr" back = dk3_new(dk3_app_t,1); if(back) { dk3app_init(back); switch(tp) { case DK3_APP_TYPE_DAEMON: { back->ll_file = DK3_LL_INFO; } break; } back->app_type = tp; if(!(back->de)) { dk3app_save_group_name(back, gn); } if(!(back->de)) { dk3app_first_silence_check(back, argc, argv); } if(!(back->de)) { dk3app_language_and_region(back, argc, argv); } if(!(back->de)) { dk3app_find_names(back, wd, argc, argv); } if(!(back->de)) { dk3app_save_arguments(back, argc, argv); } if(!(back->de)) { dk3app_read_preference_files(back); } if(!(back->de)) { dk3app_process_preferences(back); } if(!(back->de)) { back->msg = dk3app_my_messages(back, dk3app_no_loc[23], dk3app_kw, 0); } back->f_readytolog = 1; if(back->de) { /* Delayed error occured. Report error, destroy structure. */ switch(back->de) { case 1: /* Error while saving command line arguments. */ case 2: /* Error while saving application name. */ case 4: /* Error while saving exec file name. */ case 6: /* Error while saving bin directory. */ case 7: /* Error while saving etc directory. */ case 8: /* Error while saving share directory. */ case 9: /* Error while saving var directory. */ case 15: /* Error while saving logname. */ case 17: /* Error while saving home directory. */ case 18: /* Error while saving application group name. */ case 21: /* Error while saving log file name. */ case 25: /* Error while saving temp dir name. */ case 28: /* Error while saving language string. */ case 29: /* Failed to save region! */ case 30: /* Failed to save language! */ case 33: /* Pref */ case 34: /* Pref storage */ case 35: /* Cmd prefs iterator */ case 36: /* Cmd prefs storage */ case 37: /* Store host name */ { dk3app_log_i1(back, DK3_LL_ERROR, 9); } break; case 3: /* Failed to find executable file name. */ { /* Failed to find executable file name. */ dk3app_log_i1(back, DK3_LL_ERROR, 40); } break; case 5: /* Incomplete exec file name. */ { /* No separator in executable file name! */ dk3app_log_i1(back, DK3_LL_ERROR, 40); } case 10: /* Program is started from root directory. */ { /* Too few directories in hierarchy! */ dk3app_log_i1(back, DK3_LL_ERROR, 41); } break; case 11: /* Error while creating etc directory name! */ case 12: /* Error while creating share directory name! */ case 13: /* Error while creating var directory name! */ { /* Name of executable file too long! */ dk3app_log_i1(back, DK3_LL_ERROR, 42); } break; case 14: { /* Failed to retrieve log name! */ /* Failed to retrieve log name! */ dk3app_log_i1(back, DK3_LL_ERROR, 43); } break; case 16: { /* Failed to retrieve home directory! */ /* Failed to retrieve home directory! */ dk3app_log_i1(back, DK3_LL_ERROR, 44); } break; case 19: { /* Log file name too long. */ /* Log file name gets too long! */ dk3app_log_i1(back, DK3_LL_ERROR, 45); } break; case 20: { /* Failed to create log directory! */ dk3app_log_i1(back, DK3_LL_ERROR, 46); } break; case 22: { /* Failed to convert PID to dkChar! */ dk3app_log_i1(back, DK3_LL_ERROR, 47); } break; case 23: { /* Home directory name missing! */ dk3app_log_i1(back, DK3_LL_ERROR, 44); } break; case 24: { /* Application name missing! */ dk3app_log_i1(back, DK3_LL_ERROR, 48); } break; case 26: { /* Name of tmp dir gets too long! */ dk3app_log_i1(back, DK3_LL_ERROR, 49); } break; case 27: { /* var dir name missing! */ dk3app_log_i1(back, DK3_LL_ERROR, 50); } break; case 31: { /* Preference name too long! */ dk3app_log_i1(back, DK3_LL_ERROR, 51); } break; case 32: { /* Not a preference entry! */ dk3app_log_i1(back, DK3_LL_ERROR, 52); } break; case 38: { dk3app_log_i1(back, DK3_LL_ERROR, 131); } break; } dk3app_close(back); back = NULL; } else { #line 5616 "dk3app.ctr" dk3app_log_i3(back, DK3_LL_DEBUG, 19, 20, back->n_app); dk3app_log_i2( back, DK3_LL_DEBUG, 23, ((back->n_app) ? back->n_app: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 24, ((back->n_appgroup) ? back->n_appgroup: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 25, ((back->n_execfile) ? back->n_execfile: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 26, ((back->n_bindir) ? back->n_bindir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 27, ((back->n_etcdir) ? back->n_etcdir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 28, ((back->n_sharedir) ? back->n_sharedir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 29, ((back->n_vardir) ? back->n_vardir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 30, ((back->n_homedir) ? back->n_homedir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 31, ((back->n_tmpdir) ? back->n_tmpdir: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 32, ((back->n_logname) ? back->n_logname: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 132, ((back->n_hostname) ? back->n_hostname: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 33, ((back->n_logfilename) ? back->n_logfilename: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 34, ((back->n_language) ? back->n_language: ((back->msg) ? back->msg : dk3app_kw)[36]) ); dk3app_log_i2( back, DK3_LL_DEBUG, 35, ((back->n_region) ? back->n_region: ((back->msg) ? back->msg : dk3app_kw)[36]) ); } } else { if(tp == DK3_APP_TYPE_COMMAND) { /* ERROR: Not enough memory */ dk3sf_initialize_stderr(); dk3sf_fputs(dk3app_kw[9], stderr); dk3sf_fputs(dk3app_kw[0], stderr); fflush(stderr); } } #line 5683 "dk3app.ctr" return back; } dk3_app_t * dk3app_open_command(int argc, dkChar const * const * argv, dkChar const *gn) { dk3_app_t *back = NULL; dkChar wd[DK3_MAX_PATH]; /* Current working directory. */ if((argc) && (argv) && (gn)) { if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar), NULL)) { back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_COMMAND); } else { /* ERROR: Failed to find current working directory. */ if(!dk3app_first_silence_check(NULL, argc, argv)) { dk3sf_initialize_stderr(); dk3sf_fputs(dk3app_kw[3], stderr); dk3sf_fputs(dk3app_kw[11], stderr); dk3sf_fputs(dk3app_kw[8], stderr); dk3sf_fputs(dk3app_kw[53], stderr); dk3sf_fputs(dk3app_kw[0], stderr); fflush(stderr); } } } return back; } dk3_app_t * dk3app_open_gui(int argc, dkChar const * const * argv, dkChar const *gn) { dk3_app_t *back = NULL; dkChar wd[DK3_MAX_PATH]; /* Current working directory. */ if((argc) && (argv) && (gn)) { if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) { back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_GUI); } else { /* ERROR: Failed to find current working directory. */ } } return back; } dk3_app_t * dk3app_open_daemon( dkChar const *wd, int argc, dkChar const * const * argv, dkChar const *gn ) { dk3_app_t *back = NULL; if((wd) && (argc) && (argv) && (gn)) { back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_DAEMON); } return back; } dk3_app_t * dk3app_open_silent(int argc, dkChar const * const * argv, dkChar const *gn) { dk3_app_t *back = NULL; dkChar wd[DK3_MAX_PATH]; /* Current working directory. */ if((argc) && (argv) && (gn)) { if(dk3sf_getcwd_app(wd, DK3_SIZEOF(wd,dkChar),NULL)) { back = dk3app_open(wd, argc, argv, gn, DK3_APP_TYPE_SILENT); } else { /* ERROR: Failed to find current working directory. */ } } return back; } dkChar const * const * dk3app_get_argv(dk3_app_t const *app) { dkChar const * const *back = NULL; if(app) { back = (dkChar const * const *)(app->argv); } return back; } int dk3app_get_argc(dk3_app_t const *app) { int back = 0; if(app) { back = app->argc; } return back; } dkChar const * dk3app_get_appname(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_app; } #line 5789 "dk3app.ctr" return back; } dkChar const * dk3app_get_execfilename(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_execfile; } return back; } dkChar const * dk3app_get_bindir(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_bindir; } return back; } dkChar const * dk3app_get_etcdir(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_etcdir; } return back; } dkChar const * dk3app_get_sharedir(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_sharedir; } return back; } dkChar const * dk3app_get_vardir(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_vardir; } return back; } dkChar const * dk3app_get_logname(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_logname; } return back; } dkChar const * dk3app_get_hostname(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_hostname; } return back; } dkChar const * dk3app_get_homedir(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_homedir; } return back; } dkChar const * dk3app_get_appgroup(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_appgroup; } return back; } int dk3app_get_temp_file_name(dk3_app_t *app, dkChar *db, size_t sz) { int back = 0; char fn[16]; /* BUffer for sprintf(). */ dkChar fn2[16]; /* Short file name buffer. */ size_t s = 0; /* Buffer length needed. */ #line 5910 "dk3app.ctr" if((app) && (db) && (sz)) { if(app->n_tmpdir) { if ((DK3_APP_TYPE_DAEMON != app->app_type) && (0 == app->cr_tmp)) { dk3app_create_tmp_directory(app); app->cr_tmp = 1; } if(!(app->i_tmpcarry)) { sprintf(fn, "/%08lx.%03x", app->ul_tmpname, app->u_tmpsuffix); back = 1; if ((0UL == app->ul_tmpname) && (0 == app->u_tmpsuffix)) { if (DK3_APP_TYPE_DAEMON != app->app_type) { #line 5922 "dk3app.ctr" #line 5923 "dk3app.ctr" if (0 == dk3sf_mkdir_app(app->n_tmpdir, 0700, NULL)) { back = 0; } } } app->u_tmpsuffix += 1U; if(app->u_tmpsuffix >= 0x1000U) { app->u_tmpsuffix = 0U; #if VERSION_BEFORE_20150318 app->ul_tmpname += 1UL; if(app->ul_tmpname == 0UL) { app->i_tmpcarry = 1; back = 0; /* Too many temporary file names asked! */ dk3app_log_i1(app, DK3_LL_ERROR, 54); } #else /* 2015-03-18 We better check the variable before adding 1. Unsigned long may be larger than 32 bits. */ if (0xFFFFFFFFUL > app->ul_tmpname) { app->ul_tmpname += 1UL; } else { app->i_tmpcarry = 1; back = 0; /* Too many temporary file names asked! */ dk3app_log_i1(app, DK3_LL_ERROR, 54); } #endif } if(back) { back = 0; if(dk3str_cnv_c8_to_str_app(fn2, 15, fn, app)) { s = dk3str_len(app->n_tmpdir) + dk3str_len(fn2); if(s < sz) { dk3str_cpy_not_overlapped(db, app->n_tmpdir); dk3str_cat(db, fn2); dk3str_correct_filename(db); back = 1; } else { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } } else { /* Not directory for temporary files available! */ dk3app_log_i1(app, DK3_LL_ERROR, 55); } } #line 5974 "dk3app.ctr" return back; } dkChar const * dk3app_get_language(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_language; } return back; } dkChar const * dk3app_get_region(dk3_app_t const *app) { dkChar const *back = NULL; if(app) { back = app->n_region; } return back; } int dk3app_get_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_encoding; } return back; } int dk3app_get_output_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_output_encoding; } return back; } int dk3app_get_input_stdin_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_stdin_input_encoding; } return back; } int dk3app_get_input_file_encoding(dk3_app_t const *app) { int back = 0; if(app) { back = app->i_file_input_encoding; } return back; } int dk3app_set_pref(dk3_app_t *app, dkChar const *k, dkChar const *v) { int back = 0; if((app) && (k) && (v)) { if(!(app->s_selfprefs)) { app->s_selfprefs = dk3sto_open_app(app); if(app->s_selfprefs) { dk3sto_set_comp(app->s_selfprefs, dk3app_compare_pref, 0); } } if(!(app->i_selfprefs)) { if(app->s_selfprefs) { app->i_selfprefs = dk3sto_it_open(app->s_selfprefs); } } if((app->s_selfprefs) && (app->i_selfprefs)) { back = dk3app_add_pref(app, app->s_selfprefs, app->i_selfprefs, k, v); app->f_prefschanged = 1; } if(!back) { /* Failed to save preference value! */ dk3app_log_i5(app, DK3_LL_ERROR, 56, 57, 58, k, v); } } return back; } int dk3app_get_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s) { int back = 0; #line 6074 "dk3app.ctr" if((app) && (k) && (d) && (s)) { #line 6076 "dk3app.ctr" back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s); if(back == 0) { back = dk3app_sto_pref(app, app->i_cmdprefs, k, d, s); if(back == 0) { back = dk3app_sto_pref(app, app->i_varprefs, k, d, s); if(back == 0) { back = dk3app_sto_pref(app, app->i_constprefs, k, d, s); if(back == 0) { back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s); } } } } #line 6090 "dk3app.ctr" #line 6091 "dk3app.ctr" #line 6092 "dk3app.ctr" } #line 6093 "dk3app.ctr" return back; } int dk3app_get_sys_pref(dk3_app_t *app, dkChar const *k, dkChar *d, size_t s) { int back = 0; if((app) && (k) && (d) && (s)) { back = dk3app_sto_pref(app, app->i_selfprefs, k, d, s); if(back == 0) { back = dk3app_sto_pref(app, app->i_sysprefs, k, d, s); } } return back; } /** Check whether the use of system configuration files is allowed for a file name. @param app Application structure. @param fn Short file name. @return 1 for system config files allowed, 0 for user files only. */ static int dk3app_allow_system_config_files(dk3_app_t *app, dkChar const *fn) { int back = 1; dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ dkChar il[1024 + DK3_MAX_PATH]; /* Input line buffer. */ char bombuf[4]; /* Buffer to skip BOM. */ dkChar *p1 = NULL; /* Key (entry name). */ dkChar *p2 = NULL; /* Value. */ FILE *fipo = NULL; /* Input file. */ int ie = DK3_FILE_ENCODING_ASCII; /* Input encoding for file. */ int cc = 1; /* Flag: Can continue. */ size_t sz = 0; /* Buffer size needed. */ size_t skb; /* Number of bytes to skip. */ if(app->n_homedir) { sz = dk3str_len(app->n_homedir); sz += (2 * dk3str_len(dk3app_no_loc[20])); sz += dk3str_len(dk3app_no_loc[18]); sz += dk3str_len(dk3app_no_loc[34]); if(sz < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, app->n_homedir); dk3str_cat(fnb, dk3app_no_loc[20]); dk3str_cat(fnb, dk3app_no_loc[18]); dk3str_cat(fnb, dk3app_no_loc[20]); dk3str_cat(fnb, dk3app_no_loc[34]); skb = 0; ie = dk3sf_inspect_bom_skip_app(fnb, DK3_FILE_ENCODING_ASCII, &skb, NULL); fipo = dk3sf_fopen_app(fnb, dk3app_no_loc[22], NULL); /* READ */ if(fipo) { (void)dk3sf_apply_bom_to_file_app(fipo, ie, NULL); cc = 1; if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, NULL); } while(cc) { if(dk3sf_fgets(il, DK3_SIZEOF(il,dkChar), fipo)) { p1 = dk3str_start(il, NULL); if(p1) { if(*p1 != dkT('#')) { p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_chomp(p2, NULL); dk3str_normalize(p1, NULL, dkT('-')); switch(dk3str_array_index(dk3app_conf_file, p1, 0)) { case 0: { /* use system config files */ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) { back = 1; cc = 0; } else { if(dk3str_cmp(p2, fn) == 0) { back = 1; cc = 0; } } } break; case 1: { /* ignore system config files */ if(dk3str_cmp(p2, dk3app_no_loc[33]) == 0) { back = 0; cc = 0; } else { if(dk3str_cmp(p2, fn) == 0) { back = 0; cc = 0; } } } break; } } } } } } else { cc = 0;} } fclose(fipo); } } else { /* ERROR: Home directory name too long! */ dk3app_log_i1(app, DK3_LL_ERROR, 194); } } return back; } /** Find configuration files for a given name. @param app Application structure. @param fn File name. @param res Flag: Reverse search order. @param exclu Flag: Exclude user files. @return Pointer to search result collection on success, NULL on error. */ static dk3_search_t * dk3app_my_find_config_file(dk3_app_t *app, dkChar const *fn, int res, int exclu) { dk3_search_t *back = NULL; unsigned long items_found = 0; /* Number of items found. */ int error_occured = 0; /* Flag: Error occured. */ int i = 0; /* Current pass number. */ int r = 0; /* Result from check for conf file. */ int max = 0; /* Maximum pass number. */ int min = 0; /* Minimum pass number. */ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */ if((app) && (fn)) { back = dk3search_open_app(res, app); if(back) { min = 0; max = 16; if(app->app_type == DK3_APP_TYPE_DAEMON) { max = 6; } else { if(exclu) { max = 12; } else { if(!dk3app_allow_system_config_files(app, fn)) { min = 12; /* DEBUG: System config files skipped by user. */ dk3app_log_i1(app, DK3_LL_DEBUG, 195); } } } for(i = min; i < max; i++) { r = dk3app_check_config_file(app, fn, buffer, DK3_MAX_PATH, i, 1); if(r) { if(dk3search_add(back, buffer)) { items_found++; } else { error_occured = 1; } } } if(error_occured) { dk3search_close(back); back = NULL; } else { if(items_found == 0UL) { dk3search_close(back); back = NULL; } } } } return back; } dk3_search_t * dk3app_find_config_file(dk3_app_t *app, dkChar const *fn, int exclu) { dk3_search_t *back = NULL; if((app) && (fn)) { back = dk3app_my_find_config_file(app, fn, 0, exclu); } return back; } dk3_search_t * dk3app_find_config_file_revers(dk3_app_t *app, dkChar const *fn, int exclu) { dk3_search_t *back = NULL; if((app) && (fn)) { back = dk3app_my_find_config_file(app, fn, 1, exclu); } return back; } int dk3app_find_data_file(dk3_app_t *app, dkChar const *fn, dkChar *db, size_t sz) { int back = 0; if((app) && (fn) && (db) && (sz)) { back = dk3app_my_find_data_file(app, fn, db, sz, 1); } return back; } void dk3app_unconfigure(dk3_app_t *app) { if(app) { app->f_unconfigure = 1; } } dkChar const * const * dk3app_messages(dk3_app_t *app, dkChar const *fn, dkChar const * const *dv) { dkChar const * const *back; #line 6313 "dk3app.ctr" back = dk3app_my_messages(app, fn, dv, 0); #line 6315 "dk3app.ctr" return back; } void dk3app_help(dk3_app_t *app, dkChar const *fn, dkChar const * const *dt) { int had_success = 0; /* Flag: Success. */ dkChar buffer[DK3_MAX_PATH]; /* File name buffer. */ char lb[1024]; /* Input line buffer. */ dkChar db[1024]; /* Output line buffer. */ FILE *fipo = NULL; /* Input file. */ dkChar const * const *ptr = NULL; /* Help text line. */ #line 6330 "dk3app.ctr" if((app) && (fn) && (dt)) { dk3sf_initialize_stdout(); if(dk3app_my_find_data_file(app, fn, buffer, DK3_SIZEOF(buffer,dkChar), 0)) { fipo = dk3sf_fopen_app(buffer, dk3app_no_loc[22], app); /* UTF-8 */ if(fipo) { had_success = 1; while(fgets(lb, sizeof(lb), fipo)) { #line 6338 "dk3app.ctr" #if DK3_CHAR_SIZE == 2 if(dk3str_cnv_c8u_to_c16_app(db, DK3_SIZEOF(db,dkChar), lb, app)) { dk3sf_fputs(db, stdout); } #else switch(app->i_encoding) { case DK3_ENCODING_PLAIN: { if(dk3str_cnv_c8u_to_c8p_app(db, DK3_SIZEOF(db,dkChar), lb, app)) { fputs(db, stdout); } } break; default: { fputs(lb, stdout); } break; } #endif } fclose(fipo); } } if(!had_success) { ptr = dt; while(*ptr) { dk3sf_fputs(*(ptr++), stdout); dk3sf_fputc(dkT('\n'), stdout); } } } #line 6367 "dk3app.ctr" } int dk3app_get_stderr_log_level(dk3_app_t const *app) { int back = DK3_LL_ERROR; if(app) { back = app->ll_stderr; } return back; } void dk3app_set_stderr_log_level(dk3_app_t *app, int ll) { if(app) { app->ll_stderr = ll; } } void dk3app_log_write_error(dk3_app_t *app, int ll, size_t wished, size_t written) { dkChar b1[128]; /* Number of bytes wished to write. */ dkChar b2[128]; /* Number of bytes really written. */ #if VERSION_BEFORE_20140716 dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished)); dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written)); dk3app_log_i5(app, ll, 170, 171, 172, b2, b1); #else if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) { if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) { dk3app_log_i5(app, ll, 170, 171, 172, b2, b1); } } #endif } void dk3app_log_fwrite_error(dk3_app_t *app, int ll, size_t wished, size_t written) { dkChar b1[128]; /* Number of bytes wished to write. */ dkChar b2[128]; /* Number of bytes really written. */ #if VERSION_BEFORE_20140716 dk3sf_sprintf3(b1,dk3app_no_loc[35],((unsigned long)wished)); dk3sf_sprintf3(b2,dk3app_no_loc[35],((unsigned long)written)); dk3app_log_i5(app, ll, 174, 175, 176, b2, b1); #else if (dk3ma_um_to_string(b1, DK3_SIZEOF(b1,dkChar), (dk3_um_t)wished)) { if (dk3ma_um_to_string(b2, DK3_SIZEOF(b2,dkChar), (dk3_um_t)written)) { dk3app_log_i5(app, ll, 174, 175, 176, b2, b1); } } #endif } dkChar const * dk3app_localized(dk3_app_t const *app, size_t num) { dkChar const *back = NULL; if(app) { if(app->msg) { back = (app->msg)[num]; } else { back = dk3app_kw[num]; } } return back; } dkChar const * dk3app_not_localized(size_t num) { dkChar const *back = NULL; back = dk3app_no_loc[num]; return back; } int dk3app_get_pref_bool(dk3_app_t *app, dkChar const *name, int dv) { int back; dkChar buffer[256]; /* Buffer for preference value. */ dkChar *p1; /* Start of text. */ back = dv; if(app) { if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) { p1 = dk3str_start(buffer, NULL); if(p1) { dk3str_chomp(p1, NULL); if(dk3str_is_bool(p1)) { back = ((dk3str_is_on(p1)) ? 1 : 0); } } } } return back; } int dk3app_get_pref_int(dk3_app_t *app, dkChar const * name, int dv) { int back; int x; dkChar buffer[256]; dkChar *p1; #line 6491 "dk3app.ctr" back = dv; if(app) { if(dk3app_get_pref(app, name, buffer, DK3_SIZEOF(buffer,dkChar))) { p1 = dk3str_start(buffer, NULL); if(p1) { #if VERSION_BEFORE_20140716 if(dk3sf_sscanf3(p1, dkT("%d"), &x) == 1) #else if (0 != dk3ma_i_from_string(&x, p1, NULL)) #endif { back = x; } } } } #line 6507 "dk3app.ctr" return back; } #if 0 int dk3app_get_allowed_prng_types(dk3_app_t *app, dkChar const *il) { int back = 0; dkChar buffer[256]; dkChar *p1 = NULL; dkChar *p2 = NULL; int i = 0; if((app) && (il)) { if(dk3str_len(il) < DK3_SIZEOF(buffer,dkChar)) { dk3str_cpy_not_overlapped(buffer, il); p1 = dk3str_start(buffer, NULL); while(p1) { p2 = dk3str_chr(p1, dkT(',')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); } i = dk3str_array_index(dk3app_prng_type_names, p1, 0); switch(i) { case 0: { #if DK3_HAVE_OPENSSL_RAND_H back |= DK3_PRNG_OPENSSL; #else /* ERROR: Openssl PRNG not available! */ dk3app_log_i1(app, DK3_LL_ERROR, 192); #endif } break; case 1: { #if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM back |= DK3_PRNG_STATE; #else /* ERROR: initstate()/setstate()/random() not available. */ dk3app_log_i1(app, DK3_LL_ERROR, 191); #endif } break; case 2: { #if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48 back |= DK3_PRNG_RAND48; #else /* ERROR: lrand48()/lrand48() not available. */ dk3app_log_i1(app, DK3_LL_ERROR, 190); #endif } break; case 3: { #if DK3_HAVE_RAND && DK3_HAVE_SRAND back |= DK3_PRNG_SIMPLE; #else /* ERROR: srand()/rand() not available! */ dk3app_log_i1(app, DK3_LL_ERROR, 189); #endif } break; default: { /* Unknown PRNG type name! */ dk3app_log_i3(app, DK3_LL_ERROR, 187, 188, p1); } break; } p1 = p2; } } else { /* ERROR: Line too long for buffer! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } return back; } /** Find allowed PRNG types using preferences. @param app Application structure. @return Or-combination of DK3_PRNG_xxx. */ static int dk3app_rand_find_allowed_types(dk3_app_t *app) { int back = DK3_PRNG_ALL; dkChar buffer[256]; #line 6594 "dk3app.ctr" if(dk3app_get_pref(app,dk3app_no_loc[37],buffer,DK3_SIZEOF(buffer,dkChar))) { #line 6596 "dk3app.ctr" back = dk3app_get_allowed_prng_types(app, buffer); } #line 6599 "dk3app.ctr" return back; } /** Get bytes to seed random number generator. @param app Application structure. @param dp Destination buffer pointer. @param sz Number of bytes required. @param fn File name for seed file. @return Number of bytes found. */ static size_t dk3app_read_bytes_from_file( dk3_app_t *app, void *dp, size_t sz, dkChar const *fn ) { size_t back = 0; FILE *fipo; fipo = dk3sf_fopen_app(fn, dk3app_no_loc[36], app); if(fipo) { back = dk3sf_fread_app(dp, 1, sz, fipo, app); fclose(fipo); } return back; } /** Get bytes to seed random number generator. @param app Application structure. @param dp Destination buffer pointer. @param sz Number of bytes required. @param fn File name for seed file. @return Number of bytes found. */ static size_t dk3app_get_seed_from_source(dk3_app_t *app,void *dp,size_t sz,dkChar const *fn) { size_t back = 0; dk3_stat_t stb; int can_use_file = 1; int mode_denied; #line 6649 "dk3app.ctr" /* DEBUG: Attempting to get seed data from ... */ dk3app_log_i3(app, DK3_LL_DEBUG, 196, 197, fn); if(dk3sf_stat_app(&stb, fn, NULL)) { #line 6652 "dk3app.ctr" switch((stb.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_DIRECTORY: { /* Ignore it. */ } break; case DK3_FT_REGULAR: { /* Security checks before using the file. */ mode_denied = DK3_FPERM_G_READ | DK3_FPERM_G_WRITE | DK3_FPERM_O_READ | DK3_FPERM_O_WRITE; if((stb.ft) & DK3_FT_SYMLINK) { if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) { can_use_file = 0; /* WARNING: Symlink owner is not file owner. */ dk3app_log_i3(app, DK3_LL_ERROR, 185, 186, fn); } if((stb.perm) & mode_denied) { can_use_file = 0; /* WARNING: File not used (permissions). */ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn); } else { if((stb.lperm) & mode_denied) { can_use_file = 0; /* WARNING: File not used (permissions). */ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn); } } } else { if((stb.perm) & mode_denied) { can_use_file = 0; /* WARNING: File not used (permissions). */ dk3app_log_i3(app, DK3_LL_ERROR, 183, 184, fn); } } if(can_use_file) { back = dk3app_read_bytes_from_file(app, dp, sz, fn); } } break; default: { /* Use file. */ back = dk3app_read_bytes_from_file(app, dp, sz, fn); } break; } } #line 6696 "dk3app.ctr" /* DEBUG: Seed data: ... bytes. */ { char b1[64]; dkChar b2[64]; sprintf(b1, "%lu", (unsigned long)back); if(dk3str_cnv_c8_to_str_app(b2, DK3_SIZEOF(b2,dkChar), b1, app)) { dk3app_log_i3(app, DK3_LL_DEBUG, 198, 199, b2); } } return back; } /** Get bytes to seed random number generator. @param app Application structure. @param dp Destination buffer pointer. @param sz Number of bytes required. @param fn File name for seed file. @param passno Pass number (only 0 uses files). @return Number of bytes found. */ static size_t dk3app_get_seed_bytes( dk3_app_t *app, void *dp, size_t sz, dkChar const *fn, int passno ) { size_t back = 0; dkChar const *p1; dkChar const *p2; dkChar const *p3; dkChar const *p4; dkChar const *p5; dkChar *p6; size_t s; dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ if((app) && (dp) && (sz)) { /* $HOME/.rnd-xxx-application */ if(passno == 0) { if(dk3app_get_pref_bool(app, dk3app_no_loc[46], 1)) { p1 = dk3app_get_homedir(app); p2 = dk3app_no_loc[20]; p3 = fn; p4 = dk3app_no_loc[5]; p5 = dk3app_get_appname(app); if((p1) && (p2) && (p3) && (p4) && (p5)) { s = dk3str_len(p1); s += dk3str_len(p2); s += dk3str_len(p3); s += dk3str_len(p4); s += dk3str_len(p5); if(s < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, p1); dk3str_cat(fnb, p2); dk3str_cat(fnb, p3); dk3str_cat(fnb, p4); dk3str_cat(fnb, p5); back = dk3app_get_seed_from_source(app, dp, sz, fnb); } } } } /* EGD socket from environment. */ if(back == 0) { p1 = dk3sf_getenv(dk3app_no_loc[43]); if(p1) { back = dk3app_get_seed_from_source(app, dp, sz, p1); } } /* EGD socket from preferences. */ if(back == 0) { if(dk3app_get_pref(app, dk3app_no_loc[42], fnb, DK3_SIZEOF(fnb,dkChar))) { p6 = dk3str_start(fnb, NULL); if(p6) { dk3str_chomp(p6, NULL); back = dk3app_get_seed_from_source(app, dp, sz, p6); } } } #if !DK3_ON_WINDOWS /* /dev/urandom */ if(back == 0) { back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[44]); } /* /dev/random */ if(back == 0) { back = dk3app_get_seed_from_source(app, dp, sz, dk3app_no_loc[45]); } #endif } return back; } #if DK3_HAVE_OPENSSL_H /** Initialize OpenSSL PRNG. @param app Application structure. @return 1 on success, 0 on error. */ static int dk3app_init_prng_openssl(dk3_app_t *app) { int back = 0; int cc = 0; int passno = 0; size_t sz; char seedval[DK3_SEED_OPENSSL_BYTES]; do { cc = 0; sz = dk3app_get_seed_bytes(app,seedval,sizeof(seedval),dk3app_no_loc[41],passno); if(sz > 0) { cc = 1; RAND_seed(seedval, sz); if(RAND_status() == 1) { cc = 0; back = 1; } #if DK3_ON_WINDOWS if(back == 0) { RAND_screen(); if(RAND_status() == 1) { cc = 0; back = 1; } } #endif passno++; } } while(cc); if(!back) { /* Warning: Failed to seed OpenSSL PRNG! */ dk3app_log_i1(app, DK3_LL_ERROR, 182); } return back; } #endif #if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM /** Initialize state PRNG. @param app Application structure. @return 1 on success, 0 on error. */ static int dk3app_init_prng_state(dk3_app_t *app) { int back = 0; unsigned int seedval = 0; if(dk3app_get_seed_bytes( app, (void *)(&seedval), sizeof(unsigned int), dk3app_no_loc[40], 0 ) ) { srandom(seedval); back = 1; } if(!back) { /* Warning: Failed to seed random() PRNG! */ dk3app_log_i1(app, DK3_LL_ERROR, 181); } return back; } #endif #if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48 /** Initialize lrand48() PRNG. @param app Application structure. @return 1 on success, 0 on error. */ static int dk3app_init_prng_rand48(dk3_app_t *app) { int back = 0; long int seedval = 0L; if(dk3app_get_seed_bytes( app, (void *)(&seedval), sizeof(long int), dk3app_no_loc[39], 0 ) ) { srand48(seedval); back = 1; } if(!back) { /*Warning: Failed to seed lrand48() PRNG! */ dk3app_log_i1(app, DK3_LL_ERROR, 180); } return back; } #endif #if DK3_HAVE_RAND && DK3_HAVE_SRAND /** Initialize simple rand() PRNG. @param app Application structure. @return 1 on success, 0 on error. */ static int dk3app_init_prng_simple(dk3_app_t *app) { int back = 0; unsigned int ui; if( dk3app_get_seed_bytes( app, (void *)(&ui), sizeof(unsigned int), dk3app_no_loc[38], 0 ) ) { srand(ui); back = 1; } if(!back) { /* Warning: Failed to seed simple PRNG! */ dk3app_log_i1(app, DK3_LL_ERROR, 179); } return back; } #endif /** Attempt to initialize a PRNG. @param app Application structure. @param il Input line listing allowed PRNGs comma-separated. @return 1 on success (at least one PRNG usable), 0 on error. */ int dk3app_rand_init(dk3_app_t *app, dkChar const *il) { int back = 0; int allowed_types; if(app) { if(app->f_rand_initialized) { back = app->f_rand_success; } else { app->f_rand_initialized = 1; if(il) { allowed_types = dk3app_get_allowed_prng_types(app, il); } else { allowed_types = dk3app_rand_find_allowed_types(app); } if(!back) { if(allowed_types & DK3_PRNG_OPENSSL) { #if DK3_HAVE_OPENSSL_H back = dk3app_init_prng_openssl(app); if(back) { app->rand_type = DK3_PRNG_OPENSSL; } #endif } } if(!back) { if(allowed_types & DK3_PRNG_STATE) { #if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM back = dk3app_init_prng_state(app); if(back) { app->rand_type = DK3_PRNG_STATE; } #endif } } if(!back) { if(allowed_types & DK3_PRNG_RAND48) { #if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48 back = dk3app_init_prng_rand48(app); if(back) { app->rand_type = DK3_PRNG_RAND48; } #endif } } if(!back) { if(allowed_types & DK3_PRNG_SIMPLE) { #if DK3_HAVE_RAND && DK3_HAVE_SRAND back = dk3app_init_prng_simple(app); if(back) { app->rand_type = DK3_PRNG_SIMPLE; } #endif } } if(back) { app->f_rand_success = 1; } } } if(!back) { /* ERROR: No PRNG usable! */ dk3app_log_i1(app, DK3_LL_ERROR, 178); } return back; } /** Get random bytes. @param app Application structure. @param db Destination buffer. @param sz Size of \a db (number of bytes). @param f_crypto Flag: For cryptographic purposes. @return Number of bytes written to \a db. */ static size_t dk3app_rand_bytes_internal(dk3_app_t *app, void *db, size_t sz, int f_crypto) { size_t back = 0; unsigned char *ucptr = NULL; size_t i = 0; unsigned u = 0; if((app) && (db) && (sz)) { ucptr = (unsigned char *)db; if(!(app->f_rand_initialized)) { dk3app_rand_init(app, NULL); } if(app->f_rand_success) { switch(app->rand_type) { case DK3_PRNG_OPENSSL: { #if DK3_HAVE_OPENSSL_RAND_H if(f_crypto) { if(RAND_bytes(ucptr, (int)sz) == 1) { back = sz; } } else { if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) { back = sz; } } #else /* BUG: Not available! */ #endif } break; case DK3_PRNG_STATE: { #if DK3_HAVE_INITSTATE && DK3_HAVE_SETSTATE && DK3_HAVE_RANDOM long lval; size_t position; lval = random() >> 8; position = 0; for(i = 0; i < sz; i++) { *(ucptr++) = (unsigned char)(lval & 0x000000FFL); position++; lval = lval >> 8; if(position >= (sizeof(long) - 1)) { lval = random() >> 8; position = 0; } } back = sz; #else /* BUG: Not available! */ #endif } break; case DK3_PRNG_RAND48: { #if DK3_HAVE_NRAND48 && DK3_HAVE_LRAND48 long lval; size_t position; lval = lrand48() >> 8; position = 0; for(i = 0; i < sz; i++) { *(ucptr++) = (unsigned char)(lval & 0x000000FFL); position++; lval = lval >> 8; if(position >= (sizeof(long) - 1)) { lval = lrand48() >> 8; position = 0; } } back = sz; #else /* BUG: Not available! */ #endif } break; default: { #if DK3_HAVE_RAND && DK3_HAVE_SRAND for(i = 0; i < sz; i++) { u = rand(); #if DK3_SIZEOF_INT > 2 #if DK3_SIZEOF_INT > 4 u = u >> 28; #else u = u >> 12; #endif #else u = u >> 4; #endif u &= 0x00FFU; *(ucptr++) = (unsigned char)u; } back = sz; #else /* BUG: Not available! */ #endif } break; } } } if(back < sz) { /* ERROR: Failed to obtain enough random bytes! */ dk3app_log_i1(app, DK3_LL_ERROR, 177); } return back; } size_t dk3app_rand_bytes(dk3_app_t *app, void *db, size_t sz) { size_t back; back = dk3app_rand_bytes_internal(app, db, sz, 1); return back; } size_t dk3app_rand_bytes_non_crypto(dk3_app_t *app, void *db, size_t sz) { size_t back; back = dk3app_rand_bytes_internal(app, db, sz, 0); return back; } #endif int dk3app_process_stdin_lines( dk3_app_t *app, void *obj, dk3_line_handler_t *hf, dkChar *buffer, size_t szbuffer, int de ) { int back = 0; int must_run_directly = 0; int ie; FILE *fipo; dkChar tfn[DK3_MAX_PATH]; char b[4096]; size_t sz; #if DK3_ON_WINDOWS int oldmode; #endif if((app) && (hf) && (buffer) && (szbuffer)) { ie = de; if(ie < 0) { ie = app->i_stdin_input_encoding; } if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) { fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app); if(fipo) { #if DK3_ON_WINDOWS oldmode = _setmode(_fileno(stdin), _O_BINARY); #endif while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) { dk3sf_fwrite_app(b, 1, sz, fipo, app); } fclose(fipo); #if DK3_ON_WINDOWS _setmode(_fileno(stdin), oldmode); #endif /* 2015-08-21 Using ie instead of de. */ back = dk3stream_process_filename_lines_app( obj, hf, tfn, buffer, szbuffer, dk3app_get_encoding(app), ie, app ); dk3sf_remove_file_app(tfn, app); } else { must_run_directly = 1; } } else { must_run_directly = 1; } if(must_run_directly) { #if DK3_ON_WINDOWS oldmode = _setmode(_fileno(stdin), _O_BINARY); #endif back = dk3stream_process_file_lines_app( obj, hf, stdin, NULL, buffer, szbuffer, dk3app_get_encoding(app), de, app ); #if DK3_ON_WINDOWS _setmode(_fileno(stdin), oldmode); #endif } } return back; } int dk3app_process_stdin_chars( dk3_app_t *app, void *obj, dk3_char_handler_t *hf, int de ) { int back = 0; int must_run_directly = 0; int ie; dkChar tfn[DK3_MAX_PATH]; char b[4096]; FILE *fipo; size_t sz; #if DK3_ON_WINDOWS int oldmode; #endif #line 7230 "dk3app.ctr" if((app) && (hf)) { #line 7231 "dk3app.ctr" ie = de; if(ie < 0) { ie = app->i_stdin_input_encoding; } #line 7235 "dk3app.ctr" if(dk3app_get_temp_file_name(app, tfn, DK3_SIZEOF(tfn,dkChar))) { fipo = dk3sf_fopen_app(tfn, dk3app_no_loc[53], app); if(fipo) { #if DK3_ON_WINDOWS oldmode = _setmode(_fileno(stdin), _O_BINARY); #endif while((sz = dk3sf_fread_app(b, 1, sizeof(b), stdin, app)) > 0) { dk3sf_fwrite_app(b, 1, sz, fipo, app); } fclose(fipo); #if DK3_ON_WINDOWS _setmode(_fileno(stdin), oldmode); #endif back = dk3stream_process_filename_chars_app(obj, hf, tfn, ie, app); dk3sf_remove_file_app(tfn, app); } else { must_run_directly = 1; } } else { must_run_directly = 1; } if(must_run_directly) { #if DK3_ON_WINDOWS oldmode = _setmode(_fileno(stdin), _O_BINARY); #endif back = dk3stream_process_file_chars_app(obj, hf, stdin, NULL, ie, app); #if DK3_ON_WINDOWS _setmode(_fileno(stdin), oldmode); #endif } } #line 7266 "dk3app.ctr" return back; } #if !DK3_ON_WINDOWS #if DK3_HAVE_SETUID && DK3_HAVE_SETGID && DK3_HAVE_CHOWN #if DK3_CHAR_SIZE == 1 /** Change owner for one file if the file exists. @param app Application structure. @param ul1 File name. @param ul2 File name suffix. @param uid New user ID for file ownership. @param gid New group ID for file ownership. @return 1 on success (owner modified or file does not exist). */ static int dk3app_change_owner_for_file( dk3_app_t *app, unsigned long ul1, unsigned ul2, uid_t uid, gid_t gid ) { dkChar fnb[DK3_MAX_PATH]; /* Full name buffer. */ dkChar smb[32]; /* Small buffer. */ char tmb[32]; dk3_stat_t stb; int back = 1; #line 7298 "dk3app.ctr" sprintf(tmb, "/%08lx.%03x", ul1, ul2); if(dk3str_c8_to_str_simple_app(smb,DK3_SIZEOF(smb,dkChar),tmb,app)) { if(dk3str_len(app->n_tmpdir) < DK3_SIZEOF(fnb,dkChar)) { #line 7301 "dk3app.ctr" dk3str_cpy_not_overlapped(fnb, app->n_tmpdir); if((dk3str_len(fnb) + dk3str_len(smb)) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cat(fnb, smb); dk3str_correct_filename(fnb); if(dk3sf_stat_app(&stb, fnb, NULL)) { #line 7306 "dk3app.ctr" if(0 != chown(fnb, uid, gid)) { #line 7307 "dk3app.ctr" back = 0; } else { #line 7309 "dk3app.ctr" } } else { #line 7311 "dk3app.ctr" /* If there is no such file, there is no need to change owner. */ } } else { #line 7314 "dk3app.ctr" back = 0; } } else { #line 7317 "dk3app.ctr" back = 0; } } else { #line 7320 "dk3app.ctr" } #line 7322 "dk3app.ctr" return back; } int dk3app_change_user(dk3_app_t *app, uid_t uid, gid_t gid) { FILE *fipo; unsigned long ul1; unsigned ul2; int back = 1; #line 7333 "dk3app.ctr" if((app) && ((uid) || (gid))) { #line 7334 "dk3app.ctr" if(app->n_logfilename) { #line 7335 "dk3app.ctr" if (0 == app->cr_log) { dk3app_create_log_directory(app); app->cr_log = 1; } fipo = dk3sf_fopen_app(app->n_logfilename, dkT("a"), app); if(fipo) { fclose(fipo); } if(0 != chown(app->n_logfilename, uid, gid)) { #line 7344 "dk3app.ctr" back = 0; } else { #line 7346 "dk3app.ctr" } } else { #line 7348 "dk3app.ctr" } if(app->n_tmpdir) { #line 7350 "dk3app.ctr" if(0 != chown(app->n_tmpdir, uid, gid)) { back = 0; } if(app->i_tmpcarry) { #line 7354 "dk3app.ctr" for(ul1 = 0UL; ul1 < 0xFFFFFFFFUL; ul1++) { for(ul2 = 0U; ul2 < 0x00001000U; ul2++) { if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) { back = 0; #line 7358 "dk3app.ctr" } } } for(ul2 = 0U; ul2 < 0x00001000U; ul2++) { if(!dk3app_change_owner_for_file(app, 0xFFFFFFFFUL, ul2, uid, gid)) { back = 0; #line 7364 "dk3app.ctr" } } } else { for(ul1 = 0UL; ul1 < app->ul_tmpname; ul1++) { for(ul2 = 0U; ul2 < 0x00001000U; ul2++) { if(!dk3app_change_owner_for_file(app, ul1, ul2, uid, gid)) { back = 0; #line 7371 "dk3app.ctr" } } } for(ul2 = 0U; ul2 < app->u_tmpsuffix; ul2++) { if(!dk3app_change_owner_for_file(app,app->ul_tmpname,ul2,uid,gid)) { back = 0; #line 7377 "dk3app.ctr" } } } } else { #line 7381 "dk3app.ctr" } } else { #line 7383 "dk3app.ctr" } #line 7384 "dk3app.ctr" return back; } #endif #endif #endif int dk3app_get_dir_from_pref( dk3_app_t *app, dkChar const *pn, dkChar *buf, size_t bs, int ch ) { int back = 0; if((app) && (pn) && (buf) && (bs)) { if(dk3app_get_pref(app, pn, buf, bs)) { if(ch) { if(dk3sf_is_dir_app(buf, NULL)) { back = 1; } else { /* ERROR: Directory does not exist! */ dk3app_log_i3(app, DK3_LL_ERROR, 369, 370, pn); } } else { back = 1; } } } return back; } /* vim: set ai sw=2 : */