version 1.1.2.1, 2010/09/28 17:19:58
|
version 1.1.2.6, 2011/06/08 09:21:37
|
Line 75 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
Line 75 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
#define TIMERINTVL 30 /* interval for checking flush, mark */ |
#define TIMERINTVL 30 /* interval for checking flush, mark */ |
#define TTYMSGTIME 1 /* timeout passed to ttymsg */ |
#define TTYMSGTIME 1 /* timeout passed to ttymsg */ |
|
|
|
#include "config.h" |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
#include <sys/mman.h> |
#include <sys/mman.h> |
Line 97 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
Line 99 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
#include <err.h> |
#include <err.h> |
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
|
#ifdef HAVE_LIBUTIL_H |
#include <libutil.h> |
#include <libutil.h> |
|
#else |
|
#include <util.h> |
|
#endif |
#include <limits.h> |
#include <limits.h> |
#include <paths.h> |
#include <paths.h> |
#include <signal.h> |
#include <signal.h> |
Line 106 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
Line 112 __FBSDID("$FreeBSD: src/usr.sbin/syslogd/syslogd.c,v 1
|
#include <string.h> |
#include <string.h> |
#include <sysexits.h> |
#include <sysexits.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#if defined(__FreeBSD__) && (__FreeBSD__ > 8) |
#include <utmpx.h> |
#include <utmpx.h> |
|
#else |
|
#include <utmp.h> |
|
#endif |
|
|
#include "pathnames.h" |
#include "pathnames.h" |
#include "ttymsg.h" |
|
|
|
|
// CPP: |
|
#include "defs.h" |
|
#include "clog.h" |
|
#include <sys/mman.h> |
|
#include <dirent.h> |
|
// CPP:: |
|
|
#define SYSLOG_NAMES |
#define SYSLOG_NAMES |
#include <sys/syslog.h> |
#include <sys/syslog.h> |
|
|
Line 182 struct filed {
|
Line 198 struct filed {
|
char f_pname[MAXPATHLEN]; |
char f_pname[MAXPATHLEN]; |
pid_t f_pid; |
pid_t f_pid; |
} f_pipe; |
} f_pipe; |
|
// CPP: |
|
struct { |
|
char f_rname[MAXPATHLEN]; |
|
struct clogFooter *f_footer; |
|
size_t f_size; |
|
} f_ring; |
|
// CPP:: |
} f_un; |
} f_un; |
char f_prevline[MAXSVLINE]; /* last message logged */ |
char f_prevline[MAXSVLINE]; /* last message logged */ |
char f_lasttime[16]; /* time of last occurrence */ |
char f_lasttime[16]; /* time of last occurrence */ |
Line 260 int repeatinterval[] = { 30, 120, 600 }; /* # of secs
|
Line 283 int repeatinterval[] = { 30, 120, 600 }; /* # of secs
|
#define F_USERS 5 /* list of users */ |
#define F_USERS 5 /* list of users */ |
#define F_WALL 6 /* everyone logged on */ |
#define F_WALL 6 /* everyone logged on */ |
#define F_PIPE 7 /* pipe to program */ |
#define F_PIPE 7 /* pipe to program */ |
|
#define F_RING 8 /* ring buffer (circular log) */ |
|
|
const char *TypeNames[8] = { | // CPP: |
| const char *TypeNames[] = { |
"UNUSED", "FILE", "TTY", "CONSOLE", |
"UNUSED", "FILE", "TTY", "CONSOLE", |
"FORW", "USERS", "WALL", "PIPE" | "FORW", "USERS", "WALL", "PIPE", |
| "RING" |
}; |
}; |
|
// CPP:: |
|
|
static struct filed *Files; /* Log files that we write to */ |
static struct filed *Files; /* Log files that we write to */ |
static struct filed consfile; /* Console */ |
static struct filed consfile; /* Console */ |
Line 337 static int waitdaemon(int, int, int);
|
Line 364 static int waitdaemon(int, int, int);
|
static void timedout(int); |
static void timedout(int); |
static void double_rbuf(int); |
static void double_rbuf(int); |
|
|
|
// CPP: |
|
static const char * |
|
ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) |
|
{ |
|
struct iovec localiov[7]; |
|
ssize_t left, wret; |
|
int cnt, fd; |
|
static char device[MAXNAMLEN] = _PATH_DEV; |
|
static char errbuf[1024]; |
|
char *p; |
|
int forked; |
|
|
|
forked = 0; |
|
if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) |
|
return ("too many iov's (change code in wall/ttymsg.c)"); |
|
|
|
p = device + sizeof(_PATH_DEV) - 1; |
|
strlcpy(p, line, sizeof(device)); |
|
if (strncmp(p, "pts/", 4) == 0) |
|
p += 4; |
|
if (strchr(p, '/') != NULL) { |
|
/* A slash is an attempt to break security... */ |
|
(void) snprintf(errbuf, sizeof(errbuf), |
|
"Too many '/' in \"%s\"", device); |
|
return (errbuf); |
|
} |
|
|
|
/* |
|
* open will fail on slip lines or exclusive-use lines |
|
* if not running as root; not an error. |
|
*/ |
|
if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) { |
|
if (errno == EBUSY || errno == EACCES) |
|
return (NULL); |
|
(void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device, |
|
strerror(errno)); |
|
return (errbuf); |
|
} |
|
|
|
for (cnt = 0, left = 0; cnt < iovcnt; ++cnt) |
|
left += iov[cnt].iov_len; |
|
|
|
for (;;) { |
|
wret = writev(fd, iov, iovcnt); |
|
if (wret >= left) |
|
break; |
|
if (wret >= 0) { |
|
left -= wret; |
|
if (iov != localiov) { |
|
bcopy(iov, localiov, |
|
iovcnt * sizeof(struct iovec)); |
|
iov = localiov; |
|
} |
|
for (cnt = 0; (size_t)wret >= iov->iov_len; ++cnt) { |
|
wret -= iov->iov_len; |
|
++iov; |
|
--iovcnt; |
|
} |
|
if (wret) { |
|
iov->iov_base = (char *)iov->iov_base + wret; |
|
iov->iov_len -= wret; |
|
} |
|
continue; |
|
} |
|
if (errno == EWOULDBLOCK) { |
|
int cpid; |
|
|
|
if (forked) { |
|
(void) close(fd); |
|
_exit(1); |
|
} |
|
cpid = fork(); |
|
if (cpid < 0) { |
|
(void) snprintf(errbuf, sizeof(errbuf), |
|
"fork: %s", strerror(errno)); |
|
(void) close(fd); |
|
return (errbuf); |
|
} |
|
if (cpid) { /* parent */ |
|
(void) close(fd); |
|
return (NULL); |
|
} |
|
forked++; |
|
/* wait at most tmout seconds */ |
|
(void) signal(SIGALRM, SIG_DFL); |
|
(void) signal(SIGTERM, SIG_DFL); /* XXX */ |
|
(void) sigsetmask(0); |
|
(void) alarm((u_int)tmout); |
|
(void) fcntl(fd, F_SETFL, 0); /* clear O_NONBLOCK */ |
|
continue; |
|
} |
|
/* |
|
* We get ENODEV on a slip line if we're running as root, |
|
* and EIO if the line just went away. |
|
*/ |
|
if (errno == ENODEV || errno == EIO) |
|
break; |
|
(void) close(fd); |
|
if (forked) |
|
_exit(1); |
|
(void) snprintf(errbuf, sizeof(errbuf), |
|
"%s: %s", device, strerror(errno)); |
|
return (errbuf); |
|
} |
|
|
|
(void) close(fd); |
|
if (forked) |
|
_exit(0); |
|
return (NULL); |
|
} |
|
|
|
static ssize_t |
|
rbwrite(struct filed *f, char *buf, size_t nbytes) |
|
{ |
|
ssize_t err, out = 0; |
|
size_t maxwrite = f->f_un.f_ring.f_footer->cf_max - f->f_un.f_ring.f_footer->cf_next; |
|
|
|
f->f_un.f_ring.f_footer->cf_lock = 1; |
|
while (nbytes > 0) { |
|
maxwrite = f->f_un.f_ring.f_footer->cf_max - f->f_un.f_ring.f_footer->cf_next; |
|
if (maxwrite > nbytes) |
|
maxwrite = nbytes; |
|
err = pwrite(f->f_file, buf, maxwrite, f->f_un.f_ring.f_footer->cf_next); |
|
if (err == -1) { |
|
f->f_un.f_ring.f_footer->cf_lock = 0; |
|
return -1; |
|
} |
|
nbytes -= err; |
|
out += err; |
|
buf += err; |
|
f->f_un.f_ring.f_footer->cf_next += err; |
|
if (f->f_un.f_ring.f_footer->cf_next == f->f_un.f_ring.f_footer->cf_max) { |
|
f->f_un.f_ring.f_footer->cf_next = 0; |
|
f->f_un.f_ring.f_footer->cf_wrap = 1; |
|
} |
|
} |
|
|
|
f->f_un.f_ring.f_footer->cf_lock = 0; |
|
return out; |
|
} |
|
static ssize_t |
|
rbwritev(struct filed *f, struct iovec *iov, int iovcnt) |
|
{ |
|
register int i; |
|
ssize_t err, out = 0; |
|
|
|
for(i = 0; i < iovcnt; i++) { |
|
err = rbwrite(f, iov[i].iov_base, iov[i].iov_len); |
|
if (err == -1) |
|
return -1; |
|
out += err; |
|
} |
|
|
|
return out; |
|
} |
|
// CPP:: |
|
|
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
{ |
{ |
Line 1278 fprintlog(struct filed *f, int flags, const char *msg)
|
Line 1462 fprintlog(struct filed *f, int flags, const char *msg)
|
} |
} |
break; |
break; |
|
|
|
// CPP: |
|
case F_RING: |
|
dprintf(" %s\n", f->f_un.f_ring.f_rname); |
|
v->iov_base = "\n"; |
|
v->iov_len = 1; |
|
if (rbwritev(f, iov, 7) == -1) { |
|
int e = errno; |
|
|
|
munmap(f->f_un.f_ring.f_footer, sizeof(struct clogFooter)); |
|
close(f->f_file); |
|
f->f_type = F_UNUSED; |
|
errno = e; |
|
logerror(f->f_un.f_fname); |
|
} |
|
break; |
|
// CPP:: |
|
|
case F_PIPE: |
case F_PIPE: |
dprintf(" %s\n", f->f_un.f_pipe.f_pname); |
dprintf(" %s\n", f->f_un.f_pipe.f_pname); |
v->iov_base = lf; |
v->iov_base = lf; |
Line 1343 static void
|
Line 1544 static void
|
wallmsg(struct filed *f, struct iovec *iov, const int iovlen) |
wallmsg(struct filed *f, struct iovec *iov, const int iovlen) |
{ |
{ |
static int reenter; /* avoid calling ourselves */ |
static int reenter; /* avoid calling ourselves */ |
struct utmpx *ut; |
|
int i; |
int i; |
const char *p; |
const char *p; |
|
|
if (reenter++) |
if (reenter++) |
return; |
return; |
|
#if defined(__FreeBSD__) && (__FreeBSD__ > 8) |
|
struct utmpx *ut; |
|
|
setutxent(); |
setutxent(); |
/* NOSTRICT */ |
/* NOSTRICT */ |
while ((ut = getutxent()) != NULL) { |
while ((ut = getutxent()) != NULL) { |
if (ut->ut_type != USER_PROCESS) |
if (ut->ut_type != USER_PROCESS) |
continue; |
continue; |
|
#else |
|
struct utmp ut_, *ut = &ut_; |
|
FILE *uf; |
|
char line[sizeof(ut_.ut_line) + 1]; |
|
|
|
if ((uf = fopen(_PATH_UTMP, "r")) == NULL) { |
|
logerror(_PATH_UTMP); |
|
reenter = 0; |
|
return; |
|
} |
|
/* NOSTRICT */ |
|
while (fread((char *)ut, sizeof(ut_), 1, uf) == 1) { |
|
if (ut->ut_name[0] == '\0') |
|
continue; |
|
/* We must use strncpy since ut_* may not be NUL terminated. */ |
|
strncpy(line, ut->ut_line, sizeof(line) - 1); |
|
line[sizeof(line) - 1] = '\0'; |
|
#endif |
if (f->f_type == F_WALL) { |
if (f->f_type == F_WALL) { |
if ((p = ttymsg(iov, iovlen, ut->ut_line, |
if ((p = ttymsg(iov, iovlen, ut->ut_line, |
TTYMSGTIME)) != NULL) { |
TTYMSGTIME)) != NULL) { |
Line 1366 wallmsg(struct filed *f, struct iovec *iov, const int
|
Line 1587 wallmsg(struct filed *f, struct iovec *iov, const int
|
for (i = 0; i < MAXUNAMES; i++) { |
for (i = 0; i < MAXUNAMES; i++) { |
if (!f->f_un.f_uname[i][0]) |
if (!f->f_un.f_uname[i][0]) |
break; |
break; |
|
#if defined(__FreeBSD__) && (__FreeBSD__ > 8) |
if (!strcmp(f->f_un.f_uname[i], ut->ut_user)) { |
if (!strcmp(f->f_un.f_uname[i], ut->ut_user)) { |
|
#else |
|
if (!strncmp(f->f_un.f_uname[i], ut->ut_name, UT_NAMESIZE)) { |
|
#endif |
if ((p = ttymsg(iov, iovlen, ut->ut_line, |
if ((p = ttymsg(iov, iovlen, ut->ut_line, |
TTYMSGTIME)) != NULL) { |
TTYMSGTIME)) != NULL) { |
errno = 0; /* already in msg */ |
errno = 0; /* already in msg */ |
Line 1376 wallmsg(struct filed *f, struct iovec *iov, const int
|
Line 1601 wallmsg(struct filed *f, struct iovec *iov, const int
|
} |
} |
} |
} |
} |
} |
|
#if defined(__FreeBSD__) && (__FreeBSD__ > 8) |
endutxent(); |
endutxent(); |
|
#else |
|
fclose(uf); |
|
#endif |
reenter = 0; |
reenter = 0; |
} |
} |
|
|
Line 1580 init(int signo)
|
Line 1809 init(int signo)
|
} |
} |
f->f_un.f_pipe.f_pid = 0; |
f->f_un.f_pipe.f_pid = 0; |
break; |
break; |
|
// CPP: |
|
case F_RING: |
|
munmap(f->f_un.f_ring.f_footer, sizeof(struct clogFooter)); |
|
close(f->f_file); |
|
break; |
|
// CPP:: |
} |
} |
next = f->f_next; |
next = f->f_next; |
if (f->f_program) free(f->f_program); |
if (f->f_program) free(f->f_program); |
Line 1721 init(int signo)
|
Line 1956 init(int signo)
|
} |
} |
break; |
break; |
|
|
|
// CPP: |
|
case F_RING: |
|
printf("%s", f->f_un.f_ring.f_rname); |
|
break; |
|
// CPP:: |
|
|
case F_PIPE: |
case F_PIPE: |
printf("%s", f->f_un.f_pipe.f_pname); |
printf("%s", f->f_un.f_pipe.f_pname); |
break; |
break; |
Line 1771 cfline(const char *line, struct filed *f, const char *
|
Line 2012 cfline(const char *line, struct filed *f, const char *
|
const char *p, *q; |
const char *p, *q; |
char *bp; |
char *bp; |
char buf[MAXLINE], ebuf[100]; |
char buf[MAXLINE], ebuf[100]; |
|
struct stat sb; |
|
|
dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); |
dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); |
|
|
Line 1977 cfline(const char *line, struct filed *f, const char *
|
Line 2219 cfline(const char *line, struct filed *f, const char *
|
f->f_type = F_FILE; |
f->f_type = F_FILE; |
} |
} |
break; |
break; |
|
|
|
// CPP: |
|
case '%': |
|
if ((f->f_file = open(p + 1, O_RDWR, 0)) < 0) { |
|
f->f_type = F_UNUSED; |
|
logerror(p + 1); |
|
break; |
|
} |
|
if (fstat(f->f_file, &sb) < 0) { |
|
close(f->f_file); |
|
f->f_type = F_UNUSED; |
|
logerror(p + 1); |
|
break; |
|
} |
|
f->f_un.f_ring.f_footer = mmap(NULL, sizeof(struct clogFooter), PROT_READ | PROT_WRITE, MAP_SHARED, |
|
f->f_file, sb.st_size - sizeof(struct clogFooter)); |
|
if (!f->f_un.f_ring.f_footer) { |
|
close(f->f_file); |
|
f->f_type = F_UNUSED; |
|
logerror(p + 1); |
|
break; |
|
} |
|
if (memcmp(&(f->f_un.f_ring.f_footer->cf_magic), MAGIC, 4)) { |
|
munmap(f->f_un.f_ring.f_footer, sizeof(struct clogFooter)); |
|
close(f->f_file); |
|
f->f_type = F_UNUSED; |
|
errno = ENODEV; |
|
logerror(p + 1); |
|
break; |
|
} |
|
f->f_un.f_ring.f_size = sb.st_size; |
|
strcpy(f->f_un.f_ring.f_rname, p + 1); |
|
f->f_type = F_RING; |
|
break; |
|
// CPP:: |
|
|
case '|': |
case '|': |
f->f_un.f_pipe.f_pid = 0; |
f->f_un.f_pipe.f_pid = 0; |