- dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len);
-}
-
-static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) {
- struct msghdr msghdr;
- struct cmsghdr *cmsg;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
- union sockaddr_union sa;
-
- assert(s);
- assert(iovec);
- assert(n_iovec > 0);
-
- zero(msghdr);
- msghdr.msg_iov = (struct iovec*) iovec;
- msghdr.msg_iovlen = n_iovec;
-
- zero(sa);
- sa.un.sun_family = AF_UNIX;
- strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path));
- msghdr.msg_name = &sa;
- msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path);
-
- if (ucred) {
- zero(control);
- msghdr.msg_control = &control;
- msghdr.msg_controllen = sizeof(control);
-
- cmsg = CMSG_FIRSTHDR(&msghdr);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_CREDENTIALS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
- memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred));
- msghdr.msg_controllen = cmsg->cmsg_len;
- }
-
- /* Forward the syslog message we received via /dev/log to
- * /run/systemd/syslog. Unfortunately we currently can't set
- * the SO_TIMESTAMP auxiliary data, and hence we don't. */
-
- if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
- return;
-
- /* The socket is full? I guess the syslog implementation is
- * too slow, and we shouldn't wait for that... */
- if (errno == EAGAIN)
- return;
-
- if (ucred && errno == ESRCH) {
- struct ucred u;
-
- /* Hmm, presumably the sender process vanished
- * by now, so let's fix it as good as we
- * can, and retry */
-
- u = *ucred;
- u.pid = getpid();
- memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred));
-
- if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0)
- return;
-
- if (errno == EAGAIN)
- return;
- }
-
- log_debug("Failed to forward syslog message: %m");
-}
-
-static void forward_syslog_raw(Server *s, const char *buffer, struct ucred *ucred, struct timeval *tv) {
- struct iovec iovec;
-
- assert(s);
- assert(buffer);
-
- IOVEC_SET_STRING(iovec, buffer);
- forward_syslog_iovec(s, &iovec, 1, ucred, tv);
-}
-
-static void forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) {
- struct iovec iovec[5];
- char header_priority[6], header_time[64], header_pid[16];
- int n = 0;
- time_t t;
- struct tm *tm;
- char *ident_buf = NULL;
-
- assert(s);
- assert(priority >= 0);
- assert(priority <= 999);
- assert(message);
-
- /* First: priority field */
- snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
- char_array_0(header_priority);
- IOVEC_SET_STRING(iovec[n++], header_priority);
-
- /* Second: timestamp */
- t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC));
- tm = localtime(&t);
- if (!tm)
- return;
- if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
- return;
- IOVEC_SET_STRING(iovec[n++], header_time);
-
- /* Third: identifier and PID */
- if (ucred) {
- if (!identifier) {
- get_process_comm(ucred->pid, &ident_buf);
- identifier = ident_buf;
- }
-
- snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
- char_array_0(header_pid);
-
- if (identifier)
- IOVEC_SET_STRING(iovec[n++], identifier);
-
- IOVEC_SET_STRING(iovec[n++], header_pid);
- } else if (identifier) {
- IOVEC_SET_STRING(iovec[n++], identifier);
- IOVEC_SET_STRING(iovec[n++], ": ");
- }
-
- /* Fourth: message */
- IOVEC_SET_STRING(iovec[n++], message);
-
- forward_syslog_iovec(s, iovec, n, ucred, tv);
-
- free(ident_buf);
-}
-
-static int fixup_priority(int priority) {
-
- if ((priority & LOG_FACMASK) == 0)
- return (priority & LOG_PRIMASK) | LOG_USER;
-
- return priority;
-}
-
-static void forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred) {
- struct iovec iovec[5];
- char header_priority[6], header_pid[16];
- int n = 0;
- char *ident_buf = NULL;
- int fd;
-
- assert(s);
- assert(priority >= 0);
- assert(priority <= 999);
- assert(message);
-
- /* Never allow messages with kernel facility to be written to
- * kmsg, regardless where the data comes from. */
- priority = fixup_priority(priority);
-
- /* First: priority field */
- snprintf(header_priority, sizeof(header_priority), "<%i>", priority);
- char_array_0(header_priority);
- IOVEC_SET_STRING(iovec[n++], header_priority);
-
- /* Second: identifier and PID */
- if (ucred) {
- if (!identifier) {
- get_process_comm(ucred->pid, &ident_buf);
- identifier = ident_buf;
- }
-
- snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid);
- char_array_0(header_pid);
-
- if (identifier)
- IOVEC_SET_STRING(iovec[n++], identifier);
-
- IOVEC_SET_STRING(iovec[n++], header_pid);
- } else if (identifier) {
- IOVEC_SET_STRING(iovec[n++], identifier);
- IOVEC_SET_STRING(iovec[n++], ": ");
- }
-
- /* Fourth: message */
- IOVEC_SET_STRING(iovec[n++], message);
- IOVEC_SET_STRING(iovec[n++], "\n");
-
- fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0) {
- log_debug("Failed to open /dev/kmsg for logging: %s", strerror(errno));
- goto finish;
- }
-
- if (writev(fd, iovec, n) < 0)
- log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno));
-
- close_nointr_nofail(fd);
-
-finish:
- free(ident_buf);