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