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