chiark / gitweb /
cgroup: rename cg_update_unified() → cg_unified_update()
[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 static int log_dispatch(
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(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(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         size_t l;
736
737         if (error < 0)
738                 error = -error;
739
740         if (_likely_(LOG_PRI(level) > log_max_level))
741                 return -error;
742
743         /* Make sure that %m maps to the specified error */
744         if (error != 0)
745                 errno = error;
746
747         /* Prepend the object name before the message */
748         if (object) {
749                 size_t n;
750
751                 n = strlen(object);
752                 l = n + 2 + LINE_MAX;
753
754                 buffer = newa(char, l);
755                 b = stpcpy(stpcpy(buffer, object), ": ");
756         } else {
757                 l = LINE_MAX;
758                 b = buffer = newa(char, l);
759         }
760
761         vsnprintf(b, l, format, ap);
762
763         return log_dispatch(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
764 }
765
766 int log_object_internal(
767                 int level,
768                 int error,
769                 const char *file,
770                 int line,
771                 const char *func,
772                 const char *object_field,
773                 const char *object,
774                 const char *extra_field,
775                 const char *extra,
776                 const char *format, ...) {
777
778         va_list ap;
779         int r;
780
781         va_start(ap, format);
782         r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap);
783         va_end(ap);
784
785         return r;
786 }
787
788 static void log_assert(
789                 int level,
790                 const char *text,
791                 const char *file,
792                 int line,
793                 const char *func,
794                 const char *format) {
795
796         static char buffer[LINE_MAX];
797
798         if (_likely_(LOG_PRI(level) > log_max_level))
799                 return;
800
801         DISABLE_WARNING_FORMAT_NONLITERAL;
802         snprintf(buffer, sizeof buffer, format, text, file, line, func);
803         REENABLE_WARNING;
804
805         log_abort_msg = buffer;
806
807         log_dispatch(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
808 }
809
810 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
811         log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
812         abort();
813 }
814
815 noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
816         log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
817         abort();
818 }
819
820 void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
821         PROTECT_ERRNO;
822         log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
823 }
824
825 int log_oom_internal(const char *file, int line, const char *func) {
826         log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
827         return -ENOMEM;
828 }
829
830 int log_format_iovec(
831                 struct iovec *iovec,
832                 unsigned iovec_len,
833                 unsigned *n,
834                 bool newline_separator,
835                 int error,
836                 const char *format,
837                 va_list ap) {
838
839         static const char nl = '\n';
840
841         while (format && *n + 1 < iovec_len) {
842                 va_list aq;
843                 char *m;
844                 int r;
845
846                 /* We need to copy the va_list structure,
847                  * since vasprintf() leaves it afterwards at
848                  * an undefined location */
849
850                 if (error != 0)
851                         errno = error;
852
853                 va_copy(aq, ap);
854                 r = vasprintf(&m, format, aq);
855                 va_end(aq);
856                 if (r < 0)
857                         return -EINVAL;
858
859                 /* Now, jump enough ahead, so that we point to
860                  * the next format string */
861                 VA_FORMAT_ADVANCE(format, ap);
862
863                 IOVEC_SET_STRING(iovec[(*n)++], m);
864
865                 if (newline_separator) {
866                         iovec[*n].iov_base = (char*) &nl;
867                         iovec[*n].iov_len = 1;
868                         (*n)++;
869                 }
870
871                 format = va_arg(ap, char *);
872         }
873         return 0;
874 }
875
876 int log_struct_internal(
877                 int level,
878                 int error,
879                 const char *file,
880                 int line,
881                 const char *func,
882                 const char *format, ...) {
883
884         char buf[LINE_MAX];
885         bool found = false;
886         PROTECT_ERRNO;
887         va_list ap;
888
889         if (error < 0)
890                 error = -error;
891
892         if (_likely_(LOG_PRI(level) > log_max_level))
893                 return -error;
894
895         if (log_target == LOG_TARGET_NULL)
896                 return -error;
897
898         if ((level & LOG_FACMASK) == 0)
899                 level = log_facility | LOG_PRI(level);
900
901 #if 0 /// elogind does not support logging to systemd-journald
902         if (IN_SET(log_target, LOG_TARGET_AUTO,
903                                LOG_TARGET_JOURNAL_OR_KMSG,
904                                LOG_TARGET_JOURNAL) &&
905             journal_fd >= 0) {
906                 char header[LINE_MAX];
907                 struct iovec iovec[17] = {};
908                 unsigned n = 0, i;
909                 int r;
910                 struct msghdr mh = {
911                         .msg_iov = iovec,
912                 };
913                 bool fallback = false;
914
915                 /* If the journal is available do structured logging */
916                 log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL);
917                 IOVEC_SET_STRING(iovec[n++], header);
918
919                 va_start(ap, format);
920                 r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, true, error, format, ap);
921                 if (r < 0)
922                         fallback = true;
923                 else {
924                         mh.msg_iovlen = n;
925                         (void) sendmsg(journal_fd, &mh, MSG_NOSIGNAL);
926                 }
927
928                 va_end(ap);
929                 for (i = 1; i < n; i += 2)
930                         free(iovec[i].iov_base);
931
932                 if (!fallback)
933                         return -error;
934         }
935 #endif // 0
936
937         /* Fallback if journal logging is not available or didn't work. */
938
939         va_start(ap, format);
940         while (format) {
941                 va_list aq;
942
943                 if (error != 0)
944                         errno = error;
945
946                 va_copy(aq, ap);
947                 vsnprintf(buf, sizeof(buf), format, aq);
948                 va_end(aq);
949
950                 if (startswith(buf, "MESSAGE=")) {
951                         found = true;
952                         break;
953                 }
954
955                 VA_FORMAT_ADVANCE(format, ap);
956
957                 format = va_arg(ap, char *);
958         }
959         va_end(ap);
960
961         if (!found)
962                 return -error;
963
964         return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
965 }
966
967 int log_set_target_from_string(const char *e) {
968         LogTarget t;
969
970         t = log_target_from_string(e);
971         if (t < 0)
972                 return -EINVAL;
973
974         log_set_target(t);
975         return 0;
976 }
977
978 int log_set_max_level_from_string(const char *e) {
979         int t;
980
981         t = log_level_from_string(e);
982         if (t < 0)
983                 return -EINVAL;
984
985         log_set_max_level(t);
986         return 0;
987 }
988
989 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
990
991         /*
992          * The systemd.log_xyz= settings are parsed by all tools, and
993          * so is "debug".
994          *
995          * However, "quiet" is only parsed by PID 1, and only turns of
996          * status output to /dev/console, but does not alter the log
997          * level.
998          */
999
1000         if (streq(key, "debug") && !value)
1001                 log_set_max_level(LOG_DEBUG);
1002
1003         else if (proc_cmdline_key_streq(key, "systemd.log_target")) {
1004
1005                 if (proc_cmdline_value_missing(key, value))
1006                         return 0;
1007
1008                 if (log_set_target_from_string(value) < 0)
1009                         log_warning("Failed to parse log target '%s'. Ignoring.", value);
1010
1011         } else if (proc_cmdline_key_streq(key, "systemd.log_level")) {
1012
1013                 if (proc_cmdline_value_missing(key, value))
1014                         return 0;
1015
1016                 if (log_set_max_level_from_string(value) < 0)
1017                         log_warning("Failed to parse log level '%s'. Ignoring.", value);
1018
1019         } else if (proc_cmdline_key_streq(key, "systemd.log_color")) {
1020
1021                 if (log_show_color_from_string(value ?: "1") < 0)
1022                         log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
1023
1024         } else if (proc_cmdline_key_streq(key, "systemd.log_location")) {
1025
1026                 if (log_show_location_from_string(value ?: "1") < 0)
1027                         log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
1028         }
1029
1030         return 0;
1031 }
1032
1033 void log_parse_environment(void) {
1034         const char *e;
1035
1036         if (get_ctty_devnr(0, NULL) < 0)
1037                 /* Only try to read the command line in daemons.  We assume that anything that has a controlling tty is
1038                    user stuff. */
1039                 (void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
1040
1041         e = secure_getenv("SYSTEMD_LOG_TARGET");
1042         if (e && log_set_target_from_string(e) < 0)
1043                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
1044
1045         e = secure_getenv("SYSTEMD_LOG_LEVEL");
1046         if (e && log_set_max_level_from_string(e) < 0)
1047                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
1048
1049         e = secure_getenv("SYSTEMD_LOG_COLOR");
1050         if (e && log_show_color_from_string(e) < 0)
1051                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1052
1053         e = secure_getenv("SYSTEMD_LOG_LOCATION");
1054         if (e && log_show_location_from_string(e) < 0)
1055                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
1056 }
1057
1058 LogTarget log_get_target(void) {
1059         return log_target;
1060 }
1061
1062 int log_get_max_level(void) {
1063         return log_max_level;
1064 }
1065
1066 void log_show_color(bool b) {
1067         show_color = b;
1068 }
1069
1070 bool log_get_show_color(void) {
1071         return show_color;
1072 }
1073
1074 void log_show_location(bool b) {
1075         show_location = b;
1076 }
1077
1078 bool log_get_show_location(void) {
1079         return show_location;
1080 }
1081
1082 int log_show_color_from_string(const char *e) {
1083         int t;
1084
1085         t = parse_boolean(e);
1086         if (t < 0)
1087                 return t;
1088
1089         log_show_color(t);
1090         return 0;
1091 }
1092
1093 int log_show_location_from_string(const char *e) {
1094         int t;
1095
1096         t = parse_boolean(e);
1097         if (t < 0)
1098                 return t;
1099
1100         log_show_location(t);
1101         return 0;
1102 }
1103
1104 bool log_on_console(void) {
1105         if (IN_SET(log_target, LOG_TARGET_CONSOLE,
1106                                LOG_TARGET_CONSOLE_PREFIXED))
1107                 return true;
1108
1109         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1110 }
1111
1112 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1113         [LOG_TARGET_CONSOLE] = "console",
1114         [LOG_TARGET_CONSOLE_PREFIXED] = "console-prefixed",
1115         [LOG_TARGET_KMSG] = "kmsg",
1116 #if 0 /// elogind does not support logging to systemd-journald
1117         [LOG_TARGET_JOURNAL] = "journal",
1118         [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1119 #endif // 0
1120         [LOG_TARGET_SYSLOG] = "syslog",
1121         [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1122         [LOG_TARGET_AUTO] = "auto",
1123         [LOG_TARGET_SAFE] = "safe",
1124         [LOG_TARGET_NULL] = "null"
1125 };
1126
1127 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1128
1129 #if 0 /// UNNEEDED by elogind
1130 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1131         if (si->ssi_pid > 0) {
1132                 _cleanup_free_ char *p = NULL;
1133
1134                 get_process_comm(si->ssi_pid, &p);
1135
1136                 log_full(level,
1137                          "Received SIG%s from PID %"PRIu32" (%s).",
1138                          signal_to_string(si->ssi_signo),
1139                          si->ssi_pid, strna(p));
1140         } else
1141                 log_full(level,
1142                          "Received SIG%s.",
1143                          signal_to_string(si->ssi_signo));
1144
1145 }
1146
1147 void log_set_upgrade_syslog_to_journal(bool b) {
1148         upgrade_syslog_to_journal = b;
1149 }
1150 #endif // 0
1151
1152 int log_syntax_internal(
1153                 const char *unit,
1154                 int level,
1155                 const char *config_file,
1156                 unsigned config_line,
1157                 int error,
1158                 const char *file,
1159                 int line,
1160                 const char *func,
1161                 const char *format, ...) {
1162
1163         PROTECT_ERRNO;
1164         char buffer[LINE_MAX];
1165         va_list ap;
1166         const char *unit_fmt = NULL;
1167
1168         if (error < 0)
1169                 error = -error;
1170
1171         if (_likely_(LOG_PRI(level) > log_max_level))
1172                 return -error;
1173
1174         if (log_target == LOG_TARGET_NULL)
1175                 return -error;
1176
1177         if (error != 0)
1178                 errno = error;
1179
1180         va_start(ap, format);
1181         vsnprintf(buffer, sizeof(buffer), format, ap);
1182         va_end(ap);
1183
1184         if (unit)
1185                 unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
1186
1187         return log_struct_internal(
1188                         level, error,
1189                         file, line, func,
1190                         "MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
1191                         "CONFIG_FILE=%s", config_file,
1192                         "CONFIG_LINE=%u", config_line,
1193                         LOG_MESSAGE("%s:%u: %s", config_file, config_line, buffer),
1194                         unit_fmt, unit,
1195                         NULL);
1196 }
1197
1198 void log_set_always_reopen_console(bool b) {
1199         always_reopen_console = b;
1200 }