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