1 /*
2 Copyright (C) 2015-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: dk4applog.ctr
12 */
13
14 /** @file dk4applog.c The dk4applog module.
15 */
16
17
18
19 #ifndef DK4APP_H_INCLUDED
20 #include <libdk4app/dk4app.h>
21 #endif
22
23 #ifndef DK4CONST_H_INCLUDED
24 #include <libdk4base/dk4const.h>
25 #endif
26
27 #ifndef DK4TIME_H_INCLUDED
28 #include <libdk4c/dk4time.h>
29 #endif
30
31 #ifndef DK4TIMEDK_H_INCLUDED
32 #include <libdk4c/dk4timedk.h>
33 #endif
34
35 #ifndef DK4MAODD_H_INCLUDED
36 #include <libdk4maiodd/dk4maodd.h>
37 #endif
38
39 #ifndef DK4FPUT_H_INCLUDED
40 #include <libdk4c/dk4fput.h>
41 #endif
42
43 #ifndef DK4MEM_H_INCLUDED
44 #include <libdk4base/dk4mem.h>
45 #endif
46
47 #ifndef DK4FOP8_H_INCLUDED
48 #include <libdk4c/dk4fopc8.h>
49 #endif
50
51 #ifndef DK4FOPD_H_INCLUDED
52 #include <libdk4c/dk4fopd.h>
53 #endif
54
55 #ifndef DK4MAODD_H_INCLUDED
56 #include <libdk4maiodd/dk4maodd.h>
57 #endif
58
59 #ifndef DK4ENC_H_INCLUDED
60 #include <libdk4c/dk4enc.h>
61 #endif
62
63 #ifndef DK4APPMKDH_H_INCLUDED
64 #include <libdk4app/dk4appmkdh.h>
65 #endif
66
67 #ifndef DK4MPL_H_INCLUDED
68 #include <libdk4base/dk4mpl.h>
69 #endif
70
71 #ifndef DK4FS_H_INCLUDED
72 #include <libdk4c/dk4fs.h>
73 #endif
74
75 #if DK4_HAVE_ASSERT_H
76 #ifndef ASSERT_H_INCLUDED
77 #include <assert.h>
78 #define ASSERT_H_INCLUDED 1
79 #endif
80 #endif
81
82 #ifdef __cplusplus
83 extern "C" {
84 #endif
85
86 /** Log at application startup.
87 @param app Application structure.
88 */
89 void
90 dk4app_log_startup_debug(dk4_app_t *app);
91
92 #ifdef __cplusplus
93 }
94 #endif
95
96
97
98
99
100
101 /** Constant char texts used by the module, not localized.
102 */
103 static const dkChar * const dk4app_log_kwnl[] = {
104 /* 0 */
105 dkT("w"),
106
107 /* 1 */
108 dkT("a"),
109
110 /* 2 */
111 dkT("dk4debug.str"),
112
113 /* 3 */
114 dkT("-"),
115
116 /* 4 */
117 dkT("+"),
118
119 /* 5 */
120 dkT("ascii"),
121
122 /* 6 */
123 dkT("ansi"),
124
125 /* 7 */
126 dkT("utf-8"),
127
128 /* 8 */
129 dkT("utf-16"),
130
131 /* 9 */
132 dkT("utf-16-le"),
133
134 /* 10 */
135 dkT("utf-16-be"),
136
137 /* 11 */
138 dkT("c32"),
139
140 /* 12 */
141 dkT("c32-le"),
142
143 /* 13 */
144 dkT("c32-be"),
145
146 /* 14 */
147 dkT("dk3pref.conf"),
148
149 /* 15 */
150 dkT("dk4pref.conf"),
151
152 NULL
153
154 };
155
156
157
158 /** The message texts for the base log domain, nearly always loaded.
159 */
160 static const dkChar * const dk4app_def_msg_base[] = {
161 /* 0 */
162 dkT("NONE"),
163
164 /* 1 */
165 dkT("Panic"),
166
167 /* 2 */
168 dkT("Fatal"),
169
170 /* 3 */
171 dkT("Error"),
172
173 /* 4 */
174 dkT("Warning"),
175
176 /* 5 */
177 dkT("Info"),
178
179 /* 6 */
180 dkT("Progress"),
181
182 /* 7 */
183 dkT("Debug"),
184
185 /* 8 */
186 dkT("Ignore"),
187
188 /* 9 */
189 dkT("Illegal option: \""),
190
191 /* 10 */
192 dkT("\"!"),
193
194 /* 11 */
195 dkT("Option \""),
196
197 /* 12 */
198 dkT("\" requires argument!"),
199
200 /* 13 */
201 dkT("Option \""),
202
203 /* 14 */
204 dkT("\" requires a boolean argument!\n\tRejected text: \""),
205
206 /* 15 */
207 dkT("\"!"),
208
209 /* 16 */
210 dkT("Option \""),
211
212 /* 17 */
213 dkT("\" requires a size argument!\n\tRejected text: \""),
214
215 /* 18 */
216 dkT("\"!"),
217
218 /* 19 */
219 dkT("Option \""),
220
221 /* 20 */
222 dkT("\" requires integer argument!\n\tRejected text: \""),
223
224 /* 21 */
225 dkT("\"!"),
226
227 /* 22 */
228 dkT("Option \""),
229
230 /* 23 */
231 dkT("\" requires unsigned integer argument!\n\tRejected text: \""),
232
233 /* 24 */
234 dkT("\"!"),
235
236 /* 25 */
237 dkT("Option \""),
238
239 /* 26 */
240 dkT("\" requires floating point (double) argument!\n\tRejected text: \""),
241
242 /* 27 */
243 dkT("\"!"),
244
245 /* 28 */
246 dkT("Option \"--"),
247
248 /* 29 */
249 dkT("Option \"--"),
250
251 /* 30 */
252 dkT("Option \"--"),
253
254 /* 31 */
255 dkT("Option \"--"),
256
257 /* 32 */
258 dkT("Option \"--"),
259
260 /* 33 */
261 dkT("Option \"--"),
262
263 /* 34 */
264 dkT("Failed to save preference value!\n\t\""),
265
266 /* 35 */
267 dkT("\"=\""),
268
269 /* 36 */
270 dkT("\"!"),
271
272 /* 37 */
273 dkT("Value required for command line preference \""),
274
275 /* 38 */
276 dkT("\"!"),
277
278 /* 39 */
279 dkT("Option too long!\n\t\""),
280
281 /* 40 */
282 dkT("\"!"),
283
284 /* 41 */
285 dkT("Failed to remove file:\n\t\""),
286
287 /* 42 */
288 dkT("\"!\n\tPath name too long."),
289
290 /* 43 */
291 dkT("Failed to create directory:\n\t\""),
292
293 /* 44 */
294 dkT("\"!\n\tPath exists, but is not a directory!"),
295
296 /* 45 */
297 dkT("\n\tLocal network interface is down!"),
298
299 /* 46 */
300 dkT("Failed to create directory:\n\t\""),
301
302 /* 47 */
303 dkT("\"!\n\tIllegal path."),
304
305 /* 48 */
306 dkT("\"!\n\tFile or directory in use."),
307
308 /* 49 */
309 dkT("\"!\n\tPath already exists."),
310
311 /* 50 */
312 dkT("\"!\n\tPath name points outside accessible address space."),
313
314 /* 51 */
315 dkT("\"!\n\tPath not found (one path component does not exist)."),
316
317 /* 52 */
318 dkT("\"!\n\tPath specifies a directory."),
319
320 /* 53 */
321 dkT("\"!\n\tNo function for wide-char mkdir available."),
322
323 /* 54 */
324 dkT("No wide-char function to remove files available."),
325
326 /* 55 */
327 dkT("\"!\n\tInsufficient permissions."),
328
329 /* 56 */
330 dkT("\"!\n\tFile system is mounted read-only."),
331
332 /* 57 */
333 dkT("\"!\n\tConflict with extended attribute."),
334
335 /* 58 */
336 dkT("\"!\n\tNot allowed for this file system type."),
337
338 /* 59 */
339 dkT("\"!\n\tI/O error on device."),
340
341 /* 60 */
342 dkT("\"!\n\tDisk space or quota problem."),
343
344 /* 61 */
345 dkT("\"!\n\tToo many symbolic links in path (probably symlink loop)."),
346
347 /* 62 */
348 dkT("\"!\n\tInsufficient kernel memory."),
349
350 /* 63 */
351 dkT("\"!\n\tToo many entries in parent directory."),
352
353 /* 64 */
354 dkT("\"!\n\tFile server not available."),
355
356 /* 65 */
357 dkT("\"!\n\tName too long."),
358
359 /* 66 */
360 dkT("Failed to remove directory:\n\t\""),
361
362 /* 67 */
363 dkT("\"!\n\tDirectory not empty."),
364
365 /* 68 */
366 dkT("\"!\n\tInvalid path name."),
367
368 /* 69 */
369 dkT("\"!\n\tWindows error code: "),
370
371 /* 70 */
372 dkT(" (0x"),
373
374 /* 71 */
375 dkT(")."),
376
377 /* 72 */
378 dkT("\"!"),
379
380 /* 73 */
381 dkT("\"!\n\tParent directory not found (device or server share)!"),
382
383 /* 74 */
384 dkT("\"!\n\tBad network resource name (share name)!"),
385
386 /* 75 */
387 dkT("\"!\n\tBad network resource name (server name)!"),
388
389 /* 76 */
390 dkT("\n\tNo route to network destination available!"),
391
392 /* 77 */
393 dkT("\"!"),
394
395 /* 78 */
396 dkT("\n\tAttempt to read from outside file!"),
397
398 /* 79 */
399 dkT("\"!\n\tError code: "),
400
401 /* 80 */
402 dkT("."),
403
404 /* 81 */
405 dkT("Options --help, --version, and --license are mutually exclusive!"),
406
407 /* 82 */
408 dkT("Numeric overflow in size calculation!"),
409
410 /* 83 */
411 dkT("Numeric overflow in size calculation!\n\t"),
412
413 /* 84 */
414 dkT(" elements of "),
415
416 /* 85 */
417 dkT(" bytes."),
418
419 /* 86 */
420 dkT("Memory allocation failed! Invalid size(s) specified."),
421
422 /* 87 */
423 dkT("Memory allocation failed! Invalid size(s) specified.\n\tNumber of elements: "),
424
425 /* 88 */
426 dkT(", element size: "),
427
428 /* 89 */
429 dkT("."),
430
431 /* 90 */
432 dkT("Not enough memory! Allcation failed."),
433
434 /* 91 */
435 dkT("Not enough memory! Allcation failed.\n\tNumber of elements: "),
436
437 /* 92 */
438 dkT(", element size: "),
439
440 /* 93 */
441 dkT("."),
442
443 /* 94 */
444 dkT("Further file removal attempts failed in:\n\t\""),
445
446 /* 95 */
447 dkT("\"!"),
448
449 /* 96 */
450 dkT("Further subdirectory removal attempts failed in:\n\t\""),
451
452 /* 97 */
453 dkT("\"!"),
454
455 /* 98 */
456 dkT("File or directory name too long:\n\t\""),
457
458 /* 99 */
459 dkT("\"!"),
460
461 /* 100 */
462 dkT("Failed to expand file name:\n\t\""),
463
464 /* 101 */
465 dkT("\"!"),
466
467 /* 102 */
468 dkT("\"!\n\tNo function for directory traversal available!"),
469
470 /* 103 */
471 dkT("\"!\n\tMemory allocation failed!"),
472
473 /* 104 */
474 dkT("\"!\n\tFailed to open directory for traversal!"),
475
476 /* 105 */
477 dkT("\"!\n\tDirectory or file name too large!"),
478
479 /* 106 */
480 dkT("\"!\n\tMultiple matching files!"),
481
482 /* 107 */
483 dkT("\"!\n\tNo matching file!"),
484
485 /* 108 */
486 dkT("Failed to open file:\n\t\""),
487
488 /* 109 */
489 dkT("\"!\n\tNot a regular file!"),
490
491 /* 110 */
492 dkT("\"!\n\tPath contains symbolic links!"),
493
494 /* 111 */
495 dkT("\"!\n\tPath is a symbolic link!"),
496
497 /* 112 */
498 dkT("\"!\n\tSymbolic link owner is not target owner!"),
499
500 /* 113 */
501 dkT("\"!\n\tSignal received!"),
502
503 /* 114 */
504 dkT("\"!\n\tToo many open files in process!"),
505
506 /* 115 */
507 dkT("\"!\n\tToo many open files on system!"),
508
509 /* 116 */
510 dkT("\"!\n\tDevice for special file does not exist!"),
511
512 /* 117 */
513 dkT("\"!\n\tFile size too large for off_t data type!"),
514
515 /* 118 */
516 dkT("Read operation failed!"),
517
518 /* 119 */
519 dkT("Read operation failed, error code:"),
520
521 /* 120 */
522 dkT("."),
523
524 /* 121 */
525 dkT("\n\tOperation would block!"),
526
527 /* 122 */
528 dkT("\n\tBad file descriptor (bug)!"),
529
530 /* 123 */
531 dkT("\n\tBuffer is outside usable address space (bug)!"),
532
533 /* 124 */
534 dkT("\n\tSignal received!"),
535
536 /* 125 */
537 dkT("\n\tFile descriptor attached to unsuitable object (bug)!"),
538
539 /* 126 */
540 dkT("\n\tI/O error!"),
541
542 /* 127 */
543 dkT("\n\tFile descriptor attachted to directory (bug)!"),
544
545 /* 128 */
546 dkT("Write operation failed!"),
547
548 /* 129 */
549 dkT("Write operation failed, error code:"),
550
551 /* 130 */
552 dkT("."),
553
554 /* 131 */
555 dkT("\n\tNo space left on device!"),
556
557 /* 132 */
558 dkT("\n\tFile size would exceed limits!"),
559
560 /* 133 */
561 dkT("\n\tNo reader attached to pipe or socket!"),
562
563 /* 134 */
564 dkT("\n\tSocket not connected!"),
565
566 /* 135 */
567 dkT("\n\tBuffer size outside supported range!"),
568
569 /* 136 */
570 dkT("\n\tInsufficient system resources available!"),
571
572 /* 137 */
573 dkT("\n\tNonexistent or incapable device!"),
574
575 /* 138 */
576 dkT("\n\tInsufficient permissions!"),
577
578 /* 139 */
579 dkT("\n\tUnexpected control part in normal-mode message!"),
580
581 /* 140 */
582 dkT("\n\tConnection reset by peer!"),
583
584 /* 141 */
585 dkT("\n\tTimed out!"),
586
587 /* 142 */
588 dkT("\n\tInsufficient memory available!"),
589
590 /* 143 */
591 dkT("\n\tFile descriptor is socket or FIFO!"),
592
593 /* 144 */
594 dkT("Failed to open directory:\n\t\""),
595
596 /* 145 */
597 dkT("\"!\n\tNo function found for directory traversal!"),
598
599 /* 146 */
600 dkT("\"!\n\tNumeric overflow in size calculation!"),
601
602 /* 147 */
603 dkT("\"!\n\tPath not found!"),
604
605 /* 148 */
606 dkT("\"!\n\tDirectory does not exist!"),
607
608 /* 149 */
609 dkT("Failed to obtain information about file/directory:\n\t\""),
610
611 /* 150 */
612 dkT("\"!\n\tOne path component is not a directory."),
613
614 /* 151 */
615 dkT("\"!\n\tCurrently used by another process."),
616
617 /* 152 */
618 dkT("Not a directory:\n\t\""),
619
620 /* 153 */
621 dkT("\"!"),
622
623 /* 154 */
624 dkT("\" in \""),
625
626 /* 155 */
627 dkT("Failed to change file buffering!"),
628
629 /* 156 */
630 dkT("Failed to change buffering for file\n\""),
631
632 /* 157 */
633 dkT("\"!"),
634
635 /* 158 */
636 dkT("Neither setvbuf() nor setbuffer() function available!"),
637
638 /* 159 */
639 dkT("Syntax error, expected line:\n\"name = width height [border-left border-right border-top border-bottom]\""),
640
641 /* 160 */
642 dkT("Preference value found: \""),
643
644 /* 161 */
645 dkT("\"=\""),
646
647 /* 162 */
648 dkT("\"."),
649
650 /* 163 */
651 dkT("Preference value too long: \""),
652
653 /* 164 */
654 dkT("\"=\""),
655
656 /* 165 */
657 dkT("\"!"),
658
659 /* 166 */
660 dkT("Preference value not found: \""),
661
662 /* 167 */
663 dkT("\"!"),
664
665 NULL
666
667 };
668
669
670
671 static const dkChar * const dk4app_def_msg_debug[] = {
672 /* 0 */
673 dkT("Host name: "),
674
675 /* 1 */
676 dkT("User name: "),
677
678 /* 2 */
679 dkT("Home directory: "),
680
681 /* 3 */
682 dkT("Language: "),
683
684 /* 4 */
685 dkT("Region: "),
686
687 /* 5 */
688 dkT("Encoding: "),
689
690 /* 6 */
691 dkT("Encoding expected on standard input: "),
692
693 /* 7 */
694 dkT("Encoding expected on files: "),
695
696 /* 8 */
697 dkT("Program name: "),
698
699 /* 9 */
700 dkT("Program group: "),
701
702 /* 10 */
703 dkT("Directory etc: "),
704
705 /* 11 */
706 dkT("Directory bin: "),
707
708 /* 12 */
709 dkT("Directory share: "),
710
711 /* 13 */
712 dkT("Directory lib: "),
713
714 /* 14 */
715 dkT("Directory var: "),
716
717 /* 15 */
718 dkT("Directory tmp: "),
719
720 /* 16 */
721 dkT("Logging enabled: "),
722
723 /* 17 */
724 dkT("Log file: "),
725
726 /* 18 */
727 dkT("Log level to log on stderr: "),
728
729 /* 19 */
730 dkT("Log level to log to file: "),
731
732 /* 20 */
733 dkT("Log level to keep log file: "),
734
735 /* 21 */
736 dkT("Data file search for \""),
737
738 /* 22 */
739 dkT("\" failed."),
740
741 /* 23 */
742 dkT("\" succeeded.\n\t"),
743
744 /* 24 */
745 dkT("Configuration file search for \""),
746
747 /* 25 */
748 dkT("Delete directory: "),
749
750 /* 26 */
751 dkT("Delete file: "),
752
753 /* 27 */
754 dkT("Delete file or directory: "),
755
756 /* 28 */
757 dkT("Preference files:"),
758
759 /* 29 */
760 dkT("UNUSED"),
761
762 /* 30 */
763 dkT("+ "),
764
765 /* 31 */
766 dkT("- "),
767
768 /* 32 */
769 dkT("Search for data file \""),
770
771 /* 33 */
772 dkT("Search for configuration file \""),
773
774 /* 34 */
775 dkT("\" (compression allowed):"),
776
777 /* 35 */
778 dkT("\" (no compression allowed):"),
779
780 /* 36 */
781 dkT("Collecting paper size data."),
782
783 /* 37 */
784 dkT("\" (gzip compression allowed):"),
785
786 /* 38 */
787 dkT("\" (bzip2 compression allowed):"),
788
789 /* 39 */
790 dkT("\" (gzip/bzip2 compression allowed):"),
791
792 /* 40 */
793 dkT("String copy allocated: \""),
794
795 /* 41 */
796 dkT("\"."),
797
798 /* 42 */
799 dkT("Successfully converted to integer."),
800
801 /* 43 */
802 dkT("Not an integer!"),
803
804 /* 44 */
805 dkT("Successfully converted to unsigned integer."),
806
807 /* 45 */
808 dkT("Not an unsigned integer!"),
809
810 /* 46 */
811 dkT("Successfully converted to boolean."),
812
813 /* 47 */
814 dkT("Not a boolean!"),
815
816 /* 48 */
817 dkT("Successfully converted to size specification."),
818
819 /* 49 */
820 dkT("Not a size specification!"),
821
822 NULL
823
824 };
825
826
827
828 /** Ensure the messages texts for the base log domain are loaded.
829 @param app Application structure.
830 @param logdom Log text domain.
831 */
832 static
833 void
dk4app_log_load_base_texts(dk4_app_t * app)834 dk4app_log_load_base_texts(dk4_app_t *app)
835 {
836
837 if (NULL != app) {
838 if ((NULL == app->msg_base) || (0 == app->sz_msg_base)) {
839
840 app->sz_msg_base = dk4app_string_table_size(dk4app_def_msg_base);
841 app->msg_base = dk4app_string_table(
842 app, dkT("dk4base.str"), dk4app_def_msg_base
843 );
844 }
845 #if TRACE_DEBUG
846 else {
847 }
848 #endif
849 } else {
850 }
851 }
852
853
854
855 /** Check whether there is at least one non-NULL pointer in array.
856 CRT on Windows: Not used.
857 @param msg Array to check.
858 @param sz Size of array.
859 @return 1 if any valid pointer was found, 0 otherwise.
860 */
861 static
862 int
dk4app_log_any_non_null(const dkChar * const * msg,size_t sz)863 dk4app_log_any_non_null(const dkChar * const *msg, size_t sz)
864 {
865 size_t i;
866 int back = 0;
867 for (i = 0; ((i < sz) && (0 == back)); i++) {
868 if (NULL != msg[i]) { back = 1; }
869 }
870 return back;
871 }
872
873
874
875 int
dk4app_log_do(dk4_app_t const * app,int ll)876 dk4app_log_do(dk4_app_t const *app, int ll)
877 {
878 int back = 0;
879
880 if (NULL != app) {
881 #if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
882 if (0 != app->log_enabled) {
883 if (app->ll_stderr >= ll) {
884 back = 1;
885 }
886 if (app->ll_file >= ll) {
887 back = 1;
888 }
889 }
890 #endif
891 }
892
893 return back;
894 }
895
896
897
898 /** Log multi part message to one file.
899 CRT on Windows: Required.
900 @param app Application structure, may be NULL.
901 @param priority Log priority.
902 @param msg Pointer to message parts array.
903 @param sz Number of message parts.
904 @param outfile Output file
905 @param showtime Flag: Show timestamp.
906 @param timer Timestamp of previous log message if any.
907 @param havetime Flag: Timer already contains a value.
908 */
909 static
910 void
dk4app_log_msg_to_file(dk4_app_t const * app,int priority,const dkChar * const * msg,size_t sz,FILE * outfile,int showtime,dk4_time_t * timer,int * havetime)911 dk4app_log_msg_to_file(
912 dk4_app_t const *app,
913 int priority,
914 const dkChar * const *msg,
915 size_t sz,
916 FILE *outfile,
917 int showtime,
918 dk4_time_t *timer,
919 int *havetime
920 )
921 {
922 #if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
923 dkChar lnb[64];
924 dkChar buf[64];
925 size_t i;
926 dk4_time_t ct;
927 int res;
928
929 dk4time_get(&ct);
930 /* Print timestamp */
931 if ((0 != showtime) && ((0 == *havetime) || (ct != *timer))) {
932 *havetime = 1;
933 *timer = ct;
934 if (0 != dk4time_as_text(buf, DK4_SIZEOF(buf,dkChar), &ct, NULL)) {
935 dk4fputs(dkT("# "), outfile, NULL);
936 dk4fputs(buf, outfile, NULL);
937 dk4fputc(dkT('\n'), outfile, NULL);
938 }
939 }
940 /* Print error position */
941 if (NULL != app->source_file_name) {
942 dk4fputs(app->source_file_name, outfile, NULL);
943 dk4fputc(dkT(':'), outfile, NULL);
944 if ((dk4_um_t)0UL != app->source_file_line) {
945 res = dk4ma_write_decimal_unsigned(
946 lnb, DK4_SIZEOF(lnb,dkChar), app->source_file_line, 0, NULL
947 );
948 if (0 != res) {
949 dk4fputs(lnb, outfile, NULL);
950 dk4fputc(dkT(':'), outfile, NULL);
951 }
952 }
953 dk4fputc(dkT(' '), outfile, NULL);
954 }
955 /* Print message */
956 switch (priority) {
957 case DK4_LL_PANIC:
958 case DK4_LL_FATAL:
959 case DK4_LL_ERROR:
960 case DK4_LL_WARNING:
961 {
962 dk4fputs((app->msg_base)[priority], outfile, NULL);
963 dk4fputs(dkT(": "), outfile, NULL);
964 } break;
965 }
966 for (i = 0; i < sz; i++) {
967 dk4fputs(msg[i], outfile, NULL);
968 }
969 dk4fputc(dkT('\n'), outfile, NULL);
970 fflush(outfile);
971 #endif
972 }
973
974
975
976 void
dk4app_log_msg(dk4_app_t * app,int priority,const dkChar * const * msg,size_t sz)977 dk4app_log_msg(
978 dk4_app_t *app,
979 int priority,
980 const dkChar * const *msg,
981 size_t sz
982 )
983 {
984 FILE *fipo;
985
986 if (NULL != app) {
987 if (0 != dk4app_log_do(app, priority)) {
988 dk4app_log_load_base_texts(app);
989 if (0 != dk4app_log_any_non_null(msg, sz)) {
990 #if (!(DK4_ON_WINDOWS && DK4_WIN_DENY_CRT))
991 if (app->ll_stderr >= priority) {
992 if (0 == app->have_stderr_init) {
993 dk4fput_initialize_stderr();
994 app->have_stderr_init = 1;
995 }
996 dk4app_log_msg_to_file(
997 app, priority, msg, sz, stderr,
998 app->log_stderr_time, &(app->timer_stderr), &(app->have_stderr_time)
999 );
1000 }
1001 if (app->ll_file >= priority) {
1002 if (NULL != app->log_file_name) {
1003 #if VERSION_BEFORE_20160127
1004 #else
1005 if (0 == app->have_file_opened) {
1006 (void)dk4app_mkdir_hierarchy(app->log_file_name, 0, NULL);
1007 }
1008 #endif
1009 fipo = dk4fopen(
1010 app->log_file_name,
1011 dk4app_log_kwnl[(0 != app->have_file_opened) ? 1 : 0],
1012 (DK4_FOPEN_SC_WR_SYMLINK_OWNER | DK4_FOPEN_SC_IS_REGULAR),
1013 NULL
1014 );
1015 app->have_file_opened = 1;
1016 if (NULL != fipo) {
1017 dk4app_log_msg_to_file(
1018 app, priority, msg, sz, fipo,
1019 app->log_stderr_time, &(app->timer_file), &(app->have_file_time)
1020 );
1021 fclose(fipo);
1022 }
1023 }
1024 }
1025 if (priority < app->ll_found) {
1026 app->ll_found = priority;
1027 }
1028 #endif
1029 }
1030 }
1031 }
1032
1033 }
1034
1035
1036
1037 void
dk4app_log_1(dk4_app_t * app,const dkChar * const * msg,size_t sz_msg,int priority,size_t msgind)1038 dk4app_log_1(
1039 dk4_app_t *app,
1040 const dkChar * const *msg,
1041 size_t sz_msg,
1042 int priority,
1043 size_t msgind
1044 )
1045 {
1046 const dkChar *msgtext;
1047
1048 if (NULL != app) {
1049 if (0 != dk4app_log_do(app, priority)) {
1050 dk4app_log_load_base_texts(app);
1051 if ((NULL != msg) && (0 < sz_msg) && (msgind < sz_msg)) {
1052 msgtext = msg[msgind];
1053 dk4app_log_msg(app, priority, &msgtext, 1);
1054 }
1055 }
1056 }
1057
1058 }
1059
1060
1061
1062 void
dk4app_log_2(dk4_app_t * app,const dkChar * const * msg,size_t sz_msg,int priority,size_t i1,const dkChar * t1)1063 dk4app_log_2(
1064 dk4_app_t *app,
1065 const dkChar * const *msg,
1066 size_t sz_msg,
1067 int priority,
1068 size_t i1,
1069 const dkChar *t1
1070 )
1071 {
1072 const dkChar *msgtext[3];
1073
1074 if (NULL != app) {
1075 if (0 != dk4app_log_do(app, priority)) {
1076 dk4app_log_load_base_texts(app);
1077 if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg)) {
1078 msgtext[0] = msg[i1];
1079 msgtext[1] = t1;
1080 dk4app_log_msg(app, priority, msgtext, 2);
1081 }
1082 }
1083 }
1084
1085 }
1086
1087
1088
1089 void
dk4app_log_3(dk4_app_t * app,const dkChar * const * msg,size_t sz_msg,int priority,size_t i1,size_t i2,const dkChar * t1)1090 dk4app_log_3(
1091 dk4_app_t *app,
1092 const dkChar * const *msg,
1093 size_t sz_msg,
1094 int priority,
1095 size_t i1,
1096 size_t i2,
1097 const dkChar *t1
1098 )
1099 {
1100 const dkChar *msgtext[3];
1101
1102 if (NULL != app) {
1103 if (0 != dk4app_log_do(app, priority)) {
1104 dk4app_log_load_base_texts(app);
1105 if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
1106 msgtext[0] = msg[i1];
1107 msgtext[1] = t1;
1108 msgtext[2] = msg[i2];
1109 dk4app_log_msg(app, priority, msgtext, 3);
1110 }
1111 }
1112 }
1113
1114 }
1115
1116
1117
1118 void
dk4app_log_5(dk4_app_t * app,const dkChar * const * msg,size_t sz_msg,int priority,size_t i1,size_t i2,size_t i3,const dkChar * t1,const dkChar * t2)1119 dk4app_log_5(
1120 dk4_app_t *app,
1121 const dkChar * const *msg,
1122 size_t sz_msg,
1123 int priority,
1124 size_t i1,
1125 size_t i2,
1126 size_t i3,
1127 const dkChar *t1,
1128 const dkChar *t2
1129 )
1130 {
1131 const dkChar *msgtext[5];
1132
1133 if (NULL != app) {
1134 if (0 != dk4app_log_do(app, priority)) {
1135 dk4app_log_load_base_texts(app);
1136 if ((NULL != msg) && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg)) {
1137 msgtext[0] = msg[i1];
1138 msgtext[1] = t1;
1139 msgtext[2] = msg[i2];
1140 msgtext[3] = t2;
1141 msgtext[4] = msg[i3];
1142 dk4app_log_msg(app, priority, msgtext, 5);
1143 }
1144 }
1145 }
1146
1147 }
1148
1149
1150
1151 void
dk4app_log_7(dk4_app_t * app,const dkChar * const * msg,size_t sz_msg,int priority,size_t i1,size_t i2,size_t i3,size_t i4,const dkChar * t1,const dkChar * t2,const dkChar * t3)1152 dk4app_log_7(
1153 dk4_app_t *app,
1154 const dkChar * const *msg,
1155 size_t sz_msg,
1156 int priority,
1157 size_t i1,
1158 size_t i2,
1159 size_t i3,
1160 size_t i4,
1161 const dkChar *t1,
1162 const dkChar *t2,
1163 const dkChar *t3
1164 )
1165 {
1166 const dkChar *msgtext[7];
1167
1168 if (NULL != app) {
1169 if (0 != dk4app_log_do(app, priority)) {
1170 dk4app_log_load_base_texts(app);
1171 if (
1172 (NULL != msg)
1173 && (0 < sz_msg) && (i1 < sz_msg) && (i2 < sz_msg) && (i3 < sz_msg)
1174 )
1175 {
1176 msgtext[0] = msg[i1];
1177 msgtext[1] = t1;
1178 msgtext[2] = msg[i2];
1179 msgtext[3] = t2;
1180 msgtext[4] = msg[i3];
1181 msgtext[5] = t3;
1182 msgtext[6] = msg[i4];
1183 dk4app_log_msg(app, priority, msgtext, 7);
1184 }
1185 }
1186 }
1187
1188 }
1189
1190
1191
1192 void
dk4app_log_base1(dk4_app_t * app,int priority,size_t msgind)1193 dk4app_log_base1(
1194 dk4_app_t *app,
1195 int priority,
1196 size_t msgind
1197 )
1198 {
1199
1200 if (NULL != app) {
1201 if (0 != dk4app_log_do(app, priority)) {
1202 dk4app_log_load_base_texts(app);
1203 dk4app_log_1(app, app->msg_base, app->sz_msg_base, priority, msgind);
1204 }
1205 }
1206
1207 }
1208
1209
1210
1211 void
dk4app_log_base2(dk4_app_t * app,int priority,size_t i1,const dkChar * t1)1212 dk4app_log_base2(
1213 dk4_app_t *app,
1214 int priority,
1215 size_t i1,
1216 const dkChar *t1
1217 )
1218 {
1219
1220 if (NULL != app) {
1221 if (0 != dk4app_log_do(app, priority)) {
1222 dk4app_log_load_base_texts(app);
1223 dk4app_log_2(app,app->msg_base,app->sz_msg_base,priority,i1,t1);
1224 }
1225 }
1226
1227 }
1228
1229
1230
1231 void
dk4app_log_base2c(dk4_app_t * app,int priority,size_t i1,size_t i2)1232 dk4app_log_base2c(
1233 dk4_app_t *app,
1234 int priority,
1235 size_t i1,
1236 size_t i2
1237 )
1238 {
1239 const dkChar *msgptr[2];
1240
1241 if (NULL != app) {
1242 if (0 != dk4app_log_do(app, priority)) {
1243 if ((app->sz_msg_base > i1) && (app->sz_msg_base > i2)) {
1244 dk4app_log_load_base_texts(app);
1245 msgptr[0] = (app->msg_base)[i1];
1246 msgptr[1] = (app->msg_base)[i2];
1247 dk4app_log_msg(app, priority, msgptr, 2);
1248 }
1249 }
1250 }
1251
1252 }
1253
1254
1255
1256 void
dk4app_log_base3(dk4_app_t * app,int priority,size_t i1,size_t i2,const dkChar * t1)1257 dk4app_log_base3(
1258 dk4_app_t *app,
1259 int priority,
1260 size_t i1,
1261 size_t i2,
1262 const dkChar *t1
1263 )
1264 {
1265
1266 if (NULL != app) {
1267 if (0 != dk4app_log_do(app, priority)) {
1268 dk4app_log_load_base_texts(app);
1269 dk4app_log_3(app,app->msg_base,app->sz_msg_base,priority,i1,i2,t1);
1270 }
1271 }
1272
1273 }
1274
1275
1276
1277 void
dk4app_log_base5(dk4_app_t * app,int priority,size_t i1,size_t i2,size_t i3,const dkChar * t1,const dkChar * t2)1278 dk4app_log_base5(
1279 dk4_app_t *app,
1280 int priority,
1281 size_t i1,
1282 size_t i2,
1283 size_t i3,
1284 const dkChar *t1,
1285 const dkChar *t2
1286 )
1287 {
1288
1289 if (NULL != app) {
1290 if (0 != dk4app_log_do(app, priority)) {
1291 dk4app_log_load_base_texts(app);
1292 dk4app_log_5(app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,t1,t2);
1293 }
1294 }
1295
1296 }
1297
1298
1299
1300 void
dk4app_log_base7(dk4_app_t * app,int priority,size_t i1,size_t i2,size_t i3,size_t i4,const dkChar * t1,const dkChar * t2,const dkChar * t3)1301 dk4app_log_base7(
1302 dk4_app_t *app,
1303 int priority,
1304 size_t i1,
1305 size_t i2,
1306 size_t i3,
1307 size_t i4,
1308 const dkChar *t1,
1309 const dkChar *t2,
1310 const dkChar *t3
1311 )
1312 {
1313
1314 if (NULL != app) {
1315 if (0 != dk4app_log_do(app, priority)) {
1316 dk4app_log_load_base_texts(app);
1317 dk4app_log_7(
1318 app,app->msg_base,app->sz_msg_base,priority,i1,i2,i3,i4,t1,t2,t3
1319 );
1320 }
1321 }
1322
1323 }
1324
1325
1326
1327 void
dk4app_log_with_errno(dk4_app_t * app,int priority,size_t i1,size_t i2,size_t i3,size_t i4,size_t i5,const dkChar * t1,int errn)1328 dk4app_log_with_errno(
1329 dk4_app_t *app,
1330 int priority,
1331 size_t i1,
1332 size_t i2,
1333 size_t i3,
1334 size_t i4,
1335 size_t i5,
1336 const dkChar *t1,
1337 int errn
1338 )
1339 {
1340 dkChar enb[64];
1341 int res;
1342
1343 if (NULL != app) {
1344 res = dk4ma_write_decimal_signed(
1345 enb, DK4_SIZEOF(enb,dkChar), (dk4_im_t)errn, 0, NULL
1346 );
1347 if (0 != res) {
1348 dk4app_log_base5(app, priority, i1, i2, i3, t1, enb);
1349 } else {
1350 dk4app_log_base3(app, priority, i4, i5, t1);
1351 }
1352 }
1353
1354 }
1355
1356
1357
1358 const dkChar *
dk4app_get_log_source_file(dk4_app_t const * app)1359 dk4app_get_log_source_file(dk4_app_t const *app)
1360 {
1361 const dkChar *back = NULL;
1362
1363 if (NULL != app) {
1364 back = app->source_file_name;
1365 }
1366
1367 return back;
1368 }
1369
1370
1371
1372 dk4_um_t
dk4app_get_log_source_line(dk4_app_t const * app)1373 dk4app_get_log_source_line(dk4_app_t const *app)
1374 {
1375 dk4_um_t back = (dk4_um_t)0UL;
1376
1377 if (NULL != app) {
1378 back = app->source_file_line;
1379 }
1380
1381 return back;
1382 }
1383
1384
1385
1386 void
dk4app_set_log_source_file(dk4_app_t * app,const dkChar * fn)1387 dk4app_set_log_source_file(dk4_app_t *app, const dkChar *fn)
1388 {
1389
1390 if (NULL != app) {
1391 app->source_file_name = fn;
1392 }
1393 }
1394
1395
1396
1397 void
dk4app_set_log_source_line(dk4_app_t * app,dk4_um_t lineno)1398 dk4app_set_log_source_line(dk4_app_t *app, dk4_um_t lineno)
1399 {
1400
1401 if (NULL != app) {
1402 app->source_file_line = lineno;
1403 }
1404 }
1405
1406
1407
1408 const dkChar * const *
dk4app_log_debug_texts(dk4_app_t * app,size_t * szptr)1409 dk4app_log_debug_texts(dk4_app_t *app, size_t *szptr)
1410 {
1411 const dkChar * const *back = NULL;
1412
1413 if (NULL != app) {
1414 dk4app_log_load_base_texts(app);
1415 if ((NULL != app->msg_debug) && (0 < app->sz_msg_debug)) {
1416 back = app->msg_debug;
1417 } else {
1418 app->msg_debug = dk4app_string_table(
1419 app, dk4app_log_kwnl[2], dk4app_def_msg_debug
1420 );
1421 app->sz_msg_debug = dk4app_string_table_size(app->msg_debug);
1422 back = app->msg_debug;
1423 }
1424 } else {
1425 back = dk4app_def_msg_debug;
1426 }
1427 if (NULL != szptr) {
1428 *szptr = dk4app_string_table_size(dk4app_def_msg_debug);
1429 }
1430
1431 return back;
1432 }
1433
1434
1435
1436 static
1437 void
dk4app_log_two_strings_at_startup(dk4_app_t * app,const dkChar * title,const dkChar * value)1438 dk4app_log_two_strings_at_startup(
1439 dk4_app_t *app,
1440 const dkChar *title,
1441 const dkChar *value
1442 )
1443 {
1444 const dkChar *msg[3];
1445 #if DK4_USE_ASSERT
1446 assert(NULL != app);
1447 #endif
1448 msg[0] = title;
1449 msg[1] = value;
1450 if (NULL == value) {
1451 msg[1] = dk4app_log_kwnl[3];
1452 }
1453 msg[2] = NULL;
1454 dk4app_log_msg(app, DK4_LL_DEBUG, msg, 2);
1455 }
1456
1457
1458
1459 static
1460 void
dk4app_log_startup_log_level(dk4_app_t * app,const dkChar * title,int ll)1461 dk4app_log_startup_log_level(
1462 dk4_app_t *app,
1463 const dkChar *title,
1464 int ll
1465 )
1466 {
1467 const dkChar *llstr = NULL;
1468 #if DK4_USE_ASSERT
1469 assert(NULL != app);
1470 #endif
1471 if ((DK4_LL_NONE <= ll) && (DK4_LL_IGNORE >= ll)) {
1472 llstr = (app->msg_base)[(size_t)ll];
1473 }
1474 dk4app_log_two_strings_at_startup(app, title, llstr);
1475 }
1476
1477
1478
1479 static
1480 void
dk4app_log_startup_encoding(dk4_app_t * app,const dkChar * title,int enc,int isfileenc)1481 dk4app_log_startup_encoding(
1482 dk4_app_t *app,
1483 const dkChar *title,
1484 int enc,
1485 int isfileenc
1486 )
1487 {
1488 const dkChar *encstr = NULL;
1489 #if DK4_USE_ASSERT
1490 assert(NULL != app);
1491 #endif
1492 if (0 != isfileenc) {
1493 switch (enc) {
1494 case DK4_FILE_ENCODING_PLAIN : {
1495 encstr = dk4app_log_kwnl[5];
1496 } break;
1497 case DK4_FILE_ENCODING_WIN1252 : {
1498 encstr = dk4app_log_kwnl[6];
1499 } break;
1500 case DK4_FILE_ENCODING_UTF8 : {
1501 encstr = dk4app_log_kwnl[7];
1502 } break;
1503 case DK4_FILE_ENCODING_UTF16_LE : {
1504 encstr = dk4app_log_kwnl[9];
1505 } break;
1506 case DK4_FILE_ENCODING_UTF16_BE : {
1507 encstr = dk4app_log_kwnl[10];
1508 } break;
1509 case DK4_FILE_ENCODING_32_LE : {
1510 encstr = dk4app_log_kwnl[12];
1511 } break;
1512 case DK4_FILE_ENCODING_32_BE : {
1513 encstr = dk4app_log_kwnl[13];
1514 } break;
1515 }
1516 } else {
1517 switch (enc) {
1518 case DK4_ENCODING_PLAIN : {
1519 encstr = dk4app_log_kwnl[5];
1520 } break;
1521 case DK4_ENCODING_WIN1252 : {
1522 encstr = dk4app_log_kwnl[6];
1523 } break;
1524 case DK4_ENCODING_UTF8 : {
1525 encstr = dk4app_log_kwnl[7];
1526 } break;
1527 case DK4_ENCODING_UTF16 : {
1528 encstr = dk4app_log_kwnl[8];
1529 } break;
1530 case DK4_ENCODING_32 : {
1531 encstr = dk4app_log_kwnl[11];
1532 } break;
1533 }
1534 }
1535 dk4app_log_two_strings_at_startup(app, title, encstr);
1536 }
1537
1538
1539
1540 void
dk4app_log_startup_debug(dk4_app_t * app)1541 dk4app_log_startup_debug(dk4_app_t *app)
1542 {
1543 dkChar fnb[DK4_MAX_PATH];
1544 dk4_er_t er;
1545 const dkChar *msgtxt[3];
1546 const dkChar * const *debmsg = NULL;
1547 size_t szdebmsg = 0;
1548 int res = 0;
1549 int pn = 0;
1550
1551 #if DK4_USE_ASSERT
1552 assert(NULL != app);
1553 #endif
1554 if (NULL != app) {
1555 if (0 != dk4app_log_do(app, DK4_LL_DEBUG)) {
1556 /* Obtain localized texts */
1557 dk4app_log_load_base_texts(app);
1558 debmsg = dk4app_log_debug_texts(app, &szdebmsg);
1559
1560 /* 0 Host name */
1561 dk4app_log_two_strings_at_startup(app, debmsg[0], app->host_name);
1562
1563 /* 1 User name */
1564 dk4app_log_two_strings_at_startup(app, debmsg[1], app->user_name);
1565
1566 /* 2 Home dir */
1567 dk4app_log_two_strings_at_startup(app, debmsg[2], app->user_home);
1568
1569 /* 3 Language */
1570 dk4app_log_two_strings_at_startup(app, debmsg[3], app->language);
1571
1572 /* 4 Region */
1573 dk4app_log_two_strings_at_startup(app, debmsg[4], app->region);
1574
1575 /* 5 Encoding */
1576 dk4app_log_startup_encoding(app, debmsg[5], app->encoding, 0);
1577
1578 /* 6 Encoding stdin */
1579 dk4app_log_startup_encoding(app, debmsg[6], app->enc_in_std, 1);
1580
1581 /* 7 Encoding files */
1582 dk4app_log_startup_encoding(app, debmsg[7], app->enc_in_file, 1);
1583
1584 /* 8 Program name */
1585 dk4app_log_two_strings_at_startup(app, debmsg[8], app->prog_name);
1586
1587 /* 9 Program group */
1588 dk4app_log_two_strings_at_startup(app, debmsg[9], app->group_name);
1589
1590 /* 10 etc */
1591 dk4app_log_two_strings_at_startup(app, debmsg[10], app->dir_etc);
1592
1593 /* 11 bin */
1594 dk4app_log_two_strings_at_startup(app, debmsg[11], app->dir_bin);
1595
1596 /* 12 share */
1597 dk4app_log_two_strings_at_startup(app, debmsg[12], app->dir_share);
1598
1599 /* 13 lib */
1600 dk4app_log_two_strings_at_startup(app, debmsg[13], app->dir_lib);
1601
1602 /* 14 var */
1603 dk4app_log_two_strings_at_startup(app, debmsg[14], app->dir_var);
1604
1605 /* 15 tmp */
1606 dk4app_log_two_strings_at_startup(app, debmsg[15], app->dir_tmp);
1607
1608 /* 17 Log file */
1609 dk4app_log_two_strings_at_startup(app, debmsg[17], app->log_file_name);
1610
1611 /* 16 Logging enabled */
1612 dk4app_log_two_strings_at_startup(
1613 app, debmsg[16], dk4app_log_kwnl[(0 != app->log_enabled) ? 4 : 3]
1614 );
1615
1616 /* 18 Log level stderr */
1617 dk4app_log_startup_log_level(app, debmsg[18], app->ll_stderr);
1618
1619 /* 19 Log level file */
1620 dk4app_log_startup_log_level(app, debmsg[19], app->ll_file);
1621
1622 /* 20 Log level keep */
1623 dk4app_log_startup_log_level(app, debmsg[20], app->ll_file_keep);
1624
1625 /* Preferences files */
1626 dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 28);
1627 for (pn = 0; (pn <= DK4_FS_CONF_MAX); pn++) {
1628 #if DK4_HAVE_COMPATDKTOOLS3
1629 dk4error_init(&er);
1630 res = dk4fs_config_construct_compat_one(
1631 fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[14],
1632 app->dir_share, app->dir_etc, app->user_home,
1633 app->prog_name, app->group_name, pn, 1, &er
1634 );
1635 if (0 != res) {
1636 res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
1637 if (0 != res) {
1638 msgtxt[0] = debmsg[30];
1639 msgtxt[1] = fnb;
1640 dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
1641 } else {
1642 msgtxt[0] = debmsg[31];
1643 msgtxt[1] = fnb;
1644 dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
1645 }
1646 }
1647 #endif
1648 dk4error_init(&er);
1649 res = dk4fs_config_construct_compat_one(
1650 fnb, DK4_SIZEOF(fnb,dkChar), dk4app_log_kwnl[15],
1651 app->dir_share, app->dir_etc, app->user_home,
1652 app->prog_name, app->group_name, pn, 0, &er
1653 );
1654 if (0 != res) {
1655 res = dk4fs_attempt_file_name(fnb, DK4_SIZEOF(fnb,dkChar), 1, NULL);
1656 if (0 != res) {
1657 msgtxt[0] = debmsg[30];
1658 msgtxt[1] = fnb;
1659 dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
1660 } else {
1661 msgtxt[0] = debmsg[31];
1662 msgtxt[1] = fnb;
1663 dk4app_log_msg(app, DK4_LL_DEBUG, msgtxt, 2);
1664 }
1665 }
1666 }
1667 #if VERSION_BEFORE_2017_03_13
1668 dk4app_log_1(app, debmsg, szdebmsg, DK4_LL_DEBUG, 29);
1669 #endif
1670 }
1671 }
1672
1673 }
1674
1675