1176998Sphk/*-
2176998Sphk * Copyright (c) 2005-2008 Poul-Henning Kamp
3176998Sphk * All rights reserved.
4176998Sphk *
5176998Sphk * Redistribution and use in source and binary forms, with or without
6176998Sphk * modification, are permitted provided that the following conditions
7176998Sphk * are met:
8176998Sphk * 1. Redistributions of source code must retain the above copyright
9176998Sphk *    notice, this list of conditions and the following disclaimer.
10176998Sphk * 2. Redistributions in binary form must reproduce the above copyright
11176998Sphk *    notice, this list of conditions and the following disclaimer in the
12176998Sphk *    documentation and/or other materials provided with the distribution.
13176998Sphk *
14176998Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15176998Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16176998Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17176998Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18176998Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19176998Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20176998Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21176998Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22176998Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23176998Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24176998Sphk * SUCH DAMAGE.
25176998Sphk *
26176998Sphk * $FreeBSD$
27176998Sphk */
28176998Sphk
29176998Sphk#include <stdio.h>
30176998Sphk#include <assert.h>
31176998Sphk#include <unistd.h>
32176998Sphk#include <err.h>
33176998Sphk#include <time.h>
34176998Sphk#include <string.h>
35176998Sphk#include <stdlib.h>
36179000Sphk#include <sysexits.h>
37176998Sphk#include <regex.h>
38176998Sphk
39176998Sphk#include "libfifolog.h"
40176998Sphk
41176998Sphkstatic time_t opt_B;
42176998Sphkstatic time_t opt_E;
43176998Sphkstatic const char *opt_T;
44176998Sphkstatic const char *opt_o;
45176998Sphkstatic const char *opt_R;
46176998Sphkstatic regex_t R;
47176998Sphk
48176998Sphkstatic FILE *fo;
49176998Sphk
50176998Sphkstatic void
51176998SphkRender(void *priv __unused, time_t now, unsigned flag __unused, const unsigned char *p, unsigned l __unused)
52176998Sphk{
53176998Sphk	static struct tm utc;
54176998Sphk	char buf[128];
55176998Sphk	int i;
56176998Sphk
57176998Sphk	if (now < opt_B || now > opt_E)
58176998Sphk		return;
59176998Sphk
60176998Sphk	if (opt_R != NULL && regexec(&R, (const char *)p, 0, NULL, 0))
61176998Sphk		return;
62176998Sphk
63177795Sphk	if (opt_T != NULL && *opt_T == '\0') {
64177795Sphk		fprintf(fo, "%s\n", p);
65177795Sphk	} else if (opt_T != NULL) {
66176998Sphk		(void)gmtime_r(&now, &utc);
67176998Sphk		i = strftime(buf, sizeof buf, opt_T, &utc);
68176998Sphk		assert(i > 0);
69176998Sphk		fprintf(fo, "%s %s\n", buf, p);
70176998Sphk	} else {
71176998Sphk		fprintf(fo, "%12ld %s\n", (long)now, p);
72176998Sphk	}
73176998Sphk}
74176998Sphk
75176998Sphk/*--------------------------------------------------------------------*/
76176998Sphk
77176998Sphkstatic void
78176998SphkUsage(void)
79176998Sphk{
80176998Sphk	fprintf(stderr,
81176998Sphk		"Usage: fiforead [options] fifofile\n"
82176998Sphk		"\t-b <start time integer>\n"
83176998Sphk		"\t-B <start time>\n"
84176998Sphk		"\t-e <end time integer>\n"
85176998Sphk		"\t-E <end time>\n"
86176998Sphk		"\t-o <output file>\n"
87176998Sphk		"\t-R <regexp> # match regexp\n"
88176998Sphk		"\t-t # format timestamps as %%Y%%m%%d%%H%%M%%S\n"
89176998Sphk		"\t-T <timestamp format>\n"
90176998Sphk	);
91179000Sphk	exit (EX_USAGE);
92176998Sphk}
93176998Sphk
94176998Sphkint
95176998Sphkmain(int argc, char * const *argv)
96176998Sphk{
97176998Sphk	int ch, i;
98176998Sphk	off_t o;
99176998Sphk	struct fifolog_reader *fl;
100176998Sphk
101176998Sphk	time(&opt_E);
102176998Sphk	opt_o = "-";
103176998Sphk	while ((ch = getopt(argc, argv, "b:B:e:E:o:R:tT:")) != -1) {
104176998Sphk		switch (ch) {
105176998Sphk		case 'b':
106176998Sphk			opt_B = strtoul(optarg, NULL, 0);
107176998Sphk			break;
108176998Sphk		case 'B':
109176998Sphk			opt_B = get_date(optarg);
110176998Sphk			if (opt_B == -1)
111176998Sphk				errx(1, "Didn't understand \"%s\"", optarg);
112176998Sphk			break;
113176998Sphk		case 'e':
114176998Sphk			opt_E = strtoul(optarg, NULL, 0);
115176998Sphk			break;
116176998Sphk		case 'E':
117176998Sphk			opt_E = get_date(optarg);
118176998Sphk			if (opt_E == -1)
119176998Sphk				errx(1, "Didn't understand \"%s\"", optarg);
120176998Sphk			break;
121176998Sphk		case 'o':
122176998Sphk			opt_o = optarg;
123176998Sphk			break;
124176998Sphk		case 'R':
125176998Sphk			opt_R = optarg;
126176998Sphk			break;
127176998Sphk		case 't':
128176998Sphk			opt_T = "%Y%m%d%H%M%S";
129176998Sphk			break;
130176998Sphk		case 'T':
131176998Sphk			opt_T = optarg;
132176998Sphk			break;
133176998Sphk		default:
134176998Sphk			Usage();
135176998Sphk		}
136176998Sphk	}
137176998Sphk	argc -= optind;
138176998Sphk	argv += optind;
139176998Sphk
140176998Sphk	if (opt_R != NULL) {
141176998Sphk		i = regcomp(&R, opt_R, REG_NOSUB);
142176998Sphk		if (i != 0) {
143176998Sphk			char buf[BUFSIZ];
144176998Sphk			(void)regerror(i, &R, buf, sizeof buf);
145176998Sphk			fprintf(stderr, "-R argument: %s\n", buf);
146176998Sphk			exit (1);
147176998Sphk		}
148176998Sphk	}
149176998Sphk
150179000Sphk	if (argv[0] == NULL)
151179000Sphk		Usage();
152179000Sphk
153176998Sphk	fprintf(stderr, "From\t%jd %s", (intmax_t)opt_B, ctime(&opt_B));
154176998Sphk	fprintf(stderr, "To\t%jd %s", (intmax_t)opt_E, ctime(&opt_E));
155176998Sphk	if (opt_B >= opt_E)
156176998Sphk		errx(1, "Begin time not before End time");
157176998Sphk
158176998Sphk	fl = fifolog_reader_open(argv[0]);
159219027Sphk
160176998Sphk	if (!strcmp(opt_o, "-"))
161176998Sphk		fo = stdout;
162176998Sphk	else {
163176998Sphk		fo = fopen(opt_o, "w");
164176998Sphk		if (fo == NULL)
165176998Sphk			err(1, "Cannot open: %s", argv[1]);
166176998Sphk	}
167176998Sphk
168176998Sphk	o = fifolog_reader_seek(fl, opt_B);
169176998Sphk	fifolog_reader_process(fl, o, Render, NULL, opt_E);
170176998Sphk	return (0);
171176998Sphk}
172