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