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