diff -rc /usr/src/usr.sbin/syslogd/syslog.conf.5 syslogd/syslog.conf.5 *** /usr/src/usr.sbin/syslogd/syslog.conf.5 Tue Apr 3 11:25:59 2001 --- syslogd/syslog.conf.5 Mon Oct 1 22:56:53 2001 *************** *** 302,307 **** --- 302,313 ---- An asterisk. Selected messages are written to all logged-in users. .It + A percent sign + .Pq Dq \&% , + followed by a pathname (beginning with a leading slash). Selected messages + are written to a circular log file. See clog(8) for a discussion of + circular log files. + .It A vertical bar .Pq Dq \&| , followed by a command to pipe the selected diff -rc /usr/src/usr.sbin/syslogd/syslogd.c syslogd/syslogd.c *** /usr/src/usr.sbin/syslogd/syslogd.c Sun Feb 18 10:22:59 2001 --- syslogd/syslogd.c Mon Oct 1 22:47:58 2001 *************** *** 69,74 **** --- 69,75 ---- * by Peter da Silva. * -u and -v by Harlan Stenn. * Priority comparison code by Harlan Stenn. + * Ring buffer code by Jeff Wheelhouse. */ #define MAXLINE 1024 /* maximum line length */ *************** *** 89,94 **** --- 90,96 ---- #include #include #include + #include #include #include *************** *** 108,113 **** --- 110,116 ---- #include #include #include "pathnames.h" + #include "../clog/clog.h" #define SYSLOG_NAMES #include *************** *** 121,126 **** --- 124,130 ---- const char *ConfFile = _PATH_LOGCONF; const char *PidFile = _PATH_LOGPID; const char ctty[] = _PATH_CONSOLE; + const char ring_magic[] = "CLOG"; #define dprintf if (Debug) printf *************** *** 171,176 **** --- 175,185 ---- char f_pname[MAXPATHLEN]; pid_t f_pid; } f_pipe; + struct { + char f_rname[MAXPATHLEN]; + struct clog_footer *f_footer; + size_t f_size; + } f_ring; } f_un; char f_prevline[MAXSVLINE]; /* last message logged */ char f_lasttime[16]; /* time of last occurrence */ *************** *** 246,255 **** #define F_USERS 5 /* list of users */ #define F_WALL 6 /* everyone logged on */ #define F_PIPE 7 /* pipe to program */ ! char *TypeNames[8] = { "UNUSED", "FILE", "TTY", "CONSOLE", ! "FORW", "USERS", "WALL", "PIPE" }; struct filed *Files; --- 255,266 ---- #define F_USERS 5 /* list of users */ #define F_WALL 6 /* everyone logged on */ #define F_PIPE 7 /* pipe to program */ + #define F_RING 8 /* ring buffer (circular log) */ ! char *TypeNames[9] = { "UNUSED", "FILE", "TTY", "CONSOLE", ! "FORW", "USERS", "WALL", "PIPE", ! "RING" }; struct filed *Files; *************** *** 299,304 **** --- 310,317 ---- void printline __P((char *, char *)); void printsys __P((char *)); int p_open __P((char *, pid_t *)); + ssize_t rbwrite __P((struct filed *, char *, size_t)); + ssize_t rbwritev __P((struct filed *, struct iovec *, int)); void readklog __P((void)); void reapchild __P((int)); char *ttymsg __P((struct iovec *, int, char *, int)); *************** *** 1038,1043 **** --- 1051,1071 ---- (void)fsync(f->f_file); break; + 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; + (void)munmap(f->f_un.f_ring.f_footer,sizeof(struct clog_footer)); + (void)close(f->f_file); + f->f_type = F_UNUSED; + errno = e; + logerror(f->f_un.f_fname); + } + + break; + case F_PIPE: dprintf(" %s\n", f->f_un.f_pipe.f_pname); v->iov_base = "\n"; *************** *** 1366,1371 **** --- 1394,1403 ---- f->f_un.f_pipe.f_pname); f->f_un.f_pipe.f_pid = 0; break; + case F_RING: + (void)munmap(f->f_un.f_ring.f_footer,sizeof(struct clog_footer)); + (void)close(f->f_file); + break; } next = f->f_next; if (f->f_program) free(f->f_program); *************** *** 1475,1480 **** --- 1507,1516 ---- printf("%s", f->f_un.f_forw.f_hname); break; + case F_RING: + printf("%s", f->f_un.f_ring.f_rname); + break; + case F_PIPE: printf("%s", f->f_un.f_pipe.f_pname); break; *************** *** 1508,1513 **** --- 1544,1550 ---- int error, i, pri; char *bp, *p, *q; char buf[MAXLINE], ebuf[100]; + struct stat sb; dprintf("cfline(\"%s\", f, \"%s\", \"%s\")\n", line, prog, host); *************** *** 1660,1665 **** --- 1697,1734 ---- } break; + 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) { + (void)close(f->f_file); + f->f_type = F_UNUSED; + logerror(p+1); + break; + } + f->f_un.f_ring.f_footer = mmap(NULL,sizeof(struct clog_footer),PROT_READ|PROT_WRITE,MAP_SHARED,f->f_file,sb.st_size-sizeof(struct clog_footer)); + if (f->f_un.f_ring.f_footer==NULL) { + (void)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_CONST,4)!=0) { + (void)munmap(f->f_un.f_ring.f_footer,sizeof(struct clog_footer)); + (void)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; + (void)strcpy(f->f_un.f_ring.f_rname, p + 1); + f->f_type = F_RING; + break; + case '|': f->f_un.f_pipe.f_pid = 0; (void)strcpy(f->f_un.f_pipe.f_pname, p + 1); *************** *** 2291,2293 **** --- 2360,2409 ---- return(socks); } + + + ssize_t rbwritev(struct filed *f, struct iovec *iov, int iovcnt) { + int i; + ssize_t out = 0; + ssize_t err; + + for(i=0;if_un.f_ring.f_footer->cf_max - f->f_un.f_ring.f_footer->cf_next; + ssize_t err; + ssize_t out = 0; + + 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; + } + + +