/* Copyright (C) 2011-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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 */ /** @file dk3app.c The dk3app module. */ #line 701 "dk3app.ctr" #include "dk3all.h" #include "dk3unused.h" #if DK3_HAVE_OPENSSL_RAND_H #include #endif #line 713 "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 836 "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 2447 "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 2479 "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 2498 "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 2508 "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 DK3_ARG_UNUSED(crit) ) { int back = 0; dk3app_pref_t const *pl = NULL; /* Left object. */ dk3app_pref_t const *pr = NULL; /* Right object. */ DK3_UNUSED_ARG(crit) 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 2558 "dk3app.ctr" ptr = ta; for(i = 0; i < n; i++) { #line 2560 "dk3app.ctr" if(*ptr) { #line 2561 "dk3app.ctr" dk3_delete(*ptr); } *(ptr++) = NULL; } dk3_delete(ta); #line 2566 "dk3app.ctr" } /** Delete message catalog entry. @param mc Message catalog entry to delete. */ static void dk3app_mc_delete(dk3app_mc_t *mc) { #line 2578 "dk3app.ctr" if(mc) { #line 2579 "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 2587 "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 2607 "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 2617 "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 DK3_ARG_UNUSED(cr) ) { int back = 0; dk3app_mc_t const *pl = NULL; /* Left message catalog. */ dk3app_mc_t const *pr = NULL; /* Right message catalog. */ DK3_UNUSED_ARG(cr) 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 2679 "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 2711 "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 2784 "dk3app.ctr" if(app->n_logfilename) { #line 2785 "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 2806 "dk3app.ctr" #if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1) /* Switch to 16 bit characters. */ #if defined(_MSC_VER) (void)_setmode(_fileno(fipo), _O_U16TEXT); #endif /* 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 2822 "dk3app.ctr" } } #line 2824 "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 2849 "dk3app.ctr" if((app) && (msg) && (nmsg)) { #line 2850 "dk3app.ctr" if(app->f_readytolog) { #line 2851 "dk3app.ctr" if(ll < app->ll_highest) { #line 2852 "dk3app.ctr" app->ll_highest = ll; } switch(app->app_type) { case DK3_APP_TYPE_COMMAND: { #line 2856 "dk3app.ctr" if(app->ll_file >= ll) { #line 2857 "dk3app.ctr" dk3app_log_file(app, ll, msg, nmsg); } else { #line 2859 "dk3app.ctr" } if(app->ll_stderr >= ll) { #line 2861 "dk3app.ctr" dk3sf_initialize_stderr(); dk3app_log_to_file( app, ll, msg, nmsg, stderr, &(app->t_last_log_stderr) ); } else { #line 2866 "dk3app.ctr" } } break; case DK3_APP_TYPE_GUI: case DK3_APP_TYPE_DAEMON: #line 2870 "dk3app.ctr" { #line 2871 "dk3app.ctr" if(app->ll_file >= ll) { #line 2872 "dk3app.ctr" dk3app_log_file(app, ll, msg, nmsg); } } break; } } else { #line 2877 "dk3app.ctr" } } else { #line 2879 "dk3app.ctr" } #line 2880 "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 2889 "dk3app.ctr" if((app) && (msg)) { m[0] = msg[i1]; m[1] = NULL; dk3app_log_msg(app, ll, (dkChar const * const *)m, 1); } #line 2894 "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 2922 "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 2929 "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 2941 "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 2950 "dk3app.ctr" } void dk3app_log_i1(dk3_app_t *app, int ll, size_t i1) { #line 2958 "dk3app.ctr" if(app) { dk3app_log_1(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1); } #line 2961 "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 2989 "dk3app.ctr" if(app) { dk3app_log_3(app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, st); } #line 2992 "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 3003 "dk3app.ctr" if(app) { dk3app_log_5( app, ll, ((app->msg) ? app->msg : dk3app_kw), i1, i2, i3, st1, st2 ); } #line 3008 "dk3app.ctr" } void dk3app_set_source_file(dk3_app_t *app, dkChar const *fn) { if(app) { #line 3016 "dk3app.ctr" app->n_sourcefile = fn; } } void dk3app_set_source_line(dk3_app_t *app, unsigned long li) { if(app) { #line 3026 "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 3039 "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 3051 "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 3084 "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 3090 "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 3152 "dk3app.ctr" if(dk3sf_stat_app(&stb, db, NULL)) { switch((stb.ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { back = 1; #line 3156 "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 3177 "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 3196 "dk3app.ctr" if(dk3sf_stat_app(&stb,n,app)) { #line 3197 "dk3app.ctr" back = dk3sf_remove_file_app(n, app); } else { #line 3199 "dk3app.ctr" back = 1; /* File does not exist. */ } #line 3201 "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 3222 "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 3247 "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 3262 "dk3app.ctr" for(u = 0; u < 0x1000U; u++) { dk3app_delete_one_temp_file(app, n, u, f); } #line 3265 "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 3280 "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 3298 "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 3328 "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 3438 "dk3app.ctr" } else { if(verb) { /* Internal error, some directory not set! */ } } } else { if(verb) { dk3app_log_i1(app, DK3_LL_ERROR, 38); } } #line 3448 "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 3482 "dk3app.ctr" if(dk3app_config_name(app, dk3app_no_loc[21], fnb, DK3_MAX_PATH, 14, 0)) { #line 3484 "dk3app.ctr" ptr = dk3str_rchr(fnb, DK3_CHAR_SEP); if(ptr) { *ptr = dkT('\0'); #line 3488 "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 3493 "dk3app.ctr" #if DK3_ON_WINDOWS && (DK3_CHAR_SIZE > 1) /* Switch to 16 bit characters. */ #if defined(_MSC_VER) (void)_setmode(_fileno(fipo), _O_U16TEXT); #endif /* 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 3527 "dk3app.ctr" } } else { #line 3529 "dk3app.ctr" } #line 3530 "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 3543 "dk3app.ctr" if(app) { if(app->f_unconfigure) { #line 3546 "dk3app.ctr" dk3app_do_unconfigure(app); } else { if(app->f_prefschanged) { #line 3549 "dk3app.ctr" dk3app_do_save_config(app); } } /* Clean up preferences system. */ #line 3553 "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 3607 "dk3app.ctr" if(app->ll_highest > app->ll_tmp_keep) { dk3app_remove_temporary_files(app); } /* Remove log file if no longer needed. */ #line 3611 "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 3623 "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 3634 "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 3642 "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 3659 "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 3706 "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 3748 "dk3app.ctr" app->i_file_input_encoding = dk3app_get_default_file_encoding(app); app->de = 0; /* No error found yet. */ #line 3750 "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 3785 "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 3799 "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( #if (!(DK3_ON_WINDOWS)) && (DK3_CHAR_SIZE == 1) dk3_app_t *app, #else dk3_app_t * DK3_ARG_UNUSED(app), #endif dkChar *db, size_t sz ) { int back = 0; #line 3909 "dk3app.ctr" #if DK3_ON_WINDOWS DK3_UNUSED_ARG(app) #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); } } } #else DK3_UNUSED_ARG(app) #endif #endif #line 3968 "dk3app.ctr" return back; } /** Find language, region and encoding. @param app Application structure. */ static void dk3app_language_and_region(dk3_app_t *app) { 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 3984 "dk3app.ctr" if(dk3app_get_language_string(app, buffer, DK3_SIZEOF(buffer,dkChar))) { app->n_langstr = dk3str_dup_app(buffer, NULL); #line 3986 "dk3app.ctr" if(app->n_langstr) { ptr = dk3str_chr(buffer, dkT('.')); if(ptr) { *(ptr++) = dkT('\0'); #line 3990 "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 4006 "dk3app.ctr" *(ptr++) = dkT('\0'); #line 4007 "dk3app.ctr" p2 = ptr; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; } app->n_region = dk3str_dup_app(ptr, NULL); if(!(app->n_region)) { #line 4010 "dk3app.ctr" app->de = 29; } } if(!(app->de)) { #line 4014 "dk3app.ctr" p2 = buffer; while(*p2) { *p2 = dk3str_tolower(*p2); p2++; } app->n_language = dk3str_dup_app(buffer, NULL); if(!(app->n_language)) { #line 4017 "dk3app.ctr" app->de = 30; } } } else { #line 4021 "dk3app.ctr" app->de = 28; } } #line 4024 "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 4092 "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 4097 "dk3app.ctr" cc = 0; if(dk3str_len(buffer) > 1) { #line 4099 "dk3app.ctr" if(!dk3app_is_root_directory(buffer)) { #line 4100 "dk3app.ctr" pCurrent = dk3str_rchr(buffer, DK3_CHAR_SEP); if(pCurrent) { #line 4102 "dk3app.ctr" cc = 1; #line 4103 "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 4109 "dk3app.ctr" cc = 0; sz = dk3str_len(buffer); dirname[sz] = dkT('\0'); back = 1; } else { #line 4114 "dk3app.ctr" if(pPrevious) { *pPrevious = DK3_CHAR_SEP; } pPrevious = pCurrent; *pCurrent = dkT('\0'); } } } } } } #line 4123 "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 argv Command line arguments array. */ static void dk3app_find_names( dk3_app_t *app, dkChar const *wd, 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 4154 "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 4157 "dk3app.ctr" if(n_app) { #line 4158 "dk3app.ctr" app->n_app = (dkChar const *)n_app; #line 4159 "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 4308 "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 4361 "dk3app.ctr" if(dk3sf_mkdir_app(buffer, 0755, NULL)) { dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, app->n_app); #line 4365 "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 4375 "dk3app.ctr" app->de = 20; } } else { #line 4378 "dk3app.ctr" app->de = 20; } } else { app->de = 19; } #if DK3_HAVE_UMASK umask(oldumask); #endif } break; } } if(!(app->de)) { #line 4390 "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 4415 "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 4420 "dk3app.ctr" (void)dk3sf_mkdir_app(buffer,0700,NULL); dk3str_cat(buffer, dk3app_no_loc[20]); dk3str_cat(buffer, dkpidbuffer); #line 4424 "dk3app.ctr" #line 4425 "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 4472 "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 4480 "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 4541 "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 4563 "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 4577 "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 4602 "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 4632 "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 4649 "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 4664 "dk3app.ctr" } } if(!(app->i_cmdprefs)) { if(app->s_cmdprefs) { app->i_cmdprefs = dk3sto_it_open(app->s_cmdprefs); } else { app->de = 35; #line 4671 "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 4676 "dk3app.ctr" } } } else { app->de = 32; #line 4680 "dk3app.ctr" } } else { app->de = 32; #line 4683 "dk3app.ctr" } } else { app->de = 31; #line 4686 "dk3app.ctr" } #line 4687 "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 4778 "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 4785 "dk3app.ctr" ispref = 0; if(*tptr == DK3_CHAR_MINUS) { if(tptr[1] == DK3_CHAR_MINUS) { if(tptr[2] == DK3_CHAR_SLASH) { ispref = 1; #line 4790 "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 4807 "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 4820 "dk3app.ctr" app->n_appgroup = dk3str_dup_app(gn,NULL); if(!(app->n_appgroup)) { app->de = 18; } #line 4824 "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 4845 "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 4862 "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 4878 "dk3app.ctr" if(dv) { ptr = dv; while(*(ptr++)) { back++; } back++; } #line 4883 "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 4896 "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 4933 "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 4965 "dk3app.ctr" if((app) && (fn) && (dv)) { #line 4966 "dk3app.ctr" /* Find array size. */ sz_defaults = dk3app_mc_array_size(dv); if(sz_defaults) { #line 4969 "dk3app.ctr" if((app->s_mc) && (app->i_mc)) { #line 4970 "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 4973 "dk3app.ctr" if(mcptr->nmsg >= sz_defaults) { back = mcptr->msg; #line 4975 "dk3app.ctr" } else { #line 4976 "dk3app.ctr" errors_occured = 1; /* Too short */ } } else { #line 4979 "dk3app.ctr" } } else { #line 4981 "dk3app.ctr" } if((!(back)) && (errors_occured == 0)) { #line 4983 "dk3app.ctr" if(dk3app_my_find_data_file(app, fn, fnb, DK3_MAX_PATH, verb)) { source_file = dk3app_get_source_file(app); #line 4985 "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 4990 "dk3app.ctr" rb = dk3_new_app(DK3_PCDKCHAR,sz_defaults,(verb ? app : NULL)); if(rb) { #line 4992 "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 5042 "dk3app.ctr" dk3app_set_source_line(app, 0UL); if((current_index >= (sz_defaults - 1)) && (!(errors_occured))) { if(!(app->s_mc)) { #line 5045 "dk3app.ctr" app->s_mc = dk3sto_open_app(verb ? app : NULL); if(app->s_mc) { #line 5047 "dk3app.ctr" dk3sto_set_comp(app->s_mc, dk3app_mc_compare, 0); } else { #line 5049 "dk3app.ctr" } } if(!(app->i_mc)) { #line 5052 "dk3app.ctr" if(app->s_mc) { #line 5053 "dk3app.ctr" app->i_mc = dk3sto_it_open(app->s_mc); } else { #line 5055 "dk3app.ctr" } } if((app->s_mc) && (app->i_mc)) { #line 5058 "dk3app.ctr" mcptr = dk3app_mc_new(fn, rb, sz_defaults, 1, (verb ? app: NULL)); if(mcptr) { #line 5061 "dk3app.ctr" if(dk3sto_add(app->s_mc, mcptr)) { #line 5062 "dk3app.ctr" back = rb; } else { dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5067 "dk3app.ctr" dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5070 "dk3app.ctr" dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { /* Error occured or not enough strings. */ if(errors_occured) { #line 5074 "dk3app.ctr" if(verb) { /* Errors while reading file! */ } } else { #line 5078 "dk3app.ctr" if(verb) { /* Too few entries in file! */ } } dk3app_mc_table_delete(rb, sz_defaults); rb = NULL; } } else { #line 5086 "dk3app.ctr" } fclose(fipo); } else { #line 5089 "dk3app.ctr" } dk3app_set_source_file(app, source_file); dk3app_set_source_line(app, source_line); } else { #line 5093 "dk3app.ctr" } } else { #line 5095 "dk3app.ctr" } } else { #line 5097 "dk3app.ctr" } if(!(back)) { #line 5099 "dk3app.ctr" back = dv; } } else { #line 5102 "dk3app.ctr" } #line 5103 "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 5151 "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 5177 "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 5306 "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 5310 "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 5329 "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 5348 "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 5367 "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 5388 "dk3app.ctr" if(dk3app_get_pref(app, dk3app_no_loc[ind], buffer, sz)) { #line 5389 "dk3app.ctr" p1 = dk3str_start(buffer, NULL); if(p1) { #line 5392 "dk3app.ctr" dk3str_chomp(p1, NULL); #line 5394 "dk3app.ctr" i = dk3str_array_abbr(dk3app_log_levels, p1, dkT('$'), 0); if(i >= 0) { #line 5396 "dk3app.ctr" if(i <= DK3_LL_IGNORE) { back = i; #line 5398 "dk3app.ctr" } } else { #line 5400 "dk3app.ctr" } } else { #line 5402 "dk3app.ctr" } } else { #line 5404 "dk3app.ctr" } #line 5405 "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 5467 "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 5488 "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 5515 "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); } if(!(back->de)) { dk3app_find_names(back, wd, 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); } break; 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 5634 "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 5701 "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 5807 "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 5928 "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 5940 "dk3app.ctr" #line 5941 "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 5992 "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 6092 "dk3app.ctr" if((app) && (k) && (d) && (s)) { #line 6094 "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 6108 "dk3app.ctr" #line 6109 "dk3app.ctr" #line 6110 "dk3app.ctr" } #line 6111 "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 6331 "dk3app.ctr" back = dk3app_my_messages(app, fn, dv, 0); #line 6333 "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 6348 "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 6356 "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 6385 "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 (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); } } } 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 (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); } } } 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 6497 "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 6513 "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 6600 "dk3app.ctr" if(dk3app_get_pref(app,dk3app_no_loc[37],buffer,DK3_SIZEOF(buffer,dkChar))) { #line 6602 "dk3app.ctr" back = dk3app_get_allowed_prng_types(app, buffer); } #line 6605 "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 6655 "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 6658 "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 6702 "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 defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1010000FL if(RAND_bytes(ucptr, (int)sz) == 1) { back = sz; } #else if(RAND_pseudo_bytes(ucptr, (int)sz) > -1) { back = sz; } #endif } #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 7242 "dk3app.ctr" if((app) && (hf)) { #line 7243 "dk3app.ctr" ie = de; if(ie < 0) { ie = app->i_stdin_input_encoding; } #line 7247 "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 7278 "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 7310 "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 7313 "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 7318 "dk3app.ctr" if(0 != chown(fnb, uid, gid)) { #line 7319 "dk3app.ctr" back = 0; } else { #line 7321 "dk3app.ctr" } } else { #line 7323 "dk3app.ctr" /* If there is no such file, there is no need to change owner. */ } } else { #line 7326 "dk3app.ctr" back = 0; } } else { #line 7329 "dk3app.ctr" back = 0; } } else { #line 7332 "dk3app.ctr" } #line 7334 "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 7345 "dk3app.ctr" if((app) && ((uid) || (gid))) { #line 7346 "dk3app.ctr" if(app->n_logfilename) { #line 7347 "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 7356 "dk3app.ctr" back = 0; } else { #line 7358 "dk3app.ctr" } } else { #line 7360 "dk3app.ctr" } if(app->n_tmpdir) { #line 7362 "dk3app.ctr" if(0 != chown(app->n_tmpdir, uid, gid)) { back = 0; } if(app->i_tmpcarry) { #line 7366 "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 7370 "dk3app.ctr" } } } for(ul2 = 0U; ul2 < 0x00001000U; ul2++) { if(!dk3app_change_owner_for_file(app, 0xFFFFFFFFUL, ul2, uid, gid)) { back = 0; #line 7376 "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 7383 "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 7389 "dk3app.ctr" } } } } else { #line 7393 "dk3app.ctr" } } else { #line 7395 "dk3app.ctr" } #line 7396 "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 : */