chiark / gitweb /
core: link user keyring to session keyring (#6275)
[elogind.git] / src / basic / log.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <inttypes.h>
23 #include <limits.h>
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/signalfd.h>
29 #include <sys/socket.h>
30 #include <sys/time.h>
31 #include <sys/uio.h>
32 #include <sys/un.h>
33 #include <time.h>
34 #include <unistd.h>
35
36 #include "sd-messages.h"
37
38 #include "alloc-util.h"
39 #include "fd-util.h"
40 #include "format-util.h"
41 #include "io-util.h"
42 #include "log.h"
43 #include "macro.h"
44 #include "missing.h"
45 #include "parse-util.h"
46 #include "proc-cmdline.h"
47 #include "process-util.h"
48 #include "signal-util.h"
49 #include "socket-util.h"
50 #include "stdio-util.h"
51 #include "string-table.h"
52 #include "string-util.h"
53 #include "syslog-util.h"
54 #include "terminal-util.h"
55 #include "time-util.h"
56 #include "util.h"
57
58 #define SNDBUF_SIZE (8*1024*1024)
59
60 static LogTarget log_target = LOG_TARGET_CONSOLE;
61 static int log_max_level = LOG_INFO;
62 static int log_facility = LOG_DAEMON;
63
64 static int console_fd = STDERR_FILENO;
65 static int syslog_fd = -1;
66 static int kmsg_fd = -1;
67 static int journal_fd = -1;
68
69 static bool syslog_is_stream = false;
70
71 static bool show_color = false;
72 static bool show_location = false;
73
74 #if 0 /// UNNEEDED by elogind
75 static bool upgrade_syslog_to_journal = false;
76 #endif // 0
77 static bool always_reopen_console = false;
78
79 /* Akin to glibc's __abort_msg; which is private and we hence cannot
80  * use here. */
81 static char *log_abort_msg = NULL;
82
83 void log_close_console(void) {
84
85         if (console_fd < 0)
86                 return;
87
88         if (getpid() == 1) {
89                 if (console_fd >= 3)
90                         safe_close(console_fd);
91
92                 console_fd = -1;
93         }
94 }
95
96 static int log_open_console(void) {
97
98         if (console_fd >= 0)
99                 return 0;
100
101         if (always_reopen_console) {
102                 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
103                 if (console_fd < 0)
104                         return console_fd;
105         } else
106                 console_fd = STDERR_FILENO;
107
108         return 0;
109 }
110
111 void log_close_kmsg(void) {
112         kmsg_fd = safe_close(kmsg_fd);
113 }
114
115 static int log_open_kmsg(void) {
116
117         if (kmsg_fd >= 0)
118                 return 0;
119
120         kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
121         if (kmsg_fd < 0)
122                 return -errno;
123
124         return 0;
125 }
126
127 void log_close_syslog(void) {
128         syslog_fd = safe_close(syslog_fd);
129 }
130
131 static int create_log_socket(int type) {
132         struct timeval tv;
133         int fd;
134
135         fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0);
136         if (fd < 0)
137                 return -errno;
138
139         (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
140
141         /* We need a blocking fd here since we'd otherwise lose
142         messages way too early. However, let's not hang forever in the
143         unlikely case of a deadlock. */
144         if (getpid() == 1)
145                 timeval_store(&tv, 10 * USEC_PER_MSEC);
146         else
147                 timeval_store(&tv, 10 * USEC_PER_SEC);
148         (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
149
150         return fd;
151 }
152
153 static int log_open_syslog(void) {
154
155         static const union sockaddr_union sa = {
156                 .un.sun_family = AF_UNIX,
157                 .un.sun_path = "/dev/log",
158         };
159
160         int r;
161
162         if (syslog_fd >= 0)
163                 return 0;
164
165         syslog_fd = create_log_socket(SOCK_DGRAM);
166         if (syslog_fd < 0) {
167                 r = syslog_fd;
168                 goto fail;
169         }
170
171         if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
172                 safe_close(syslog_fd);
173
174                 /* Some legacy syslog systems still use stream
175                  * sockets. They really shouldn't. But what can we
176                  * do... */
177                 syslog_fd = create_log_socket(SOCK_STREAM);
178                 if (syslog_fd < 0) {
179                         r = syslog_fd;
180                         goto fail;
181                 }
182
183                 if (connect(syslog_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
184                         r = -errno;
185                         goto fail;
186                 }
187
188                 syslog_is_stream = true;
189         } else
190                 syslog_is_stream = false;
191
192         return 0;
193
194 fail:
195         log_close_syslog();
196         return r;
197 }
198
199 void log_close_journal(void) {
200 #if 0 /// elogind does not support journald
201         journal_fd = safe_close(journal_fd);
202 #endif // 0
203 }
204
205 #if 0 /// UNNEEDED by elogind
206 static int log_open_journal(void) {
207
208         static const union sockaddr_union sa = {
209                 .un.sun_family = AF_UNIX,
210                 .un.sun_path = "/run/systemd/journal/socket",
211         };
212
213         int r;
214
215         if (journal_fd >= 0)
216                 return 0;
217
218         journal_fd = create_log_socket(SOCK_DGRAM);
219         if (journal_fd < 0) {
220                 r = journal_fd;
221                 goto fail;
222         }
223
224         if (connect(journal_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
225                 r = -errno;
226                 goto fail;
227         }
228
229         return 0;
230
231 fail:
232         log_close_journal();
233         return r;
234 }
235 #endif // 0
236
237 int log_open(void) {
238         int r;
239
240         /* If we don't use the console we close it here, to not get
241          * killed by SAK. If we don't use syslog we close it here so
242          * that we are not confused by somebody deleting the socket in
243          * the fs. If we don't use /dev/kmsg we still keep it open,
244          * because there is no reason to close it. */
245
246         if (log_target == LOG_TARGET_NULL) {
247                 log_close_journal();
248                 log_close_syslog();
249                 log_close_console();
250                 return 0;
251         }
252
253         if (!IN_SET(log_target, LOG_TARGET_AUTO, LOG_TARGET_SAFE) ||
254             getpid() == 1 ||
255             isatty(STDERR_FILENO) <= 0) {
256
257 #if 0 /// elogind does not support logging to systemd-journald
258                 if (IN_SET(log_target, LOG_TARGET_AUTO,
259                                        LOG_TARGET_JOURNAL_OR_KMSG,
260                                        LOG_TARGET_JOURNAL)) {
261                         r = log_open_journal();
262                         if (r >= 0) {
263                                 log_close_syslog();
264                                 log_close_console();
265                                 return r;
266                         }
267                 }
268 #endif // 0
269
270                 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
271                                        LOG_TARGET_SYSLOG)) {
272                         r = log_open_syslog();
273                         if (r >= 0) {
274                                 log_close_journal();
275                                 log_close_console();
276                                 return r;
277                         }
278                 }
279
280                 if (IN_SET(log_target, LOG_TARGET_AUTO,
281                                        LOG_TARGET_SAFE,
282                                        LOG_TARGET_JOURNAL_OR_KMSG,
283                                        LOG_TARGET_SYSLOG_OR_KMSG,
284                                        LOG_TARGET_KMSG)) {
285                         r = log_open_kmsg();
286                         if (r >= 0) {
287                                 log_close_journal();
288                                 log_close_syslog();
289                                 log_close_console();
290                                 return r;
291                         }
292                 }
293         }
294
295         log_close_journal();
296         log_close_syslog();
297
298         return log_open_console();
299 }
300
301 void log_set_target(LogTarget target) {
302         assert(target >= 0);
303         assert(target < _LOG_TARGET_MAX);
304
305 #if 0 /// elogind does not support logging to systemd-journald
306         if (upgrade_syslog_to_journal) {
307                 if (target == LOG_TARGET_SYSLOG)
308                         target = LOG_TARGET_JOURNAL;
309                 else if (target == LOG_TARGET_SYSLOG_OR_KMSG)
310                         target = LOG_TARGET_JOURNAL_OR_KMSG;
311         }
312 #endif // 0
313
314         log_target = target;
315 }
316
317 void log_close(void) {
318         log_close_journal();
319         log_close_syslog();
320         log_close_kmsg();
321         log_close_console();
322 }
323
324 #if 0 /// UNNEEDED by elogind
325 void log_forget_fds(void) {
326         console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
327 }
328 #endif // 0
329
330 void log_set_max_level(int level) {
331         assert((level & LOG_PRIMASK) == level);
332
333         log_max_level = level;
334 }
335
336 void log_set_facility(int facility) {
337         log_facility = facility;
338 }
339
340 static int write_to_console(
341                 int level,
342                 int error,
343                 const char *file,
344                 int line,
345                 const char *func,
346                 const char *buffer) {
347
348         char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2];
349         struct iovec iovec[6] = {};
350         unsigned n = 0;
351         bool highlight;
352
353         if (console_fd < 0)
354                 return 0;
355
356         if (log_target == LOG_TARGET_CONSOLE_PREFIXED) {
357                 xsprintf(prefix, "<%i>", level);
358                 IOVEC_SET_STRING(iovec[n++], prefix);
359         }
360
361         highlight = LOG_PRI(level) <= LOG_ERR && show_color;
362
363         if (show_location) {
364                 snprintf(location, sizeof(location), "(%s:%i) ", file, line);
365                 IOVEC_SET_STRING(iovec[n++], location);
366         }
367
368         if (highlight)
369                 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED);
370         IOVEC_SET_STRING(iovec[n++], buffer);
371         if (highlight)
372                 IOVEC_SET_STRING(iovec[n++], ANSI_NORMAL);
373         IOVEC_SET_STRING(iovec[n++], "\n");
374
375         if (writev(console_fd, iovec, n) < 0) {
376
377                 if (errno == EIO && getpid() == 1) {
378
379                         /* If somebody tried to kick us from our
380                          * console tty (via vhangup() or suchlike),
381                          * try to reconnect */
382
383                         log_close_console();
384                         log_open_console();
385
386                         if (console_fd < 0)
387                                 return 0;
388
389                         if (writev(console_fd, iovec, n) < 0)
390                                 return -errno;
391                 } else
392                         return -errno;
393         }
394
395         return 1;
396 }
397
398 static int write_to_syslog(
399                 int level,
400                 int error,
401                 const char *file,
402                 int line,
403                 const char *func,
404                 const char *buffer) {
405
406         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
407              header_time[64],
408              header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
409         struct iovec iovec[5] = {};
410         struct msghdr msghdr = {
411                 .msg_iov = iovec,
412                 .msg_iovlen = ELEMENTSOF(iovec),
413         };
414         time_t t;
415         struct tm *tm;
416
417         if (syslog_fd < 0)
418                 return 0;
419
420         xsprintf(header_priority, "<%i>", level);
421
422         t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC);
423         tm = localtime(&t);
424         if (!tm)
425                 return -EINVAL;
426
427         if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
428                 return -EINVAL;
429
430         xsprintf(header_pid, "["PID_FMT"]: ", getpid());
431
432         IOVEC_SET_STRING(iovec[0], header_priority);
433         IOVEC_SET_STRING(iovec[1], header_time);
434         IOVEC_SET_STRING(iovec[2], program_invocation_short_name);
435         IOVEC_SET_STRING(iovec[3], header_pid);
436         IOVEC_SET_STRING(iovec[4], buffer);
437
438         /* When using syslog via SOCK_STREAM separate the messages by NUL chars */
439         if (syslog_is_stream)
440                 iovec[4].iov_len++;
441
442         for (;;) {
443                 ssize_t n;
444
445                 n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
446                 if (n < 0)
447                         return -errno;
448
449                 if (!syslog_is_stream ||
450                     (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec)))
451                         break;
452
453                 IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n);
454         }
455
456         return 1;
457 }
458
459 static int write_to_kmsg(
460                 int level,
461                 int error,
462                 const char *file,
463                 int line,
464                 const char *func,
465                 const char *buffer) {
466
467         char header_priority[2 + DECIMAL_STR_MAX(int) + 1],
468              header_pid[4 + DECIMAL_STR_MAX(pid_t) + 1];
469         struct iovec iovec[5] = {};
470
471         if (kmsg_fd < 0)
472                 return 0;
473
474         xsprintf(header_priority, "<%i>", level);
475         xsprintf(header_pid, "["PID_FMT"]: ", getpid());
476
477         IOVEC_SET_STRING(iovec[0], header_priority);
478         IOVEC_SET_STRING(iovec[1], program_invocation_short_name);
479         IOVEC_SET_STRING(iovec[2], header_pid);
480         IOVEC_SET_STRING(iovec[3], buffer);
481         IOVEC_SET_STRING(iovec[4], "\n");
482
483         if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0)
484                 return -errno;
485
486         return 1;
487 }
488
489 #if 0 /// UNNEEDED by elogind
490 static int log_do_header(
491                 char *header,
492                 size_t size,
493                 int level,
494                 int error,
495                 const char *file, int line, const char *func,
496                 const char *object_field, const char *object,
497                 const char *extra_field, const char *extra) {
498
499         snprintf(header, size,
500                  "PRIORITY=%i\n"
501                  "SYSLOG_FACILITY=%i\n"
502                  "%s%s%s"
503                  "%s%.*i%s"
504                  "%s%s%s"
505                  "%s%.*i%s"
506                  "%s%s%s"
507                  "%s%s%s"
508                  "SYSLOG_IDENTIFIER=%s\n",
509                  LOG_PRI(level),
510                  LOG_FAC(level),
511                  isempty(file) ? "" : "CODE_FILE=",
512                  isempty(file) ? "" : file,
513                  isempty(file) ? "" : "\n",
514                  line ? "CODE_LINE=" : "",
515                  line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
516                  line ? "\n" : "",
517                  isempty(func) ? "" : "CODE_FUNC=",
518                  isempty(func) ? "" : func,
519                  isempty(func) ? "" : "\n",
520                  error ? "ERRNO=" : "",
521                  error ? 1 : 0, error,
522                  error ? "\n" : "",
523                  isempty(object) ? "" : object_field,
524                  isempty(object) ? "" : object,
525                  isempty(object) ? "" : "\n",
526                  isempty(extra) ? "" : extra_field,
527                  isempty(extra) ? "" : extra,
528                  isempty(extra) ? "" : "\n",
529                  program_invocation_short_name);
530
531         return 0;
532 }
533
534 static int write_to_journal(
535                 int level,
536                 int error,
537                 const char *file,
538                 int line,
539                 const char *func,
540                 const char *object_field,
541                 const char *object,
542                 const char *extra_field,
543                 const char *extra,
544                 const char *buffer) {
545
546         char header[LINE_MAX];
547         struct iovec iovec[4] = {};
548         struct msghdr mh = {};
549
550         if (journal_fd < 0)
551                 return 0;
552
553         log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra);
554
555         IOVEC_SET_STRING(iovec[0], header);
556         IOVEC_SET_STRING(iovec[1], "MESSAGE=");
557         IOVEC_SET_STRING(iovec[2], buffer);
558         IOVEC_SET_STRING(iovec[3], "\n");
559
560         mh.msg_iov = iovec;
561         mh.msg_iovlen = ELEMENTSOF(iovec);
562
563         if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
564                 return -errno;
565
566         return 1;
567 }
568 #endif // 0
569
570 int log_dispatch_internal(
571                 int level,
572                 int error,
573                 const char *file,
574                 int line,
575                 const char *func,
576                 const char *object_field,
577                 const char *object,
578                 const char *extra,
579                 const char *extra_field,
580                 char *buffer) {
581
582         assert(buffer);
583
584         if (error < 0)
585                 error = -error;
586
587         if (log_target == LOG_TARGET_NULL)
588                 return -error;
589
590         /* Patch in LOG_DAEMON facility if necessary */
591         if ((level & LOG_FACMASK) == 0)
592                 level = log_facility | LOG_PRI(level);
593
594         do {
595                 char *e;
596                 int k = 0;
597
598                 buffer += strspn(buffer, NEWLINE);
599
600                 if (buffer[0] == 0)
601                         break;
602
603                 if ((e = strpbrk(buffer, NEWLINE)))
604                         *(e++) = 0;
605
606 #if 0 /// elogind does not support logging to systemd-journald
607                 if (IN_SET(log_target, LOG_TARGET_AUTO,
608                                        LOG_TARGET_JOURNAL_OR_KMSG,
609                                        LOG_TARGET_JOURNAL)) {
610
611                         k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
612                         if (k < 0) {
613                                 if (k != -EAGAIN)
614                                         log_close_journal();
615                                 log_open_kmsg();
616                         }
617                 }
618 #endif // 0
619
620                 if (IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
621                                        LOG_TARGET_SYSLOG)) {
622
623                         k = write_to_syslog(level, error, file, line, func, buffer);
624                         if (k < 0) {
625                                 if (k != -EAGAIN)
626                                         log_close_syslog();
627                                 log_open_kmsg();
628                         }
629                 }
630
631                 if (k <= 0 &&
632                     IN_SET(log_target, LOG_TARGET_AUTO,
633                                        LOG_TARGET_SAFE,
634                                        LOG_TARGET_SYSLOG_OR_KMSG,
635                                        LOG_TARGET_JOURNAL_OR_KMSG,
636                                        LOG_TARGET_KMSG)) {
637
638                         k = write_to_kmsg(level, error, file, line, func, buffer);
639                         if (k < 0) {
640                                 log_close_kmsg();
641                                 log_open_console();
642                         }
643                 }
644
645                 if (k <= 0)
646                         (void) write_to_console(level, error, file, line, func, buffer);
647
648                 buffer = e;
649         } while (buffer);
650
651         return -error;
652 }
653
654 int log_dump_internal(
655         int level,
656         int error,
657         const char *file,
658         int line,
659         const char *func,
660         char *buffer) {
661
662         PROTECT_ERRNO;
663
664         /* This modifies the buffer... */
665
666         if (error < 0)
667                 error = -error;
668
669         if (_likely_(LOG_PRI(level) > log_max_level))
670                 return -error;
671
672         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
673 }
674
675 int log_internalv(
676                 int level,
677                 int error,
678                 const char *file,
679                 int line,
680                 const char *func,
681                 const char *format,
682                 va_list ap) {
683
684         PROTECT_ERRNO;
685         char buffer[LINE_MAX];
686
687         if (error < 0)
688                 error = -error;
689
690         if (_likely_(LOG_PRI(level) > log_max_level))
691                 return -error;
692
693         /* Make sure that %m maps to the specified error */
694         if (error != 0)
695                 errno = error;
696
697         vsnprintf(buffer, sizeof(buffer), format, ap);
698
699         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
700 }
701
702 int log_internal(
703                 int level,
704                 int error,
705                 const char *file,
706                 int line,
707                 const char *func,
708                 const char *format, ...) {
709
710         va_list ap;
711         int r;
712
713         va_start(ap, format);
714         r = log_internalv(level, error, file, line, func, format, ap);
715         va_end(ap);
716
717         return r;
718 }
719
720 int log_object_internalv(
721                 int level,
722                 int error,
723                 const char *file,
724                 int line,
725                 const char *func,
726                 const char *object_field,
727                 const char *object,
728                 const char *extra_field,
729                 const char *extra,
730                 const char *format,
731                 va_list ap) {
732
733         PROTECT_ERRNO;
734         char *buffer, *b;
735
736         if (error < 0)
737                 error = -error;
738
739         if (_likely_(LOG_PRI(level) > log_max_level))
740                 return -error;
741
742         /* Make sure that %m maps to the specified error */
743         if (error != 0)
744                 errno = error;
745
746         /* Prepend the object name before the message */
747         if (object) {
748                 size_t n;
749
750                 n = strlen(object);
751                 buffer = newa(char, n + 2 + LINE_MAX);
752                 b = stpcpy(stpcpy(buffer, object), ": ");
753         } else
754                 b = buffer = newa(char, LINE_MAX);
755
756         vsnprintf(b, LINE_MAX, format, ap);
757
758         return log_dispatch_internal(level, error, file, line, func,
759                                      object_field, object, extra_field, extra, buffer);
760 }
761
762 int log_object_internal(
763                 int level,
764                 int error,
765                 const char *file,
766                 int line,
767                 const char *func,
768                 const char *object_field,
769                 const char *object,
770                 const char *extra_field,
771                 const char *extra,
772                 const char *format, ...) {
773
774         va_list ap;
775         int r;
776
777         va_start(ap, format);
778         r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
779         va_end(ap);
780
781         return r;
782 }
783
784 static void log_assert(
785                 int level,
786                 const char *text,
787                 const char *file,
788                 int line,
789                 const char *func,
790                 const char *format) {
791
792         static char buffer[LINE_MAX];
793
794         if (_likely_(LOG_PRI(level) > log_max_level))
795                 return;
796
797         DISABLE_WARNING_FORMAT_NONLITERAL;
798         snprintf(buffer, sizeof buffer, format, text, file, line, func);
799         REENABLE_WARNING;
800
801         log_abort_msg = buffer;
802
803         log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
804 }
805
806 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
807         log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
808         abort();
809 }
810
811 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
812         log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
813         abort();
814 }
815
816 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
817         PROTECT_ERRNO;
818         log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
819 }
820
821 int log_oom_internal(const char *file, int line, const char *func) {
822         log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
823         return -ENOMEM;
824 }
825
826 int log_format_iovec(
827                 struct iovec *iovec,
828                 unsigned iovec_len,
829                 unsigned *n,
830                 bool newline_separator,
831                 int error,
832                 const char *format,
833                 va_list ap) {
834
835         static const char nl = '\n';
836
837         while (format && *n + 1 < iovec_len) {
838                 va_list aq;
839                 char *m;
840                 int r;
841
842                 /* We need to copy the va_list structure,
843                  * since vasprintf() leaves it afterwards at
844                  * an undefined location */
845
846                 if (error != 0)
847                         errno = error;
848
849                 va_copy(aq, ap);
850                 r = vasprintf(&m, format, aq);
851                 va_end(aq);
852                 if (r < 0)
853                         return -EINVAL;
854
855                 /* Now, jump enough ahead, so that we point to
856                  * the next format string */
857                 VA_FORMAT_ADVANCE(format, ap);
858
859                 IOVEC_SET_STRING(iovec[(*n)++], m);
860
861                 if (newline_separator) {
862                         iovec[*n].iov_base = (char*) &nl;
863                         iovec[*n].iov_len = 1;
864                         (*n)++;
865                 }
866
867                 format = va_arg(ap, char *);
868         }
869         return 0;
870 }
871
872 int log_struct_internal(
873                 int level,
874                 int error,
875                 const char *file,
876                 int line,
877                 const char *func,
878                 const char *format, ...) {
879
880         char buf[LINE_MAX];
881         bool found = false;
882         PROTECT_ERRNO;
883         va_list ap;
884
885         if (error < 0)
886                 error = -error;
887
888         if (_likely_(LOG_PRI(level) > log_max_level))
889                 return -error;
890
891         if (log_target == LOG_TARGET_NULL)
892                 return -error;
893
894         if ((level & LOG_FACMASK) == 0)
895                 level = log_facility | LOG_PRI(level);
896
897 #if 0 /// elogind does not support logging to systemd-journald
898         if (IN_SET(log_target, LOG_TARGET_AUTO,
899                                LOG_TARGET_JOURNAL_OR_KMSG,
900                                LOG_TARGET_JOURNAL) &&
901             journal_fd >= 0) {
902                 char header[LINE_MAX];
903                 struct iovec iovec[17] = {};
904                 unsigned n = 0, i;
905                 int r;
906                 struct msghdr mh = {
907                         .msg_iov = iovec,
908                 };
909                 bool fallback = false;
910
911                 /* If the journal is available do structured logging */
912                 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
913                 IOVEC_SET_STRING(iovec[n++], header);
914
915                 va_start(ap, format);
916                 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
917                 if (r < 0)
918                         fallback = true;
919                 else {
920                         mh.msg_iovlen = n;
921                         (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
922                 }
923
924                 va_end(ap);
925                 for (i = 1; i < n; i += 2)
926                         free(iovec[i].iov_base);
927
928                 if (!fallback)
929                         return -error;
930         }
931 #endif // 0
932
933         /* Fallback if journal logging is not available or didn't work. */
934
935         va_start(ap, format);
936         while (format) {
937                 va_list aq;
938
939                 if (error != 0)
940                         errno = error;
941
942                 va_copy(aq, ap);
943                 vsnprintf(buf, sizeof(buf), format, aq);
944                 va_end(aq);
945
946                 if (startswith(buf, "MESSAGE=")) {
947                         found = true;
948                         break;
949                 }
950
951                 VA_FORMAT_ADVANCE(format, ap);
952
953                 format = va_arg(ap, char *);
954         }
955         va_end(ap);
956
957         if (!found)
958                 return -error;
959
960         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
961 }
962
963 int log_set_target_from_string(const char *e) {
964         LogTarget t;
965
966         t = log_target_from_string(e);
967         if (t < 0)
968                 return -EINVAL;
969
970         log_set_target(t);
971         return 0;
972 }
973
974 int log_set_max_level_from_string(const char *e) {
975         int t;
976
977         t = log_level_from_string(e);
978         if (t < 0)
979                 return -EINVAL;
980
981         log_set_max_level(t);
982         return 0;
983 }
984
985 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
986
987         /*
988          * The systemd.log_xyz= settings are parsed by all tools, and
989          * so is "debug".
990          *
991          * However, "quiet" is only parsed by PID 1, and only turns of
992          * status output to /dev/console, but does not alter the log
993          * level.
994          */
995
996         if (streq(key, "debug") && !value)
997                 log_set_max_level(LOG_DEBUG);
998
999         else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1000
1001                 if (proc_cmdline_value_missing(key, value))
1002                         return 0;
1003
1004                 if (log_set_target_from_string(value) < 0)
1005                         log_warning("Failed to parse log target '%s'. Ignoring.", value);
1006
1007         } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1008
1009                 if (proc_cmdline_value_missing(key, value))
1010                         return 0;
1011
1012                 if (log_set_max_level_from_string(value) < 0)
1013                         log_warning("Failed to parse log level '%s'. Ignoring.", value);
1014
1015         } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1016
1017                 if (log_show_color_from_string(value ?: "1") < 0)
1018                         log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1019
1020         } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1021
1022                 if (log_show_location_from_string(value ?: "1") < 0)
1023                         log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1024         }
1025
1026         return 0;
1027 }
1028
1029 void log_parse_environment(void) {
1030         const char *e;
1031
1032         if (get_ctty_devnr(0, NULL) < 0)
1033                 /* Only try to read the command line in daemons.  We assume that anything that has a controlling tty is
1034                    user stuff. */
1035                 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1036
1037         e = secure_getenv("SYSTEMD_LOG_TARGET");
1038         if (e && log_set_target_from_string(e) < 0)
1039                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1040
1041         e = secure_getenv("SYSTEMD_LOG_LEVEL");
1042         if (e && log_set_max_level_from_string(e) < 0)
1043                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1044
1045         e = secure_getenv("SYSTEMD_LOG_COLOR");
1046         if (e && log_show_color_from_string(e) < 0)
1047                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1048
1049         e = secure_getenv("SYSTEMD_LOG_LOCATION");
1050         if (e && log_show_location_from_string(e) < 0)
1051                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1052 }
1053
1054 LogTarget log_get_target(void) {
1055         return log_target;
1056 }
1057
1058 int log_get_max_level(void) {
1059         return log_max_level;
1060 }
1061
1062 void log_show_color(bool b) {
1063         show_color = b;
1064 }
1065
1066 bool log_get_show_color(void) {
1067         return show_color;
1068 }
1069
1070 void log_show_location(bool b) {
1071         show_location = b;
1072 }
1073
1074 bool log_get_show_location(void) {
1075         return show_location;
1076 }
1077
1078 int log_show_color_from_string(const char *e) {
1079         int t;
1080
1081         t = parse_boolean(e);
1082         if (t < 0)
1083                 return t;
1084
1085         log_show_color(t);
1086         return 0;
1087 }
1088
1089 int log_show_location_from_string(const char *e) {
1090         int t;
1091
1092         t = parse_boolean(e);
1093         if (t < 0)
1094                 return t;
1095
1096         log_show_location(t);
1097         return 0;
1098 }
1099
1100 bool log_on_console(void) {
1101         if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1102                                LOG_TARGET_CONSOLE_PREFIXED))
1103                 return true;
1104
1105         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1106 }
1107
1108 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1109         [LOG_TARGET_CONSOLE] = "console",
1110         [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1111         [LOG_TARGET_KMSG] = "kmsg",
1112 #if 0 /// elogind does not support logging to systemd-journald
1113         [LOG_TARGET_JOURNAL] = "journal",
1114         [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1115 #endif // 0
1116         [LOG_TARGET_SYSLOG] = "syslog",
1117         [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1118         [LOG_TARGET_AUTO] = "auto",
1119         [LOG_TARGET_SAFE] = "safe",
1120         [LOG_TARGET_NULL] = "null"
1121 };
1122
1123 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1124
1125 #if 0 /// UNNEEDED by elogind
1126 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1127         if (si->ssi_pid > 0) {
1128                 _cleanup_free_ char *p = NULL;
1129
1130                 get_process_comm(si->ssi_pid, &p);
1131
1132                 log_full(level,
1133                          "Received SIG%s from PID %"PRIu32" (%s).",
1134                          signal_to_string(si->ssi_signo),
1135                          si->ssi_pid, strna(p));
1136         } else
1137                 log_full(level,
1138                          "Received SIG%s.",
1139                          signal_to_string(si->ssi_signo));
1140
1141 }
1142
1143 void log_set_upgrade_syslog_to_journal(bool b) {
1144         upgrade_syslog_to_journal = b;
1145 }
1146 #endif // 0
1147
1148 int log_syntax_internal(
1149                 const char *unit,
1150                 int level,
1151                 const char *config_file,
1152                 unsigned config_line,
1153                 int error,
1154                 const char *file,
1155                 int line,
1156                 const char *func,
1157                 const char *format, ...) {
1158
1159         PROTECT_ERRNO;
1160         char buffer[LINE_MAX];
1161         va_list ap;
1162         const char *unit_fmt = NULL;
1163
1164         if (error < 0)
1165                 error = -error;
1166
1167         if (_likely_(LOG_PRI(level) > log_max_level))
1168                 return -error;
1169
1170         if (log_target == LOG_TARGET_NULL)
1171                 return -error;
1172
1173         if (error != 0)
1174                 errno = error;
1175
1176         va_start(ap, format);
1177         vsnprintf(buffer, sizeof(buffer), format, ap);
1178         va_end(ap);
1179
1180         if (unit)
1181                 unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1182
1183         return log_struct_internal(
1184                         level, error,
1185                         file, line, func,
1186                         "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1187                         "CONFIG_FILE=%s", config_file,
1188                         "CONFIG_LINE=%u", config_line,
1189                         LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1190                         unit_fmt, unit,
1191                         NULL);
1192 }
1193
1194 #if 0 /// UNNEEDED by elogind
1195 void log_set_always_reopen_console(bool b) {
1196         always_reopen_console = b;
1197 }
1198 #endif // 0