1 /*
2 Copyright (C) 2011-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: dk3sf.ctr
12 */
13
14 /** @file dk3sf.c The dk3sf module.
15 */
16
17
18 #include <libdk3c/dk3all.h>
19 #include <libdk3c/dk3unused.h>
20
21
22
23
24
25
26
27
28 #if DK3_ON_WINDOWS || DK3_HAVE_BACKSLASH
29
30 /** File path component separator.
31 */
32 #define DK3_C8_SEP '\\'
33
34 /** Not a file path component separator.
35 */
36 #define DK3_C8_NOSEP '/'
37
38 #else
39
40 /** File path component separator.
41 */
42 #define DK3_C8_SEP '/'
43
44 /** Not a file path component separator.
45 */
46 #define DK3_C8_NOSEP '\\'
47
48 #endif
49
50
51
52 /** Add bit to set after testing another bit.
53 */
54 #define DK3SF_ADDIF(a,b) if(m & a) { back |= b; }
55
56
57
58 /** Function names used in error messages.
59 */
60 dkChar const * const dk3sf_function_names[] = {
61 /* 0 */
62 dkT(""),
63
64 /* 1 */
65 dkT("fclose: "),
66
67 /* 2 */
68 dkT("rmdir: "),
69
70 /* 3 */
71 dkT("unlink: "),
72
73 /* 4 */
74 dkT("getpwuid: "),
75
76 /* 5 */
77 dkT("lstat64: "),
78
79 /* 6 */
80 dkT("stat64: "),
81
82 /* 7 */
83 dkT("stat: "),
84
85 /* 8 */
86 dkT("lstat: "),
87
88 /* 9 */
89 dkT("fopen: "),
90
91 /* 10 */
92 dkT("localtime_r: "),
93
94 /* 11 */
95 dkT("getcwd: "),
96
97 /* 12 */
98 dkT("mkdir: "),
99
100 /* 13 */
101 dkT("gethostname: "),
102
103 /* 14 */
104 dkT("read: "),
105
106 /* 15 */
107 dkT("_read: "),
108
109 /* 16 */
110 dkT("write: "),
111
112 /* 17 */
113 dkT("_write: "),
114
115 /* 18 */
116 dkT("fread: "),
117
118 /* 19 */
119 dkT("_fread: "),
120
121 /* 20 */
122 dkT("fwrite: "),
123
124 /* 21 */
125 dkT("_fwrite: "),
126
127 /* 22 */
128 dkT("chdir: "),
129
130 /* 23 */
131 dkT("fputs: "),
132
133 /* 24 */
134 dkT("fputc: "),
135
136 /* 25 */
137 dkT("fgets: "),
138
139 NULL
140
141 };
142
143
144
145 void
146 #if (DK3_CHAR_SIZE == 1) && DK3_HAVE_STRERROR && (!DK3_ON_WINDOWS)
dk3sf_report_errno(dk3_app_t * app,int err,dkChar const * fctn)147 dk3sf_report_errno(dk3_app_t *app, int err, dkChar const *fctn)
148 #else
149 dk3sf_report_errno(
150 dk3_app_t * DK3_ARG_UNUSED(app),
151 int DK3_ARG_UNUSED(err),
152 dkChar const * DK3_ARG_UNUSED(fctn)
153 )
154 #endif
155 {
156 #if (DK3_CHAR_SIZE == 1) && DK3_HAVE_STRERROR && (!DK3_ON_WINDOWS)
157 dkChar const *msgarray[2];
158 #if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
159 char const *oldlocale = NULL;
160 char const *langptr = NULL;
161 #endif
162 if((app) && (fctn)) {
163 msgarray[0] = fctn;
164 errno = 0;
165 #if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
166 langptr = getenv("LANG");
167 if(langptr) {
168 oldlocale = setlocale(LC_MESSAGES, langptr);
169 }
170 #endif
171 msgarray[1] = strerror(err);
172 if(0 == errno) {
173 dk3app_log_3(app, DK3_LL_ERROR, msgarray, 0, 1, dk3sf_function_names[0]);
174 }
175 #if DK3_HAVE_GETENV && DK3_HAVE_SETLOCALE
176 if(langptr) {
177 if(oldlocale) { setlocale(LC_MESSAGES, oldlocale); }
178 }
179 #endif
180 }
181 #else
182 DK3_UNUSED_ARG(app)
183 DK3_UNUSED_ARG(err)
184 DK3_UNUSED_ARG(fctn)
185 #endif
186 }
187
188
189
190
191 #if DK3_ON_WINDOWS
192 /* +++ Windows +++ */
193
194
195
196 /** Unlocalized 8-bit character keywords used by module.
197 */
198 static char const * const dk3sf_kw_win_c8[] = {
199 /* 0 */ "HOMEDRIVE",
200 /* 1 */ "HOMEPATH",
201 /* 2 */ "USERPROFILE",
202 /* 3 */ "LOCALAPPDATA",
203 /* 4 */ "\\AppData\\Local",
204 /* 5 */ "APPDATA",
205 /* 6 */ "\\AppData\\Roaming",
206 /* 7 */ "TEMP",
207 /* 8 */ "TMP",
208 /* 9 */ "\\AppData\\Local\\Temp",
209 NULL
210 };
211
212
213
214 /** Unlocalized 16-bit character keywords used by module.
215 */
216 static wchar_t const * const dk3sf_kw_win_c16[] = {
217 /* 0 */ L"HOMEDRIVE",
218 /* 1 */ L"HOMEPATH",
219 /* 2 */ L"USERPROFILE",
220 /* 3 */ L"LOCALAPPDATA",
221 /* 4 */ L"\\AppData\\Local",
222 /* 5 */ L"APPDATA",
223 /* 6 */ L"\\AppData\\Roaming",
224 /* 7 */ L"TEMP",
225 /* 8 */ L"TMP",
226 /* 9 */ L"\\AppData\\Local\\Temp",
227 NULL
228 };
229
230
231
232 dk3_um_t
dk3sf_getpid(void)233 dk3sf_getpid(void)
234 {
235 dk3_um_t back;
236 back = (dk3_um_t)_getpid();
237 return back;
238 }
239
240
241
242 dk3_c16_t *
dk3sf_c16_getenv(dk3_c16_t const * name)243 dk3sf_c16_getenv(dk3_c16_t const *name)
244 {
245 dk3_c16_t *back = NULL;
246 if(name) {
247 back = _wgetenv(name);
248 }
249 return back;
250 }
251
252
253 dk3_c8_t *
dk3sf_c8_getenv(char const * name)254 dk3sf_c8_getenv(char const *name)
255 {
256 char *back = NULL;
257 if(name) {
258 back = getenv(name);
259 }
260 return back;
261 }
262
263
264 int
dk3sf_c16_remove_dir_app(dk3_c16_t const * n,dk3_app_t * app)265 dk3sf_c16_remove_dir_app(dk3_c16_t const *n, dk3_app_t *app)
266 {
267 int back = 0;
268 if(n) {
269 if(_wrmdir(n) == 0) {
270 back = 1;
271 } else {
272 if(app) {
273 /* Failed to remove directory! */
274 #if DK3_CHAR_SIZE == 2
275 dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
276 #else
277 dk3app_log_i1(app, DK3_LL_ERROR, 68);
278 #endif
279 }
280 }
281 }
282 return back;
283 }
284
285
286
287 int
dk3sf_c8_remove_dir_app(char const * n,dk3_app_t * app)288 dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
289 {
290 int back = 0;
291 if(n) {
292 if(_rmdir(n) == 0) {
293 back = 1;
294 } else {
295 if(app) {
296 /* Failed to remove directory! */
297 #if DK3_CHAR_SIZE == 1
298 dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
299 #else
300 dk3app_log_i1(app, DK3_LL_ERROR, 68);
301 #endif
302 }
303 }
304 }
305 return back;
306 }
307
308
309 int
dk3sf_c16_remove_file_app(dk3_c16_t const * n,dk3_app_t * app)310 dk3sf_c16_remove_file_app(dk3_c16_t const *n, dk3_app_t *app)
311 {
312 int back = 0;
313 if(n) {
314 if(_wunlink(n) == 0) {
315 back = 1;
316 } else {
317 if(app) {
318 /* Failed to remove file! */
319 #if DK3_CHAR_SIZE == 2
320 dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
321 #else
322 dk3app_log_i1(app, DK3_LL_ERROR, 90);
323 #endif
324 }
325 }
326 }
327 return back;
328 }
329
330
331 int
dk3sf_c8_remove_file_app(char const * n,dk3_app_t * app)332 dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
333 {
334 int back = 0;
335 if(n) {
336 if(_unlink(n) == 0) {
337 back = 1;
338 } else {
339 if(app) {
340 /* ERROR: Failed to remove file! */
341 #if DK3_CHAR_SIZE == 1
342 dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
343 #else
344 dk3app_log_i1(app, DK3_LL_ERROR, 90);
345 #endif
346 }
347 }
348 }
349 return back;
350 }
351
352
353 /** Attempt to retrieve home directory name.
354 @param d Destination buffer.
355 @param sz Size of \a d (number of characters).
356 @param n1 Name of first environment variable to check.
357 @param n2 Name of second environment variable to check.
358 @param n3 Trailing string to remove if found.
359 @return 1 on success, 0 on error.
360 */
361 static
362 int
dk3sf_c8_attempt_home(char * d,size_t sz,char const * n1,char const * n2,char const * n3)363 dk3sf_c8_attempt_home(
364 char *d, size_t sz, char const *n1, char const *n2, char const *n3
365 )
366 {
367 int back = 0;
368 char *p1 = NULL; /* Value of first environment variable. */
369 char *p2 = NULL; /* Value of second environment variable. */
370 size_t s = 0; /* Buffer size needed. */
371 size_t s2 = 0; /* Size of trailing part to remove. */
372 p2 = NULL;
373
374 p1 = getenv(n1);
375 if(p1) {
376 if(n2) { p2 = getenv(n2); }
377 if((p2) || (!(n2))) {
378 s = dk3str_c8_len(p1);
379 if(p2) { s += dk3str_c8_len(p2); }
380 if(s < sz) {
381 dk3str_c8_cpy_not_overlapped(d, p1);
382 if(p2) { dk3str_c8_cat(d, p2); }
383 if(n3) {
384 s2 = dk3str_c8_len(n3);
385 if(s2 < 2) {
386 if(dk3str_c8_casecmp(&(d[s - s2]), n3) == 0) {
387 d[s - s2] = '\0';
388 back = 1;
389 }
390 }
391 } else {
392 back = 1;
393 }
394 }
395 }
396
397
398
399 }
400 return back;
401 }
402
403
404 int
dk3sf_c8_get_home_app(char * d,size_t s,dk3_app_t * DK3_ARG_UNUSED (app))405 dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t * DK3_ARG_UNUSED(app))
406 {
407 int back = 0;
408 DK3_UNUSED_ARG(app)
409 if((d) && (s)) {
410 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[0], dk3sf_kw_win_c8[1], NULL);
411 if(!back) {
412 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[2], NULL, NULL);
413 }
414 if(!back) {
415 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, dk3sf_kw_win_c8[4]);
416 }
417 if(!back) {
418 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, dk3sf_kw_win_c8[6]);
419 }
420 if(!back) {
421 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, dk3sf_kw_win_c8[9]);
422 }
423 if(!back) {
424 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, dk3sf_kw_win_c8[9]);
425 }
426 if(!back) {
427 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[3], NULL, NULL);
428 }
429 if(!back) {
430 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[5], NULL, NULL);
431 }
432 if(!back) {
433 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[7], NULL, NULL);
434 }
435 if(!back) {
436 back = dk3sf_c8_attempt_home(d, s, dk3sf_kw_win_c8[8], NULL, NULL);
437 }
438
439
440
441 }
442 return back;
443 }
444
445
446
447 /** Attempt to retrieve home directory name.
448 @param d Destination buffer.
449 @param sz Size of \a d (number of characters).
450 @param n1 Name of first environment variable to check.
451 @param n2 Name of second environment variable to check.
452 @param n3 Trailing string to remove if found.
453 @return 1 on success, 0 on error.
454 */
455 static
456 int
dk3sf_c16_attempt_home(dk3_c16_t * d,size_t sz,dk3_c16_t const * n1,dk3_c16_t const * n2,dk3_c16_t const * n3)457 dk3sf_c16_attempt_home(
458 dk3_c16_t *d, size_t sz,
459 dk3_c16_t const *n1, dk3_c16_t const *n2, dk3_c16_t const *n3
460 )
461 {
462 int back = 0;
463 dk3_c16_t *p1 = NULL; /* Value of first environment variable. */
464 dk3_c16_t *p2 = NULL; /* Value of second environment variable. */
465 size_t s = 0; /* Buffer size needed. */
466 size_t s2 = 0; /* Size of trailing text to remove. */
467 p2 = NULL;
468
469 p1 = _wgetenv(n1);
470 if(p1) {
471 if(n2) { p2 = _wgetenv(n2); }
472 if((p2) || (!(n2))) {
473 s = dk3str_c16_len(p1);
474 if(p2) { s += dk3str_c16_len(p2); }
475 if(s < sz) {
476 dk3str_c16_cpy(d, p1);
477 if(p2) { dk3str_c16_cat(d, p2); }
478 if(n3) {
479 s2 = dk3str_c16_len(n3);
480 if(s2 < 2) {
481 if(dk3str_c16_casecmp(&(d[s - s2]), n3) == 0) {
482 d[s - s2] = 0x0000U;
483 back = 1;
484 }
485 }
486 } else {
487 back = 1;
488 }
489 }
490 }
491
492
493
494 }
495 return back;
496 }
497
498
499
500 int
dk3sf_c16_get_home_app(dk3_c16_t * d,size_t s,dk3_app_t * DK3_ARG_UNUSED (app))501 dk3sf_c16_get_home_app(dk3_c16_t *d, size_t s, dk3_app_t * DK3_ARG_UNUSED(app))
502 {
503 int back = 0;
504 DK3_UNUSED_ARG(app)
505 if((d) && (s)) {
506 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[0], dk3sf_kw_win_c16[1], NULL);
507 if(!back) {
508 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[2], NULL, NULL);
509 }
510 if(!back) {
511 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, dk3sf_kw_win_c16[4]);
512 }
513 if(!back) {
514 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, dk3sf_kw_win_c16[6]);
515 }
516 if(!back) {
517 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, dk3sf_kw_win_c16[9]);
518 }
519 if(!back) {
520 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, dk3sf_kw_win_c16[9]);
521 }
522 if(!back) {
523 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[3], NULL, NULL);
524 }
525 if(!back) {
526 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[5], NULL, NULL);
527 }
528 if(!back) {
529 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[7], NULL, NULL);
530 }
531 if(!back) {
532 back = dk3sf_c16_attempt_home(d, s, dk3sf_kw_win_c16[8], NULL, NULL);
533 }
534
535
536
537 }
538 return back;
539 }
540
541
542 int
dk3sf_c8_get_logname_app(char * d,size_t s,dk3_app_t * app)543 dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
544 {
545 int back = 0;
546 DWORD sz = 0; /* Buffer size / Result length. */
547 sz = (DWORD)s;
548 if((d) && (s)) {
549 if(GetUserNameA(d, &sz)) {
550 if(sz) {
551 d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = '\0';
552 back = 1;
553 }
554 } else {
555 if(app) {
556 /* Failed to find current user name */
557 dk3app_log_i1(app, DK3_LL_ERROR, 43);
558 }
559 }
560 }
561 return back;
562 }
563
564
565
566 int
dk3sf_c16_get_logname_app(dk3_c16_t * d,size_t s,dk3_app_t * app)567 dk3sf_c16_get_logname_app(dk3_c16_t *d, size_t s, dk3_app_t *app)
568 {
569 int back = 0;
570 DWORD sz = 0; /* Buffer size / result length. */
571 if((d) && (s)) {
572 sz = (DWORD)s;
573 if(GetUserNameW(d, &sz)) {
574 if(sz) {
575 d[((size_t)sz < s) ? ((size_t)sz) : (s - 1)] = 0U;
576 back = 1;
577 }
578 } else {
579 if(app) {
580 /* Failed to find current user name */
581 dk3app_log_i1(app, DK3_LL_ERROR, 43);
582 }
583 }
584 }
585 return back;
586 }
587
588
589 int
dk3sf_time(dk3_time_t * timer)590 dk3sf_time(dk3_time_t *timer)
591 {
592 int back = 1;
593 _time64(timer);
594 return back;
595 }
596
597
598
599 static
600 int
dk3sf_convert_file_type(int m)601 dk3sf_convert_file_type(int m)
602 {
603 int back = 0;
604 switch(m & _S_IFMT) {
605 #ifdef _S_IFIFO
606 case _S_IFIFO: back = DK3_FT_FIFO; break;
607 #endif
608 #ifdef _S_IFCHR
609 case _S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
610 #endif
611 #ifdef _S_IFDIR
612 case _S_IFDIR: back = DK3_FT_DIRECTORY; break;
613 #endif
614 #ifdef _S_IFBLK
615 case _S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
616 #endif
617 #ifdef _S_IFREG
618 case _S_IFREG: back = DK3_FT_REGULAR; break;
619 #endif
620 }
621 return back;
622 }
623
624
625
626 static
627 int
dk3sf_convert_file_permissions(int m)628 dk3sf_convert_file_permissions(int m)
629 {
630 int back = 0;
631 DK3SF_ADDIF(_S_IREAD,DK3_FPERM_U_READ)
632 DK3SF_ADDIF(_S_IWRITE,DK3_FPERM_U_WRITE)
633 DK3SF_ADDIF(_S_IEXEC,DK3_FPERM_U_EXEC)
634 return back;
635 }
636
637
638 #if (1 == DK3_CHAR_SIZE) || (VERSION_BEFORE_2019_10_20)
639
640 /** Convert file permissions back from dktools to system values.
641 @param m File permissions in dktools notation.
642 @return File permissions in system notation.
643 */
644 static
645 int
dk3sf_convert_back_file_permissions(int m)646 dk3sf_convert_back_file_permissions(int m)
647 {
648 int back = 0;
649 DK3SF_ADDIF(DK3_FPERM_U_READ,S_IREAD)
650 DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWRITE)
651 DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IEXEC)
652 return back;
653 }
654
655 #endif
656
657
658 #if VERSION_BEFORE_2012_04_14
659
660 static
661 void
dk3sf_convert_filetime(dk3_time_t * pd,FILETIME * ps)662 dk3sf_convert_filetime(dk3_time_t *pd, FILETIME *ps)
663 {
664 __int64 i1;
665 __int64 i2;
666 i1 = (__int64)(ps->dwHighDateTime);
667 i2 = (__int64)(ps->dwLowDateTime);
668 i1 = ((i1 << 32) & 0xFFFFFFFF00000000UL) | (i2 & 0x00000000FFFFFFFFUL);
669 *pd = (dk3_time_t)i1;
670 }
671
672 #endif
673
674
675 int
dk3sf_c8_stat_app(dk3_stat_t * st,char const * fn,dk3_app_t * app)676 dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
677 {
678 WIN32_FIND_DATAA wfd;
679 DWORD dwFileAttributes;
680 HANDLE hFFF;
681 #if VERSION_BEFORE_2012_04_14
682 int ec = 0;
683 #endif
684 int back = 0;
685 struct __stat64 stb; /* Internal buffer for _stat64(). */
686
687 if((st) && (fn)) {
688 dk3mem_res((void *)st, sizeof(dk3_stat_t));
689 st->cReparse = 0x00;
690 st->dwReparse = (DWORD)0;
691 if(_stat64(fn, &stb) == 0) {
692 back = 1;
693 st->u = (dk3_um_t)(stb.st_uid);
694 st->g = (dk3_um_t)(stb.st_gid);
695 st->device = (dk3_um_t)(stb.st_dev);
696 st->rdev = (dk3_um_t)(stb.st_rdev);
697 st->inode = (dk3_um_t)(stb.st_ino);
698 st->nlink = (dk3_um_t)(stb.st_nlink);
699 st->cre = (dk3_time_t)(stb.st_ctime);
700 st->mod = (dk3_time_t)(stb.st_mtime);
701 st->acc = (dk3_time_t)(stb.st_atime);
702 st->ft = dk3sf_convert_file_type(stb.st_mode);
703 st->perm = dk3sf_convert_file_permissions(stb.st_mode);
704 st->sz = (dk3_um_t)(stb.st_size);
705 st->lsz = st->sz;
706 st->ai = 0x00;
707 dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
708 dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
709 dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
710 st->lu = st->u;
711 st->lg = st->g;
712 st->ldevice = st->device;
713 st->lrdev = st->rdev;
714 st->linode = st->inode;
715 st->lnlink = st->nlink;
716 st->lft = st->ft;
717 st->lperm = st->perm;
718 st->lsz = st->sz;
719 #if VERSION_BEFORE_2012_04_14
720 if(DK3_FT_DIRECTORY == st->ft) {
721 WIN32_FIND_DATAA wfdFileDetails;
722 HANDLE hFileSearch;
723
724 hFileSearch = FindFirstFileA(fn, &wfdFileDetails);
725 if(INVALID_HANDLE_VALUE != hFileSearch) {
726 if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
727 if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
728 /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
729 } else {
730 if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
731 /* Symbolic link */
732 st->lsz = dk3ma_um_add_ok(
733 dk3ma_um_mul_ok(
734 (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
735 dk3ma_um_add_ok(
736 (dk3_um_t)(MAXDWORD),
737 DK3_UM_1,
738 &ec
739 ),
740 &ec
741 ),
742 (dk3_um_t)(wfdFileDetails.nFileSizeLow),
743 &ec
744 );
745 dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
746 dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
747 dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
748 st->ft |= DK3_FT_SYMLINK;
749 } else {
750 }
751 }
752 }
753 FindClose(hFileSearch);
754 }
755 }
756 #else
757 dwFileAttributes = GetFileAttributesA(fn);
758 if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
759 if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
760 st->cReparse = 'r';
761 hFFF = FindFirstFileA(fn, &wfd);
762 if(INVALID_HANDLE_VALUE != hFFF) {
763 if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
764 st->dwReparse = wfd.dwReserved0;
765 switch(wfd.dwReserved0) {
766 case IO_REPARSE_TAG_MOUNT_POINT: {
767 st->cReparse = 'm';
768 } break;
769 case IO_REPARSE_TAG_SYMLINK: {
770 st->cReparse = 'l';
771 } break;
772 }
773 }
774 FindClose(hFFF);
775 }
776 }
777 }
778 #endif
779 } else {
780 if(app) {
781 /* stat() failed! */
782 #if DK3_CHAR_SIZE == 1
783 dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
784 #else
785 dk3app_log_i1(app, DK3_LL_ERROR, 73);
786 #endif
787 }
788 }
789 }
790 return back;
791 }
792
793
794
795 /** Check whether opening a file is allowed.
796 @param fn File name.
797 @param want_to_write Flag: Write access is wanted.
798 @param app Application structure for diagnostics, may be NULL.
799 @return 1 for write allowed, 0 for write denied.
800 */
801 static
802 int
dk3sf_c8_check_open_file(char const * fn,int want_to_write,dk3_app_t * app)803 dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
804 {
805 int back = 1;
806 dk3_stat_t stb; /* Internal buffer for checks. */
807 if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
808 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
809 if(app) {
810 back = 0;
811 /* ERROR: Name refers a directory! */
812 #if DK3_CHAR_SIZE == 1
813 dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
814 #else
815 dk3app_log_i1(app, DK3_LL_ERROR, 76);
816 #endif
817 }
818 }
819 if(want_to_write) {
820 /* Place for additional checks to write files here. */
821 }
822 }
823 return back;
824 }
825
826
827
828 FILE *
dk3sf_c8_fopen_app(char const * fn,char const * mo,dk3_app_t * app)829 dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
830 {
831 FILE *back = NULL;
832 char const *moptr = NULL; /* Check mode string. */
833 int want_to_write = 0; /* Flag: Write access wanted. */
834
835 if((fn) && (mo)) {
836 moptr = mo;
837 while(*moptr) {
838 switch(*moptr) {
839 case 'w': case 'a': case '+': { want_to_write = 1; } break;
840 }
841 moptr++;
842 }
843 if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
844 back = fopen(fn, mo);
845 if(!(back)) {
846 if(app) {
847 /* Failed to open file for writing! */
848 if(want_to_write) {
849 #if DK3_CHAR_SIZE == 1
850 dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
851 #else
852 dk3app_log_i1(app, DK3_LL_ERROR, 79);
853 #endif
854 } else {
855 #if DK3_CHAR_SIZE == 1
856 dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
857 #else
858 dk3app_log_i1(app, DK3_LL_ERROR, 145);
859 #endif
860 }
861 }
862 }
863 }
864 }
865 return back;
866 }
867
868
869
870
871 int
dk3sf_localtime_app(dk3_tm_t * dest,dk3_time_t * timer,dk3_app_t * app)872 dk3sf_localtime_app(
873 dk3_tm_t *dest,
874 dk3_time_t *timer,
875 dk3_app_t *app
876 )
877 {
878 int back = 0;
879 struct tm res;
880 if((dest) && (timer)) {
881 if(0 == _localtime64_s(&res, timer)) {
882 back = 1;
883 dest->Y = 1900 + res.tm_year;
884 dest->M = 1 + res.tm_mon;
885 dest->D = res.tm_mday;
886 dest->h = res.tm_hour;
887 dest->m = res.tm_min;
888 dest->s = res.tm_sec;
889 } else {
890 if(app) {
891 /* ERROR: _localtime64_s failed! */
892 dk3app_log_i1(app, DK3_LL_ERROR, 268);
893 }
894 }
895 }
896 return back;
897 }
898
899
900
901 int
dk3sf_c8_time_convert_app(char * dest,size_t sz,dk3_time_t const * timer,dk3_app_t * app)902 dk3sf_c8_time_convert_app(
903 char *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
904 )
905 {
906 int back = 0;
907 char buffer[64]; /* Buffer for sprintf() result. */
908 struct tm res; /* Result from localtime(). */
909 if((dest) && (sz) && (timer)) {
910 if(0 == _localtime64_s(&res, timer)) {
911 sprintf(
912 buffer,
913 "%04d-%02d-%02d %02d:%02d:%02d",
914 (1900 + res.tm_year),
915 (1 + res.tm_mon),
916 res.tm_mday,
917 res.tm_hour,
918 res.tm_min,
919 res.tm_sec
920 );
921 if(sz > dk3str_c8_len(buffer)) {
922 dk3str_c8_cpy_not_overlapped(dest, buffer);
923 back = 1;
924 } else {
925 if(app) {
926 /* Buffer too small! */
927 dk3app_log_i1(app, DK3_LL_ERROR, 38);
928 }
929 }
930 } else {
931 if(app) {
932 /* _localtime64_s failed! */
933 dk3app_log_i1(app, DK3_LL_ERROR, 80);
934 }
935 }
936 }
937 return back;
938 }
939
940
941
942 int
dk3sf_c8_getcwd_app(char * dest,size_t sz,dk3_app_t * app)943 dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
944 {
945 int back = 0;
946 if((dest) && (sz)) {
947 if(_getcwd(dest, (int)sz)) {
948 back = 1;
949 } else {
950 if(app) {
951 switch(errno) {
952 case ERANGE: {
953 /* Buffer too small! */
954 dk3app_log_i1(app, DK3_LL_ERROR, 38);
955 } break;
956 default: {
957 dk3app_log_i1(app, DK3_LL_ERROR, 53);
958 } break;
959 }
960 }
961 }
962 }
963 return back;
964 }
965
966
967
968 int
dk3sf_c8_find_exec_app(char * d,size_t s,char const * DK3_ARG_UNUSED (w),char const * DK3_ARG_UNUSED (c),dk3_app_t * app)969 dk3sf_c8_find_exec_app(
970 char *d,
971 size_t s,
972 char const * DK3_ARG_UNUSED(w),
973 char const * DK3_ARG_UNUSED(c),
974 dk3_app_t *app
975 )
976 {
977 int back = 0;
978 DK3_UNUSED_ARG(w)
979 DK3_UNUSED_ARG(c)
980 if((d) && (s)) {
981 if(GetModuleFileNameA(GetModuleHandle(NULL),d,(DWORD)s)) {
982 back = 1;
983 } else {
984 if(app) {
985 /* Failed to find name of executable! */
986 dk3app_log_i1(app, DK3_LL_ERROR, 40);
987 }
988 }
989 }
990 return back;
991 }
992
993
994
995 static
996 int
dk3sf_c8_is_drive(char const * p)997 dk3sf_c8_is_drive(char const *p)
998 {
999 int back = 0;
1000
1001 if(dk3str_c8_len(p) == 2) {
1002 if((*p >= 'a') && (*p <= 'z')) {
1003 back = 1;
1004 }
1005 if((*p >= 'A') && (*p <= 'Z')) {
1006 back = 1;
1007 }
1008 if(back) {
1009 back = 0;
1010 if(p[1] == ':') { back = 1; }
1011 }
1012 }
1013 return back;
1014 }
1015
1016
1017 int
dk3sf_c8_mkdir_app(char const * p,int mo,dk3_app_t * app)1018 dk3sf_c8_mkdir_app(
1019 char const *p,
1020 #if VERSION_BEFORE_2019_10_20
1021 int mo,
1022 #else
1023 int DK3_ARG_UNUSED(mo),
1024 #endif
1025 dk3_app_t *app
1026 )
1027 {
1028 int back = 0;
1029 char buffer[DK3_MAX_PATH]; /* Path name for parent directories. */
1030 char *ptr = NULL; /* Slash/backslash position. */
1031 int cc = 1; /* Flag: Can continue. */
1032 #if VERSION_BEFORE_2019_10_20
1033 int m = 0; /* File permissions. */
1034 #endif
1035 dk3_stat_t stb;
1036 #if (!(VERSION_BEFORE_2019_10_20))
1037 DK3_UNUSED_ARG(mo)
1038 #endif
1039
1040 if(p) {
1041 #if VERSION_BEFORE_2019_10_20
1042 m = dk3sf_convert_back_file_permissions(mo);
1043 #endif
1044 if(dk3str_c8_len(p) < sizeof(buffer)) {
1045 dk3str_c8_cpy_not_overlapped(buffer, p);
1046 ptr = buffer; cc = 1;
1047 while((cc) && (ptr)) {
1048 ptr = dk3str_c8_chr(ptr, '\\');
1049 if(ptr) {
1050 *ptr = '\0';
1051 if((dk3str_c8_len(buffer) > 0) && (!dk3sf_c8_is_drive(buffer))) {
1052 if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
1053 if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
1054 cc = 0;
1055 if(app) {
1056 /* Not a directory! */
1057 #if DK3_CHAR_SIZE == 1
1058 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
1059 #else
1060 dk3app_log_i1(app, DK3_LL_ERROR, 83);
1061 #endif
1062 }
1063 }
1064 } else {
1065 if(_mkdir(buffer) != 0) {
1066 cc = 0;
1067 if(app) {
1068 /* Failed to create directory! */
1069 #if DK3_CHAR_SIZE == 1
1070 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
1071 #else
1072 dk3app_log_i1(app, DK3_LL_ERROR, 86);
1073 #endif
1074 }
1075 }
1076 }
1077 }
1078 *ptr = '\\';
1079 ptr++;
1080 }
1081 }
1082 if(cc) {
1083 if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
1084 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
1085 back = 1;
1086 } else {
1087 if(app) {
1088 /* Not a directory! */
1089 #if DK3_CHAR_SIZE == 1
1090 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
1091 #else
1092 dk3app_log_i1(app, DK3_LL_ERROR, 83);
1093 #endif
1094 }
1095 }
1096 } else {
1097 if(_mkdir(buffer) == 0) {
1098 back = 1;
1099 } else {
1100 #if DK3_CHAR_SIZE == 1
1101 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
1102 #else
1103 dk3app_log_i1(app, DK3_LL_ERROR, 86);
1104 #endif
1105 }
1106 }
1107 }
1108 } else {
1109 if(app) {
1110 /* Path too long! */
1111 #if DK3_CHAR_SIZE == 1
1112 dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
1113 #else
1114 dk3app_log_i1(app, DK3_LL_ERROR, 87);
1115 #endif
1116 }
1117 }
1118 }
1119 return back;
1120 }
1121
1122
1123
1124 int
dk3sf_c16_stat_app(dk3_stat_t * st,dk3_c16_t const * fn,dk3_app_t * app)1125 dk3sf_c16_stat_app(dk3_stat_t *st, dk3_c16_t const *fn, dk3_app_t *app)
1126 {
1127 WIN32_FIND_DATAW wfd;
1128 DWORD dwFileAttributes;
1129 HANDLE hFFF;
1130 #if VERSION_BEFORE_2012_04_14
1131 int ec = 0;
1132 #endif
1133 int back = 0;
1134 struct __stat64 stb; /* Result from _wstat64(). */
1135
1136 if((st) && (fn)) {
1137 dk3mem_res((void *)st, sizeof(dk3_stat_t));
1138 st->cReparse = 0x00;
1139 st->dwReparse = (DWORD)0;
1140 if(_wstat64(fn, &stb) == 0) {
1141 back = 1;
1142 st->u = (dk3_um_t)(stb.st_uid);
1143 st->g = (dk3_um_t)(stb.st_gid);
1144 st->device = (dk3_um_t)(stb.st_dev);
1145 st->rdev = (dk3_um_t)(stb.st_rdev);
1146 st->inode = (dk3_um_t)(stb.st_ino);
1147 st->nlink = (dk3_um_t)(stb.st_nlink);
1148 st->cre = (dk3_time_t)(stb.st_ctime);
1149 st->mod = (dk3_time_t)(stb.st_mtime);
1150 st->acc = (dk3_time_t)(stb.st_atime);
1151 st->ft = dk3sf_convert_file_type(stb.st_mode);
1152 st->perm = dk3sf_convert_file_permissions(stb.st_mode);
1153 st->sz = (dk3_um_t)(stb.st_size);
1154 st->lsz = st->sz;
1155 st->ai = 0x00;
1156 dk3mem_cpy((void *)(&(st->lcre)), (void *)(&(st->cre)), sizeof(dk3_time_t));
1157 dk3mem_cpy((void *)(&(st->lmod)), (void *)(&(st->mod)), sizeof(dk3_time_t));
1158 dk3mem_cpy((void *)(&(st->lacc)), (void *)(&(st->acc)), sizeof(dk3_time_t));
1159 st->lu = st->u;
1160 st->lg = st->g;
1161 st->ldevice = st->device;
1162 st->lrdev = st->rdev;
1163 st->linode = st->inode;
1164 st->lnlink = st->nlink;
1165 st->lft = st->ft;
1166 st->lperm = st->perm;
1167 st->lsz = st->sz;
1168 #if VERSION_BEFORE_2012_04_14
1169 if(DK3_FT_DIRECTORY == st->ft) {
1170 WIN32_FIND_DATAW wfdFileDetails;
1171 HANDLE hFileSearch;
1172
1173 hFileSearch = FindFirstFileW(fn, &wfdFileDetails);
1174 if(INVALID_HANDLE_VALUE != hFileSearch) {
1175 if(FILE_ATTRIBUTE_REPARSE_POINT & (wfdFileDetails.dwFileAttributes)) {
1176
1177 if(IO_REPARSE_TAG_MOUNT_POINT == wfdFileDetails.dwReserved0) {
1178
1179 /* ##### st->ft = DK3_FT_WINDOWS_MOUNT_POINT; */
1180 } else {
1181 if(IO_REPARSE_TAG_SYMLINK == wfdFileDetails.dwReserved0) {
1182
1183 /* Symbolic link */
1184 st->lsz = dk3ma_um_add_ok(
1185 dk3ma_um_mul_ok(
1186 (dk3_um_t)(wfdFileDetails.nFileSizeHigh),
1187 dk3ma_um_add_ok(
1188 (dk3_um_t)(MAXDWORD),
1189 DK3_UM_1,
1190 &ec
1191 ),
1192 &ec
1193 ),
1194 (dk3_um_t)(wfdFileDetails.nFileSizeLow),
1195 &ec
1196 );
1197 dk3sf_convert_filetime(&(st->lcre), &(wfdFileDetails.ftCreationTime));
1198 dk3sf_convert_filetime(&(st->lmod), &(wfdFileDetails.ftLastWriteTime));
1199 dk3sf_convert_filetime(&(st->lacc), &(wfdFileDetails.ftLastAccessTime));
1200 st->ft |= DK3_FT_SYMLINK;
1201 } else {
1202 }
1203 }
1204 }
1205 FindClose(hFileSearch);
1206 }
1207 }
1208 #else
1209 dwFileAttributes = GetFileAttributesW(fn);
1210 if(INVALID_FILE_ATTRIBUTES != dwFileAttributes) {
1211 if(dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1212 st->cReparse = 'r';
1213 hFFF = FindFirstFileW(fn, &wfd);
1214 if(INVALID_HANDLE_VALUE != hFFF) {
1215 if((wfd.dwFileAttributes) & FILE_ATTRIBUTE_REPARSE_POINT) {
1216 st->dwReparse = wfd.dwReserved0;
1217 switch(wfd.dwReserved0) {
1218 case IO_REPARSE_TAG_MOUNT_POINT: {
1219 st->cReparse = 'm';
1220 } break;
1221 case IO_REPARSE_TAG_SYMLINK: {
1222 st->cReparse = 'l';
1223 } break;
1224 }
1225 }
1226 FindClose(hFFF);
1227 }
1228 }
1229 }
1230 #endif
1231 } else {
1232 if(app) {
1233 /* _wstat64() failed! */
1234 #if DK3_CHAR_SIZE == 2
1235 dk3app_log_i3(app, DK3_LL_ERROR, 61, 163, fn);
1236 #else
1237 dk3app_log_i1(app, DK3_LL_ERROR, 73);
1238 #endif
1239 }
1240 }
1241 }
1242 return back;
1243 }
1244
1245
1246
1247 static
1248 int
dk3sf_c16_check_open_file(dk3_c16_t const * fn,int want_to_write,dk3_app_t * app)1249 dk3sf_c16_check_open_file(dk3_c16_t const *fn, int want_to_write, dk3_app_t *app)
1250 {
1251 int back = 1;
1252 dk3_stat_t stb; /* Check for existing file. */
1253 if(dk3sf_c16_stat_app(&stb, fn, NULL)) {
1254 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
1255 if(app) {
1256 back = 0;
1257 /* Name refers a directory! */
1258 #if DK3_CHAR_SIZE == 2
1259 dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
1260 #else
1261 dk3app_log_i1(app, DK3_LL_ERROR, 76);
1262 #endif
1263 }
1264 }
1265 if(want_to_write) {
1266 /* Place for additional checks to write files here. */
1267 }
1268 }
1269 return back;
1270 }
1271
1272
1273
1274 FILE *
dk3sf_c16_fopen_app(dk3_c16_t const * fn,dk3_c16_t const * mo,dk3_app_t * app)1275 dk3sf_c16_fopen_app(dk3_c16_t const *fn, dk3_c16_t const *mo, dk3_app_t *app)
1276 {
1277 FILE *back = NULL;
1278 dk3_c16_t const *moptr = NULL; /* Traverse mode string. */
1279 int want_to_write = 0; /* Flag: Write access wanted. */
1280 if((fn) && (mo)) {
1281 moptr = mo;
1282 while(*moptr) {
1283 switch(*moptr) {
1284 case L'w': case L'a': case L'+': { want_to_write = 1; } break;
1285 }
1286 moptr++;
1287 }
1288 if(dk3sf_c16_check_open_file(fn, want_to_write, app)) {
1289 back = _wfopen(fn, mo);
1290 if(!(back)) {
1291 if(app) {
1292 /* Failed to open file for writing! */
1293 if(want_to_write) {
1294 #if DK3_CHAR_SIZE == 2
1295 dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
1296 #else
1297 dk3app_log_i1(app, DK3_LL_ERROR, 79);
1298 #endif
1299 } else {
1300 #if DK3_CHAR_SIZE == 2
1301 dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
1302 #else
1303 dk3app_log_i1(app, DK3_LL_ERROR, 145);
1304 #endif
1305 }
1306 }
1307 }
1308 }
1309 }
1310 return back;
1311 }
1312
1313
1314
1315 int
dk3sf_c16_time_convert_app(dk3_c16_t * dest,size_t sz,dk3_time_t const * timer,dk3_app_t * app)1316 dk3sf_c16_time_convert_app(
1317 dk3_c16_t *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
1318 )
1319 {
1320 int back = 0;
1321 char buffer[64];
1322 if(dk3sf_c8_time_convert_app(buffer, sizeof(buffer), timer, app)) {
1323 back = dk3str_cnv_c8p_to_c16_app(dest, sz, buffer, app);
1324 }
1325 return back;
1326 }
1327
1328
1329
1330 int
dk3sf_c16_getcwd_app(dk3_c16_t * dest,size_t sz,dk3_app_t * app)1331 dk3sf_c16_getcwd_app(dk3_c16_t *dest, size_t sz, dk3_app_t *app)
1332 {
1333 int back = 0;
1334 if((dest) && (sz)) {
1335 if(_wgetcwd(dest, (int)sz)) {
1336 back = 1;
1337 } else {
1338 if(app) {
1339 switch(errno) {
1340 #ifdef ERANGE
1341 case ERANGE: {
1342 /* Buffer too small! */
1343 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1344 } break;
1345 #endif
1346 default: {
1347 /* Failed to find current working directory! */
1348 dk3app_log_i1(app, DK3_LL_ERROR, 53);
1349 } break;
1350 }
1351 }
1352 }
1353 }
1354 return back;
1355 }
1356
1357
1358
1359 int
dk3sf_c16_find_exec_app(dk3_c16_t * d,size_t s,dk3_c16_t const * DK3_ARG_UNUSED (w),dk3_c16_t const * DK3_ARG_UNUSED (c),dk3_app_t * app)1360 dk3sf_c16_find_exec_app(
1361 dk3_c16_t *d,
1362 size_t s,
1363 dk3_c16_t const * DK3_ARG_UNUSED(w),
1364 dk3_c16_t const * DK3_ARG_UNUSED(c),
1365 dk3_app_t *app
1366 )
1367 {
1368 int back = 0;
1369 DK3_UNUSED_ARG(w)
1370 DK3_UNUSED_ARG(c)
1371 if((d) && (s)) {
1372 if(GetModuleFileNameW(GetModuleHandle(NULL),d,(DWORD)s)) {
1373 back = 1;
1374 } else {
1375 if(app) {
1376 /* Failed to find name of executable! */
1377 dk3app_log_i1(app, DK3_LL_ERROR, 40);
1378 }
1379 }
1380 }
1381 return back;
1382 }
1383
1384
1385
1386 static
1387 int
dk3sf_c16_is_drive(dk3_c16_t const * p)1388 dk3sf_c16_is_drive(dk3_c16_t const *p)
1389 {
1390 int back = 0;
1391 if(dk3str_c16_len(p) == 2) {
1392 if((*p >= L'A') && (*p <= L'Z')) {
1393 back = 1;
1394 }
1395 if((*p >= L'a') && (*p <= L'z')) {
1396 back = 1;
1397 }
1398 if(back) {
1399 back = 0;
1400 if(p[1] == L':') { back = 1; }
1401 }
1402 }
1403 return back;
1404 }
1405
1406
1407
1408 int
dk3sf_c16_mkdir_app(dk3_c16_t const * p,int mo,dk3_app_t * app)1409 dk3sf_c16_mkdir_app(
1410 dk3_c16_t const *p,
1411 #if VERSION_BEFORE_2019_10_20
1412 int mo,
1413 #else
1414 int DK3_ARG_UNUSED(mo),
1415 #endif
1416 dk3_app_t *app
1417 )
1418 {
1419 int back = 0;
1420 dk3_c16_t buffer[DK3_MAX_PATH]; /* File names of parent directories. */
1421 dk3_c16_t *ptr = NULL; /* Current slash/backslash position. */
1422 int cc = 1; /* Flag: Can continue. */
1423 #if VERSION_BEFORE_2019_10_20
1424 int m = 0; /* Permissions. */
1425 #endif
1426 dk3_stat_t stb; /* Test whether file/dir exists. */
1427 #if (!(VERSION_BEFORE_2019_10_20))
1428 DK3_UNUSED_ARG(mo)
1429 #endif
1430 if(p) {
1431 #if VERSION_BEFORE_2019_10_20
1432 m = dk3sf_convert_back_file_permissions(mo);
1433 #endif
1434 if(dk3str_c16_len(p) < sizeof(buffer)) {
1435 dk3str_c16_cpy(buffer, p);
1436 ptr = buffer; cc = 1;
1437 while((cc) && (ptr)) {
1438 ptr = dk3str_c16_chr(ptr, 0x005CU);
1439 if(ptr) {
1440 *ptr = 0U;
1441 if((dk3str_c16_len(buffer) > 0) && (!dk3sf_c16_is_drive(buffer))) {
1442 if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
1443 if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
1444 cc = 0;
1445 if(app) {
1446 /* Not a directory! */
1447 #if DK3_CHAR_SIZE == 2
1448 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
1449 #else
1450 dk3app_log_i1(app, DK3_LL_ERROR, 83);
1451 #endif
1452 }
1453 }
1454 } else {
1455 if(_wmkdir(buffer) != 0) {
1456 cc = 0;
1457 if(app) {
1458 /* Failed to create directory! */
1459 #if DK3_CHAR_SIZE == 2
1460 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
1461 #else
1462 dk3app_log_i1(app, DK3_LL_ERROR, 86);
1463 #endif
1464 }
1465 }
1466 }
1467 }
1468 *ptr = 0x005CU;
1469 ptr++;
1470 }
1471 }
1472 if(cc) {
1473 if(dk3sf_c16_stat_app(&stb, buffer, NULL)) {
1474 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
1475 back = 1;
1476 } else {
1477 if(app) {
1478 /* Not a directory! */
1479 #if DK3_CHAR_SIZE == 2
1480 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
1481 #else
1482 dk3app_log_i1(app, DK3_LL_ERROR, 83);
1483 #endif
1484 }
1485 }
1486 } else {
1487 if(_wmkdir(buffer) == 0) {
1488 back = 1;
1489 } else {
1490 #if DK3_CHAR_SIZE == 2
1491 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
1492 #else
1493 dk3app_log_i1(app, DK3_LL_ERROR, 86);
1494 #endif
1495 }
1496 }
1497 }
1498 } else {
1499 if(app) {
1500 /* Path too long! */
1501 #if DK3_CHAR_SIZE == 2
1502 dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
1503 #else
1504 dk3app_log_i1(app, DK3_LL_ERROR, 87);
1505 #endif
1506 }
1507 }
1508 }
1509 return back;
1510 }
1511
1512
1513
1514 int
dk3sf_c16_get_hostname_app(dk3_c16_t * db,size_t sz,dk3_app_t * app)1515 dk3sf_c16_get_hostname_app(dk3_c16_t *db, size_t sz, dk3_app_t *app)
1516 {
1517 int back = 0;
1518 DWORD s = 0; /* Buffer size / result length. */
1519 if((db) && (sz)) {
1520 s = (DWORD)sz;
1521 if(GetComputerNameExW(ComputerNameNetBIOS, db, &s)) {
1522 if((size_t)s < sz) {
1523 db[(size_t)s] = L'\0';
1524 } else {
1525 db[sz - 1] = L'\0';
1526 }
1527 back = 1;
1528 } else {
1529 if(app) {
1530 /* ERROR: Failed to find NetBIOS name! */
1531 dk3app_log_i1(app, DK3_LL_ERROR, 131);
1532 }
1533 }
1534 }
1535 return back;
1536 }
1537
1538
1539
1540 int
dk3sf_c8_get_hostname_app(char * db,size_t sz,dk3_app_t * app)1541 dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
1542 {
1543 int back = 0;
1544 DWORD s = 0; /* Buffer size / result length. */
1545 if((db) && (sz)) {
1546 s = (DWORD)sz;
1547 if(GetComputerNameExA(ComputerNameNetBIOS, db, &s)) {
1548 if((size_t)s < sz) {
1549 db[(size_t)s] = '\0';
1550 } else {
1551 db[sz - 1] = '\0';
1552 }
1553 back = 1;
1554 } else {
1555 if(app) {
1556 /* ERROR: Failed to find NetBIOS name! */
1557 dk3app_log_i1(app, DK3_LL_ERROR, 131);
1558 }
1559 }
1560 }
1561 return back;
1562 }
1563
1564
1565
1566 #if DK3_CHAR_SIZE > 1
1567 #if DK3_CHAR_SIZE > 2
1568 #error "dkChar must be 8 or 16 bit!"
1569 #else
1570 /* +++ Windows, dkChar 16 bit +++ */
1571
1572
1573
1574 int
dk3sf_fgets_fn_app(dkChar * db,size_t sz,FILE * fi,dkChar const * fn,dk3_app_t * app)1575 dk3sf_fgets_fn_app(
1576 dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
1577 )
1578 {
1579 int back = 0;
1580
1581 if((db) && (sz) && (fi)) {
1582 if(fgetws(db, (int)sz, fi)) {
1583 if(db[0] == DK3_CHAR_BOM) {
1584 dk3str_c16_cpy(db, &(db[1]));
1585 }
1586 back = 1;
1587 } else {
1588 if(!feof(fi)) {
1589 if(app) {
1590 if(fn) {
1591 dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
1592 } else {
1593 dk3app_log_i1(app, DK3_LL_ERROR, 345);
1594 }
1595 }
1596 }
1597 }
1598 }
1599 return back;
1600 }
1601
1602
1603
1604 int
dk3sf_fputc_fn_app(dkChar ch,FILE * fi,dkChar const * fn,dk3_app_t * app)1605 dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
1606 {
1607 int back = 0;
1608 if(fi) {
1609 if(fputwc(ch, fi) != WEOF) {
1610 back = 1;
1611 } else {
1612 if(app) {
1613 if(fn) {
1614 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
1615 } else {
1616 dk3app_log_i1(app, DK3_LL_ERROR, 120);
1617 }
1618 }
1619 }
1620 }
1621 return back;
1622 }
1623
1624
1625
1626 int
dk3sf_fputs_fn_app(dkChar const * st,FILE * fi,dkChar const * fn,dk3_app_t * app)1627 dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
1628 {
1629 int back = 0;
1630 if((st) && (fi)) {
1631 if(fputws(st, fi) != WEOF) {
1632 back = 1;
1633 } else {
1634 if(app) {
1635 if(fn) {
1636 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
1637 } else {
1638 dk3app_log_i1(app, DK3_LL_ERROR, 120);
1639 }
1640 }
1641 }
1642 }
1643 return back;
1644 }
1645
1646
1647
1648 void
dk3sf_initialize_stdout(void)1649 dk3sf_initialize_stdout(void)
1650 {
1651 static int not_bom_written_to_stdout = 1;
1652 if(not_bom_written_to_stdout) {
1653 not_bom_written_to_stdout = 0;
1654 #if defined(_MSC_VER)
1655 (void)_setmode(_fileno(stdout), _O_U16TEXT);
1656 #endif
1657 if(!_isatty(_fileno(stdout))) {
1658 fputwc(0xFEFF, stdout);
1659 }
1660 }
1661 }
1662
1663
1664
1665 void
dk3sf_initialize_stdout_no_bom(void)1666 dk3sf_initialize_stdout_no_bom(void)
1667 {
1668 static int not_bom_written_to_stdout = 1;
1669 if(not_bom_written_to_stdout) {
1670 not_bom_written_to_stdout = 0;
1671 #if defined(_MSC_VER)
1672 (void)_setmode(_fileno(stdout), _O_U16TEXT);
1673 #endif
1674 }
1675 }
1676
1677
1678
1679 void
dk3sf_initialize_stderr(void)1680 dk3sf_initialize_stderr(void)
1681 {
1682 static int not_bom_written_to_stderr = 1;
1683 if(not_bom_written_to_stderr) {
1684 not_bom_written_to_stderr = 0;
1685 #if defined(_MSC_VER)
1686 (void)_setmode(_fileno(stderr), _O_U16TEXT);
1687 #endif
1688 if(!_isatty(_fileno(stderr))) {
1689 fputwc(0xFEFF, stderr);
1690 }
1691 }
1692 }
1693
1694
1695
1696 void
dk3sf_initialize_file(FILE * fipo)1697 dk3sf_initialize_file(FILE *fipo)
1698 {
1699 #if defined(_MSC_VER)
1700 (void)_setmode(_fileno(fipo), _O_U16TEXT);
1701 #endif
1702 fputwc(0xFEFF, fipo);
1703 }
1704
1705
1706
1707 /* --- Windows, dkChar 16 bit --- */
1708 #endif
1709 #else
1710 /* +++ Windows, dkChar 8 bit +++ */
1711
1712
1713
1714 int
dk3sf_fgets_fn_app(dkChar * db,size_t sz,FILE * fi,dkChar const * fn,dk3_app_t * app)1715 dk3sf_fgets_fn_app(
1716 dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
1717 )
1718 {
1719 int back = 0;
1720 if((db) && (sz) && (fi)) {
1721 if(fgets(db, sz, fi)) {
1722 back = 1;
1723 } else {
1724 if(!feof(fi)) {
1725 if(app) {
1726 if(fn) {
1727 dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
1728 } else {
1729 dk3app_log_i1(app, DK3_LL_ERROR, 345);
1730 }
1731 }
1732 }
1733 }
1734 }
1735 return back;
1736 }
1737
1738
1739 int
dk3sf_fputs_fn_app(dkChar const * st,FILE * fi,dkChar const * fn,dk3_app_t * app)1740 dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
1741 {
1742 int back = 0;
1743 if((st) && (fi)) {
1744 if(fputs(st, fi) != EOF) {
1745 back = 1;
1746 } else {
1747 if(app) {
1748 if(fn) {
1749 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
1750 } else {
1751 dk3app_log_i1(app, DK3_LL_ERROR, 120);
1752 }
1753 }
1754 }
1755 }
1756 return back;
1757 }
1758
1759
1760
1761 int
dk3sf_fputc_fn_app(dkChar ch,FILE * fi,dkChar const * fn,dk3_app_t * app)1762 dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
1763 {
1764 int back = 0;
1765 if(fi) {
1766 if(fputc(ch, fi) != EOF) {
1767 back = 1;
1768 } else {
1769 if(app) {
1770 if(fn) {
1771 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
1772 } else {
1773 dk3app_log_i1(app, DK3_LL_ERROR, 120);
1774 }
1775 }
1776 }
1777 }
1778 return back;
1779 }
1780
1781
1782
1783 void
dk3sf_initialize_stdout(void)1784 dk3sf_initialize_stdout(void)
1785 {
1786 }
1787
1788
1789
1790 void
dk3sf_initialize_stderr(void)1791 dk3sf_initialize_stderr(void)
1792 {
1793 }
1794
1795
1796 void
dk3sf_initialize_file(FILE * fipo)1797 dk3sf_initialize_file(FILE *fipo)
1798 {
1799 }
1800
1801
1802 /* --- Windows, dkChar 8 bit --- */
1803 #endif
1804
1805 /* --- Windows --- */
1806 #else
1807 /* +++ non-Windows +++ */
1808
1809
1810
1811 /** 8-bit character keywords for use on non-Windows systems.
1812 */
1813 static char const * const kw_c8_no_win[] = {
1814 /* 0 */ "/",
1815 /* 1 */ "PATH",
1816 NULL
1817 };
1818
1819
1820
1821 dk3_um_t
dk3sf_getpid(void)1822 dk3sf_getpid(void)
1823 {
1824 dk3_um_t back = DK3_UM_0;
1825 #if DK3_HAVE_GETPID
1826 back = (dk3_um_t)getpid();
1827 #else
1828 #if DK3_HAVE__GETPID
1829 back = (dk3_um_t)_getpid();
1830 #else
1831 #error "No getpid() function!"
1832 #endif
1833 #endif
1834 return back;
1835 }
1836
1837
1838
1839 dk3_c8_t *
dk3sf_c8_getenv(char const * name)1840 dk3sf_c8_getenv(char const *name)
1841 {
1842 char *back = NULL;
1843 if(name) {
1844 back = getenv(name);
1845 }
1846 return back;
1847 }
1848
1849
1850
1851 int
dk3sf_c8_remove_dir_app(char const * n,dk3_app_t * app)1852 dk3sf_c8_remove_dir_app(char const *n, dk3_app_t *app)
1853 {
1854 int back = 0;
1855 if(n) {
1856 #if DK3_HAVE_RMDIR
1857 if(rmdir(n) == 0) {
1858 back = 1;
1859 } else {
1860 if(app) {
1861 /* Failed to remove directory! */
1862 #if DK3_CHAR_SIZE == 1
1863 dk3app_log_i3(app, DK3_LL_ERROR, 69, 70, n);
1864 #else
1865 dk3app_log_i1(app, DK3_LL_ERROR, 68);
1866 #endif
1867 dk3sf_report_errno(app, errno, dk3sf_function_names[2]);
1868 }
1869 }
1870 #else
1871 #error "No rmdir() function!"
1872 #endif
1873 }
1874 return back;
1875 }
1876
1877
1878 int
dk3sf_c8_remove_file_app(char const * n,dk3_app_t * app)1879 dk3sf_c8_remove_file_app(char const *n, dk3_app_t *app)
1880 {
1881 int back = 0;
1882 if(n) {
1883 #if DK3_HAVE_UNLINK
1884 if(unlink(n) == 0) {
1885 back = 1;
1886 } else {
1887 if(app) {
1888 /* ERROR: Failed to unlink file */
1889 #if DK3_CHAR_SIZE == 1
1890 dk3app_log_i3(app, DK3_LL_ERROR, 88, 89, n);
1891 #else
1892 dk3app_log_i1(app, DK3_LL_ERROR, 90);
1893 #endif
1894 dk3sf_report_errno(app, errno, dk3sf_function_names[3]);
1895 }
1896 }
1897 #else
1898 #error "No support for unlink"
1899 #endif
1900 }
1901 return back;
1902 }
1903
1904
1905 /** Copy logname of user record to buffer.
1906 @param d Destination buffer.
1907 @param s Size of \a d.
1908 @param p User record.
1909 @param app Application structure for diagnostics, may be NULL.
1910 @return 1 on success, 0 on error.
1911 */
1912 static
1913 int
dk3sf_c8_copy_logname(char * d,size_t s,struct passwd * p,dk3_app_t * app)1914 dk3sf_c8_copy_logname(char *d, size_t s, struct passwd *p, dk3_app_t *app)
1915 {
1916 int back = 0;
1917
1918 if(p) {
1919 if(p->pw_name) {
1920 if(dk3str_c8_len(p->pw_name) < s) {
1921 dk3str_c8_cpy_not_overlapped(d, p->pw_name);
1922 back = 1;
1923 } else {
1924 if(app) {
1925 /* Destination buffer too small! */
1926 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1927 }
1928 }
1929 } else {
1930 if(app) {
1931 /* No name entry in record! */
1932 dk3app_log_i1(app, DK3_LL_ERROR, 91);
1933 }
1934 }
1935 }
1936 return back;
1937 }
1938
1939
1940
1941 int
dk3sf_c8_get_logname_app(char * d,size_t s,dk3_app_t * app)1942 dk3sf_c8_get_logname_app(char *d, size_t s, dk3_app_t *app)
1943 {
1944 int back = 0;
1945 uid_t u = 0; /* Current user ID. */
1946 struct passwd *p = NULL; /* Current user to process. */
1947 char uidbuffer[128]; /* Text buffer to store UID. */
1948
1949 if((d) && (s)) {
1950 u = getuid();
1951 #if DK3_HAVE_GETPWUID
1952 p = getpwuid(u);
1953 if(p) {
1954 back = dk3sf_c8_copy_logname(d, s, p, app);
1955 } else {
1956 if(app) {
1957 /* No passwd record for UID! */
1958 #if DK3_CHAR_SIZE == 1
1959 dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
1960 dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
1961 #else
1962 dk3app_log_i1(app, DK3_LL_ERROR, 94);
1963 #endif
1964 dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
1965 }
1966 }
1967 #else
1968 #if DK3_HAVE_SETPWENT
1969 setpwent();
1970 #endif
1971 {
1972 int cc;
1973 int found;
1974 cc = 1; found = 0;
1975 while(cc) {
1976 p = getpwent();
1977 if(p) {
1978 if(p->pw_uid == u) {
1979 cc = 0;
1980 found = 1;
1981 back = dk3sf_c8_copy_logname(d, s, p, app);
1982 }
1983 } else { cc = 0; }
1984 }
1985 if(!found) {
1986 if(app) {
1987 /* No passwd record for UID! */
1988 #if DK3_CHAR_SIZE == 1
1989 dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
1990 dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
1991 #else
1992 dk3app_log_i1(app, DK3_LL_ERROR, 94);
1993 #endif
1994 }
1995 }
1996 }
1997 #if DK3_HAVE_SETPWENT
1998 endpwent();
1999 #endif
2000 #endif
2001 }
2002 return back;
2003 }
2004
2005
2006
2007 int
dk3sf_c8_get_home_app(char * d,size_t s,dk3_app_t * app)2008 dk3sf_c8_get_home_app(char *d, size_t s, dk3_app_t *app)
2009 {
2010 int back = 0;
2011 uid_t u = 0; /* Current user ID to process. */
2012 struct passwd *p = NULL; /* Current user to process. */
2013 char uidbuffer[128]; /* Text buffer to store UID. */
2014 if((d) && (s)) {
2015 u = getuid();
2016 #if DK3_HAVE_GETPWUID
2017 p = getpwuid(u);
2018 if(p) {
2019 if(p->pw_dir) {
2020 if(dk3str_c8_len(p->pw_dir) < s) {
2021 dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
2022 back = 1;
2023 } else {
2024 if(app) {
2025 /* Destination buffer too small! */
2026 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2027 }
2028 }
2029 } else {
2030 if(app) {
2031 /* Home directory entry empty! */
2032 dk3app_log_i1(app, DK3_LL_ERROR, 95);
2033 }
2034 }
2035 } else {
2036 if(app) {
2037 /* No passwd record for uid! */
2038 #if DK3_CHAR_SIZE == 1
2039 dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
2040 dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
2041 #else
2042 dk3app_log_i1(app, DK3_LL_ERROR, 94);
2043 #endif
2044 dk3sf_report_errno(app, errno, dk3sf_function_names[4]);
2045 }
2046 }
2047 #else
2048 {
2049 int cc;
2050 int found;
2051 cc = 1; found = 0;
2052 #if DK3_HAVE_SETPWENT
2053 setpwent();
2054 #endif
2055 while(cc) {
2056 p = getpwent();
2057 if(p) {
2058 if(p->pw_uid == u) {
2059 cc = 0; found = 1;
2060 if(p->pw_dir) {
2061 if(dk3str_c8_len(p->pw_dir) < s) {
2062 dk3str_c8_cpy_not_overlapped(d, p->pw_dir);
2063 back = 1;
2064 } else {
2065 if(app) {
2066 /* Destination buffer too small! */
2067 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2068 }
2069 }
2070 } else {
2071 if(app) {
2072 /* Home directory entry empty! */
2073 dk3app_log_i1(app, DK3_LL_ERROR, 95);
2074 }
2075 }
2076 }
2077 } else { cc = 0; }
2078 }
2079 #if DK3_HAVE_SETPWENT
2080 endpwent();
2081 #endif
2082 if(!found) {
2083 if(app) {
2084 /* No entry for uid! */
2085 #if DK3_CHAR_SIZE == 1
2086 dk3ma_um_to_c8_string(uidbuffer, sizeof(uidbuffer), (dk3_um_t)u);
2087 dk3app_log_i3(app, DK3_LL_ERROR, 92, 93, uidbuffer);
2088 #else
2089 dk3app_log_i1(app, DK3_LL_ERROR, 94);
2090 #endif
2091 }
2092 }
2093 }
2094 #endif
2095 }
2096 return back;
2097 }
2098
2099
2100 int
dk3sf_time(dk3_time_t * timer)2101 dk3sf_time(dk3_time_t *timer)
2102 {
2103 int back = 1;
2104 time(timer);
2105 return back;
2106 }
2107
2108
2109
2110 /** Convert file type from system representation to DK3_FT_xxx.
2111 @param m File type as found by stat().
2112 @return DK3_FT_xxx.
2113 */
2114 static
2115 int
dk3sf_convert_file_type(mode_t m)2116 dk3sf_convert_file_type(mode_t m)
2117 {
2118 int back = 0;
2119 switch(m & S_IFMT) {
2120 case S_IFIFO: back = DK3_FT_FIFO; break;
2121 case S_IFCHR: back = DK3_FT_SPECIAL_CHAR; break;
2122 case S_IFDIR: back = DK3_FT_DIRECTORY; break;
2123 case S_IFBLK: back = DK3_FT_SPECIAL_BLOCK; break;
2124 case S_IFREG: back = DK3_FT_REGULAR; break;
2125 case S_IFSOCK: back = DK3_FT_SOCKET; break;
2126 #ifdef S_IFMPC
2127 case S_IFMPC: back = DK3_FT_MUX_CHAR; break;
2128 #endif
2129 #ifdef S_IFNAM
2130 case S_IFNAM: back = DK3_FT_XENIX_SPECIAL; break;
2131 #endif
2132 #ifdef S_INSEM
2133 case S_INSEM: back = DK3_FT_XENIX_SEMAPHORE; break;
2134 #endif
2135 #ifdef S_INSHD
2136 case S_INSHD: back = DK3_FT_XENIX_SHARED_DATA; break;
2137 #endif
2138 #ifdef S_IFMPB
2139 case S_IFMPB: back = DK3_FT_MUX_BLOCK; break;
2140 #endif
2141 #ifdef S_IFCMP
2142 case S_IFCMP: back = DK3_FT_VXFS_COMPRESSED; break;
2143 #endif
2144 #ifdef S_IFNWK
2145 case S_IFNWK: back = DK3_FT_NETWORK_SPECIAL; break;
2146 #endif
2147 #ifdef S_IFSHAD
2148 case S_IFSHAD: back = DK3_FT_ACL_SHADOW; break;
2149 #endif
2150 #ifdef S_IFDOOR
2151 case S_IFDOOR: back = DK3_FT_DOOR; break;
2152 #endif
2153 #ifdef S_IFWHT
2154 case S_IFWHT: back = DK3_FT_WHITEOUT; break;
2155 #endif
2156 }
2157 return back;
2158 }
2159
2160
2161
2162 /** Convert file permissions from system representation to
2163 DK3_PERM_xxx
2164 @param m File mode as obtained from stat().
2165 @return DK3_PERM_xxx value or combination.
2166 */
2167 static
2168 int
dk3sf_convert_file_permissions(mode_t m)2169 dk3sf_convert_file_permissions(mode_t m)
2170 {
2171 int back = 0;
2172 DK3SF_ADDIF(S_IRUSR,DK3_FPERM_U_READ)
2173 DK3SF_ADDIF(S_IWUSR,DK3_FPERM_U_WRITE)
2174 DK3SF_ADDIF(S_IXUSR,DK3_FPERM_U_EXEC)
2175 DK3SF_ADDIF(S_IRGRP,DK3_FPERM_G_READ)
2176 DK3SF_ADDIF(S_IWGRP,DK3_FPERM_G_WRITE)
2177 DK3SF_ADDIF(S_IXGRP,DK3_FPERM_G_EXEC)
2178 DK3SF_ADDIF(S_IROTH,DK3_FPERM_O_READ)
2179 DK3SF_ADDIF(S_IWOTH,DK3_FPERM_O_WRITE)
2180 DK3SF_ADDIF(S_IXOTH,DK3_FPERM_O_EXEC)
2181 DK3SF_ADDIF(S_ISUID,DK3_FPERM_SUID)
2182 DK3SF_ADDIF(S_ISGID,DK3_FPERM_SGID)
2183 DK3SF_ADDIF(S_ISVTX,DK3_FPERM_VTX)
2184 return back;
2185 }
2186
2187
2188
2189 #if (1 == DK3_CHAR_SIZE) || (VERSION_BEFORE_2019_10_20)
2190
2191 /** Convert file permissions back from dktools to system values.
2192 @param m File permissions in dktools notation.
2193 @return File permissions in system notation.
2194 */
2195 static
2196 mode_t
dk3sf_convert_back_file_permissions(int m)2197 dk3sf_convert_back_file_permissions(int m)
2198 {
2199 mode_t back = 0;
2200 DK3SF_ADDIF(DK3_FPERM_U_READ,S_IRUSR)
2201 DK3SF_ADDIF(DK3_FPERM_U_WRITE,S_IWUSR)
2202 DK3SF_ADDIF(DK3_FPERM_U_EXEC,S_IXUSR)
2203 DK3SF_ADDIF(DK3_FPERM_G_READ,S_IRGRP)
2204 DK3SF_ADDIF(DK3_FPERM_G_WRITE,S_IWGRP)
2205 DK3SF_ADDIF(DK3_FPERM_G_EXEC,S_IXGRP)
2206 DK3SF_ADDIF(DK3_FPERM_O_READ,S_IROTH)
2207 DK3SF_ADDIF(DK3_FPERM_O_WRITE,S_IWOTH)
2208 DK3SF_ADDIF(DK3_FPERM_O_EXEC,S_IXOTH)
2209 DK3SF_ADDIF(DK3_FPERM_SUID,S_ISUID)
2210 DK3SF_ADDIF(DK3_FPERM_SGID,S_ISGID)
2211 DK3SF_ADDIF(DK3_FPERM_VTX,S_ISVTX)
2212 return back;
2213 }
2214
2215 #endif
2216
2217
2218 int
dk3sf_c8_stat_app(dk3_stat_t * st,char const * fn,dk3_app_t * app)2219 dk3sf_c8_stat_app(dk3_stat_t *st, char const *fn, dk3_app_t *app)
2220 {
2221 int back = 0;
2222
2223 if((st) && (fn)) {
2224 #if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_STAT64
2225 struct stat64 stb; /* Result from stat64(). */
2226 #if DK3_HAVE_LSTAT64
2227 struct stat64 lstb; /* Result from lstat64(). */
2228 #endif
2229
2230 if(stat64(fn, &stb) == 0) {
2231 st->u = (dk3_um_t)(stb.st_uid);
2232 st->g = (dk3_um_t)(stb.st_gid);
2233 st->device = (dk3_um_t)(stb.st_dev);
2234 st->rdev = (dk3_um_t)(stb.st_rdev);
2235 st->inode = (dk3_um_t)(stb.st_ino);
2236 st->nlink = (dk3_um_t)(stb.st_nlink);
2237 st->cre = (dk3_time_t)(stb.st_ctime);
2238 st->mod = (dk3_time_t)(stb.st_mtime);
2239 st->acc = (dk3_time_t)(stb.st_atime);
2240 st->ft = dk3sf_convert_file_type(stb.st_mode);
2241 st->perm = dk3sf_convert_file_permissions(stb.st_mode);
2242 st->sz = (dk3_um_t)(stb.st_size);
2243 st->lsz = st->sz;
2244 st->ai = 0x00;
2245 #if DK3_HAVE_LSTAT64
2246 if(lstat64(fn, &lstb) == 0) {
2247 back = 1;
2248 if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
2249 st->ft |= DK3_FT_SYMLINK;
2250 st->lu = (dk3_um_t)(lstb.st_uid);
2251 st->lg = (dk3_um_t)(lstb.st_gid);
2252 st->ldevice = (dk3_um_t)(lstb.st_dev);
2253 st->lrdev = (dk3_um_t)(lstb.st_rdev);
2254 st->linode = (dk3_um_t)(lstb.st_ino);
2255 st->lnlink = (dk3_um_t)(lstb.st_nlink);
2256 st->lcre = (dk3_time_t)(lstb.st_ctime);
2257 st->lmod = (dk3_time_t)(lstb.st_mtime);
2258 st->lacc = (dk3_time_t)(lstb.st_atime);
2259 st->lft = dk3sf_convert_file_type(lstb.st_mode);
2260 st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
2261 st->lsz = (dk3_um_t)(lstb.st_size);
2262 if(lstb.st_uid != stb.st_uid) {
2263 st->ai |= DK3_STAT_AI_USER_DIFFERS;
2264 }
2265 if(lstb.st_gid != stb.st_gid) {
2266 st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
2267 }
2268 if(lstb.st_dev != stb.st_dev) {
2269 st->ai |= DK3_STAT_AI_FAR_LINK;
2270 }
2271 }
2272 } else {
2273 if(app) {
2274 /* lstat() failed! */
2275 #if DK3_CHAR_SIZE == 1
2276 dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
2277 #else
2278 dk3app_log_i1(app, DK3_LL_ERROR, 98);
2279 #endif
2280 }
2281 }
2282 #else
2283 back = 1;
2284 #endif
2285 } else {
2286 #if DK3_HAVE_LSTAT64
2287 if(lstat64(fn, &lstb) == 0) {
2288 back = 1;
2289 st->u = DK3_UM_0;
2290 st->g = DK3_UM_0;
2291 st->device = DK3_UM_0;
2292 st->rdev = DK3_UM_0;
2293 st->inode = DK3_UM_0;
2294 st->nlink = DK3_UM_0;
2295 st->cre = (dk3_time_t)0UL;
2296 st->mod = (dk3_time_t)0UL;
2297 st->acc = (dk3_time_t)0UL;
2298 st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
2299 st->perm = 0;
2300 st->sz = DK3_UM_0;
2301 st->ai = 0x00;
2302 st->lu = (dk3_um_t)(lstb.st_uid);
2303 st->lg = (dk3_um_t)(lstb.st_gid);
2304 st->ldevice = (dk3_um_t)(lstb.st_dev);
2305 st->lrdev = (dk3_um_t)(lstb.st_rdev);
2306 st->linode = (dk3_um_t)(lstb.st_ino);
2307 st->lnlink = (dk3_um_t)(lstb.st_nlink);
2308 st->lcre = (dk3_time_t)(lstb.st_ctime);
2309 st->lmod = (dk3_time_t)(lstb.st_mtime);
2310 st->lacc = (dk3_time_t)(lstb.st_atime);
2311 st->lft = dk3sf_convert_file_type(lstb.st_mode);
2312 st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
2313 st->lsz = (dk3_um_t)(lstb.st_size);
2314 } else {
2315 if(app) {
2316 /* stat failed */
2317 #if DK3_CHAR_SIZE == 1
2318 dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
2319 #else
2320 dk3app_log_i1(app, DK3_LL_ERROR, 99);
2321 #endif
2322 dk3sf_report_errno(app, errno, dk3sf_function_names[5]);
2323 }
2324 }
2325 #else
2326 if(app) {
2327 /* stat failed */
2328 #if DK3_CHAR_SIZE == 1
2329 dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
2330 #else
2331 dk3app_log_i1(app, DK3_LL_ERROR, 99);
2332 #endif
2333 dk3sf_report_errno(app, errno, dk3sf_function_names[6]);
2334 }
2335 #endif
2336 }
2337 #else
2338 #if DK3_HAVE_STAT
2339 struct stat stb;
2340 #if DK3_HAVE_LSTAT
2341 struct stat lstb;
2342 #endif
2343
2344 if(stat(fn, &stb) == 0) {
2345 st->u = (dk3_um_t)(stb.st_uid);
2346 st->g = (dk3_um_t)(stb.st_gid);
2347 st->device = (dk3_um_t)(stb.st_dev);
2348 st->rdev = (dk3_um_t)(stb.st_rdev);
2349 st->inode = (dk3_um_t)(stb.st_ino);
2350 st->nlink = (dk3_um_t)(stb.st_nlink);
2351 st->cre = (dk3_time_t)(stb.st_ctime);
2352 st->mod = (dk3_time_t)(stb.st_mtime);
2353 st->acc = (dk3_time_t)(stb.st_atime);
2354 st->ft = dk3sf_convert_file_type(stb.st_mode);
2355 st->perm = dk3sf_convert_file_permissions(stb.st_mode);
2356 st->sz = (dk3_um_t)(stb.st_size);
2357 st->lsz = st->sz;
2358 st->ai = 0x00;
2359 #if DK3_HAVE_LSTAT
2360 if(lstat(fn, &lstb) == 0) {
2361 back = 1;
2362 if(((lstb.st_mode) & S_IFMT) == S_IFLNK) {
2363 st->ft |= DK3_FT_SYMLINK;
2364 st->lu = (dk3_um_t)(lstb.st_uid);
2365 st->lg = (dk3_um_t)(lstb.st_gid);
2366 st->ldevice = (dk3_um_t)(lstb.st_dev);
2367 st->lrdev = (dk3_um_t)(lstb.st_rdev);
2368 st->linode = (dk3_um_t)(lstb.st_ino);
2369 st->lnlink = (dk3_um_t)(lstb.st_nlink);
2370 st->lcre = (dk3_time_t)(lstb.st_ctime);
2371 st->lmod = (dk3_time_t)(lstb.st_mtime);
2372 st->lacc = (dk3_time_t)(lstb.st_atime);
2373 st->lft = dk3sf_convert_file_type(lstb.st_mode);
2374 st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
2375 st->lsz = (dk3_um_t)(lstb.st_size);
2376 if(lstb.st_uid != stb.st_uid) {
2377 st->ai |= DK3_STAT_AI_USER_DIFFERS;
2378 }
2379 if(lstb.st_gid != stb.st_gid) {
2380 st->ai |= DK3_STAT_AI_GROUP_DIFFERS;
2381 }
2382 if(lstb.st_dev != stb.st_dev) {
2383 st->ai |= DK3_STAT_AI_FAR_LINK;
2384 }
2385 }
2386 } else {
2387 if(app) {
2388 /* lstat() failed! */
2389 #if DK3_CHAR_SIZE == 1
2390 dk3app_log_i3(app, DK3_LL_ERROR, 96, 97, fn);
2391 #else
2392 dk3app_log_i1(app, DK3_LL_ERROR, 98);
2393 #endif
2394 }
2395 }
2396 #else
2397 back = 1;
2398 #endif
2399 } else {
2400 #if DK3_HAVE_LSTAT
2401 if(lstat(fn,&lstb) == 0) {
2402 back = 1;
2403 st->u = DK3_UM_0;
2404 st->g = DK3_UM_0;
2405 st->device = DK3_UM_0;
2406 st->rdev = DK3_UM_0;
2407 st->inode = DK3_UM_0;
2408 st->nlink = DK3_UM_0;
2409 st->cre = (dk3_time_t)0UL;
2410 st->mod = (dk3_time_t)0UL;
2411 st->acc = (dk3_time_t)0UL;
2412 st->ft = DK3_FT_SYMLINK | DK3_FT_BAD_SYMLINK;
2413 st->perm = 0;
2414 st->sz = DK3_UM_0;
2415 st->ai = 0x00;
2416 st->lu = (dk3_um_t)(lstb.st_uid);
2417 st->lg = (dk3_um_t)(lstb.st_gid);
2418 st->ldevice = (dk3_um_t)(lstb.st_dev);
2419 st->lrdev = (dk3_um_t)(lstb.st_rdev);
2420 st->linode = (dk3_um_t)(lstb.st_ino);
2421 st->lnlink = (dk3_um_t)(lstb.st_nlink);
2422 st->lcre = (dk3_time_t)(lstb.st_ctime);
2423 st->lmod = (dk3_time_t)(lstb.st_mtime);
2424 st->lacc = (dk3_time_t)(lstb.st_atime);
2425 st->lft = dk3sf_convert_file_type(lstb.st_mode);
2426 st->lperm = dk3sf_convert_file_permissions(lstb.st_mode);
2427 st->lsz = (dk3_um_t)(lstb.st_size);
2428 } else {
2429 if(app) {
2430 /* stat() failed! */
2431 #if DK3_CHAR_SIZE == 1
2432 dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
2433 #else
2434 dk3app_log_i1(app, DK3_LL_ERROR, 99);
2435 #endif
2436 dk3sf_report_errno(app, errno, dk3sf_function_names[8]);
2437 }
2438 }
2439 #else
2440 if(app) {
2441 /* stat() failed! */
2442 #if DK3_CHAR_SIZE == 1
2443 dk3app_log_i3(app, DK3_LL_ERROR, 61, 62, fn);
2444 #else
2445 dk3app_log_i1(app, DK3_LL_ERROR, 99);
2446 #endif
2447 dk3sf_report_errno(app, errno, dk3sf_function_names[7]);
2448 }
2449 #endif
2450 }
2451 #else
2452 #error "Not stat() function available!"
2453 #endif
2454 #endif
2455 }
2456 return back;
2457 }
2458
2459
2460
2461 /** Check whether opening a file is allowed.
2462 @param fn File name.
2463 @param want_to_write Flag: Write access is wanted.
2464 @param app Application structure for diagnostics, may be NULL.
2465 @return 1 for write allowed, 0 for write denied.
2466 */
2467 static
2468 int
dk3sf_c8_check_open_file(char const * fn,int want_to_write,dk3_app_t * app)2469 dk3sf_c8_check_open_file(char const *fn, int want_to_write, dk3_app_t *app)
2470 {
2471 int back = 1;
2472 dk3_stat_t stb; /* Check for existing file. */
2473 if(dk3sf_c8_stat_app(&stb, fn, NULL)) {
2474 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
2475 if(app) {
2476 back = 0;
2477 /* Name refers a directory! */
2478 #if DK3_CHAR_SIZE == 1
2479 dk3app_log_i3(app, DK3_LL_ERROR, 74, 75, fn);
2480 #else
2481 dk3app_log_i1(app, DK3_LL_ERROR, 76);
2482 #endif
2483 }
2484 }
2485 if(want_to_write) {
2486 if((stb.ft) & DK3_FT_SYMLINK) {
2487 if((stb.ai) & DK3_STAT_AI_USER_DIFFERS) {
2488 back = 0;
2489 /* Symlink owner is not file owner! */
2490 #if DK3_CHAR_SIZE == 1
2491 dk3app_log_i3(app, DK3_LL_ERROR, 100, 101, fn);
2492 #else
2493 dk3app_log_i1(app, DK3_LL_ERROR, 102);
2494 #endif
2495 }
2496 }
2497 }
2498 }
2499 return back;
2500 }
2501
2502
2503
2504 FILE *
dk3sf_c8_fopen_app(char const * fn,char const * mo,dk3_app_t * app)2505 dk3sf_c8_fopen_app(char const *fn, char const *mo, dk3_app_t *app)
2506 {
2507 FILE *back = NULL;
2508 char const *moptr = NULL; /* Traverse mode string. */
2509 int want_to_write = 0; /* Flag: Write access wanted. */
2510
2511 if((fn) && (mo)) {
2512 moptr = mo;
2513 while(*moptr) {
2514 switch(*moptr) {
2515 case 'w': case 'a': case '+': { want_to_write = 1; } break;
2516 }
2517 moptr++;
2518 }
2519 if(dk3sf_c8_check_open_file(fn, want_to_write, app)) {
2520 #if DK3_HAVE_LARGEFILE64_SOURCE && DK3_HAVE_FOPEN64
2521 back = fopen64(fn, mo);
2522 #else
2523 back = fopen(fn, mo);
2524 #endif
2525 if(!(back)) {
2526 if(app) {
2527 /* Failed to open file for writing! */
2528 if(want_to_write) {
2529 #if DK3_CHAR_SIZE == 1
2530 dk3app_log_i3(app, DK3_LL_ERROR, 77, 78, fn);
2531 #else
2532 dk3app_log_i1(app, DK3_LL_ERROR, 79);
2533 #endif
2534 } else {
2535 #if DK3_CHAR_SIZE == 1
2536 dk3app_log_i3(app, DK3_LL_ERROR, 143, 144, fn);
2537 #else
2538 dk3app_log_i1(app, DK3_LL_ERROR, 145);
2539 #endif
2540 }
2541 dk3sf_report_errno(app, errno, dk3sf_function_names[9]);
2542 }
2543 }
2544 }
2545 }
2546 return back;
2547 }
2548
2549
2550 #if DK3_HAVE_LOCALTIME_R
2551 int
dk3sf_localtime_app(dk3_tm_t * dest,dk3_time_t * timer,dk3_app_t * app)2552 dk3sf_localtime_app(
2553 dk3_tm_t *dest,
2554 dk3_time_t *timer,
2555 dk3_app_t *app
2556 )
2557 {
2558 int back = 0;
2559 struct tm res, *rp;
2560 if((dest) && (timer)) {
2561 if((rp = localtime_r(timer, &res)) != NULL) {
2562 back = 1;
2563 dest->Y = 1900 + rp->tm_year;
2564 dest->M = 1 + rp->tm_mon;
2565 dest->D = rp->tm_mday;
2566 dest->h = rp->tm_hour;
2567 dest->m = rp->tm_min;
2568 dest->s = rp->tm_sec;
2569 } else {
2570 if(app) {
2571 /* ERROR: localtime_r failed! */
2572 dk3app_log_i1(app, DK3_LL_ERROR, 268);
2573 dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
2574 }
2575 }
2576 }
2577 return back;
2578 }
2579
2580 int
dk3sf_c8_time_convert_app(dkChar * dest,size_t sz,dk3_time_t const * timer,dk3_app_t * app)2581 dk3sf_c8_time_convert_app(
2582 dkChar *dest, size_t sz, dk3_time_t const *timer, dk3_app_t *app
2583 )
2584 {
2585 int back = 0;
2586 char buffer[64]; /* Buffer. */
2587 struct tm res, *rp; /* Conversion result. */
2588 if((dest) && (sz) && (timer)) {
2589 rp = localtime_r(timer, &res);
2590 if(rp) {
2591 sprintf(
2592 buffer,
2593 "%04d-%02d-%02d %02d:%02d:%02d",
2594 (1900 + rp->tm_year),
2595 (1 + rp->tm_mon),
2596 rp->tm_mday,
2597 rp->tm_hour,
2598 rp->tm_min,
2599 rp->tm_sec
2600 );
2601 if(sz > dk3str_c8_len(buffer)) {
2602 dk3str_c8_cpy_not_overlapped(dest, buffer);
2603 back = 1;
2604 } else {
2605 if(app) {
2606 /* Buffer too small! */
2607 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2608 }
2609 }
2610 } else {
2611 if(app) {
2612 /* localtime_r failed! */
2613 dk3app_log_i1(app, DK3_LL_ERROR, 80);
2614 dk3sf_report_errno(app, errno, dk3sf_function_names[10]);
2615 }
2616 }
2617 }
2618 return back;
2619 }
2620 #else
2621 #error "Function localtime_r() not available!"
2622 #endif
2623
2624
2625
2626 #if DK3_HAVE_GETCWD || DK3_HAVE__GETCWD
2627 int
dk3sf_c8_getcwd_app(char * dest,size_t sz,dk3_app_t * app)2628 dk3sf_c8_getcwd_app(char *dest, size_t sz, dk3_app_t *app)
2629 {
2630 int back = 0;
2631 if((dest) && (sz)) {
2632 #if DK3_HAVE_GETCWD
2633 if(getcwd(dest, sz))
2634 #else
2635 if(_getcwd(dest, sz))
2636 #endif
2637 {
2638 back = 1;
2639 } else {
2640 if(app) {
2641 switch(errno) {
2642 #ifdef ERANGE
2643 case ERANGE: {
2644 /* Buffer too small! */
2645 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2646 } break;
2647 #endif
2648 default: {
2649 dk3app_log_i1(app, DK3_LL_ERROR, 53);
2650 dk3sf_report_errno(app, errno, dk3sf_function_names[11]);
2651 } break;
2652 }
2653 }
2654 }
2655 }
2656 return back;
2657 }
2658 #else
2659 #error "Neither getcwd() or _getcwd() available!"
2660 #endif
2661
2662
2663
2664 /** Check whether or not a file is executable.
2665 @param f File name.
2666 @return 1 for exectuable, 0 for not executable.
2667 */
2668 static
2669 int
dk3sf_c8_check_exec(char const * f)2670 dk3sf_c8_check_exec(char const *f)
2671 {
2672 int back = 0;
2673 int testperm; /* Permissions of file. */
2674 dk3_stat_t stb; /* stat() result to check for file. */
2675
2676 if(dk3sf_c8_stat_app(&stb, f, NULL)) {
2677 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
2678 testperm = (DK3_FPERM_U_EXEC | DK3_FPERM_G_EXEC | DK3_FPERM_O_EXEC);
2679 if((stb.perm) & testperm) {
2680 back = 1;
2681 } else {
2682 }
2683 } else {
2684 }
2685 } else {
2686 }
2687 return back;
2688 }
2689
2690
2691
2692 int
dk3sf_c8_find_exec_app(char * d,size_t s,char const * w,char const * c,dk3_app_t * app)2693 dk3sf_c8_find_exec_app(
2694 char *d, size_t s, char const *w, char const *c, dk3_app_t *app
2695 )
2696 {
2697 int back = 0;
2698 int cc = 0; /* Flag: Can continue. */
2699 char *pathcopy = NULL; /* Copy of parent directory. */
2700 char *p = NULL;
2701 char *pn = NULL;
2702 size_t tsl = 0; /* Needed buffer length. */
2703
2704 if((d) && (s) && (w) && (c)) {
2705 if(dk3str_c8_chr(c, DK3_C8_SEP)) {
2706 if(dk3str_c8_is_abs_path(c)) {
2707 if(dk3str_c8_len(c) < s) {
2708 dk3str_c8_cpy_not_overlapped(d, c);
2709 back = 1;
2710 } else {
2711 if(app) {
2712 /* c too long! */
2713 #if DK3_CHAR_SIZE == 1
2714 dk3app_log_i3(app, DK3_LL_ERROR, 103, 104, c);
2715 #else
2716 dk3app_log_i1(app, DK3_LL_ERROR, 105);
2717 #endif
2718 }
2719 }
2720 } else {
2721 if(dk3str_c8_len(w) < s) {
2722 dk3str_c8_cpy_not_overlapped(d, w);
2723 back = dk3str_c8_append_path_app(d, s, c, app);
2724 if(back) {
2725 }
2726 } else {
2727 if(app) {
2728 /* w too long! */
2729 #if DK3_CHAR_SIZE == 1
2730 dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, w);
2731 #else
2732 dk3app_log_i1(app, DK3_LL_ERROR, 87);
2733 #endif
2734 }
2735 }
2736 }
2737 } else {
2738 p = getenv(kw_c8_no_win[1]);
2739 if(p) {
2740 pathcopy = dk3str_dup_app(p, app);
2741 if(pathcopy) {
2742 p = pathcopy; cc = 1;
2743 while((p) && (cc) && (back == 0)) {
2744 pn = dk3str_c8_chr(p, ':');
2745 if(pn) { *(pn++) = '\0'; }
2746 if(dk3str_c8_len(p)) {
2747 tsl = dk3str_c8_len(p);
2748 tsl += dk3str_c8_len(kw_c8_no_win[0]);
2749 tsl += dk3str_c8_len(c);
2750 if(tsl < s) {
2751 dk3str_c8_cpy_not_overlapped(d, p);
2752 dk3str_c8_cat(d, kw_c8_no_win[0]);
2753 dk3str_c8_cat(d, c);
2754 back = dk3sf_c8_check_exec(d);
2755 } else {
2756 cc = 0;
2757 if(app) {
2758 /* Destination buffer too small! */
2759 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2760 }
2761 }
2762 } else {
2763 tsl = dk3str_c8_len(w);
2764 tsl += dk3str_c8_len(kw_c8_no_win[0]);
2765 tsl += dk3str_c8_len(c);
2766 if(tsl < s) {
2767 dk3str_c8_cpy_not_overlapped(d, w);
2768 dk3str_c8_cat(d, kw_c8_no_win[0]);
2769 dk3str_c8_cat(d, c);
2770 back = dk3sf_c8_check_exec(d);
2771 } else {
2772 cc = 0;
2773 if(app) {
2774 /* Destination buffer too small! */
2775 dk3app_log_i1(app, DK3_LL_ERROR, 38);
2776 }
2777 }
2778 }
2779 p = pn;
2780 }
2781 dk3_delete(pathcopy);
2782 } else {
2783 }
2784 } else {
2785 if(app) {
2786 /* PATH environment variable not defined. */
2787 dk3app_log_i1(app, DK3_LL_ERROR, 106);
2788 }
2789 }
2790 }
2791 }
2792 return back;
2793 }
2794
2795
2796
2797 int
dk3sf_c8_mkdir_app(char const * p,int mo,dk3_app_t * app)2798 dk3sf_c8_mkdir_app(char const *p, int mo, dk3_app_t *app)
2799 {
2800 int back = 0;
2801 char buffer[DK3_MAX_PATH]; /* File names of parent directories. */
2802 char *ptr = NULL; /* Current path separator. */
2803 int cc = 0; /* Flag: Can continue. */
2804 mode_t m = 0; /* File creation mode. */
2805 dk3_stat_t stb; /* Check for existance of file or directory. */
2806
2807 if(p) {
2808 m = dk3sf_convert_back_file_permissions(mo);
2809 if(dk3str_c8_len(p) < sizeof(buffer)) {
2810 dk3str_c8_cpy_not_overlapped(buffer, p);
2811 ptr = buffer; cc = 1;
2812 while((cc) && (ptr)) {
2813 ptr = dk3str_c8_chr(ptr, DK3_C8_SEP);
2814 if(ptr) {
2815 *ptr = '\0';
2816 if(dk3str_c8_len(buffer) > 0) {
2817 if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
2818 if(((stb.ft) & (~(DK3_FT_SYMLINK))) != DK3_FT_DIRECTORY) {
2819 cc = 0;
2820 if(app) {
2821 /* Not a directory! */
2822 #if DK3_CHAR_SIZE == 1
2823 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
2824 #else
2825 dk3app_log_i1(app, DK3_LL_ERROR, 83);
2826 #endif
2827 }
2828 }
2829 } else {
2830 #if DK3_HAVE_MKDIR
2831 #if DK3_HAVE_MKDIR2
2832 if(mkdir(buffer, m) == 0)
2833 #else
2834 if(mkdir(buffer) == 0)
2835 #endif
2836 {
2837 #if DK3_HAVE_CHMOD
2838 (void)chmod(buffer, m);
2839 #endif
2840 } else {
2841 cc = 0;
2842 if(app) {
2843 /* Failed to create directory! */
2844 #if DK3_CHAR_SIZE == 1
2845 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
2846 #else
2847 dk3app_log_i1(app, DK3_LL_ERROR, 86);
2848 #endif
2849 dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
2850 }
2851 }
2852 #else
2853 cc = 0;
2854 if(app) {
2855 /* No mkdir() function available! */
2856 dk3app_log_i1(app, DK3_LL_ERROR, 107);
2857 }
2858 #endif
2859 }
2860 }
2861 *ptr = DK3_C8_SEP;
2862 ptr++;
2863 }
2864 }
2865 if(cc) {
2866 if(dk3sf_c8_stat_app(&stb, buffer, NULL)) {
2867 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
2868 back = 1;
2869 } else {
2870 if(app) {
2871 /* Not a directory! */
2872 #if DK3_CHAR_SIZE == 1
2873 dk3app_log_i3(app, DK3_LL_ERROR, 81, 82, buffer);
2874 #else
2875 dk3app_log_i1(app, DK3_LL_ERROR, 83);
2876 #endif
2877 }
2878 }
2879 } else {
2880 #if DK3_HAVE_MKDIR
2881 #if DK3_HAVE_MKDIR2
2882 if(mkdir(buffer, m) == 0)
2883 #else
2884 if(mkdir(buffer) == 0)
2885 #endif
2886 {
2887 back = 1;
2888 #if DK3_HAVE_CHMOD
2889 (void)chmod(buffer, m);
2890 #endif
2891 } else {
2892 #if DK3_CHAR_SIZE == 1
2893 dk3app_log_i3(app, DK3_LL_ERROR, 84, 85, buffer);
2894 #else
2895 dk3app_log_i1(app, DK3_LL_ERROR, 86);
2896 #endif
2897 dk3sf_report_errno(app, errno, dk3sf_function_names[12]);
2898 }
2899 #else
2900 if(app) {
2901 /* No mkdir() function available! */
2902 dk3app_log_i1(app, DK3_LL_ERROR, 107);
2903 }
2904 #endif
2905 }
2906 }
2907 } else {
2908 if(app) {
2909 /* Path too long! */
2910 #if DK3_CHAR_SIZE == 1
2911 dk3app_log_i3(app, DK3_LL_ERROR, 59, 60, p);
2912 #else
2913 dk3app_log_i1(app, DK3_LL_ERROR, 87);
2914 #endif
2915 }
2916 }
2917 }
2918 return back;
2919 }
2920
2921
2922 int
dk3sf_c8_get_hostname_app(char * db,size_t sz,dk3_app_t * app)2923 dk3sf_c8_get_hostname_app(char *db, size_t sz, dk3_app_t *app)
2924 {
2925 int back = 0;
2926 char *ptr = NULL; /* Begin of DNS domain name. */
2927 if((db) && (sz)) {
2928 if(gethostname(db, sz) == 0) {
2929 back = 1;
2930 ptr = dk3str_c8_chr(db, '.');
2931 if(ptr) {
2932 *ptr = '\0';
2933 }
2934 } else {
2935 if(app) {
2936 /* ERROR: Failed to find host name! */
2937 dk3app_log_i1(app, DK3_LL_ERROR, 131);
2938 dk3sf_report_errno(app, errno, dk3sf_function_names[13]);
2939 }
2940 }
2941 }
2942 return back;
2943 }
2944
2945
2946
2947 #if DK3_CHAR_SIZE > 1
2948 #error "dkChar must be 8 bit on non-Windows systems!"
2949 #else
2950 /* +++ non-Windows, dkChar 8 bit +++ */
2951
2952
2953
2954 int
dk3sf_fgets_fn_app(dkChar * db,size_t sz,FILE * fi,dkChar const * fn,dk3_app_t * app)2955 dk3sf_fgets_fn_app(
2956 dkChar *db, size_t sz, FILE *fi, dkChar const *fn, dk3_app_t *app
2957 )
2958 {
2959 int back = 0;
2960 if((db) && (sz) && (fi)) {
2961 if(fgets(db, (int)sz, fi)) {
2962 back = 1;
2963 } else {
2964 if(!feof(fi)) {
2965 if(app) {
2966 if(fn) {
2967 dk3app_log_i3(app, DK3_LL_ERROR, 346, 347, fn);
2968 } else {
2969 dk3app_log_i1(app, DK3_LL_ERROR, 345);
2970 }
2971 dk3sf_report_errno(app, errno, dk3sf_function_names[25]);
2972 }
2973 }
2974 }
2975 }
2976 return back;
2977 }
2978
2979
2980
2981 int
dk3sf_fputs_fn_app(dkChar const * st,FILE * fi,dkChar const * fn,dk3_app_t * app)2982 dk3sf_fputs_fn_app(dkChar const *st,FILE *fi,dkChar const *fn,dk3_app_t *app)
2983 {
2984 int back = 0;
2985 if((st) && (fi)) {
2986 if(fputs(st, fi) >= 0) {
2987 back = 1;
2988 } else {
2989 if(app) {
2990 if(fn) {
2991 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
2992 } else {
2993 dk3app_log_i1(app, DK3_LL_ERROR, 120);
2994 }
2995 dk3sf_report_errno(app, errno, dk3sf_function_names[23]);
2996 }
2997 }
2998 }
2999 return back;
3000 }
3001
3002
3003
3004 int
dk3sf_fputc_fn_app(dkChar ch,FILE * fi,dkChar const * fn,dk3_app_t * app)3005 dk3sf_fputc_fn_app(dkChar ch, FILE *fi, dkChar const *fn, dk3_app_t *app)
3006 {
3007 int back = 0;
3008 if(fi) {
3009 if(fputc(ch, fi) != EOF) {
3010 back = 1;
3011 } else {
3012 if(app) {
3013 if(fn) {
3014 dk3app_log_i3(app, DK3_LL_ERROR, 343, 344, fn);
3015 } else {
3016 dk3app_log_i1(app, DK3_LL_ERROR, 120);
3017 }
3018 dk3sf_report_errno(app, errno, dk3sf_function_names[24]);
3019 }
3020 }
3021 }
3022 return back;
3023 }
3024
3025
3026
3027 void
dk3sf_initialize_stdout(void)3028 dk3sf_initialize_stdout(void)
3029 {
3030 }
3031
3032
3033
3034 void
dk3sf_initialize_stderr(void)3035 dk3sf_initialize_stderr(void)
3036 {
3037 }
3038
3039
3040
3041 void
dk3sf_initialize_file(FILE * DK3_ARG_UNUSED (fipo))3042 dk3sf_initialize_file(FILE * DK3_ARG_UNUSED(fipo) )
3043 {
3044 DK3_UNUSED_ARG(fipo)
3045 }
3046
3047
3048
3049 /* --- non-Windows, dkChar 8 bit --- */
3050 #endif
3051
3052 /* --- non-Windows --- */
3053 #endif
3054
3055
3056
3057 int
dk3sf_must_expand(dkChar const * fn)3058 dk3sf_must_expand(dkChar const *fn)
3059 {
3060 int back = 0;
3061
3062 if(fn) {
3063 #if DK3_ON_WINDOWS
3064 dkChar const *ptr;
3065 ptr = fn;
3066 while((*ptr) && (back == 0)) {
3067 switch(*ptr) {
3068 case dkT('?'):
3069 case dkT('*'):
3070 {
3071 back = 1;
3072 }
3073 break;
3074 }
3075 ptr++;
3076 }
3077 #endif
3078 }
3079 return back;
3080 }
3081
3082
3083
3084 int
dk3sf_c8_fputc(char c,FILE * f)3085 dk3sf_c8_fputc(char c, FILE *f)
3086 {
3087 int back = 0;
3088 if(f) {
3089 #if DK3_CHAR_SIZE > 1
3090 #if DK3_CHAR_SIZE > 2
3091 if(fputwc((((wchar_t)c) & 0x000000FFUL), f) != WEOF) {
3092 back = 1;
3093 }
3094 #else
3095 if(fputwc((((wchar_t)c) & 0x00FFU), f) != WEOF) {
3096 back = 1;
3097 }
3098 #endif
3099 #else
3100 if(fputc(c, f) != EOF) {
3101 back = 1;
3102 }
3103 #endif
3104 }
3105 return back;
3106 }
3107
3108
3109
3110 int
dk3sf_c8_fputs(char const * s,FILE * f)3111 dk3sf_c8_fputs(char const *s, FILE *f)
3112 {
3113 int back = 0;
3114 char const *ptr = NULL;
3115 if((s) && (f)) {
3116 back = 1;
3117 ptr = s;
3118 while(*ptr) {
3119 if(!dk3sf_c8_fputc(*(ptr++), f)) {
3120 back = 0;
3121 }
3122 }
3123 }
3124 return back;
3125 }
3126
3127
3128
3129 size_t
dk3sf_read_app(int fd,void * buf,size_t s,dk3_app_t * app)3130 dk3sf_read_app(int fd, void *buf, size_t s, dk3_app_t *app)
3131 {
3132 size_t back = 0;
3133
3134 if((buf) && (s)) {
3135 #if DK3_ON_WINDOWS
3136 int rb;
3137
3138 rb = _read(fd, buf, (unsigned int)s);
3139 if(rb >= 0) {
3140 back = (size_t)rb;
3141 } else {
3142 /* ERROR: Read failed! */
3143 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3144 }
3145
3146 #else
3147
3148 #if DK3_HAVE_READ
3149 ssize_t rb = 0; /* Number of bytes read. */
3150
3151 rb = read(fd, buf, s);
3152 if(rb >= (ssize_t)0) {
3153 back = (size_t)rb;
3154 } else {
3155 if(app) {
3156 /* ERROR: Read failed! */
3157 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3158 dk3sf_report_errno(app, errno, dk3sf_function_names[14]);
3159 }
3160 }
3161 #else
3162 #if DK3_HAVE__READ
3163 ssize_t rb = 0; /* Number of bytes read. */
3164
3165 rb = _read(fd, buf, s);
3166 if(rb >= (ssize_t)0) {
3167 back = (size_t)rb;
3168 } else {
3169 if(app) {
3170 /* ERROR: Read failed! */
3171 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3172 dk3sf_report_errno(app, errno, dk3sf_function_names[15]);
3173 }
3174 }
3175 #else
3176 #error "No read() function available!"
3177 #endif
3178 #endif
3179
3180 #endif
3181 }
3182 return back;
3183 }
3184
3185
3186
3187 int
dk3sf_write_app(int fd,char const * buf,size_t s,dk3_app_t * app)3188 dk3sf_write_app(int fd, char const *buf, size_t s, dk3_app_t *app)
3189 {
3190 int back = 0;
3191 if((buf) && (s)) {
3192 #if DK3_ON_WINDOWS
3193 int wb;
3194 wb = _write(fd, buf, (unsigned int)s);
3195 if(wb >= 0) {
3196 if((size_t)wb == s) {
3197 back = 1;
3198 } else {
3199 if(app) {
3200 /* ERROR: Not all bytes written! */
3201 dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
3202 }
3203 }
3204 } else {
3205 if(app) {
3206 /* ERROR: Write failed! */
3207 dk3app_log_i1( app, DK3_LL_ERROR, 173);
3208 }
3209 }
3210 #else
3211 #if DK3_HAVE_WRITE
3212 ssize_t wb;
3213 wb = write(fd, buf, s);
3214 if(wb >= 0) {
3215 if((size_t)wb == s) {
3216 back = 1;
3217 } else {
3218 if(app) {
3219 /* ERROR: Not all bytes written! */
3220 dk3app_log_write_error(app, DK3_LL_ERROR, s, (size_t)wb);
3221 }
3222 }
3223 } else {
3224 if(app) {
3225 /* ERROR: Write failed! */
3226 dk3app_log_i1(app, DK3_LL_ERROR, 173);
3227 dk3sf_report_errno(app, errno, dk3sf_function_names[16]);
3228 }
3229 }
3230 #else
3231 #if DK3_HAVE__WRITE
3232 ssize_t wb;
3233 wb = _write(fd, buf, s);
3234 if(wb >= 0) {
3235 if((size_t)wb == s) {
3236 back = 1;
3237 } else {
3238 if(app) {
3239 /* ERROR: Not all bytes written! */
3240 dk3app_log_write_error(app, DK3_LL_ERROR, s, wb);
3241 }
3242 }
3243 } else {
3244 if(app) {
3245 /* ERROR: Write failed! */
3246 dk3app_log_i1(app, DK3_LL_ERROR, 173);
3247 dk3sf_report_errno(app, errno, dk3sf_function_names[17]);
3248 }
3249 }
3250 #else
3251 #error "No write() function available!"
3252 #endif
3253 #endif
3254 #endif
3255 }
3256 return back;
3257 }
3258
3259
3260 size_t
dk3sf_fread_app(void * db,size_t sz,size_t ne,FILE * fi,dk3_app_t * app)3261 dk3sf_fread_app(void *db, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
3262 {
3263 size_t back = 0;
3264 if((db) && (sz) && (ne) && (fi)) {
3265 #if DK3_ON_WINDOWS
3266 back = fread(db, sz, ne, fi);
3267 if(back < ne) {
3268 if(ferror(fi)) {
3269 if(app) {
3270 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3271 }
3272 }
3273 clearerr(fi);
3274 }
3275 #else
3276 #if DK3_HAVE_FREAD
3277 back = fread(db, sz, ne, fi);
3278 if(back < ne) {
3279 if(ferror(fi)) {
3280 if(app) {
3281 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3282 dk3sf_report_errno(app, errno, dk3sf_function_names[18]);
3283 }
3284 } clearerr(fi);
3285 }
3286 #else
3287 #if DK3_HAVE__FREAD
3288 back = _fread(db, sz, ne, fi);
3289 if(back < ne) {
3290 if(ferror(fi)) {
3291 if(app) {
3292 dk3app_log_i1(app, DK3_LL_ERROR, 124);
3293 dk3sf_report_errno(app, errno, dk3sf_function_names[19]);
3294 }
3295 } clearerr(fi);
3296 }
3297 #else
3298 #error "No fread() function available!"
3299 #endif
3300 #endif
3301 #endif
3302 }
3303 return back;
3304 }
3305
3306
3307
3308 int
dk3sf_fwrite_app(void const * sb,size_t sz,size_t ne,FILE * fi,dk3_app_t * app)3309 dk3sf_fwrite_app(void const *sb, size_t sz, size_t ne, FILE *fi, dk3_app_t *app)
3310 {
3311 int back = 0;
3312 if((sb) && (sz) && (ne) && (fi)) {
3313 #if DK3_ON_WINDOWS
3314 size_t wb;
3315 wb = fwrite(sb, sz, ne, fi);
3316 if(wb == ne) {
3317 back = 1;
3318 } else {
3319 if(app) {
3320 dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
3321 }
3322 }
3323 #else
3324 #if DK3_HAVE_FWRITE
3325 size_t wb;
3326 wb = fwrite(sb, sz, ne, fi);
3327 if(wb == ne) {
3328 back = 1;
3329 } else {
3330 if(app) {
3331 dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
3332 dk3sf_report_errno(app, errno, dk3sf_function_names[20]);
3333 }
3334 }
3335 #else
3336 #if DK3_HAVE__FWRITE
3337 size_t wb;
3338 wb = _fwrite(sb, sz, ne, fi);
3339 if(wb == ne) {
3340 back = 1;
3341 } else {
3342 if(app) {
3343 dk3app_log_fwrite_error(app, DK3_LL_ERROR, ne, wb);
3344 dk3sf_report_errno(app, errno, dk3sf_function_names[21]);
3345 }
3346 }
3347 #else
3348 #error "No fwrite() function available!"
3349 #endif
3350 #endif
3351 #endif
3352 }
3353 return back;
3354 }
3355
3356
3357
3358 int
dk3sf_inspect_bom_skip_app(dkChar const * fn,int dv,size_t * skb,dk3_app_t * app)3359 dk3sf_inspect_bom_skip_app(
3360 dkChar const *fn,
3361 int dv,
3362 size_t *skb,
3363 dk3_app_t *app
3364 )
3365 {
3366 int back = -1;
3367 int found = 0; /* Flag: Any form of BOM found .*/
3368 FILE *fipo = NULL; /* Input file. */
3369 unsigned char bb[4]; /* Buffer for BOM. */
3370 size_t rb = 0; /* Number of bytes read. */
3371
3372 if(skb) { *skb = 0; }
3373 back = dv;
3374 if(fn) {
3375 fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app);
3376 if(fipo) {
3377 rb = dk3sf_fread_app(bb, 1, 4, fipo, app);
3378 /* Check UTF-8 */
3379 if(rb >= 3) {
3380 if((bb[0] == 0xEF) && (bb[1] == 0xBB) && (bb[2] == 0xBF)) {
3381 found = 1; back = DK3_FILE_ENCODING_UTF8;
3382 if(skb) { *skb = 3; }
3383 }
3384 }
3385 if(!found) {
3386 if(rb >= 2) {
3387 if((bb[0] == 0xFE) && (bb[1] == 0xFF)) {
3388 found = 1; back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
3389 if(skb) { *skb = 2; }
3390 } else {
3391 if((bb[0] == 0xFF) && (bb[1] == 0xFE)) {
3392 found = 1; back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
3393 if(skb) { *skb = 2; }
3394 if(rb >= 4) {
3395 if((bb[2] == 0x00) && (bb[3] == 0x00)) {
3396 back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
3397 if(skb) { *skb = 4; }
3398 }
3399 }
3400 }
3401 }
3402 }
3403 }
3404 if(!found) {
3405 if(rb >= 4) {
3406 if((bb[0] == 0x00) && (bb[1] == 0x00)
3407 && (bb[2] == 0xFE) && (bb[3] == 0xFF)
3408 )
3409 {
3410 found = 1; back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
3411 if(skb) { *skb = 4; }
3412 }
3413 }
3414 }
3415 if(!found) {
3416 /* No BOM found */
3417 back = dv;
3418 }
3419 fclose(fipo);
3420 }
3421 }
3422 return back;
3423 }
3424
3425
3426
3427 int
dk3sf_inspect_bom_app(dkChar const * fn,int dv,dk3_app_t * app)3428 dk3sf_inspect_bom_app(dkChar const *fn, int dv, dk3_app_t *app)
3429 {
3430 int back;
3431 back = dk3sf_inspect_bom_skip_app(fn, dv, NULL, app);
3432 return back;
3433 }
3434
3435
3436
3437 int
dk3sf_apply_bom_to_file_app(FILE * fipo,int enc,dk3_app_t * app)3438 dk3sf_apply_bom_to_file_app(FILE *fipo, int enc, dk3_app_t *app)
3439 {
3440 int back = 0;
3441
3442 #if DK3_ON_WINDOWS
3443 if(fipo) {
3444 switch(enc) {
3445 case DK3_FILE_ENCODING_ASCII: {
3446 back = 1;
3447 } break;
3448 case DK3_FILE_ENCODING_UTF8: {
3449 back = 1;
3450 #if defined(_MSC_VER)
3451 _setmode(_fileno(fipo), _O_U8TEXT);
3452 #endif
3453 } break;
3454 case DK3_FILE_ENCODING_UTF16_LSB_FIRST: {
3455 #if defined(_MSC_VER)
3456 _setmode(_fileno(fipo), _O_U16TEXT);
3457 #endif
3458 } break;
3459 default: {
3460 /* ERROR: Encoding can not be handled directly by file! */
3461 dk3app_log_i1(app, DK3_LL_ERROR, 204);
3462 } break;
3463 }
3464 }
3465 #else
3466 if(fipo) {
3467 switch(enc) {
3468 case DK3_FILE_ENCODING_ASCII: case DK3_FILE_ENCODING_UTF8: {
3469 back = 1;
3470 } break;
3471 default: {
3472 /* ERROR: Encoding can not be handled direcly by file! */
3473 dk3app_log_i1(app, DK3_LL_ERROR, 204);
3474 } break;
3475 }
3476 }
3477 #endif
3478
3479 return back;
3480 }
3481
3482
3483
3484 int
dk3sf_is_dir_app(dkChar const * n,dk3_app_t * app)3485 dk3sf_is_dir_app(dkChar const *n, dk3_app_t *app)
3486 {
3487 int back = 0;
3488 dk3_stat_t stb;
3489 if(dk3sf_stat_app(&stb, n, app)) {
3490 if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_DIRECTORY) {
3491 back = 1;
3492 } else {
3493 if(app) {
3494 /* ERROR: n is not a directory! */
3495 dk3app_log_i3(app, DK3_LL_ERROR, 202, 203, n);
3496 }
3497 }
3498 }
3499 return back;
3500 }
3501
3502
3503
3504 int
dk3sf_chdir_app(dkChar const * dn,dk3_app_t * app)3505 dk3sf_chdir_app(dkChar const *dn, dk3_app_t *app)
3506 {
3507 int back = 0;
3508 if(dn) {
3509 #if DK3_CHAR_SIZE > 1
3510 #if DK3_ON_WINDOWS
3511 if(_wchdir(dn) == 0) {
3512 back = 1;
3513 } else {
3514 if(app) {
3515 dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
3516 }
3517 }
3518 #else
3519 #error "No chdir() function (16-bit) on non-Windows systems!"
3520 #endif
3521 #else
3522 #if DK3_ON_WINDOWS
3523 if(chdir(dn) == 0) {
3524 back = 1;
3525 } else {
3526 if(app) {
3527 dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
3528 }
3529 }
3530 #else
3531 #if DK3_HAVE_CHDIR
3532 if(chdir(dn) == 0) {
3533 back = 1;
3534 } else {
3535 if(app) {
3536 dk3app_log_i3(app, DK3_LL_ERROR, 242, 243, dn);
3537 dk3sf_report_errno(app, errno, dk3sf_function_names[22]);
3538 }
3539 }
3540 #else
3541 #error "No chdir() function available!"
3542 #endif
3543 #endif
3544 #endif
3545 }
3546 return back;
3547 }
3548
3549
3550
3551 int
dk3sf_must_rebuild(dkChar const * dn,dkChar const * sn)3552 dk3sf_must_rebuild(dkChar const *dn, dkChar const *sn)
3553 {
3554 int back = 1;
3555 dk3_stat_t stbs;
3556 dk3_stat_t stbd;
3557 if((dn) && (sn)) {
3558 if(dk3sf_stat_app(&stbd, dn, NULL)) {
3559 if(dk3sf_stat_app(&stbs, sn, NULL)) {
3560 if(stbd.mod > stbs.mod) {
3561 back = 0;
3562 }
3563 }
3564 }
3565 }
3566 return back;
3567 }
3568
3569
3570
3571 int
dk3sf_filename_to_c8(char * fnb,size_t szfnb,dkChar const * src,dk3_app_t * app)3572 dk3sf_filename_to_c8(
3573 char *fnb, size_t szfnb, dkChar const *src, dk3_app_t *app
3574 )
3575 {
3576 int back = 0;
3577 if((fnb) && (szfnb) && (src)) {
3578 #if DK3_CHAR_SIZE > 1
3579 #if DK3_CHAR_SIZE > 2
3580 #error "Only 1- or 2-byte character support available!"
3581 #else
3582 #if DK3_ON_WINDOWS
3583 back = dk3str_cnv_c16_to_c8p_app(fnb, szfnb, src, app);
3584 #else
3585 #error "2-byte character support is available on Windows platforms only!"
3586 #endif
3587 #endif
3588 #else
3589 if(dk3str_len(src) < szfnb) {
3590 dk3str_cpy_not_overlapped(fnb, src);
3591 back = 1;
3592 } else {
3593 /* ERROR: File name too long! */
3594 if(app) {
3595 dk3app_log_i3(app, DK3_LL_ERROR, 65, 66, src);
3596 }
3597 }
3598 #endif
3599 }
3600 return back;
3601 }
3602
3603
3604
3605 int
dk3sf_scan_double_app(dkChar const * txt,double * v,dk3_app_t * app)3606 dk3sf_scan_double_app(dkChar const *txt, double *v, dk3_app_t *app)
3607 {
3608 int back = 0;
3609
3610 if((txt) && (v)) {
3611 #if DK3_HAVE_SETLOCALE
3612 char oldlocale[64];
3613 char *lcptr;
3614
3615 lcptr = setlocale(LC_NUMERIC, NULL);
3616 if(lcptr) {
3617 if(dk3str_c8_len(lcptr) < sizeof(oldlocale)) {
3618 dk3str_c8_cpy_not_overlapped(oldlocale, lcptr);
3619 setlocale(LC_NUMERIC, "C");
3620 #if VERSION_BEFORE_20140716
3621 back = dk3sf_sscanf3(txt,dkT("%lf"),v);
3622 #else
3623 back = dk3ma_d_from_string(v, txt, NULL);
3624 #endif
3625 setlocale(LC_NUMERIC, oldlocale);
3626 } else {
3627 #if VERSION_BEFORE_20140716
3628 dk3sf_sscanf3(txt,dkT("%lf"),v);
3629 #else
3630 back = dk3ma_d_from_string(v, txt, NULL);
3631 #endif
3632 if(app) {
3633 /* ERROR: Failed to save current locale! */
3634 dk3app_log_i1(app, DK3_LL_ERROR, 254);
3635 }
3636 }
3637 } else {
3638 #if VERSION_BEFORE_20140716
3639 dk3sf_sscanf3(txt,dkT("%lf"),v);
3640 #else
3641 back = dk3ma_d_from_string(v, txt, NULL);
3642 #endif
3643 if(app) {
3644 /* ERROR: Failed to obtain current locale! */
3645 dk3app_log_i1(app, DK3_LL_ERROR, 253);
3646 }
3647 }
3648 #else
3649 #if VERSION_BEFORE_20140716
3650 back = dk3sf_sscanf3(txt,dkT("%lf"),v);
3651 #else
3652 back = dk3ma_d_from_string(v, txt, NULL);
3653 #endif
3654 #endif
3655 }
3656 return back;
3657 }
3658
3659
3660
3661 int
dk3sf_get_max_files(void)3662 dk3sf_get_max_files(void)
3663 {
3664 int back = 1024;
3665 #if DK3_HAVE_SYS_RESOURCE_H
3666 #if DK3_HAVE_GETRLIMIT
3667 struct rlimit rl;
3668 if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
3669 if(rl.rlim_max != RLIM_INFINITY) {
3670 /* Open file descriptors are int, so conversion to int is ok here */
3671 back = (int)(rl.rlim_max);
3672 }
3673 }
3674 #endif
3675 #endif
3676 return back;
3677 }
3678
3679
3680
3681
3682 int
dk3sf_fclose_fn_app(FILE * fipo,dkChar const * fn,dk3_app_t * app)3683 dk3sf_fclose_fn_app(FILE *fipo, dkChar const *fn, dk3_app_t *app)
3684 {
3685 int back = 0;
3686 int res;
3687 if(fipo) {
3688 res = fclose(fipo);
3689 if(0 == res) {
3690 back = 1;
3691 } else {
3692 if(fn) {
3693 dk3app_log_i3(app, DK3_LL_ERROR, 341, 342, fn);
3694 } else {
3695 dk3app_log_i1(app, DK3_LL_ERROR, 340);
3696 }
3697 dk3sf_report_errno(app, errno, dk3sf_function_names[1]);
3698 }
3699 }
3700 return back;
3701 }
3702
3703
3704
3705 int
dk3sf_fclose_app(FILE * fipo,dk3_app_t * app)3706 dk3sf_fclose_app(FILE *fipo, dk3_app_t *app)
3707 {
3708 int back = 0;
3709 back = dk3sf_fclose_fn_app(fipo, NULL, app);
3710 return back;
3711 }
3712
3713
3714
3715 int
dk3sf_fgets(dkChar * db,size_t sz,FILE * fi)3716 dk3sf_fgets(dkChar *db, size_t sz, FILE *fi)
3717 {
3718 int back;
3719 back = dk3sf_fgets_fn_app(db, sz, fi, NULL, NULL);
3720 return back;
3721 }
3722
3723
3724
3725 int
dk3sf_fputs(dkChar const * st,FILE * fi)3726 dk3sf_fputs(dkChar const *st, FILE *fi)
3727 {
3728 int back;
3729 back = dk3sf_fputs_fn_app(st, fi, NULL, NULL);
3730 return back;
3731 }
3732
3733
3734
3735 int
dk3sf_fputt(dkChar const * const * txt,FILE * fi)3736 dk3sf_fputt(dkChar const * const *txt, FILE *fi)
3737 {
3738 dkChar const * const *ptr;
3739 int back = 0;
3740 if((txt) && (fi)) {
3741 back = 1;
3742 ptr = txt;
3743 while(*ptr) {
3744 if(!(dk3sf_fputs(*(ptr++), fi))) {
3745 back = 0;
3746 }
3747 dk3sf_fputc(dkT('\n'), fi);
3748 }
3749 }
3750 return back;
3751 }
3752
3753
3754 int
dk3sf_fputc(dkChar c,FILE * fi)3755 dk3sf_fputc(dkChar c, FILE *fi)
3756 {
3757 int back;
3758 back = dk3sf_fputc_fn_app(c, fi, NULL, NULL);
3759 return back;
3760 }
3761
3762
3763
3764 int
dk3sf_stat_app(dk3_stat_t * st,dkChar const * fn,dk3_app_t * app)3765 dk3sf_stat_app(dk3_stat_t *st, dkChar const *fn, dk3_app_t *app)
3766 {
3767 #if DK3_CHAR_SIZE > 1
3768 #if DK3_CHAR_SIZE > 2
3769 #error "System function for b-byte character strings not available!"
3770 #else
3771 #if DK3_ON_WINDOWS
3772 return(dk3sf_c16_stat_app(st, fn, app));
3773 #else
3774 #error "Wide character functions not defined on non-Windows systems!"
3775 #endif
3776 #endif
3777 #else
3778 return(dk3sf_c8_stat_app(st, fn, app));
3779 #endif
3780 }
3781
3782
3783
3784 FILE *
dk3sf_fopen_app(dkChar const * fn,dkChar const * mo,dk3_app_t * app)3785 dk3sf_fopen_app(dkChar const *fn, dkChar const *mo, dk3_app_t *app)
3786 {
3787 #if DK3_CHAR_SIZE > 1
3788 #if DK3_CHAR_SIZE > 2
3789 #error "System function for b-byte character strings not available!"
3790 #else
3791 #if DK3_ON_WINDOWS
3792 return(dk3sf_c16_fopen_app(fn, mo, app));
3793 #else
3794 #error "Wide character functions not defined on non-Windows systems!"
3795 #endif
3796 #endif
3797 #else
3798 return(dk3sf_c8_fopen_app(fn, mo, app));
3799 #endif
3800 }
3801
3802
3803
3804 int
dk3sf_time_convert_app(dkChar * dest,size_t sz,dk3_time_t const * timer,dk3_app_t * app)3805 dk3sf_time_convert_app(
3806 dkChar *dest,
3807 size_t sz,
3808 dk3_time_t const *timer,
3809 dk3_app_t *app
3810 )
3811 {
3812 #if DK3_CHAR_SIZE > 1
3813 #if DK3_CHAR_SIZE > 2
3814 #error "System function for b-byte character strings not available!"
3815 #else
3816 #if DK3_ON_WINDOWS
3817 return(dk3sf_c16_time_convert_app(dest, sz, timer, app));
3818 #else
3819 #error "Wide character functions not defined on non-Windows systems!"
3820 #endif
3821 #endif
3822 #else
3823 return(dk3sf_c8_time_convert_app(dest, sz, timer, app));
3824 #endif
3825 }
3826
3827
3828
3829 int
dk3sf_getcwd_app(dkChar * dest,size_t sz,dk3_app_t * app)3830 dk3sf_getcwd_app(dkChar *dest, size_t sz, dk3_app_t *app)
3831 {
3832 #if DK3_CHAR_SIZE > 1
3833 #if DK3_CHAR_SIZE > 2
3834 #error "System function for b-byte character strings not available!"
3835 #else
3836 #if DK3_ON_WINDOWS
3837 return(dk3sf_c16_getcwd_app(dest, sz, app));
3838 #else
3839 #error "Wide character functions not defined on non-Windows systems!"
3840 #endif
3841 #endif
3842 #else
3843 return(dk3sf_c8_getcwd_app(dest, sz, app));
3844 #endif
3845 }
3846
3847
3848
3849 int
dk3sf_find_exec_app(dkChar * d,size_t s,dkChar const * w,dkChar const * c,dk3_app_t * app)3850 dk3sf_find_exec_app(
3851 dkChar *d,
3852 size_t s,
3853 dkChar const *w,
3854 dkChar const *c,
3855 dk3_app_t *app
3856 )
3857 {
3858 #if DK3_CHAR_SIZE > 1
3859 #if DK3_CHAR_SIZE > 2
3860 #error "System function for b-byte character strings not available!"
3861 #else
3862 #if DK3_ON_WINDOWS
3863 return(dk3sf_c16_find_exec_app(d, s, w, c, app));
3864 #else
3865 #error "Wide character functions not defined on non-Windows systems!"
3866 #endif
3867 #endif
3868 #else
3869 return(dk3sf_c8_find_exec_app(d, s, w, c, app));
3870 #endif
3871 }
3872
3873
3874
3875 int
dk3sf_get_logname_app(dkChar * d,size_t s,dk3_app_t * app)3876 dk3sf_get_logname_app(dkChar *d, size_t s, dk3_app_t *app)
3877 {
3878 #if DK3_CHAR_SIZE > 1
3879 #if DK3_CHAR_SIZE > 2
3880 #error "System function for b-byte character strings not available!"
3881 #else
3882 #if DK3_ON_WINDOWS
3883 return(dk3sf_c16_get_logname_app(d, s, app));
3884 #else
3885 #error "Wide character functions not defined on non-Windows systems!"
3886 #endif
3887 #endif
3888 #else
3889 return(dk3sf_c8_get_logname_app(d, s, app));
3890 #endif
3891 }
3892
3893
3894
3895 int
dk3sf_get_home_app(dkChar * d,size_t s,dk3_app_t * app)3896 dk3sf_get_home_app(dkChar *d, size_t s, dk3_app_t *app)
3897 {
3898 #if DK3_CHAR_SIZE > 1
3899 #if DK3_CHAR_SIZE > 2
3900 #error "System function for b-byte character strings not available!"
3901 #else
3902 #if DK3_ON_WINDOWS
3903 return(dk3sf_c16_get_home_app(d, s, app));
3904 #else
3905 #error "Wide character functions not defined on non-Windows systems!"
3906 #endif
3907 #endif
3908 #else
3909 return(dk3sf_c8_get_home_app(d, s, app));
3910 #endif
3911 }
3912
3913
3914
3915 int
dk3sf_mkdir_app(dkChar const * p,int mo,dk3_app_t * app)3916 dk3sf_mkdir_app(dkChar const *p, int mo, dk3_app_t *app)
3917 {
3918 #if DK3_CHAR_SIZE > 1
3919 #if DK3_CHAR_SIZE > 2
3920 #error "System function for b-byte character strings not available!"
3921 #else
3922 #if DK3_ON_WINDOWS
3923 return(dk3sf_c16_mkdir_app(p, mo, app));
3924 #else
3925 #error "Wide character functions not defined on non-Windows systems!"
3926 #endif
3927 #endif
3928 #else
3929 return(dk3sf_c8_mkdir_app(p, mo, app));
3930 #endif
3931 }
3932
3933
3934
3935 int
dk3sf_remove_file_app(dkChar const * n,dk3_app_t * app)3936 dk3sf_remove_file_app(dkChar const *n, dk3_app_t *app)
3937 {
3938 #if DK3_CHAR_SIZE > 1
3939 #if DK3_CHAR_SIZE > 2
3940 #error "System function for b-byte character strings not available!"
3941 #else
3942 #if DK3_ON_WINDOWS
3943 return(dk3sf_c16_remove_file_app(n, app));
3944 #else
3945 #error "Wide character functions not defined on non-Windows systems!"
3946 #endif
3947 #endif
3948 #else
3949 return(dk3sf_c8_remove_file_app(n, app));
3950 #endif
3951 }
3952
3953
3954
3955 int
dk3sf_remove_dir_app(dkChar const * n,dk3_app_t * app)3956 dk3sf_remove_dir_app(dkChar const *n, dk3_app_t *app)
3957 {
3958 #if DK3_CHAR_SIZE > 1
3959 #if DK3_CHAR_SIZE > 2
3960 #error "System function for b-byte character strings not available!"
3961 #else
3962 #if DK3_ON_WINDOWS
3963 return(dk3sf_c16_remove_dir_app(n, app));
3964 #else
3965 #error "Wide character functions not defined on non-Windows systems!"
3966 #endif
3967 #endif
3968 #else
3969 return(dk3sf_c8_remove_dir_app(n, app));
3970 #endif
3971 }
3972
3973
3974
3975 int
dk3sf_get_hostname_app(dkChar * db,size_t sz,dk3_app_t * app)3976 dk3sf_get_hostname_app(dkChar *db, size_t sz, dk3_app_t *app)
3977 {
3978 #if DK3_CHAR_SIZE > 1
3979 #if DK3_CHAR_SIZE > 2
3980 #error "System function for b-byte character strings not available!"
3981 #else
3982 #if DK3_ON_WINDOWS
3983 return(dk3sf_c16_get_hostname_app(db, sz, app));
3984 #else
3985 #error "Wide character functions not defined on non-Windows systems!"
3986 #endif
3987 #endif
3988 #else
3989 return(dk3sf_c8_get_hostname_app(db, sz, app));
3990 #endif
3991 }
3992
3993
3994
3995 dkChar *
dk3sf_getenv(dkChar const * name)3996 dk3sf_getenv(dkChar const *name)
3997 {
3998 #if DK3_CHAR_SIZE > 1
3999 #if DK3_CHAR_SIZE > 2
4000 #error "System function for b-byte character strings not available!"
4001 #else
4002 #if DK3_ON_WINDOWS
4003 return(dk3sf_c16_getenv(name));
4004 #else
4005 #error "Wide character functions not defined on non-Windows systems!"
4006 #endif
4007 #endif
4008 #else
4009 return(dk3sf_c8_getenv(name));
4010 #endif
4011 }
4012
4013
4014
4015
4016 /* vim: set ai sw=2 : */
4017
4018