chiark / gitweb /
56469b32b5d44dfe69e822921130cbe2c8c7163b
[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                         va_copy(aq, ap);
817                         if (vasprintf(&buf, format, aq) < 0) {
818                                 va_end(aq);
819                                 r = -ENOMEM;
820                                 goto finish;
821                         }
822                         va_end(aq);
823
824                         /* Now, jump enough ahead, so that we point to
825                          * the next format string */
826                         VA_FORMAT_ADVANCE(format, ap);
827
828                         IOVEC_SET_STRING(iovec[n++], buf);
829
830                         iovec[n].iov_base = (char*) &nl;
831                         iovec[n].iov_len = 1;
832                         n++;
833
834                         format = va_arg(ap, char *);
835                 }
836
837                 mh.msg_iovlen = n;
838
839                 if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0)
840                         r = -errno;
841                 else
842                         r = 1;
843
844         finish:
845                 va_end(ap);
846                 for (i = 1; i < n; i += 2)
847                         free(iovec[i].iov_base);
848
849         } else {
850                 char buf[LINE_MAX];
851                 bool found = false;
852
853                 /* Fallback if journal logging is not available */
854
855                 va_start(ap, format);
856                 while (format) {
857                         va_list aq;
858
859                         va_copy(aq, ap);
860                         vsnprintf(buf, sizeof(buf), format, aq);
861                         va_end(aq);
862                         char_array_0(buf);
863
864                         if (startswith(buf, "MESSAGE=")) {
865                                 found = true;
866                                 break;
867                         }
868
869                         VA_FORMAT_ADVANCE(format, ap);
870
871                         format = va_arg(ap, char *);
872                 }
873                 va_end(ap);
874
875                 if (found)
876                         r = log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
877                 else
878                         r = -EINVAL;
879         }
880
881         return r;
882 }
883
884 int log_set_target_from_string(const char *e) {
885         LogTarget t;
886
887         t = log_target_from_string(e);
888         if (t < 0)
889                 return -EINVAL;
890
891         log_set_target(t);
892         return 0;
893 }
894
895 int log_set_max_level_from_string(const char *e) {
896         int t;
897
898         t = log_level_from_string(e);
899         if (t < 0)
900                 return t;
901
902         log_set_max_level(t);
903         return 0;
904 }
905
906 static int parse_proc_cmdline_item(const char *key, const char *value) {
907
908         /*
909          * The systemd.log_xyz= settings are parsed by all tools, and
910          * so is "debug".
911          *
912          * However, "quiet" is only parsed by PID 1!
913          */
914
915         if (streq(key, "debug") && !value)
916                 log_set_max_level(LOG_DEBUG);
917
918         else if (streq(key, "systemd.log_target") && value) {
919
920                 if (log_set_target_from_string(value) < 0)
921                         log_warning("Failed to parse log target '%s'. Ignoring.", value);
922
923         } else if (streq(key, "systemd.log_level") && value) {
924
925                 if (log_set_max_level_from_string(value) < 0)
926                         log_warning("Failed to parse log level '%s'. Ignoring.", value);
927
928         } else if (streq(key, "systemd.log_color") && value) {
929
930                 if (log_show_color_from_string(value) < 0)
931                         log_warning("Failed to parse log color setting '%s'. Ignoring.", value);
932
933         } else if (streq(key, "systemd.log_location") && value) {
934
935                 if (log_show_location_from_string(value) < 0)
936                         log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
937         }
938
939         return 0;
940 }
941
942 void log_parse_environment(void) {
943         const char *e;
944
945         (void) parse_proc_cmdline(parse_proc_cmdline_item);
946
947         e = secure_getenv("SYSTEMD_LOG_TARGET");
948         if (e && log_set_target_from_string(e) < 0)
949                 log_warning("Failed to parse log target '%s'. Ignoring.", e);
950
951         e = secure_getenv("SYSTEMD_LOG_LEVEL");
952         if (e && log_set_max_level_from_string(e) < 0)
953                 log_warning("Failed to parse log level '%s'. Ignoring.", e);
954
955         e = secure_getenv("SYSTEMD_LOG_COLOR");
956         if (e && log_show_color_from_string(e) < 0)
957                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
958
959         e = secure_getenv("SYSTEMD_LOG_LOCATION");
960         if (e && log_show_location_from_string(e) < 0)
961                 log_warning("Failed to parse bool '%s'. Ignoring.", e);
962 }
963
964 LogTarget log_get_target(void) {
965         return log_target;
966 }
967
968 int log_get_max_level(void) {
969         return log_max_level;
970 }
971
972 void log_show_color(bool b) {
973         show_color = b;
974 }
975
976 bool log_get_show_color(void) {
977         return show_color;
978 }
979
980 void log_show_location(bool b) {
981         show_location = b;
982 }
983
984 bool log_get_show_location(void) {
985         return show_location;
986 }
987
988 int log_show_color_from_string(const char *e) {
989         int t;
990
991         t = parse_boolean(e);
992         if (t < 0)
993                 return t;
994
995         log_show_color(t);
996         return 0;
997 }
998
999 int log_show_location_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_location(t);
1007         return 0;
1008 }
1009
1010 bool log_on_console(void) {
1011         if (log_target == LOG_TARGET_CONSOLE)
1012                 return true;
1013
1014         return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
1015 }
1016
1017 static const char *const log_target_table[_LOG_TARGET_MAX] = {
1018         [LOG_TARGET_CONSOLE] = "console",
1019         [LOG_TARGET_KMSG] = "kmsg",
1020         [LOG_TARGET_JOURNAL] = "journal",
1021         [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg",
1022         [LOG_TARGET_SYSLOG] = "syslog",
1023         [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg",
1024         [LOG_TARGET_AUTO] = "auto",
1025         [LOG_TARGET_SAFE] = "safe",
1026         [LOG_TARGET_NULL] = "null"
1027 };
1028
1029 DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget);
1030
1031 void log_received_signal(int level, const struct signalfd_siginfo *si) {
1032         if (si->ssi_pid > 0) {
1033                 _cleanup_free_ char *p = NULL;
1034
1035                 get_process_comm(si->ssi_pid, &p);
1036
1037                 log_full(level,
1038                          "Received SIG%s from PID "PID_FMT" (%s).",
1039                          signal_to_string(si->ssi_signo),
1040                          si->ssi_pid, strna(p));
1041         } else
1042                 log_full(level,
1043                          "Received SIG%s.",
1044                          signal_to_string(si->ssi_signo));
1045
1046 }
1047
1048 void log_set_upgrade_syslog_to_journal(bool b) {
1049         upgrade_syslog_to_journal = b;
1050 }