]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservgrep.c
3 #include "../core/events.h"
14 #define CSG_BUFSIZE 512
16 pcre
*csg_curpat
; /* Compiled pattern from pcre */
17 int csg_curfile
; /* Which logfile is being searched */
18 unsigned long csg_curnum
; /* What numeric is doing a search */
19 int csg_matches
; /* How many lines have been returned so far */
20 int csg_maxmatches
=0; /* How many matches are allowed */
22 char csg_readbuf
[CSG_BUFSIZE
]; /* Buffer */
23 int csg_bytesleft
; /* How much valid data there is in the buffer */
25 void csg_handleevents(int fd
, short revents
);
26 int csg_dogrep(void *source
, int cargc
, char **cargv
);
29 extern ssize_t
pread(int fd
, void *buf
, size_t count
, off_t offset
);
33 chanservaddcommand("grep", QCMD_OPER
, 1, csg_dogrep
, "Searches the logs.");
37 chanservremovecommand("grep", csg_dogrep
);
40 int csg_dogrep(void *source
, int cargc
, char **cargv
) {
47 chanservstdmessage(sender
, QM_NOTENOUGHPARAMS
, "grep");
51 if (csg_maxmatches
>0) {
52 chanservsendmessage(sender
, "Sorry, grep is currently busy - try later.");
56 if (!(csg_curpat
=pcre_compile(cargv
[0], 0, &errptr
, &erroffset
, NULL
))) {
57 chanservsendmessage(sender
, "Error in pattern at character %d: %s",erroffset
,errptr
);
61 if ((fd
=open("chanservlog.0",O_RDONLY
))<0) {
62 chanservsendmessage(sender
, "Unable to open logfile.");
67 /* Initialise stuff for the match */
70 csg_curnum
=sender
->numeric
;
74 registerhandler(fd
, POLLIN
, csg_handleevents
);
75 chanservsendmessage(sender
, "Started grep for %s...",cargv
[0]);
80 void csg_handleevents(int fd
, short revents
) {
82 nick
*np
=getnickbynumeric(csg_curnum
);
83 char *chp
, *linestart
;
87 /* If the target user has vanished, drop everything */
89 deregisterhandler(fd
, 1);
96 res
=read(fd
, csg_readbuf
+csg_bytesleft
, CSG_BUFSIZE
-csg_bytesleft
);
99 /* End of file (or error) */
100 deregisterhandler(fd
, 1);
101 sprintf(filename
,"chanservlog.%d",++csg_curfile
);
102 if ((fd
=open(filename
,O_RDONLY
))>=0) {
103 /* Found the next file */
104 registerhandler(fd
, POLLIN
, csg_handleevents
);
106 chanservstdmessage(np
, QM_ENDOFLIST
);
114 linestart
=chp
=csg_readbuf
;
117 while (csg_bytesleft
) {
119 if (*chp
=='\r' || *chp
=='\n' || *chp
=='\0') {
120 if (linestart
==chp
) {
124 if (!pcre_exec(csg_curpat
, NULL
, linestart
, strlen(linestart
), 0, 0, NULL
, 0)) {
125 chanservsendmessage(np
, "%s", linestart
);
126 if (++csg_matches
>= csg_maxmatches
) {
127 chanservstdmessage(np
, QM_ENDOFLIST
);
129 deregisterhandler(fd
, 1);
140 csg_bytesleft
=(chp
-linestart
);
141 memmove(csg_readbuf
, linestart
, csg_bytesleft
);
144 pos
=lseek(fd
, 0, SEEK_CUR
);
145 if (!pread(fd
, csg_readbuf
+csg_bytesleft
, 1, pos
)) {