syslogd.c (671d7001679ca9eaf16a9ca7ceb77c139847b4db) syslogd.c (1a874a126a54fdc188cebd0c58579851c37d1814)
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1983, 1988, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 122 unchanged lines hidden (view full) ---

131#include <errno.h>
132#include <fcntl.h>
133#include <fnmatch.h>
134#include <libutil.h>
135#include <limits.h>
136#include <netdb.h>
137#include <paths.h>
138#include <signal.h>
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1983, 1988, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 122 unchanged lines hidden (view full) ---

131#include <errno.h>
132#include <fcntl.h>
133#include <fnmatch.h>
134#include <libutil.h>
135#include <limits.h>
136#include <netdb.h>
137#include <paths.h>
138#include <signal.h>
139#include <stdbool.h>
139#include <stdio.h>
140#include <stdlib.h>
141#include <string.h>
142#include <sysexits.h>
143#include <unistd.h>
144#include <utmpx.h>
145
146#include "pathnames.h"

--- 215 unchanged lines hidden (view full) ---

362
363static int UniquePriority; /* Only log specified priority? */
364static int LogFacPri; /* Put facility and priority in log message: */
365 /* 0=no, 1=numeric, 2=names */
366static int KeepKernFac; /* Keep remotely logged kernel facility */
367static int needdofsync = 0; /* Are any file(s) waiting to be fsynced? */
368static struct pidfh *pfh;
369static int sigpipe[2]; /* Pipe to catch a signal during select(). */
140#include <stdio.h>
141#include <stdlib.h>
142#include <string.h>
143#include <sysexits.h>
144#include <unistd.h>
145#include <utmpx.h>
146
147#include "pathnames.h"

--- 215 unchanged lines hidden (view full) ---

363
364static int UniquePriority; /* Only log specified priority? */
365static int LogFacPri; /* Put facility and priority in log message: */
366 /* 0=no, 1=numeric, 2=names */
367static int KeepKernFac; /* Keep remotely logged kernel facility */
368static int needdofsync = 0; /* Are any file(s) waiting to be fsynced? */
369static struct pidfh *pfh;
370static int sigpipe[2]; /* Pipe to catch a signal during select(). */
371static bool RFC3164OutputFormat = true; /* Use legacy format by default. */
370
371static volatile sig_atomic_t MarkSet, WantDie, WantInitialize, WantReapchild;
372
372
373static volatile sig_atomic_t MarkSet, WantDie, WantInitialize, WantReapchild;
374
375struct iovlist;
376
373static int allowaddr(char *);
374static int addfile(struct filed *);
375static int addpeer(struct peer *);
376static int addsock(struct sockaddr *, socklen_t, struct socklist *);
377static struct filed *cfline(const char *, const char *, const char *);
378static const char *cvthname(struct sockaddr *);
379static void deadq_enter(pid_t, const char *);
380static int deadq_remove(struct deadq_entry *);
381static int deadq_removebypid(pid_t);
382static int decode(const char *, const CODE *);
383static void die(int) __dead2;
384static void dodie(int);
385static void dofsync(void);
386static void domark(int);
387static void fprintlog_first(struct filed *, const char *, const char *,
388 const char *, const char *, const char *, const char *, int);
377static int allowaddr(char *);
378static int addfile(struct filed *);
379static int addpeer(struct peer *);
380static int addsock(struct sockaddr *, socklen_t, struct socklist *);
381static struct filed *cfline(const char *, const char *, const char *);
382static const char *cvthname(struct sockaddr *);
383static void deadq_enter(pid_t, const char *);
384static int deadq_remove(struct deadq_entry *);
385static int deadq_removebypid(pid_t);
386static int decode(const char *, const CODE *);
387static void die(int) __dead2;
388static void dodie(int);
389static void dofsync(void);
390static void domark(int);
391static void fprintlog_first(struct filed *, const char *, const char *,
392 const char *, const char *, const char *, const char *, int);
393static void fprintlog_write(struct filed *, struct iovlist *, int);
389static void fprintlog_successive(struct filed *, int);
390static void init(int);
391static void logerror(const char *);
392static void logmsg(int, const struct logtime *, const char *, const char *,
393 const char *, const char *, const char *, const char *, int);
394static void log_deadchild(pid_t, int, const char *);
395static void markit(void);
396static int socksetup(struct peer *);

--- 96 unchanged lines hidden (view full) ---

493 struct peer *pe;
494 struct socklist *sl;
495 pid_t ppid = 1, spid;
496 char *p;
497
498 if (madvise(NULL, 0, MADV_PROTECT) != 0)
499 dprintf("madvise() failed: %s\n", strerror(errno));
500
394static void fprintlog_successive(struct filed *, int);
395static void init(int);
396static void logerror(const char *);
397static void logmsg(int, const struct logtime *, const char *, const char *,
398 const char *, const char *, const char *, const char *, int);
399static void log_deadchild(pid_t, int, const char *);
400static void markit(void);
401static int socksetup(struct peer *);

--- 96 unchanged lines hidden (view full) ---

498 struct peer *pe;
499 struct socklist *sl;
500 pid_t ppid = 1, spid;
501 char *p;
502
503 if (madvise(NULL, 0, MADV_PROTECT) != 0)
504 dprintf("madvise() failed: %s\n", strerror(errno));
505
501 while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNop:P:sS:Tuv"))
506 while ((ch = getopt(argc, argv, "468Aa:b:cCdf:FHkl:m:nNoO:p:P:sS:Tuv"))
502 != -1)
503 switch (ch) {
504#ifdef INET
505 case '4':
506 family = PF_INET;
507 break;
508#endif
509#ifdef INET6

--- 106 unchanged lines hidden (view full) ---

616 break;
617 case 'N':
618 NoBind = 1;
619 SecureMode = 1;
620 break;
621 case 'n':
622 resolve = 0;
623 break;
507 != -1)
508 switch (ch) {
509#ifdef INET
510 case '4':
511 family = PF_INET;
512 break;
513#endif
514#ifdef INET6

--- 106 unchanged lines hidden (view full) ---

621 break;
622 case 'N':
623 NoBind = 1;
624 SecureMode = 1;
625 break;
626 case 'n':
627 resolve = 0;
628 break;
629 case 'O':
630 if (strcmp(optarg, "bsd") == 0 ||
631 strcmp(optarg, "rfc3164") == 0)
632 RFC3164OutputFormat = true;
633 else if (strcmp(optarg, "syslog") == 0 ||
634 strcmp(optarg, "rfc5424") == 0)
635 RFC3164OutputFormat = false;
636 else
637 usage();
638 break;
624 case 'o':
625 use_bootfile = 1;
626 break;
627 case 'P': /* path for alt. PID */
628 PidFile = optarg;
629 break;
630 case 's': /* no network mode */
631 SecureMode++;

--- 243 unchanged lines hidden (view full) ---

875 return;
876#endif
877}
878
879static void
880usage(void)
881{
882
639 case 'o':
640 use_bootfile = 1;
641 break;
642 case 'P': /* path for alt. PID */
643 PidFile = optarg;
644 break;
645 case 's': /* no network mode */
646 SecureMode++;

--- 243 unchanged lines hidden (view full) ---

890 return;
891#endif
892}
893
894static void
895usage(void)
896{
897
883 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
884 "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]",
885 " [-b bind_address] [-f config_file]",
886 " [-l [mode:]path] [-m mark_interval]",
887 " [-P pid_file] [-p log_socket]",
888 " [-S logpriv_socket]");
898 fprintf(stderr,
899 "usage: syslogd [-468ACcdFHknosTuv] [-a allowed_peer]\n"
900 " [-b bind_address] [-f config_file]\n"
901 " [-l [mode:]path] [-m mark_interval]\n"
902 " [-O format] [-P pid_file] [-p log_socket]\n"
903 " [-S logpriv_socket]\n");
889 exit(1);
890}
891
892/*
893 * Removes characters from log messages that are unsafe to display.
894 * TODO: Permit UTF-8 strings that include a BOM per RFC 5424?
895 */
896static void

--- 656 unchanged lines hidden (view full) ---

1553 if ((f->f_type == F_FILE) &&
1554 (f->f_flags & FFLAG_NEEDSYNC)) {
1555 f->f_flags &= ~FFLAG_NEEDSYNC;
1556 (void)fsync(f->f_file);
1557 }
1558 }
1559}
1560
904 exit(1);
905}
906
907/*
908 * Removes characters from log messages that are unsafe to display.
909 * TODO: Permit UTF-8 strings that include a BOM per RFC 5424?
910 */
911static void

--- 656 unchanged lines hidden (view full) ---

1568 if ((f->f_type == F_FILE) &&
1569 (f->f_flags & FFLAG_NEEDSYNC)) {
1570 f->f_flags &= ~FFLAG_NEEDSYNC;
1571 (void)fsync(f->f_file);
1572 }
1573 }
1574}
1575
1561#define IOV_SIZE 7
1576/*
1577 * List of iovecs to which entries can be appended.
1578 * Used for constructing the message to be logged.
1579 */
1580struct iovlist {
1581 struct iovec iov[TTYMSG_IOV_MAX];
1582 size_t iovcnt;
1583 size_t totalsize;
1584};
1585
1562static void
1586static void
1563fprintlog_first(struct filed *f, const char *hostname, const char *app_name,
1564 const char *procid, const char *msgid __unused,
1565 const char *structured_data __unused, const char *msg, int flags)
1587iovlist_init(struct iovlist *il)
1566{
1588{
1567 struct iovec iov[IOV_SIZE];
1568 struct addrinfo *r;
1569 int l, lsent = 0;
1570 char tagged_msg[MAXLINE + 1], line[MAXLINE + 1], greetings[200];
1571 char nul[] = "", space[] = " ", lf[] = "\n", crlf[] = "\r\n";
1572 char timebuf[RFC3164_DATELEN + 1];
1573 const char *msgret;
1574
1589
1575 if (strftime(timebuf, sizeof(timebuf), RFC3164_DATEFMT,
1576 &f->f_lasttime.tm) == 0)
1577 timebuf[0] = '\0';
1578 if (f->f_type == F_WALL) {
1579 /* The time displayed is not synchornized with the other log
1580 * destinations (like messages). Following fragment was using
1581 * ctime(&now), which was updating the time every 30 sec.
1582 * With f_lasttime, time is synchronized correctly.
1583 */
1584 iov[0] = (struct iovec){
1585 .iov_base = greetings,
1586 .iov_len = snprintf(greetings, sizeof(greetings),
1587 "\r\n\7Message from syslogd@%s "
1588 "at %.24s ...\r\n", hostname, timebuf)
1590 il->iovcnt = 0;
1591 il->totalsize = 0;
1592}
1593
1594static void
1595iovlist_append(struct iovlist *il, const char *str)
1596{
1597 size_t size;
1598
1599 /* Discard components if we've run out of iovecs. */
1600 if (il->iovcnt < nitems(il->iov)) {
1601 size = strlen(str);
1602 il->iov[il->iovcnt++] = (struct iovec){
1603 .iov_base = __DECONST(char *, str),
1604 .iov_len = size,
1589 };
1605 };
1590 if (iov[0].iov_len >= sizeof(greetings))
1591 iov[0].iov_len = sizeof(greetings) - 1;
1592 iov[1] = (struct iovec){
1593 .iov_base = nul,
1594 .iov_len = 0
1595 };
1596 } else {
1597 iov[0] = (struct iovec){
1598 .iov_base = timebuf,
1599 .iov_len = strlen(timebuf)
1600 };
1601 iov[1] = (struct iovec){
1602 .iov_base = space,
1603 .iov_len = 1
1604 };
1606 il->totalsize += size;
1605 }
1607 }
1608}
1606
1609
1607 if (LogFacPri) {
1608 static char fp_buf[30]; /* Hollow laugh */
1609 int fac = f->f_prevpri & LOG_FACMASK;
1610 int pri = LOG_PRI(f->f_prevpri);
1611 const char *f_s = NULL;
1612 char f_n[5]; /* Hollow laugh */
1613 const char *p_s = NULL;
1614 char p_n[5]; /* Hollow laugh */
1610static void
1611iovlist_truncate(struct iovlist *il, size_t size)
1612{
1613 struct iovec *last;
1614 size_t diff;
1615
1615
1616 if (LogFacPri > 1) {
1617 const CODE *c;
1618
1619 for (c = facilitynames; c->c_name; c++) {
1620 if (c->c_val == fac) {
1621 f_s = c->c_name;
1622 break;
1623 }
1624 }
1625 for (c = prioritynames; c->c_name; c++) {
1626 if (c->c_val == pri) {
1627 p_s = c->c_name;
1628 break;
1629 }
1630 }
1616 while (size > il->totalsize) {
1617 diff = size - il->totalsize;
1618 last = &il->iov[il->iovcnt - 1];
1619 if (diff >= last->iov_len) {
1620 /* Remove the last iovec entirely. */
1621 --il->iovcnt;
1622 il->totalsize -= last->iov_len;
1623 } else {
1624 /* Remove the last iovec partially. */
1625 last->iov_len -= diff;
1626 il->totalsize -= diff;
1631 }
1627 }
1632 if (!f_s) {
1633 snprintf(f_n, sizeof f_n, "%d", LOG_FAC(fac));
1634 f_s = f_n;
1635 }
1636 if (!p_s) {
1637 snprintf(p_n, sizeof p_n, "%d", pri);
1638 p_s = p_n;
1639 }
1640 snprintf(fp_buf, sizeof fp_buf, "<%s.%s> ", f_s, p_s);
1641 iov[2] = (struct iovec){
1642 .iov_base = fp_buf,
1643 .iov_len = strlen(fp_buf)
1644 };
1645 } else {
1646 iov[2] = (struct iovec){
1647 .iov_base = nul,
1648 .iov_len = 0
1649 };
1650 }
1628 }
1651 /* Prepend the application name to the message if provided. */
1652 if (app_name != NULL) {
1653 if (procid != NULL)
1654 snprintf(tagged_msg, sizeof(tagged_msg),
1655 "%s[%s]: %s", app_name, procid, msg);
1656 else
1657 snprintf(tagged_msg, sizeof(tagged_msg),
1658 "%s: %s", app_name, msg);
1659 msg = tagged_msg;
1660 }
1661 iov[3] = (struct iovec){
1662 .iov_base = __DECONST(char *, hostname),
1663 .iov_len = strlen(hostname)
1664 };
1665 iov[4] = (struct iovec){
1666 .iov_base = space,
1667 .iov_len = 1
1668 };
1669 iov[5] = (struct iovec){
1670 .iov_base = __DECONST(char *, msg),
1671 .iov_len = strlen(msg)
1672 };
1673 dprintf("Logging to %s", TypeNames[f->f_type]);
1674 f->f_time = now;
1629}
1675
1630
1676 switch (f->f_type) {
1677 case F_UNUSED:
1678 dprintf("\n");
1679 break;
1631static void
1632fprintlog_write(struct filed *f, struct iovlist *il, int flags)
1633{
1634 struct msghdr msghdr;
1635 struct addrinfo *r;
1636 struct socklist *sl;
1637 const char *msgret;
1638 ssize_t lsent;
1680
1639
1640 switch (f->f_type) {
1681 case F_FORW:
1641 case F_FORW:
1642 /* Truncate messages to RFC 5426 recommended size. */
1682 dprintf(" %s", f->fu_forw_hname);
1683 switch (f->fu_forw_addr->ai_addr->sa_family) {
1684#ifdef INET
1685 case AF_INET:
1686 dprintf(":%d\n",
1687 ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port));
1643 dprintf(" %s", f->fu_forw_hname);
1644 switch (f->fu_forw_addr->ai_addr->sa_family) {
1645#ifdef INET
1646 case AF_INET:
1647 dprintf(":%d\n",
1648 ntohs(satosin(f->fu_forw_addr->ai_addr)->sin_port));
1649 iovlist_truncate(il, 480);
1688 break;
1689#endif
1690#ifdef INET6
1691 case AF_INET6:
1692 dprintf(":%d\n",
1693 ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port));
1650 break;
1651#endif
1652#ifdef INET6
1653 case AF_INET6:
1654 dprintf(":%d\n",
1655 ntohs(satosin6(f->fu_forw_addr->ai_addr)->sin6_port));
1656 iovlist_truncate(il, 1180);
1694 break;
1695#endif
1696 default:
1697 dprintf("\n");
1698 }
1657 break;
1658#endif
1659 default:
1660 dprintf("\n");
1661 }
1699 /* check for local vs remote messages */
1700 if (strcasecmp(hostname, LocalHostName))
1701 l = snprintf(line, sizeof line - 1,
1702 "<%d>%.15s Forwarded from %s: %s",
1703 f->f_prevpri, (char *)iov[0].iov_base,
1704 hostname, (char *)iov[5].iov_base);
1705 else
1706 l = snprintf(line, sizeof line - 1, "<%d>%.15s %s",
1707 f->f_prevpri, (char *)iov[0].iov_base,
1708 (char *)iov[5].iov_base);
1709 if (l < 0)
1710 l = 0;
1711 else if (l > MAXLINE)
1712 l = MAXLINE;
1713
1662
1663 lsent = 0;
1714 for (r = f->fu_forw_addr; r; r = r->ai_next) {
1664 for (r = f->fu_forw_addr; r; r = r->ai_next) {
1715 struct socklist *sl;
1716
1665 memset(&msghdr, 0, sizeof(msghdr));
1666 msghdr.msg_name = r->ai_addr;
1667 msghdr.msg_namelen = r->ai_addrlen;
1668 msghdr.msg_iov = il->iov;
1669 msghdr.msg_iovlen = il->iovcnt;
1717 STAILQ_FOREACH(sl, &shead, next) {
1718 if (sl->sl_ss.ss_family == AF_LOCAL ||
1719 sl->sl_ss.ss_family == AF_UNSPEC ||
1720 sl->sl_socket < 0)
1721 continue;
1670 STAILQ_FOREACH(sl, &shead, next) {
1671 if (sl->sl_ss.ss_family == AF_LOCAL ||
1672 sl->sl_ss.ss_family == AF_UNSPEC ||
1673 sl->sl_socket < 0)
1674 continue;
1722 lsent = sendto(sl->sl_socket, line, l, 0,
1723 r->ai_addr, r->ai_addrlen);
1724 if (lsent == l)
1675 lsent = sendmsg(sl->sl_socket, &msghdr, 0);
1676 if (lsent == (ssize_t)il->totalsize)
1725 break;
1726 }
1677 break;
1678 }
1727 if (lsent == l && !send_to_all)
1679 if (lsent == (ssize_t)il->totalsize && !send_to_all)
1728 break;
1729 }
1680 break;
1681 }
1730 dprintf("lsent/l: %d/%d\n", lsent, l);
1731 if (lsent != l) {
1682 dprintf("lsent/totalsize: %zd/%zu\n", lsent, il->totalsize);
1683 if (lsent != (ssize_t)il->totalsize) {
1732 int e = errno;
1733 logerror("sendto");
1734 errno = e;
1735 switch (errno) {
1736 case ENOBUFS:
1737 case ENETDOWN:
1738 case ENETUNREACH:
1739 case EHOSTUNREACH:

--- 13 unchanged lines hidden (view full) ---

1753 f->f_type = F_UNUSED;
1754 break;
1755 }
1756 }
1757 break;
1758
1759 case F_FILE:
1760 dprintf(" %s\n", f->fu_fname);
1684 int e = errno;
1685 logerror("sendto");
1686 errno = e;
1687 switch (errno) {
1688 case ENOBUFS:
1689 case ENETDOWN:
1690 case ENETUNREACH:
1691 case EHOSTUNREACH:

--- 13 unchanged lines hidden (view full) ---

1705 f->f_type = F_UNUSED;
1706 break;
1707 }
1708 }
1709 break;
1710
1711 case F_FILE:
1712 dprintf(" %s\n", f->fu_fname);
1761 iov[6] = (struct iovec){
1762 .iov_base = lf,
1763 .iov_len = 1
1764 };
1765 if (writev(f->f_file, iov, nitems(iov)) < 0) {
1713 iovlist_append(il, "\n");
1714 if (writev(f->f_file, il->iov, il->iovcnt) < 0) {
1766 /*
1767 * If writev(2) fails for potentially transient errors
1768 * like the filesystem being full, ignore it.
1769 * Otherwise remove this logfile from the list.
1770 */
1771 if (errno != ENOSPC) {
1772 int e = errno;
1773 close_filed(f);
1774 errno = e;
1775 logerror(f->fu_fname);
1776 }
1777 } else if ((flags & SYNC_FILE) && (f->f_flags & FFLAG_SYNC)) {
1778 f->f_flags |= FFLAG_NEEDSYNC;
1779 needdofsync = 1;
1780 }
1781 break;
1782
1783 case F_PIPE:
1784 dprintf(" %s\n", f->fu_pipe_pname);
1715 /*
1716 * If writev(2) fails for potentially transient errors
1717 * like the filesystem being full, ignore it.
1718 * Otherwise remove this logfile from the list.
1719 */
1720 if (errno != ENOSPC) {
1721 int e = errno;
1722 close_filed(f);
1723 errno = e;
1724 logerror(f->fu_fname);
1725 }
1726 } else if ((flags & SYNC_FILE) && (f->f_flags & FFLAG_SYNC)) {
1727 f->f_flags |= FFLAG_NEEDSYNC;
1728 needdofsync = 1;
1729 }
1730 break;
1731
1732 case F_PIPE:
1733 dprintf(" %s\n", f->fu_pipe_pname);
1785 iov[6] = (struct iovec){
1786 .iov_base = lf,
1787 .iov_len = 1
1788 };
1734 iovlist_append(il, "\n");
1789 if (f->fu_pipe_pid == 0) {
1790 if ((f->f_file = p_open(f->fu_pipe_pname,
1791 &f->fu_pipe_pid)) < 0) {
1792 logerror(f->fu_pipe_pname);
1793 break;
1794 }
1795 }
1735 if (f->fu_pipe_pid == 0) {
1736 if ((f->f_file = p_open(f->fu_pipe_pname,
1737 &f->fu_pipe_pid)) < 0) {
1738 logerror(f->fu_pipe_pname);
1739 break;
1740 }
1741 }
1796 if (writev(f->f_file, iov, nitems(iov)) < 0) {
1742 if (writev(f->f_file, il->iov, il->iovcnt) < 0) {
1797 int e = errno;
1798
1799 deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname);
1800 close_filed(f);
1801 errno = e;
1802 logerror(f->fu_pipe_pname);
1803 }
1804 break;
1805
1806 case F_CONSOLE:
1807 if (flags & IGN_CONS) {
1808 dprintf(" (ignored)\n");
1809 break;
1810 }
1811 /* FALLTHROUGH */
1812
1813 case F_TTY:
1814 dprintf(" %s%s\n", _PATH_DEV, f->fu_fname);
1743 int e = errno;
1744
1745 deadq_enter(f->fu_pipe_pid, f->fu_pipe_pname);
1746 close_filed(f);
1747 errno = e;
1748 logerror(f->fu_pipe_pname);
1749 }
1750 break;
1751
1752 case F_CONSOLE:
1753 if (flags & IGN_CONS) {
1754 dprintf(" (ignored)\n");
1755 break;
1756 }
1757 /* FALLTHROUGH */
1758
1759 case F_TTY:
1760 dprintf(" %s%s\n", _PATH_DEV, f->fu_fname);
1815 iov[6] = (struct iovec){
1816 .iov_base = crlf,
1817 .iov_len = 2
1818 };
1761 iovlist_append(il, "\r\n");
1819 errno = 0; /* ttymsg() only sometimes returns an errno */
1762 errno = 0; /* ttymsg() only sometimes returns an errno */
1820 if ((msgret = ttymsg(iov, nitems(iov), f->fu_fname, 10))) {
1763 if ((msgret = ttymsg(il->iov, il->iovcnt, f->fu_fname, 10))) {
1821 f->f_type = F_UNUSED;
1822 logerror(msgret);
1823 }
1824 break;
1825
1826 case F_USERS:
1827 case F_WALL:
1828 dprintf("\n");
1764 f->f_type = F_UNUSED;
1765 logerror(msgret);
1766 }
1767 break;
1768
1769 case F_USERS:
1770 case F_WALL:
1771 dprintf("\n");
1829 iov[6] = (struct iovec){
1830 .iov_base = crlf,
1831 .iov_len = 2
1832 };
1833 wallmsg(f, iov, nitems(iov));
1772 iovlist_append(il, "\r\n");
1773 wallmsg(f, il->iov, il->iovcnt);
1834 break;
1835 }
1774 break;
1775 }
1776}
1777
1778static void
1779fprintlog_rfc5424(struct filed *f, const char *hostname, const char *app_name,
1780 const char *procid, const char *msgid, const char *structured_data,
1781 const char *msg, int flags)
1782{
1783 struct iovlist il;
1784 suseconds_t usec;
1785 int i;
1786 char timebuf[33], priority_number[5];
1787
1788 iovlist_init(&il);
1789 if (f->f_type == F_WALL)
1790 iovlist_append(&il, "\r\n\aMessage from syslogd ...\r\n");
1791 iovlist_append(&il, "<");
1792 snprintf(priority_number, sizeof(priority_number), "%d", f->f_prevpri);
1793 iovlist_append(&il, priority_number);
1794 iovlist_append(&il, ">1 ");
1795 if (strftime(timebuf, sizeof(timebuf), "%FT%T.______%z",
1796 &f->f_lasttime.tm) == sizeof(timebuf) - 2) {
1797 /* Add colon to the time zone offset, which %z doesn't do. */
1798 timebuf[32] = '\0';
1799 timebuf[31] = timebuf[30];
1800 timebuf[30] = timebuf[29];
1801 timebuf[29] = ':';
1802
1803 /* Overwrite space for microseconds with actual value. */
1804 usec = f->f_lasttime.usec;
1805 for (i = 25; i >= 20; --i) {
1806 timebuf[i] = usec % 10 + '0';
1807 usec /= 10;
1808 }
1809 iovlist_append(&il, timebuf);
1810 } else
1811 iovlist_append(&il, "-");
1812 iovlist_append(&il, " ");
1813 iovlist_append(&il, hostname);
1814 iovlist_append(&il, " ");
1815 iovlist_append(&il, app_name == NULL ? "-" : app_name);
1816 iovlist_append(&il, " ");
1817 iovlist_append(&il, procid == NULL ? "-" : procid);
1818 iovlist_append(&il, " ");
1819 iovlist_append(&il, msgid == NULL ? "-" : msgid);
1820 iovlist_append(&il, " ");
1821 iovlist_append(&il, structured_data == NULL ? "-" : structured_data);
1822 iovlist_append(&il, " ");
1823 iovlist_append(&il, msg);
1824
1825 fprintlog_write(f, &il, flags);
1826}
1827
1828static void
1829fprintlog_rfc3164(struct filed *f, const char *hostname, const char *app_name,
1830 const char *procid, const char *msg, int flags)
1831{
1832 struct iovlist il;
1833 const CODE *c;
1834 int facility, priority;
1835 char timebuf[RFC3164_DATELEN + 1], facility_number[5],
1836 priority_number[5];
1837 bool facility_found, priority_found;
1838
1839 if (strftime(timebuf, sizeof(timebuf), RFC3164_DATEFMT,
1840 &f->f_lasttime.tm) == 0)
1841 timebuf[0] = '\0';
1842
1843 iovlist_init(&il);
1844 switch (f->f_type) {
1845 case F_FORW:
1846 /* Message forwarded over the network. */
1847 iovlist_append(&il, "<");
1848 snprintf(priority_number, sizeof(priority_number), "%d",
1849 f->f_prevpri);
1850 iovlist_append(&il, priority_number);
1851 iovlist_append(&il, ">");
1852 iovlist_append(&il, timebuf);
1853 if (strcasecmp(hostname, LocalHostName) != 0) {
1854 iovlist_append(&il, " Forwarded from ");
1855 iovlist_append(&il, hostname);
1856 iovlist_append(&il, ":");
1857 }
1858 iovlist_append(&il, " ");
1859 break;
1860
1861 case F_WALL:
1862 /* Message written to terminals. */
1863 iovlist_append(&il, "\r\n\aMessage from syslogd@");
1864 iovlist_append(&il, hostname);
1865 iovlist_append(&il, " at ");
1866 iovlist_append(&il, timebuf);
1867 iovlist_append(&il, " ...\r\n");
1868 break;
1869
1870 default:
1871 /* Message written to files. */
1872 iovlist_append(&il, timebuf);
1873 iovlist_append(&il, " ");
1874 iovlist_append(&il, hostname);
1875 iovlist_append(&il, " ");
1876
1877 if (LogFacPri) {
1878 iovlist_append(&il, "<");
1879
1880 facility = f->f_prevpri & LOG_FACMASK;
1881 facility_found = false;
1882 if (LogFacPri > 1) {
1883 for (c = facilitynames; c->c_name; c++) {
1884 if (c->c_val == facility) {
1885 iovlist_append(&il, c->c_name);
1886 facility_found = true;
1887 break;
1888 }
1889 }
1890 }
1891 if (!facility_found) {
1892 snprintf(facility_number,
1893 sizeof(facility_number), "%d",
1894 LOG_FAC(facility));
1895 iovlist_append(&il, facility_number);
1896 }
1897
1898 iovlist_append(&il, ".");
1899
1900 priority = LOG_PRI(f->f_prevpri);
1901 priority_found = false;
1902 if (LogFacPri > 1) {
1903 for (c = prioritynames; c->c_name; c++) {
1904 if (c->c_val == priority) {
1905 iovlist_append(&il, c->c_name);
1906 priority_found = true;
1907 break;
1908 }
1909 }
1910 }
1911 if (!priority_found) {
1912 snprintf(priority_number,
1913 sizeof(priority_number), "%d", priority);
1914 iovlist_append(&il, priority_number);
1915 }
1916
1917 iovlist_append(&il, "> ");
1918 }
1919 break;
1920 }
1921
1922 /* Message body with application name and process ID prefixed. */
1923 if (app_name != NULL) {
1924 iovlist_append(&il, app_name);
1925 if (procid != NULL) {
1926 iovlist_append(&il, "[");
1927 iovlist_append(&il, procid);
1928 iovlist_append(&il, "]");
1929 }
1930 iovlist_append(&il, ": ");
1931 }
1932 iovlist_append(&il, msg);
1933
1934 fprintlog_write(f, &il, flags);
1935}
1936
1937static void
1938fprintlog_first(struct filed *f, const char *hostname, const char *app_name,
1939 const char *procid, const char *msgid __unused,
1940 const char *structured_data __unused, const char *msg, int flags)
1941{
1942
1943 dprintf("Logging to %s", TypeNames[f->f_type]);
1944 f->f_time = now;
1836 f->f_prevcount = 0;
1945 f->f_prevcount = 0;
1946 if (f->f_type == F_UNUSED) {
1947 dprintf("\n");
1948 return;
1949 }
1950
1951 if (RFC3164OutputFormat)
1952 fprintlog_rfc3164(f, hostname, app_name, procid, msg, flags);
1953 else
1954 fprintlog_rfc5424(f, hostname, app_name, procid, msgid,
1955 structured_data, msg, flags);
1837}
1838
1839/*
1840 * Prints a message to a log file that the previously logged message was
1841 * received multiple times.
1842 */
1843static void
1844fprintlog_successive(struct filed *f, int flags)

--- 379 unchanged lines hidden (view full) ---

2224 * Load hostname (may have changed).
2225 */
2226 if (signo != 0)
2227 (void)strlcpy(oldLocalHostName, LocalHostName,
2228 sizeof(oldLocalHostName));
2229 if (gethostname(LocalHostName, sizeof(LocalHostName)))
2230 err(EX_OSERR, "gethostname() failed");
2231 if ((p = strchr(LocalHostName, '.')) != NULL) {
1956}
1957
1958/*
1959 * Prints a message to a log file that the previously logged message was
1960 * received multiple times.
1961 */
1962static void
1963fprintlog_successive(struct filed *f, int flags)

--- 379 unchanged lines hidden (view full) ---

2343 * Load hostname (may have changed).
2344 */
2345 if (signo != 0)
2346 (void)strlcpy(oldLocalHostName, LocalHostName,
2347 sizeof(oldLocalHostName));
2348 if (gethostname(LocalHostName, sizeof(LocalHostName)))
2349 err(EX_OSERR, "gethostname() failed");
2350 if ((p = strchr(LocalHostName, '.')) != NULL) {
2232 *p++ = '\0';
2233 LocalDomain = p;
2351 /* RFC 5424 prefers logging FQDNs. */
2352 if (RFC3164OutputFormat)
2353 *p = '\0';
2354 LocalDomain = p + 1;
2234 } else {
2235 LocalDomain = "";
2236 }
2237
2238 /*
2239 * Load / reload timezone data (in case it changed).
2240 *
2241 * Just calling tzset() again does not work, the timezone code

--- 1189 unchanged lines hidden ---
2355 } else {
2356 LocalDomain = "";
2357 }
2358
2359 /*
2360 * Load / reload timezone data (in case it changed).
2361 *
2362 * Just calling tzset() again does not work, the timezone code

--- 1189 unchanged lines hidden ---