bridge(4): document net.link.bridge.pfil_onlyip
[dragonfly.git] / usr.sbin / clog / clog.c
blob7f5df6050e7401a2433ab66e5d205b6afd602efa
1 /*-
2 * Copyright (c) 2001
3 * Jeff Wheelhouse (jdw@wwwi.com)
5 * This code was originally developed by Jeff Wheelhouse (jdw@wwwi.com).
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistribution of source code must retail the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY JEFF WHEELHOUSE ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL JEFF WHEELHOUSE BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * $Id: clog.c,v 1.3 2001/10/02 18:51:26 jdw Exp $
31 #include <assert.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <poll.h>
35 #include <signal.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
41 #include <sys/mman.h>
42 #include <sys/sched.h>
43 #include <sys/stat.h>
44 #include <sys/uio.h>
47 #include "clog.h"
51 * The BUFFER_SIZE value is just used to allocate a buffer full of NULLs
52 * so that a new logfile can be extended to its full size.
54 * Compiling with -pedantic complains when the buffer array is declared
55 * if I declare this as a const instead of a #define.
57 #define BUFFER_SIZE 16384
59 static void init_log(const char *lname, size_t size) __dead2;
60 static void read_log(const char *lname, int optf) __dead2;
61 static void usage(void) __dead2;
63 static const char *pname;
65 int
66 main(int argc, char **argv)
68 int ch;
69 int init = 0;
70 int size = 0;
71 int optf = 0;
73 pname = argv[0];
75 while ((ch = getopt(argc, argv, "fis:")) != -1)
76 switch(ch) {
77 case 'i':
78 init = 1;
79 break;
80 case 's':
81 size = atol(optarg);
82 if (size==0) usage();
83 break;
84 case 'f':
85 optf = 1;
88 if ((size>0)&&(init==0)) {
89 fprintf(stderr,"%s: WARNING: -s argument ignored without -i.\n",pname);
90 size = 0;
92 if (argv[optind]==NULL) {
93 fprintf(stderr,"%s: ERROR: log_file argument must be specified.\n",pname);
94 usage();
96 if ((init==1)&&(size==0)) {
97 fprintf(stderr,"%s: ERROR: -i argument requires -s.\n",pname);
98 usage();
100 if ((init==1)&&(optf==1)) {
101 fprintf(stderr,"%s: ERROR: flags -f and -i are incompatible.\n",pname);
102 usage();
105 if (init==1) init_log(argv[optind],size);
106 /* if (optf==1) follow_log(artv[optind]); */
107 read_log(argv[optind],optf);
109 return 0;
113 static void
114 usage(void)
116 fprintf(stderr,"usage: %s [-i -s log_size] [ -f ] log_file\n",pname);
117 exit(1);
121 static void
122 read_log(const char *lname, int optf)
124 int fd;
125 struct stat sb;
126 struct clog_footer *pcf;
127 char *pbuffer;
128 struct iovec iov[2];
129 int iovcnt = 0;
130 uint32_t start = 0;
131 uint32_t next;
132 struct pollfd pfd;
134 pfd.fd = -1;
136 fd = open(lname,O_RDONLY);
137 if (fd==-1) {
138 fprintf(stderr,"%s: ERROR: could not open %s (%s)\n",pname,lname,strerror(errno));
139 exit(11);
142 if (fstat(fd,&sb)==-1) {
143 fprintf(stderr,"%s: ERROR: could not stat %s (%s)\n",pname,lname,strerror(errno));
144 exit(13);
146 pbuffer = mmap(NULL,sb.st_size,PROT_READ,MAP_SHARED,fd,0);
147 if (pbuffer==NULL) {
148 fprintf(stderr,"%s: ERROR: could not mmap %s body (%s)\n",pname,lname,strerror(errno));
149 exit(14);
151 pcf = (struct clog_footer*)(pbuffer + sb.st_size - sizeof(struct clog_footer));
153 if (pcf->cf_wrap==1) start = pcf->cf_next + 1;
154 while(1) {
155 while(pcf->cf_lock==1) sched_yield();
156 next = pcf->cf_next;
157 iovcnt = 0;
158 if (start>next) {
159 iov[iovcnt].iov_base = pbuffer + start;
160 iov[iovcnt++].iov_len = pcf->cf_max - start;
161 start = 0;
163 iov[iovcnt].iov_base = pbuffer + start;
164 iov[iovcnt++].iov_len = next - start;
165 if (writev(1,iov,iovcnt)==-1) {
166 fprintf(stderr,"%s: ERROR: could not write output (%s)\n",pname,strerror(errno));
167 exit(15);
169 start = next;
170 if (optf==0) break;
171 if (poll(&pfd,1,50)==-1) {
172 fprintf(stderr,"%s: ERROR: could not poll (%s)\n",pname,strerror(errno));
173 exit(16);
177 munmap(pbuffer,sb.st_size);
178 close(fd);
180 exit(0);
184 static void
185 init_log(const char *lname, size_t size)
187 int fd;
188 size_t fill = size;
189 char buffer[BUFFER_SIZE];
190 struct clog_footer cf;
192 memcpy(&cf.cf_magic,MAGIC_CONST,4);
193 cf.cf_max = size - sizeof(struct clog_footer);
195 memset(buffer,0,BUFFER_SIZE);
197 fd = open(lname,O_RDWR|O_CREAT,0666);
198 if (fd==-1) {
199 fprintf(stderr,"%s: ERROR: could not open %s (%s)\n",pname,lname,strerror(errno));
200 exit(2);
202 if (ftruncate(fd,(off_t)0)==-1) {
203 fprintf(stderr,"%s: ERROR: could not truncate %s (%s)\n",pname,lname,strerror(errno));
204 exit(3);
207 while(fill>BUFFER_SIZE) {
208 if (write(fd,buffer,BUFFER_SIZE)==-1){
209 fprintf(stderr,"%s: ERROR: could not write %s (%s)\n",pname,lname,strerror(errno));
210 exit(4);
212 fill -= BUFFER_SIZE;
214 assert(fill<=BUFFER_SIZE);
215 if (fill>0) {
216 if (write(fd,buffer,fill)==-1) {
217 fprintf(stderr,"%s: ERROR: could not write %s (%s)\n",pname,lname,strerror(errno));
218 exit(5);
221 if (lseek(fd,-(off_t)(sizeof(struct clog_footer)),SEEK_END)==-1) {
222 fprintf(stderr,"%s: ERROR: could not seek in %s (%s)\n",pname,lname,strerror(errno));
223 exit(6);
225 if (write(fd,&cf,sizeof(cf))==-1) {
226 fprintf(stderr,"%s: ERROR: could not write magic in %s (%s)\n",pname,lname,strerror(errno));
227 exit(7);
229 close(fd);
230 exit(0);