ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
searchlog.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "getln.h"
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 "buffer.h"
11#include "readwrite.h"
12#include "error.h"
13#include "errtxt.h"
14#include "subscribe.h"
15#include "idx.h"
16#include "logmsg.h"
17
18#define WHO "searchlog"
19
25
26static stralloc line = {0};
27static stralloc outline = {0};
28static char date[DATE822FMT];
29static datetime_sec when;
30static buffer bi;
31static char inbuf[256];
32
33static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
34
35static void lineout(int subwrite())
36{
37 struct datetime dt;
38 (void) scan_ulong(line.s,&when);
39 datetime_tai(&dt,when); /* there is always at least a '\n' */
40 if (!stralloc_copyb(&outline,date,date822fmt(date,&dt) - 1))
41 die_nomem();
42 if (!stralloc_cats(&outline,": ")) die_nomem();
43 if (!stralloc_catb(&outline,line.s,line.len - 1)) die_nomem();
44 if (subwrite(outline.s,outline.len) == -1)
45 logmsg(WHO,111,FATAL,B(ERR_WRITE,"output"));
46 return;
47}
48
59
60void searchlog(const char *dir,char *search,int subwrite())
61{
62
63 unsigned char x;
64 unsigned char y;
65 unsigned char *cp;
66 unsigned char *cpsearch;
67 unsigned char *cps;
68 unsigned char ch;
69 unsigned char *cplast, *cpline;
70 unsigned int searchlen;
71 int fd,match;
72
73 searchlen = str_len(search);
74 case_lowerb(search,searchlen);
75 cps = (unsigned char *) search;
76
77 while ((ch = *(cps++))) { /* search is potentially hostile */
78 if (ch >= 'a' && ch <= 'z') continue;
79 if (ch >= '0' && ch <= '9') continue;
80 if (ch == '.' || ch == '_') continue;
81 *(cps - 1) = '_'; /* will [also] match char specified */
82 }
83
84 if (!stralloc_copys(&line,dir)) die_nomem();
85 if (!stralloc_cats(&line,"/Log")) die_nomem();
86 if (!stralloc_0(&line)) die_nomem();
87 fd = open_read(line.s);
88 if (fd == -1)
89 if (errno != ENOENT)
90 logmsg(WHO,111,FATAL,B(ERR_OPEN,line.s));
91 else
92 logmsg(WHO,100,FATAL,B(line.s,ERR_NOEXIST));
93
94 buffer_init(&bi,buffer_unixread,fd,inbuf,sizeof(inbuf));
95
96 for (;;) {
97 if (getln(&bi,&line,&match,'\n') == -1)
98 logmsg(WHO,111,FATAL,ERR_READ_INPUT);
99 if (!match) break;
100 if (!searchlen) {
101 lineout(subwrite);
102 } else { /* simple case-insensitive search */
103 cpline = (unsigned char *) line.s - 1;
104 cplast = cpline + line.len - searchlen; /* line has \0 at the end */
105
106 while ((cp = ++cpline) <= cplast) {
107 cpsearch = (unsigned char *) search;
108 for (;;) {
109 x = *cpsearch++;
110 if (!x) break;
111 y = *cp++ - 'A';
112 if (y <= 'Z' - 'A') y += 'a'; else y += 'A';
113 if (x != y && x != '_') break; /* '_' = wildcard */
114 }
115
116 if (!x) {
117 lineout(subwrite);
118 break;
119 }
120 }
121 }
122 }
123 close(fd);
124}
#define DATE822FMT
Definition date822fmt.h:4
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_OPEN
Definition errtxt.h:30
#define ERR_NOEXIST
Definition errtxt.h:40
#define ERR_READ_INPUT
Definition errtxt.h:26
#define ERR_WRITE
Definition errtxt.h:17
long datetime_sec
Definition datetime.h:15
void die_nomem()
Definition getconf.c:17
#define WHO
Definition author.c:1
char inbuf[1024]
char * dir
buffer bi
void searchlog(const char *dir, char *search, int subwrite())
Definition searchlog.c:60
const char * cp
Definition ezmlm-cron.c:76
unsigned int date822fmt(char *s, const struct datetime *dt)
Definition date822fmt.c:9
int fd
Definition ezmlm-cgi.c:141
datetime_sec when
Definition ezmlm-cgi.c:173
struct datetime dt
Definition ezmlm-cgi.c:174
int match
Definition ezmlm-cgi.c:140
void datetime_tai(struct datetime *dt, datetime_sec t)
Definition datetime.c:9
int subwrite(char *s, unsigned int l)
Definition ezmlm-list.c:29
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32