]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanserv_grep.c
3 #include "../core/events.h"
14 #define CSG_BUFSIZE 1024
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 */
23 char csg_readbuf
[CSG_BUFSIZE
]; /* Buffer */
24 int csg_bytesleft
; /* How much valid data there is in the buffer */
26 void csg_handleevents(int fd
, short revents
);
27 int csg_dogrep(void *source
, int cargc
, char **cargv
);
30 extern ssize_t
pread(int fd
, void *buf
, size_t count
, off_t offset
);
34 chanservaddcommand("grep", QCMD_OPER
, 1, csg_dogrep
, "Searches the logs.","");
38 chanservremovecommand("grep", csg_dogrep
);
41 int csg_dogrep(void *source
, int cargc
, char **cargv
) {
48 chanservstdmessage(sender
, QM_NOTENOUGHPARAMS
, "grep");
52 if (csg_maxmatches
>0) {
53 chanservsendmessage(sender
, "Sorry, grep is currently busy - try later.");
57 if (!(csg_curpat
=pcre_compile(cargv
[0], 0, &errptr
, &erroffset
, NULL
))) {
58 chanservsendmessage(sender
, "Error in pattern at character %d: %s",erroffset
,errptr
);
62 if ((fd
=open("chanservlog",O_RDONLY
))<0) {
63 chanservsendmessage(sender
, "Unable to open logfile.");
68 /* Initialise stuff for the match */
71 csg_curnum
=sender
->numeric
;
76 registerhandler(fd
, POLLIN
, csg_handleevents
);
77 chanservsendmessage(sender
, "Started grep for %s...",cargv
[0]);
82 void csg_handleevents(int fd
, short revents
) {
84 nick
*np
=getnickbynumeric(csg_curnum
);
85 char *chp
, *linestart
;
89 /* If the target user has vanished, drop everything */
91 deregisterhandler(fd
, 1);
98 res
=read(fd
, csg_readbuf
+csg_bytesleft
, CSG_BUFSIZE
-csg_bytesleft
);
101 /* chanservsendmessage(np, "Closing file: res=%d, errno=%d(%s), bytes read=%d",res,errno,sys_errlist[errno],csg_bytesread); */
102 /* End of file (or error) */
103 deregisterhandler(fd
, 1);
104 sprintf(filename
,"chanservlog.%d",++csg_curfile
);
105 if ((fd
=open(filename
,O_RDONLY
))>=0) {
106 /* Found the next file */
107 registerhandler(fd
, POLLIN
, csg_handleevents
);
109 chanservstdmessage(np
, QM_ENDOFLIST
);
119 linestart
=chp
=csg_readbuf
;
122 while (csg_bytesleft
) {
124 if (*chp
=='\r' || *chp
=='\n' || *chp
=='\0') {
125 if (linestart
==chp
) {
129 if (!pcre_exec(csg_curpat
, NULL
, linestart
, strlen(linestart
), 0, 0, NULL
, 0)) {
130 chanservsendmessage(np
, "%s", linestart
);
131 if (++csg_matches
>= csg_maxmatches
) {
132 chanservstdmessage(np
, QM_ENDOFLIST
);
134 deregisterhandler(fd
, 1);
145 csg_bytesleft
=(chp
-linestart
);
146 memmove(csg_readbuf
, linestart
, csg_bytesleft
);
149 pos
=lseek(fd
, 0, SEEK_CUR
);
150 if (!pread(fd
, csg_readbuf
+csg_bytesleft
, 1, pos
)) {