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