1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <inttypes.h>
6 #include <limits.h>
7 #include <stdarg.h>
8 #include <stddef.h>
9 #include <sys/signalfd.h>
10 #include <sys/stat.h>
11 #include <sys/time.h>
12 #include <sys/uio.h>
13 #include <sys/un.h>
14 #include <unistd.h>
15 
16 #include "sd-messages.h"
17 
18 #include "alloc-util.h"
19 #include "errno-util.h"
20 #include "fd-util.h"
21 #include "format-util.h"
22 #include "io-util.h"
23 #include "log.h"
24 #include "macro.h"
25 #include "missing_syscall.h"
26 #include "parse-util.h"
27 #include "proc-cmdline.h"
28 #include "process-util.h"
29 #include "ratelimit.h"
30 #include "signal-util.h"
31 #include "socket-util.h"
32 #include "stdio-util.h"
33 #include "string-table.h"
34 #include "string-util.h"
35 #include "syslog-util.h"
36 #include "terminal-util.h"
37 #include "time-util.h"
38 #include "utf8.h"
39 
40 #define SNDBUF_SIZE (8*1024*1024)
41 
42 static log_syntax_callback_t log_syntax_callback = NULL;
43 static void *log_syntax_callback_userdata = NULL;
44 
45 static LogTarget log_target = LOG_TARGET_CONSOLE;
46 static int log_max_level = LOG_INFO;
47 static int log_facility = LOG_DAEMON;
48 
49 static int console_fd = STDERR_FILENO;
50 static int syslog_fd = -1;
51 static int kmsg_fd = -1;
52 static int journal_fd = -1;
53 
54 static bool syslog_is_stream = false;
55 
56 static int show_color = -1; /* tristate */
57 static bool show_location = false;
58 static bool show_time = false;
59 static bool show_tid = false;
60 
61 static bool upgrade_syslog_to_journal = false;
62 static bool always_reopen_console = false;
63 static bool open_when_needed = false;
64 static bool prohibit_ipc = false;
65 
66 /* Akin to glibc's __abort_msg; which is private and we hence cannot
67  * use here. */
68 static char *log_abort_msg = NULL;
69 
70 #if LOG_MESSAGE_VERIFICATION || defined(__COVERITY__)
71 bool _log_message_dummy = false; /* Always false */
72 #endif
73 
74 /* An assert to use in logging functions that does not call recursively
75  * into our logging functions (since that might lead to a loop). */
76 #define assert_raw(expr)                                                \
77         do {                                                            \
78                 if (_unlikely_(!(expr))) {                              \
79                         fputs(#expr "\n", stderr);                      \
80                         abort();                                        \
81                 }                                                       \
82         } while (false)
83 
log_close_console(void)84 static void log_close_console(void) {
85         console_fd = safe_close_above_stdio(console_fd);
86 }
87 
log_open_console(void)88 static int log_open_console(void) {
89 
90         if (!always_reopen_console) {
91                 console_fd = STDERR_FILENO;
92                 return 0;
93         }
94 
95         if (console_fd < 3) {
96                 int fd;
97 
98                 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
99                 if (fd < 0)
100                         return fd;
101 
102                 console_fd = fd_move_above_stdio(fd);
103         }
104 
105         return 0;
106 }
107 
log_close_kmsg(void)108 static void log_close_kmsg(void) {
109         kmsg_fd = safe_close(kmsg_fd);
110 }
111 
log_open_kmsg(void)112 static int log_open_kmsg(void) {
113 
114         if (kmsg_fd >= 0)
115                 return 0;
116 
117         kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
118         if (kmsg_fd < 0)
119                 return -errno;
120 
121         kmsg_fd = fd_move_above_stdio(kmsg_fd);
122         return 0;
123 }
124 
log_close_syslog(void)125 static void log_close_syslog(void) {
126         syslog_fd = safe_close(syslog_fd);
127 }
128 
create_log_socket(int type)129 static int create_log_socket(int type) {
130         struct timeval tv;
131         int fd;
132 
133         fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
134         if (fd < 0)
135                 return -errno;
136 
137         fd = fd_move_above_stdio(fd);
138         (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
139 
140         /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever
141          * in the unlikely case of a deadlock. */
142         if (getpid_cached() == 1)
143                 timeval_store(&tv, 10 * USEC_PER_MSEC);
144         else
145                 timeval_store(&tv, 10 * USEC_PER_SEC);
146         (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
147 
148         return fd;
149 }
150 
log_open_syslog(void)151 static int log_open_syslog(void) {
152 
153         static const union sockaddr_union sa = {
154                 .un.sun_family = AF_UNIX,
155                 .un.sun_path = "/dev/log",
156         };
157 
158         int r;
159 
160         if (syslog_fd >= 0)
161                 return 0;
162 
163         syslog_fd = create_log_socket(SOCK_DGRAM);
164         if (syslog_fd < 0) {
165                 r = syslog_fd;
166                 goto fail;
167         }
168 
169         if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
170                 safe_close(syslog_fd);
171 
172                 /* Some legacy syslog systems still use stream
173                  * sockets. They really shouldn't. But what can we
174                  * do... */
175                 syslog_fd = create_log_socket(SOCK_STREAM);
176                 if (syslog_fd < 0) {
177                         r = syslog_fd;
178                         goto fail;
179                 }
180 
181                 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
182                         r = -errno;
183                         goto fail;
184                 }
185 
186                 syslog_is_stream = true;
187         } else
188                 syslog_is_stream = false;
189 
190         return 0;
191 
192 fail:
193         log_close_syslog();
194         return r;
195 }
196 
log_close_journal(void)197 static void log_close_journal(void) {
198         journal_fd = safe_close(journal_fd);
199 }
200 
log_open_journal(void)201 static int log_open_journal(void) {
202 
203         static const union sockaddr_union sa = {
204                 .un.sun_family = AF_UNIX,
205                 .un.sun_path = "/run/systemd/journal/socket",
206         };
207 
208         int r;
209 
210         if (journal_fd >= 0)
211                 return 0;
212 
213         journal_fd = create_log_socket(SOCK_DGRAM);
214         if (journal_fd < 0) {
215                 r = journal_fd;
216                 goto fail;
217         }
218 
219         if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
220                 r = -errno;
221                 goto fail;
222         }
223 
224         return 0;
225 
226 fail:
227         log_close_journal();
228         return r;
229 }
230 
stderr_is_journal(void)231 static bool stderr_is_journal(void) {
232         _cleanup_free_ char *w = NULL;
233         const char *e;
234         uint64_t dev, ino;
235         struct stat st;
236 
237         e = getenv("JOURNAL_STREAM");
238         if (!e)
239                 return false;
240 
241         if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0)
242                 return false;
243         if (!e)
244                 return false;
245 
246         if (safe_atou64(w, &dev) < 0)
247                 return false;
248         if (safe_atou64(e, &ino) < 0)
249                 return false;
250 
251         if (fstat(STDERR_FILENO, &st) < 0)
252                 return false;
253 
254         return st.st_dev == dev && st.st_ino == ino;
255 }
256 
log_open(void)257 int log_open(void) {
258         int r;
259 
260         /* Do not call from library code. */
261 
262         /* This function is often called in preparation for logging. Let's make sure we don't clobber errno,
263          * so that a call to a logging function immediately following a log_open() call can still easily
264          * reference an error that happened immediately before the log_open() call. */
265         PROTECT_ERRNO;
266 
267         /* If we don't use the console, we close it here to not get killed by SAK. If we don't use syslog, we
268          * close it here too, so that we are not confused by somebody deleting the socket in the fs, and to
269          * make sure we don't use it if prohibit_ipc is set. If we don't use /dev/kmsg we still keep it open,
270          * because there is no reason to close it. */
271 
272         if (log_target == LOG_TARGET_NULL) {
273                 log_close_journal();
274                 log_close_syslog();
275                 log_close_console();
276                 return 0;
277         }
278 
279         if (getpid_cached() == 1 ||
280             stderr_is_journal() ||
281             IN_SET(log_target,
282                    LOG_TARGET_KMSG,
283                    LOG_TARGET_JOURNAL,
284                    LOG_TARGET_JOURNAL_OR_KMSG,
285                    LOG_TARGET_SYSLOG,
286                    LOG_TARGET_SYSLOG_OR_KMSG)) {
287 
288                 if (!prohibit_ipc) {
289                         if (IN_SET(log_target,
290                                    LOG_TARGET_AUTO,
291                                    LOG_TARGET_JOURNAL_OR_KMSG,
292                                    LOG_TARGET_JOURNAL)) {
293 
294                                 r = log_open_journal();
295                                 if (r >= 0) {
296                                         log_close_syslog();
297                                         log_close_console();
298                                         return r;
299                                 }
300                         }
301 
302                         if (IN_SET(log_target,
303                                    LOG_TARGET_SYSLOG_OR_KMSG,
304                                    LOG_TARGET_SYSLOG)) {
305 
306                                 r = log_open_syslog();
307                                 if (r >= 0) {
308                                         log_close_journal();
309                                         log_close_console();
310                                         return r;
311                                 }
312                         }
313                 }
314 
315                 if (IN_SET(log_target, LOG_TARGET_AUTO,
316                                        LOG_TARGET_JOURNAL_OR_KMSG,
317                                        LOG_TARGET_SYSLOG_OR_KMSG,
318                                        LOG_TARGET_KMSG)) {
319                         r = log_open_kmsg();
320                         if (r >= 0) {
321                                 log_close_journal();
322                                 log_close_syslog();
323                                 log_close_console();
324                                 return r;
325                         }
326                 }
327         }
328 
329         log_close_journal();
330         log_close_syslog();
331 
332         return log_open_console();
333 }
334 
log_set_target(LogTarget target)335 void log_set_target(LogTarget target) {
336         assert(target >= 0);
337         assert(target < _LOG_TARGET_MAX);
338 
339         if (upgrade_syslog_to_journal) {
340                 if (target == LOG_TARGET_SYSLOG)
341                         target = LOG_TARGET_JOURNAL;
342                 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
343                         target = LOG_TARGET_JOURNAL_OR_KMSG;
344         }
345 
346         log_target = target;
347 }
348 
log_close(void)349 void log_close(void) {
350         /* Do not call from library code. */
351 
352         log_close_journal();
353         log_close_syslog();
354         log_close_kmsg();
355         log_close_console();
356 }
357 
log_forget_fds(void)358 void log_forget_fds(void) {
359         /* Do not call from library code. */
360 
361         console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
362 }
363 
log_set_max_level(int level)364 void log_set_max_level(int level) {
365         assert(level == LOG_NULL || (level & LOG_PRIMASK) == level);
366 
367         log_max_level = level;
368 }
369 
log_set_facility(int facility)370 void log_set_facility(int facility) {
371         log_facility = facility;
372 }
373 
write_to_console(int level,int error,const char * file,int line,const char * func,const char * buffer)374 static int write_to_console(
375                 int level,
376                 int error,
377                 const char *file,
378                 int line,
379                 const char *func,
380                 const char *buffer) {
381 
382         char location[256],
383              header_time[FORMAT_TIMESTAMP_MAX],
384              prefix[1 + DECIMAL_STR_MAX(int) + 2],
385              tid_string[3 + DECIMAL_STR_MAX(pid_t) + 1];
386         struct iovec iovec[9];
387         const char *on = NULL, *off = NULL;
388         size_t n = 0;
389 
390         if (console_fd < 0)
391                 return 0;
392 
393         if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
394                 xsprintf(prefix, "<%i>", level);
395                 iovec[n++] = IOVEC_MAKE_STRING(prefix);
396         }
397 
398         if (show_time &&
399             format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
400                 iovec[n++] = IOVEC_MAKE_STRING(header_time);
401                 iovec[n++] = IOVEC_MAKE_STRING(" ");
402         }
403 
404         if (show_tid) {
405                 xsprintf(tid_string, "(" PID_FMT ") ", gettid());
406                 iovec[n++] = IOVEC_MAKE_STRING(tid_string);
407         }
408 
409         if (log_get_show_color())
410                 get_log_colors(LOG_PRI(level), &on, &off, NULL);
411 
412         if (show_location) {
413                 const char *lon = "", *loff = "";
414                 if (log_get_show_color()) {
415                         lon = ansi_highlight_yellow4();
416                         loff = ansi_normal();
417                 }
418 
419                 (void) snprintf(location, sizeof location, "%s%s:%i%s: ", lon, file, line, loff);
420                 iovec[n++] = IOVEC_MAKE_STRING(location);
421         }
422 
423         if (on)
424                 iovec[n++] = IOVEC_MAKE_STRING(on);
425         iovec[n++] = IOVEC_MAKE_STRING(buffer);
426         if (off)
427                 iovec[n++] = IOVEC_MAKE_STRING(off);
428         iovec[n++] = IOVEC_MAKE_STRING("\n");
429 
430         if (writev(console_fd, iovec, n) < 0) {
431 
432                 if (errno == EIO && getpid_cached() == 1) {
433 
434                         /* If somebody tried to kick us from our console tty (via vhangup() or suchlike), try
435                          * to reconnect. */
436 
437                         log_close_console();
438                         (void) log_open_console();
439                         if (console_fd < 0)
440                                 return 0;
441 
442                         if (writev(console_fd, iovec, n) < 0)
443                                 return -errno;
444                 } else
445                         return -errno;
446         }
447 
448         return 1;
449 }
450 
write_to_syslog(int level,int error,const char * file,int line,const char * func,const char * buffer)451 static int write_to_syslog(
452                 int level,
453                 int error,
454                 const char *file,
455                 int line,
456                 const char *func,
457                 const char *buffer) {
458 
459         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
460              header_time[64],
461              header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
462         time_t t;
463         struct tm tm;
464 
465         if (syslog_fd < 0)
466                 return 0;
467 
468         xsprintf(header_priority, "<%i>", level);
469 
470         t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
471         if (!localtime_r(&t, &tm))
472                 return -EINVAL;
473 
474         if (strftime(header_time, sizeof(header_time), "%h %e %T ", &tm) <= 0)
475                 return -EINVAL;
476 
477         xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
478 
479         struct iovec iovec[] = {
480                 IOVEC_MAKE_STRING(header_priority),
481                 IOVEC_MAKE_STRING(header_time),
482                 IOVEC_MAKE_STRING(program_invocation_short_name),
483                 IOVEC_MAKE_STRING(header_pid),
484                 IOVEC_MAKE_STRING(buffer),
485         };
486         const struct msghdr msghdr = {
487                 .msg_iov = iovec,
488                 .msg_iovlen = ELEMENTSOF(iovec),
489         };
490 
491         /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
492         if (syslog_is_stream)
493                 iovec[ELEMENTSOF(iovec) - 1].iov_len++;
494 
495         for (;;) {
496                 ssize_t n;
497 
498                 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
499                 if (n < 0)
500                         return -errno;
501 
502                 if (!syslog_is_stream)
503                         break;
504 
505                 if (IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n))
506                         break;
507         }
508 
509         return 1;
510 }
511 
write_to_kmsg(int level,int error,const char * file,int line,const char * func,const char * buffer)512 static int write_to_kmsg(
513                 int level,
514                 int error,
515                 const char *file,
516                 int line,
517                 const char *func,
518                 const char *buffer) {
519 
520         /* Set a ratelimit on the amount of messages logged to /dev/kmsg. This is mostly supposed to be a
521          * safety catch for the case where start indiscriminately logging in a loop. It will not catch cases
522          * where we log excessively, but not in a tight loop.
523          *
524          * Note that this ratelimit is per-emitter, so we might still overwhelm /dev/kmsg with multiple
525          * loggers.
526          */
527         static thread_local RateLimit ratelimit = { 5 * USEC_PER_SEC, 200 };
528 
529         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
530              header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
531 
532         if (kmsg_fd < 0)
533                 return 0;
534 
535         if (!ratelimit_below(&ratelimit))
536                 return 0;
537 
538         xsprintf(header_priority, "<%i>", level);
539         xsprintf(header_pid, "["PID_FMT"]: ", getpid_cached());
540 
541         const struct iovec iovec[] = {
542                 IOVEC_MAKE_STRING(header_priority),
543                 IOVEC_MAKE_STRING(program_invocation_short_name),
544                 IOVEC_MAKE_STRING(header_pid),
545                 IOVEC_MAKE_STRING(buffer),
546                 IOVEC_MAKE_STRING("\n"),
547         };
548 
549         if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
550                 return -errno;
551 
552         return 1;
553 }
554 
log_do_header(char * header,size_t size,int level,int error,const char * file,int line,const char * func,const char * object_field,const char * object,const char * extra_field,const char * extra)555 static int log_do_header(
556                 char *header,
557                 size_t size,
558                 int level,
559                 int error,
560                 const char *file, int line, const char *func,
561                 const char *object_field, const char *object,
562                 const char *extra_field, const char *extra) {
563         int r;
564 
565         error = IS_SYNTHETIC_ERRNO(error) ? 0 : ERRNO_VALUE(error);
566 
567         r = snprintf(header, size,
568                      "PRIORITY=%i\n"
569                      "SYSLOG_FACILITY=%i\n"
570                      "TID=" PID_FMT "\n"
571                      "%s%.256s%s"        /* CODE_FILE */
572                      "%s%.*i%s"          /* CODE_LINE */
573                      "%s%.256s%s"        /* CODE_FUNC */
574                      "%s%.*i%s"          /* ERRNO */
575                      "%s%.256s%s"        /* object */
576                      "%s%.256s%s"        /* extra */
577                      "SYSLOG_IDENTIFIER=%.256s\n",
578                      LOG_PRI(level),
579                      LOG_FAC(level),
580                      gettid(),
581                      isempty(file) ? "" : "CODE_FILE=",
582                      isempty(file) ? "" : file,
583                      isempty(file) ? "" : "\n",
584                      line ? "CODE_LINE=" : "",
585                      line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
586                      line ? "\n" : "",
587                      isempty(func) ? "" : "CODE_FUNC=",
588                      isempty(func) ? "" : func,
589                      isempty(func) ? "" : "\n",
590                      error ? "ERRNO=" : "",
591                      error ? 1 : 0, error,
592                      error ? "\n" : "",
593                      isempty(object) ? "" : object_field,
594                      isempty(object) ? "" : object,
595                      isempty(object) ? "" : "\n",
596                      isempty(extra) ? "" : extra_field,
597                      isempty(extra) ? "" : extra,
598                      isempty(extra) ? "" : "\n",
599                      program_invocation_short_name);
600         assert_raw((size_t) r < size);
601 
602         return 0;
603 }
604 
write_to_journal(int level,int error,const char * file,int line,const char * func,const char * object_field,const char * object,const char * extra_field,const char * extra,const char * buffer)605 static int write_to_journal(
606                 int level,
607                 int error,
608                 const char *file,
609                 int line,
610                 const char *func,
611                 const char *object_field,
612                 const char *object,
613                 const char *extra_field,
614                 const char *extra,
615                 const char *buffer) {
616 
617         char header[LINE_MAX];
618 
619         if (journal_fd < 0)
620                 return 0;
621 
622         log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
623 
624         struct iovec iovec[4] = {
625                 IOVEC_MAKE_STRING(header),
626                 IOVEC_MAKE_STRING("MESSAGE="),
627                 IOVEC_MAKE_STRING(buffer),
628                 IOVEC_MAKE_STRING("\n"),
629         };
630         const struct msghdr msghdr = {
631                 .msg_iov = iovec,
632                 .msg_iovlen = ELEMENTSOF(iovec),
633         };
634 
635         if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) < 0)
636                 return -errno;
637 
638         return 1;
639 }
640 
log_dispatch_internal(int level,int error,const char * file,int line,const char * func,const char * object_field,const char * object,const char * extra_field,const char * extra,char * buffer)641 int log_dispatch_internal(
642                 int level,
643                 int error,
644                 const char *file,
645                 int line,
646                 const char *func,
647                 const char *object_field,
648                 const char *object,
649                 const char *extra_field,
650                 const char *extra,
651                 char *buffer) {
652 
653         assert_raw(buffer);
654 
655         if (log_target == LOG_TARGET_NULL)
656                 return -ERRNO_VALUE(error);
657 
658         /* Patch in LOG_DAEMON facility if necessary */
659         if ((level & LOG_FACMASK) == 0)
660                 level |= log_facility;
661 
662         if (open_when_needed)
663                 (void) log_open();
664 
665         do {
666                 char *e;
667                 int k = 0;
668 
669                 buffer += strspn(buffer, NEWLINE);
670 
671                 if (buffer[0] == 0)
672                         break;
673 
674                 if ((e = strpbrk(buffer, NEWLINE)))
675                         *(e++) = 0;
676 
677                 if (IN_SET(log_target, LOG_TARGET_AUTO,
678                                        LOG_TARGET_JOURNAL_OR_KMSG,
679                                        LOG_TARGET_JOURNAL)) {
680 
681                         k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
682                         if (k < 0 && k != -EAGAIN)
683                                 log_close_journal();
684                 }
685 
686                 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
687                                        LOG_TARGET_SYSLOG)) {
688 
689                         k = write_to_syslog(level, error, file, line, func, buffer);
690                         if (k < 0 && k != -EAGAIN)
691                                 log_close_syslog();
692                 }
693 
694                 if (k <= 0 &&
695                     IN_SET(log_target, LOG_TARGET_AUTO,
696                                        LOG_TARGET_SYSLOG_OR_KMSG,
697                                        LOG_TARGET_JOURNAL_OR_KMSG,
698                                        LOG_TARGET_KMSG)) {
699 
700                         if (k < 0)
701                                 log_open_kmsg();
702 
703                         k = write_to_kmsg(level, error, file, line, func, buffer);
704                         if (k < 0) {
705                                 log_close_kmsg();
706                                 (void) log_open_console();
707                         }
708                 }
709 
710                 if (k <= 0)
711                         (void) write_to_console(level, error, file, line, func, buffer);
712 
713                 buffer = e;
714         } while (buffer);
715 
716         if (open_when_needed)
717                 log_close();
718 
719         return -ERRNO_VALUE(error);
720 }
721 
log_dump_internal(int level,int error,const char * file,int line,const char * func,char * buffer)722 int log_dump_internal(
723                 int level,
724                 int error,
725                 const char *file,
726                 int line,
727                 const char *func,
728                 char *buffer) {
729 
730         PROTECT_ERRNO;
731 
732         /* This modifies the buffer... */
733 
734         if (_likely_(LOG_PRI(level) > log_max_level))
735                 return -ERRNO_VALUE(error);
736 
737         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
738 }
739 
log_internalv(int level,int error,const char * file,int line,const char * func,const char * format,va_list ap)740 int log_internalv(
741                 int level,
742                 int error,
743                 const char *file,
744                 int line,
745                 const char *func,
746                 const char *format,
747                 va_list ap) {
748 
749         char buffer[LINE_MAX];
750         PROTECT_ERRNO;
751 
752         if (_likely_(LOG_PRI(level) > log_max_level))
753                 return -ERRNO_VALUE(error);
754 
755         /* Make sure that %m maps to the specified error (or "Success"). */
756         errno = ERRNO_VALUE(error);
757 
758         (void) vsnprintf(buffer, sizeof buffer, format, ap);
759 
760         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
761 }
762 
log_internal(int level,int error,const char * file,int line,const char * func,const char * format,...)763 int log_internal(
764                 int level,
765                 int error,
766                 const char *file,
767                 int line,
768                 const char *func,
769                 const char *format, ...) {
770 
771         va_list ap;
772         int r;
773 
774         va_start(ap, format);
775         r = log_internalv(level, error, file, line, func, format, ap);
776         va_end(ap);
777 
778         return r;
779 }
780 
log_object_internalv(int level,int error,const char * file,int line,const char * func,const char * object_field,const char * object,const char * extra_field,const char * extra,const char * format,va_list ap)781 int log_object_internalv(
782                 int level,
783                 int error,
784                 const char *file,
785                 int line,
786                 const char *func,
787                 const char *object_field,
788                 const char *object,
789                 const char *extra_field,
790                 const char *extra,
791                 const char *format,
792                 va_list ap) {
793 
794         PROTECT_ERRNO;
795         char *buffer, *b;
796 
797         if (_likely_(LOG_PRI(level) > log_max_level))
798                 return -ERRNO_VALUE(error);
799 
800         /* Make sure that %m maps to the specified error (or "Success"). */
801         errno = ERRNO_VALUE(error);
802 
803         /* Prepend the object name before the message */
804         if (object) {
805                 size_t n;
806 
807                 n = strlen(object);
808                 buffer = newa(char, n + 2 + LINE_MAX);
809                 b = stpcpy(stpcpy(buffer, object), ": ");
810         } else
811                 b = buffer = newa(char, LINE_MAX);
812 
813         (void) vsnprintf(b, LINE_MAX, format, ap);
814 
815         return log_dispatch_internal(level, error, file, line, func,
816                                      object_field, object, extra_field, extra, buffer);
817 }
818 
log_object_internal(int level,int error,const char * file,int line,const char * func,const char * object_field,const char * object,const char * extra_field,const char * extra,const char * format,...)819 int log_object_internal(
820                 int level,
821                 int error,
822                 const char *file,
823                 int line,
824                 const char *func,
825                 const char *object_field,
826                 const char *object,
827                 const char *extra_field,
828                 const char *extra,
829                 const char *format, ...) {
830 
831         va_list ap;
832         int r;
833 
834         va_start(ap, format);
835         r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
836         va_end(ap);
837 
838         return r;
839 }
840 
log_assert(int level,const char * text,const char * file,int line,const char * func,const char * format)841 static void log_assert(
842                 int level,
843                 const char *text,
844                 const char *file,
845                 int line,
846                 const char *func,
847                 const char *format) {
848 
849         static char buffer[LINE_MAX];
850 
851         if (_likely_(LOG_PRI(level) > log_max_level))
852                 return;
853 
854         DISABLE_WARNING_FORMAT_NONLITERAL;
855         (void) snprintf(buffer, sizeof buffer, format, text, file, line, func);
856         REENABLE_WARNING;
857 
858         log_abort_msg = buffer;
859 
860         log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
861 }
862 
log_assert_failed(const char * text,const char * file,int line,const char * func)863 _noreturn_ void log_assert_failed(
864                 const char *text,
865                 const char *file,
866                 int line,
867                 const char *func) {
868         log_assert(LOG_CRIT, text, file, line, func,
869                    "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
870         abort();
871 }
872 
log_assert_failed_unreachable(const char * file,int line,const char * func)873 _noreturn_ void log_assert_failed_unreachable(
874                 const char *file,
875                 int line,
876                 const char *func) {
877         log_assert(LOG_CRIT, "Code should not be reached", file, line, func,
878                    "%s at %s:%u, function %s(). Aborting. ��");
879         abort();
880 }
881 
log_assert_failed_return(const char * text,const char * file,int line,const char * func)882 void log_assert_failed_return(
883                 const char *text,
884                 const char *file,
885                 int line,
886                 const char *func) {
887         PROTECT_ERRNO;
888         log_assert(LOG_DEBUG, text, file, line, func,
889                    "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
890 }
891 
log_oom_internal(int level,const char * file,int line,const char * func)892 int log_oom_internal(int level, const char *file, int line, const char *func) {
893         return log_internal(level, ENOMEM, file, line, func, "Out of memory.");
894 }
895 
log_format_iovec(struct iovec * iovec,size_t iovec_len,size_t * n,bool newline_separator,int error,const char * format,va_list ap)896 int log_format_iovec(
897                 struct iovec *iovec,
898                 size_t iovec_len,
899                 size_t *n,
900                 bool newline_separator,
901                 int error,
902                 const char *format,
903                 va_list ap) {
904 
905         static const char nl = '\n';
906 
907         while (format && *n + 1 < iovec_len) {
908                 va_list aq;
909                 char *m;
910                 int r;
911 
912                 /* We need to copy the va_list structure,
913                  * since vasprintf() leaves it afterwards at
914                  * an undefined location */
915 
916                 errno = ERRNO_VALUE(error);
917 
918                 va_copy(aq, ap);
919                 r = vasprintf(&m, format, aq);
920                 va_end(aq);
921                 if (r < 0)
922                         return -EINVAL;
923 
924                 /* Now, jump enough ahead, so that we point to
925                  * the next format string */
926                 VA_FORMAT_ADVANCE(format, ap);
927 
928                 iovec[(*n)++] = IOVEC_MAKE_STRING(m);
929                 if (newline_separator)
930                         iovec[(*n)++] = IOVEC_MAKE((char *)&nl, 1);
931 
932                 format = va_arg(ap, char *);
933         }
934         return 0;
935 }
936 
log_struct_internal(int level,int error,const char * file,int line,const char * func,const char * format,...)937 int log_struct_internal(
938                 int level,
939                 int error,
940                 const char *file,
941                 int line,
942                 const char *func,
943                 const char *format, ...) {
944 
945         char buf[LINE_MAX];
946         bool found = false;
947         PROTECT_ERRNO;
948         va_list ap;
949 
950         if (_likely_(LOG_PRI(level) > log_max_level) ||
951             log_target == LOG_TARGET_NULL)
952                 return -ERRNO_VALUE(error);
953 
954         if ((level & LOG_FACMASK) == 0)
955                 level |= log_facility;
956 
957         if (IN_SET(log_target,
958                    LOG_TARGET_AUTO,
959                    LOG_TARGET_JOURNAL_OR_KMSG,
960                    LOG_TARGET_JOURNAL)) {
961 
962                 if (open_when_needed)
963                         log_open_journal();
964 
965                 if (journal_fd >= 0) {
966                         char header[LINE_MAX];
967                         struct iovec iovec[17];
968                         size_t n = 0;
969                         int r;
970                         bool fallback = false;
971 
972                         /* If the journal is available do structured logging.
973                          * Do not report the errno if it is synthetic. */
974                         log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
975                         iovec[n++] = IOVEC_MAKE_STRING(header);
976 
977                         va_start(ap, format);
978                         r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
979                         if (r < 0)
980                                 fallback = true;
981                         else {
982                                 const struct msghdr msghdr = {
983                                         .msg_iov = iovec,
984                                         .msg_iovlen = n,
985                                 };
986 
987                                 (void) sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL);
988                         }
989 
990                         va_end(ap);
991                         for (size_t i = 1; i < n; i += 2)
992                                 free(iovec[i].iov_base);
993 
994                         if (!fallback) {
995                                 if (open_when_needed)
996                                         log_close();
997 
998                                 return -ERRNO_VALUE(error);
999                         }
1000                 }
1001         }
1002 
1003         /* Fallback if journal logging is not available or didn't work. */
1004 
1005         va_start(ap, format);
1006         while (format) {
1007                 va_list aq;
1008 
1009                 errno = ERRNO_VALUE(error);
1010 
1011                 va_copy(aq, ap);
1012                 (void) vsnprintf(buf, sizeof buf, format, aq);
1013                 va_end(aq);
1014 
1015                 if (startswith(buf, "MESSAGE=")) {
1016                         found = true;
1017                         break;
1018                 }
1019 
1020                 VA_FORMAT_ADVANCE(format, ap);
1021 
1022                 format = va_arg(ap, char *);
1023         }
1024         va_end(ap);
1025 
1026         if (!found) {
1027                 if (open_when_needed)
1028                         log_close();
1029 
1030                 return -ERRNO_VALUE(error);
1031         }
1032 
1033         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
1034 }
1035 
log_struct_iovec_internal(int level,int error,const char * file,int line,const char * func,const struct iovec input_iovec[],size_t n_input_iovec)1036 int log_struct_iovec_internal(
1037                 int level,
1038                 int error,
1039                 const char *file,
1040                 int line,
1041                 const char *func,
1042                 const struct iovec input_iovec[],
1043                 size_t n_input_iovec) {
1044 
1045         PROTECT_ERRNO;
1046 
1047         if (_likely_(LOG_PRI(level) > log_max_level) ||
1048             log_target == LOG_TARGET_NULL)
1049                 return -ERRNO_VALUE(error);
1050 
1051         if ((level & LOG_FACMASK) == 0)
1052                 level |= log_facility;
1053 
1054         if (IN_SET(log_target, LOG_TARGET_AUTO,
1055                                LOG_TARGET_JOURNAL_OR_KMSG,
1056                                LOG_TARGET_JOURNAL) &&
1057             journal_fd >= 0) {
1058 
1059                 char header[LINE_MAX];
1060                 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
1061 
1062                 struct iovec iovec[1 + n_input_iovec*2];
1063                 iovec[0] = IOVEC_MAKE_STRING(header);
1064                 for (size_t i = 0; i < n_input_iovec; i++) {
1065                         iovec[1+i*2] = input_iovec[i];
1066                         iovec[1+i*2+1] = IOVEC_MAKE_STRING("\n");
1067                 }
1068 
1069                 const struct msghdr msghdr = {
1070                         .msg_iov = iovec,
1071                         .msg_iovlen = 1 + n_input_iovec*2,
1072                 };
1073 
1074                 if (sendmsg(journal_fd, &msghdr, MSG_NOSIGNAL) >= 0)
1075                         return -ERRNO_VALUE(error);
1076         }
1077 
1078         for (size_t i = 0; i < n_input_iovec; i++)
1079                 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
1080                         char *m;
1081 
1082                         m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
1083                                           input_iovec[i].iov_len - STRLEN("MESSAGE="));
1084 
1085                         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
1086                 }
1087 
1088         /* Couldn't find MESSAGE=. */
1089         return -ERRNO_VALUE(error);
1090 }
1091 
log_set_target_from_string(const char * e)1092 int log_set_target_from_string(const char *e) {
1093         LogTarget t;
1094 
1095         t = log_target_from_string(e);
1096         if (t < 0)
1097                 return t;
1098 
1099         log_set_target(t);
1100         return 0;
1101 }
1102 
log_set_max_level_from_string(const char * e)1103 int log_set_max_level_from_string(const char *e) {
1104         int t;
1105 
1106         t = log_level_from_string(e);
1107         if (t < 0)
1108                 return t;
1109 
1110         log_set_max_level(t);
1111         return 0;
1112 }
1113 
parse_proc_cmdline_item(const char * key,const char * value,void * data)1114 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
1115 
1116         /*
1117          * The systemd.log_xyz= settings are parsed by all tools, and
1118          * so is "debug".
1119          *
1120          * However, "quiet" is only parsed by PID 1, and only turns of
1121          * status output to /dev/console, but does not alter the log
1122          * level.
1123          */
1124 
1125         if (streq(key, "debug") && !value)
1126                 log_set_max_level(LOG_DEBUG);
1127 
1128         else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1129 
1130                 if (proc_cmdline_value_missing(key, value))
1131                         return 0;
1132 
1133                 if (log_set_target_from_string(value) < 0)
1134                         log_warning("Failed to parse log target '%s'. Ignoring.", value);
1135 
1136         } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1137 
1138                 if (proc_cmdline_value_missing(key, value))
1139                         return 0;
1140 
1141                 if (log_set_max_level_from_string(value) < 0)
1142                         log_warning("Failed to parse log level '%s'. Ignoring.", value);
1143 
1144         } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1145 
1146                 if (log_show_color_from_string(value ?: "1") < 0)
1147                         log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1148 
1149         } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1150 
1151                 if (log_show_location_from_string(value ?: "1") < 0)
1152                         log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1153 
1154         } else if (proc_cmdline_key_streq(key, "systemd.log_tid")) {
1155 
1156                 if (log_show_tid_from_string(value ?: "1") < 0)
1157                         log_warning("Failed to parse log tid setting '%s'. Ignoring.", value);
1158 
1159         } else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
1160 
1161                 if (log_show_time_from_string(value ?: "1") < 0)
1162                         log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
1163 
1164         }
1165 
1166         return 0;
1167 }
1168 
should_parse_proc_cmdline(void)1169 static bool should_parse_proc_cmdline(void) {
1170         const char *e;
1171         pid_t p;
1172 
1173         /* PID1 always reads the kernel command line. */
1174         if (getpid_cached() == 1)
1175                 return true;
1176 
1177         /* If the process is directly executed by PID1 (e.g. ExecStart= or generator), systemd-importd,
1178          * or systemd-homed, then $SYSTEMD_EXEC_PID= is set, and read the command line. */
1179         e = getenv("SYSTEMD_EXEC_PID");
1180         if (!e)
1181                 return false;
1182 
1183         if (streq(e, "*"))
1184                 /* For testing. */
1185                 return true;
1186 
1187         if (parse_pid(e, &p) < 0) {
1188                 /* We know that systemd sets the variable correctly. Something else must have set it. */
1189                 log_debug("Failed to parse \"$SYSTEMD_EXEC_PID=%s\". Ignoring.", e);
1190                 return false;
1191         }
1192 
1193         return getpid_cached() == p;
1194 }
1195 
log_parse_environment_variables(void)1196 void log_parse_environment_variables(void) {
1197         const char *e;
1198 
1199         e = getenv("SYSTEMD_LOG_TARGET");
1200         if (e && log_set_target_from_string(e) < 0)
1201                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1202 
1203         e = getenv("SYSTEMD_LOG_LEVEL");
1204         if (e && log_set_max_level_from_string(e) < 0)
1205                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1206 
1207         e = getenv("SYSTEMD_LOG_COLOR");
1208         if (e && log_show_color_from_string(e) < 0)
1209                 log_warning("Failed to parse log color '%s'. Ignoring.", e);
1210 
1211         e = getenv("SYSTEMD_LOG_LOCATION");
1212         if (e && log_show_location_from_string(e) < 0)
1213                 log_warning("Failed to parse log location '%s'. Ignoring.", e);
1214 
1215         e = getenv("SYSTEMD_LOG_TIME");
1216         if (e && log_show_time_from_string(e) < 0)
1217                 log_warning("Failed to parse log time '%s'. Ignoring.", e);
1218 
1219         e = getenv("SYSTEMD_LOG_TID");
1220         if (e && log_show_tid_from_string(e) < 0)
1221                 log_warning("Failed to parse log tid '%s'. Ignoring.", e);
1222 }
1223 
log_parse_environment(void)1224 void log_parse_environment(void) {
1225         /* Do not call from library code. */
1226 
1227         if (should_parse_proc_cmdline())
1228                 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1229 
1230         log_parse_environment_variables();
1231 }
1232 
log_get_target(void)1233 LogTarget log_get_target(void) {
1234         return log_target;
1235 }
1236 
log_get_max_level(void)1237 int log_get_max_level(void) {
1238         return log_max_level;
1239 }
1240 
log_show_color(bool b)1241 void log_show_color(bool b) {
1242         show_color = b;
1243 }
1244 
log_get_show_color(void)1245 bool log_get_show_color(void) {
1246         return show_color > 0; /* Defaults to false. */
1247 }
1248 
log_show_location(bool b)1249 void log_show_location(bool b) {
1250         show_location = b;
1251 }
1252 
log_get_show_location(void)1253 bool log_get_show_location(void) {
1254         return show_location;
1255 }
1256 
log_show_time(bool b)1257 void log_show_time(bool b) {
1258         show_time = b;
1259 }
1260 
log_get_show_time(void)1261 bool log_get_show_time(void) {
1262         return show_time;
1263 }
1264 
log_show_tid(bool b)1265 void log_show_tid(bool b) {
1266         show_tid = b;
1267 }
1268 
log_get_show_tid(void)1269 bool log_get_show_tid(void) {
1270         return show_tid;
1271 }
1272 
log_show_color_from_string(const char * e)1273 int log_show_color_from_string(const char *e) {
1274         int t;
1275 
1276         t = parse_boolean(e);
1277         if (t < 0)
1278                 return t;
1279 
1280         log_show_color(t);
1281         return 0;
1282 }
1283 
log_show_location_from_string(const char * e)1284 int log_show_location_from_string(const char *e) {
1285         int t;
1286 
1287         t = parse_boolean(e);
1288         if (t < 0)
1289                 return t;
1290 
1291         log_show_location(t);
1292         return 0;
1293 }
1294 
log_show_time_from_string(const char * e)1295 int log_show_time_from_string(const char *e) {
1296         int t;
1297 
1298         t = parse_boolean(e);
1299         if (t < 0)
1300                 return t;
1301 
1302         log_show_time(t);
1303         return 0;
1304 }
1305 
log_show_tid_from_string(const char * e)1306 int log_show_tid_from_string(const char *e) {
1307         int t;
1308 
1309         t = parse_boolean(e);
1310         if (t < 0)
1311                 return t;
1312 
1313         log_show_tid(t);
1314         return 0;
1315 }
1316 
log_on_console(void)1317 bool log_on_console(void) {
1318         if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1319                                LOG_TARGET_CONSOLE_PREFIXED))
1320                 return true;
1321 
1322         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1323 }
1324 
1325 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1326         [LOG_TARGET_CONSOLE]          = "console",
1327         [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1328         [LOG_TARGET_KMSG]             = "kmsg",
1329         [LOG_TARGET_JOURNAL]          = "journal",
1330         [LOG_TARGET_JOURNAL_OR_KMSG]  = "journal-or-kmsg",
1331         [LOG_TARGET_SYSLOG]           = "syslog",
1332         [LOG_TARGET_SYSLOG_OR_KMSG]   = "syslog-or-kmsg",
1333         [LOG_TARGET_AUTO]             = "auto",
1334         [LOG_TARGET_NULL]             = "null",
1335 };
1336 
1337 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1338 
log_received_signal(int level,const struct signalfd_siginfo * si)1339 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1340         assert(si);
1341 
1342         if (pid_is_valid(si->ssi_pid)) {
1343                 _cleanup_free_ char *p = NULL;
1344 
1345                 (void) get_process_comm(si->ssi_pid, &p);
1346 
1347                 log_full(level,
1348                          "Received SIG%s from PID %"PRIu32" (%s).",
1349                          signal_to_string(si->ssi_signo),
1350                          si->ssi_pid, strna(p));
1351         } else
1352                 log_full(level,
1353                          "Received SIG%s.",
1354                          signal_to_string(si->ssi_signo));
1355 }
1356 
set_log_syntax_callback(log_syntax_callback_t cb,void * userdata)1357 void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
1358         assert(!log_syntax_callback || !cb);
1359         assert(!log_syntax_callback_userdata || !userdata);
1360 
1361         log_syntax_callback = cb;
1362         log_syntax_callback_userdata = userdata;
1363 }
1364 
log_syntax_internal(const char * unit,int level,const char * config_file,unsigned config_line,int error,const char * file,int line,const char * func,const char * format,...)1365 int log_syntax_internal(
1366                 const char *unit,
1367                 int level,
1368                 const char *config_file,
1369                 unsigned config_line,
1370                 int error,
1371                 const char *file,
1372                 int line,
1373                 const char *func,
1374                 const char *format, ...) {
1375 
1376         if (log_syntax_callback)
1377                 log_syntax_callback(unit, level, log_syntax_callback_userdata);
1378 
1379         PROTECT_ERRNO;
1380         char buffer[LINE_MAX];
1381         va_list ap;
1382         const char *unit_fmt = NULL;
1383 
1384         if (_likely_(LOG_PRI(level) > log_max_level) ||
1385             log_target == LOG_TARGET_NULL)
1386                 return -ERRNO_VALUE(error);
1387 
1388         errno = ERRNO_VALUE(error);
1389 
1390         va_start(ap, format);
1391         (void) vsnprintf(buffer, sizeof buffer, format, ap);
1392         va_end(ap);
1393 
1394         if (unit)
1395                 unit_fmt = getpid_cached() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1396 
1397         if (config_file) {
1398                 if (config_line > 0)
1399                         return log_struct_internal(
1400                                         level,
1401                                         error,
1402                                         file, line, func,
1403                                         "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1404                                         "CONFIG_FILE=%s", config_file,
1405                                         "CONFIG_LINE=%u", config_line,
1406                                         LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1407                                         unit_fmt, unit,
1408                                         NULL);
1409                 else
1410                         return log_struct_internal(
1411                                         level,
1412                                         error,
1413                                         file, line, func,
1414                                         "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1415                                         "CONFIG_FILE=%s", config_file,
1416                                         LOG_MESSAGE("%s: %s", config_file, buffer),
1417                                         unit_fmt, unit,
1418                                         NULL);
1419         } else if (unit)
1420                 return log_struct_internal(
1421                                 level,
1422                                 error,
1423                                 file, line, func,
1424                                 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1425                                 LOG_MESSAGE("%s: %s", unit, buffer),
1426                                 unit_fmt, unit,
1427                                 NULL);
1428         else
1429                 return log_struct_internal(
1430                                 level,
1431                                 error,
1432                                 file, line, func,
1433                                 "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1434                                 LOG_MESSAGE("%s", buffer),
1435                                 NULL);
1436 }
1437 
log_syntax_invalid_utf8_internal(const char * unit,int level,const char * config_file,unsigned config_line,const char * file,int line,const char * func,const char * rvalue)1438 int log_syntax_invalid_utf8_internal(
1439                 const char *unit,
1440                 int level,
1441                 const char *config_file,
1442                 unsigned config_line,
1443                 const char *file,
1444                 int line,
1445                 const char *func,
1446                 const char *rvalue) {
1447 
1448         _cleanup_free_ char *p = NULL;
1449 
1450         if (rvalue)
1451                 p = utf8_escape_invalid(rvalue);
1452 
1453         return log_syntax_internal(unit, level, config_file, config_line,
1454                                    SYNTHETIC_ERRNO(EINVAL), file, line, func,
1455                                    "String is not UTF-8 clean, ignoring assignment: %s", strna(p));
1456 }
1457 
log_set_upgrade_syslog_to_journal(bool b)1458 void log_set_upgrade_syslog_to_journal(bool b) {
1459         upgrade_syslog_to_journal = b;
1460 
1461         /* Make the change effective immediately */
1462         if (b) {
1463                 if (log_target == LOG_TARGET_SYSLOG)
1464                         log_target = LOG_TARGET_JOURNAL;
1465                 else if (log_target == LOG_TARGET_SYSLOG_OR_KMSG)
1466                         log_target = LOG_TARGET_JOURNAL_OR_KMSG;
1467         }
1468 }
1469 
log_set_always_reopen_console(bool b)1470 void log_set_always_reopen_console(bool b) {
1471         always_reopen_console = b;
1472 }
1473 
log_set_open_when_needed(bool b)1474 void log_set_open_when_needed(bool b) {
1475         open_when_needed = b;
1476 }
1477 
log_set_prohibit_ipc(bool b)1478 void log_set_prohibit_ipc(bool b) {
1479         prohibit_ipc = b;
1480 }
1481 
log_emergency_level(void)1482 int log_emergency_level(void) {
1483         /* Returns the log level to use for log_emergency() logging. We use LOG_EMERG only when we are PID 1, as only
1484          * then the system of the whole system is obviously affected. */
1485 
1486         return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
1487 }
1488 
log_dup_console(void)1489 int log_dup_console(void) {
1490         int copy;
1491 
1492         /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
1493          * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
1494 
1495         if (console_fd >= 3)
1496                 return 0;
1497 
1498         copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
1499         if (copy < 0)
1500                 return -errno;
1501 
1502         console_fd = copy;
1503         return 0;
1504 }
1505 
log_setup(void)1506 void log_setup(void) {
1507         log_set_target(LOG_TARGET_AUTO);
1508         log_parse_environment();
1509         (void) log_open();
1510         if (log_on_console() && show_color < 0)
1511                 log_show_color(true);
1512 }
1513