]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanserv_grep.c
dadc0e79fa15f3f3fa056dfb490f2eaa1ce79749
3 #include "../core/events.h"
4 #include "../lib/irc_string.h"
15 #define CSG_BUFSIZE 1024
16 #define CSG_MAXSTARTPOINT 21
18 pcre
*csg_curpat
; /* Compiled pattern from pcre */
19 int csg_curfile
; /* Which logfile is being searched */
20 unsigned long csg_curnum
; /* What numeric is doing a search */
21 int csg_matches
; /* How many lines have been returned so far */
22 int csg_maxmatches
=0; /* How many matches are allowed */
23 int csg_direction
; /* Log direction (0 = forward, 1 = reverse) */
26 char csg_readbuf
[CSG_BUFSIZE
]; /* Buffer */
27 int csg_bytesleft
; /* How much valid data there is in the buffer */
29 void csg_handleevents(int fd
, short revents
);
30 int csg_dogrep(void *source
, int cargc
, char **cargv
);
31 int csg_dorgrep(void *source
, int cargc
, char **cargv
);
32 int csg_execgrep(nick
*sender
, char *pattern
);
35 extern ssize_t
pread(int fd
, void *buf
, size_t count
, off_t offset
);
39 chanservaddcommand("grep", QCMD_OPER
, 1, csg_dogrep
, "Searches the logs.","");
40 chanservaddcommand("rgrep", QCMD_OPER
, 1, csg_dorgrep
, "Searches the logs in reverse order.","");
44 chanservremovecommand("grep", csg_dogrep
);
45 chanservremovecommand("rgrep", csg_dorgrep
);
48 int csg_dogrep(void *source
, int cargc
, char **cargv
) {
52 chanservstdmessage(sender
, QM_NOTENOUGHPARAMS
, "grep");
58 return csg_execgrep(sender
, cargv
[0]);
61 int csg_dorgrep(void *source
, int cargc
, char **cargv
) {
66 chanservstdmessage(sender
, QM_NOTENOUGHPARAMS
, "rgrep");
70 if (!protectedatoi(cargv
[0], &startpoint
)) {
71 chanservsendmessage(sender
, "Error in starting day number.");
76 chanservsendmessage(sender
, "Invalid starting day number.");
80 if (startpoint
>CSG_MAXSTARTPOINT
) {
81 chanservsendmessage(sender
, "Sorry, the maximum starting day is %d days.", CSG_MAXSTARTPOINT
);
85 csg_curfile
=startpoint
;
87 return csg_execgrep(sender
, cargv
[1]);
90 int csg_execgrep(nick
*sender
, char *pattern
) {
96 if (csg_maxmatches
>0) {
97 chanservsendmessage(sender
, "Sorry, the grepper is currently busy - try later.");
101 if (!(csg_curpat
=pcre_compile(pattern
, 0, &errptr
, &erroffset
, NULL
))) {
102 chanservsendmessage(sender
, "Error in pattern at character %d: %s",erroffset
,errptr
);
106 if (csg_direction
==0 || csg_curfile
==0) {
107 if ((fd
=open("chanservlog",O_RDONLY
))<0) {
108 chanservsendmessage(sender
, "Unable to open logfile.");
113 sprintf(filename
,"chanservlog.%d",csg_curfile
);
114 if ((fd
=open(filename
,O_RDONLY
))<0) {
115 chanservsendmessage(sender
, "Unable to open logfile.");
121 /* Initialise stuff for the match */
124 csg_curnum
=sender
->numeric
;
128 registerhandler(fd
, POLLIN
, csg_handleevents
);
129 chanservsendmessage(sender
, "Started grep for %s...",pattern
);
134 void csg_handleevents(int fd
, short revents
) {
136 nick
*np
=getnickbynumeric(csg_curnum
);
137 char *chp
, *linestart
;
141 /* If the target user has vanished, drop everything */
143 deregisterhandler(fd
, 1);
150 res
=read(fd
, csg_readbuf
+csg_bytesleft
, CSG_BUFSIZE
-csg_bytesleft
);
153 /* chanservsendmessage(np, "Closing file: res=%d, errno=%d(%s), bytes read=%d",res,errno,sys_errlist[errno],csg_bytesread); */
154 /* End of file (or error) */
155 deregisterhandler(fd
, 1);
156 if (csg_direction
==0) {
157 sprintf(filename
,"chanservlog.%d",++csg_curfile
);
161 chanservstdmessage(np
, QM_ENDOFLIST
);
163 } else if (csg_curfile
==0) {
164 sprintf(filename
,"chanservlog");
166 sprintf(filename
,"chanservlog.%d",csg_curfile
);
169 if ((fd
=open(filename
,O_RDONLY
))>=0) {
170 /* Found the next file */
171 registerhandler(fd
, POLLIN
, csg_handleevents
);
173 chanservstdmessage(np
, QM_ENDOFLIST
);
183 linestart
=chp
=csg_readbuf
;
186 while (csg_bytesleft
) {
188 if (*chp
=='\r' || *chp
=='\n' || *chp
=='\0') {
189 if (linestart
==chp
) {
193 if (!pcre_exec(csg_curpat
, NULL
, linestart
, strlen(linestart
), 0, 0, NULL
, 0)) {
194 chanservsendmessage(np
, "%s", linestart
);
195 if (++csg_matches
>= csg_maxmatches
) {
196 chanservstdmessage(np
, QM_ENDOFLIST
);
198 deregisterhandler(fd
, 1);
209 csg_bytesleft
=(chp
-linestart
);
210 memmove(csg_readbuf
, linestart
, csg_bytesleft
);
213 pos
=lseek(fd
, 0, SEEK_CUR
);
214 if (!pread(fd
, csg_readbuf
+csg_bytesleft
, 1, pos
)) {