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