Import ezmlm-idx 0.40
[ezmlm] / sub_std / searchlog.c
CommitLineData
f8beb284
MW
1/*$Id: searchlog.c,v 1.6 1999/10/09 14:22:38 lindberg Exp $*/
2/*$Name: ezmlm-idx-040 $*/
3#include "case.h"
4#include "scan.h"
5#include "stralloc.h"
6#include "str.h"
7#include "open.h"
8#include "datetime.h"
9#include "date822fmt.h"
10#include "substdio.h"
11#include "readwrite.h"
12#include "strerr.h"
13#include "error.h"
14#include "errtxt.h"
15#include "subscribe.h"
16
17static stralloc line = {0};
18static stralloc outline = {0};
19static char date[DATE822FMT];
20static datetime_sec when;
21static struct datetime dt;
22static substdio ssin;
23static char inbuf[256];
24
25static void die_nomem(fatal)
26char *fatal;
27{
28 strerr_die2x(100,fatal,ERR_NOMEM);
29}
30
31static void lineout(subwrite,fatal)
32int subwrite();
33char *fatal;
34{
35 (void) scan_ulong(line.s,&when);
36 datetime_tai(&dt,when); /* there is always at least a '\n' */
37 if (!stralloc_copyb(&outline,date,date822fmt(date,&dt) - 1))
38 die_nomem(fatal);
39 if (!stralloc_cats(&outline,": ")) die_nomem(fatal);
40 if (!stralloc_catb(&outline,line.s,line.len - 1)) die_nomem(fatal);
41 if (subwrite(outline.s,outline.len) == -1)
42 strerr_die3x(111,fatal,ERR_WRITE,"output");
43 return;
44}
45
46void searchlog(dir,search,subwrite,fatal)
47/* opens dir/Log, and outputs via subwrite(s,len) any line that matches */
48/* search. A '_' is search is a wildcard. Any other non-alphanum/'.' char */
49/* is replaced by a '_' */
50
51char *dir; /* work directory */
52char *search; /* search string */
53int subwrite(); /* output fxn */
54char *fatal; /* fatal */
55{
56
57 register unsigned char x;
58 register unsigned char y;
59 register unsigned char *cp;
60 register unsigned char *cpsearch;
61 unsigned register char *cps;
62 unsigned register char ch;
63 unsigned char *cplast, *cpline;
64 unsigned int searchlen;
65 int fd,match;
66
67 searchlen = str_len(search);
68 case_lowerb(search,searchlen);
69 cps = (unsigned char *) search;
70 while ((ch = *(cps++))) { /* search is potentially hostile */
71 if (ch >= 'a' && ch <= 'z') continue;
72 if (ch >= '0' && ch <= '9') continue;
73 if (ch == '.' || ch == '_') continue;
74 *(cps - 1) = '_'; /* will [also] match char specified */
75 }
76
77 if (!stralloc_copys(&line,dir)) die_nomem(fatal);
78 if (!stralloc_cats(&line,"/Log")) die_nomem(fatal);
79 if (!stralloc_0(&line)) die_nomem(fatal);
80 fd = open_read(line.s);
81 if (fd == -1)
82 if (errno != error_noent)
83 strerr_die4sys(111,fatal,ERR_OPEN,line.s,": ");
84 else
85 strerr_die3x(100,fatal,line.s,ERR_NOEXIST);
86 substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));
87
88 for (;;) {
89 if (getln(&ssin,&line,&match,'\n') == -1)
90 strerr_die2sys(111,fatal,ERR_READ_INPUT);
91 if (!match) break;
92 if (!searchlen) {
93 lineout(subwrite,fatal);
94 } else { /* simple case-insensitive search */
95 cpline = (unsigned char *) line.s - 1;
96 cplast = cpline + line.len - searchlen; /* line has \0 at the end */
97 while ((cp = ++cpline) <= cplast) {
98 cpsearch = (unsigned char *) search;
99 for (;;) {
100 x = *cpsearch++;
101 if (!x) break;
102 y = *cp++ - 'A';
103 if (y <= 'Z' - 'A') y += 'a'; else y += 'A';
104 if (x != y && x != '_') break; /* '_' = wildcard */
105 }
106 if (!x) {
107 lineout(subwrite,fatal);
108 break;
109 }
110 }
111 }
112 }
113 close(fd);
114}