diff -Naur /aquila-0.1.9-pre11/configure.ac aquila-0.1.9-pre11-forbid/configure.ac --- /aquila-0.1.9-pre11/configure.ac 2006-10-04 12:20:32.000000000 +0300 +++ aquila-0.1.9-pre11-forbid/configure.ac 2006-10-04 16:52:10.000000000 +0300 @@ -163,6 +163,48 @@ # Checks for libraries. AC_CHECK_LIB(crypt, crypt) +AC_DEFUN([AX_PATH_LIB_PCRE],[dnl +AC_MSG_CHECKING([lib pcre]) +AC_ARG_WITH(pcre, +[ --with-pcre[[=prefix]] compile xmlpcre part (via libpcre check)],, + with_pcre="yes") +if test ".$with_pcre" = ".no" ; then + AC_MSG_RESULT([disabled]) + m4_ifval($2,$2) +else + AC_MSG_RESULT([(testing)]) + AC_CHECK_LIB(pcre, pcre_study) + if test "$ac_cv_lib_pcre_pcre_study" = "yes" ; then + PCRE_LIBS="-lpcre" + AC_MSG_CHECKING([lib pcre]) + AC_MSG_RESULT([$PCRE_LIBS]) + m4_ifval($1,$1) + else + OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS -L$with_pcre/lib" + OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_pcre/include" + AC_CHECK_LIB(pcre, pcre_compile) + CPPFLAGS="$OLDCPPFLAGS" + LDFLAGS="$OLDLDFLAGS" + if test "$ac_cv_lib_pcre_pcre_compile" = "yes" ; then + AC_MSG_RESULT(.setting PCRE_LIBS -L$with_pcre/lib -lpcre) + PCRE_LIBS="-L$with_pcre/lib -lpcre" + test -d "$with_pcre/include" && PCRE_CFLAGS="-I$with_pcre/include" + AC_MSG_CHECKING([lib pcre]) + AC_MSG_RESULT([$PCRE_LIBS]) + m4_ifval($1,$1) + else + AC_MSG_CHECKING([lib pcre]) + AC_MSG_RESULT([no, (WARNING)]) + m4_ifval($2,$2) + fi + fi +fi +AC_SUBST([PCRE_LIBS]) +AC_SUBST([PCRE_CFLAGS]) +]) + +AX_PATH_LIB_PCRE + if test "${ZLINE}" = "" ; then unset ZLIB; @@ -178,7 +220,7 @@ # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h netinet/tcp.h inttypes.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h crypt.h string.h memory.h stdlib.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h netinet/tcp.h inttypes.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h crypt.h string.h memory.h stdlib.h pcre.h]) # if epoll is enables, check for the header if test "${ALLOW_EPOLL}" != "" ; diff -Naur /aquila-0.1.9-pre11/src/Makefile.am aquila-0.1.9-pre11-forbid/src/Makefile.am --- /aquila-0.1.9-pre11/src/Makefile.am 2006-09-28 22:30:09.000000000 +0300 +++ aquila-0.1.9-pre11-forbid/src/Makefile.am 2006-10-04 16:52:34.000000000 +0300 @@ -26,7 +26,7 @@ STACKTRACEFILES = stacktrace.c bin_PROGRAMS = aquila -aquila_SOURCES = buffer.c esocket.c stringlist.c rbt.c utils.c hash.c dllist.c leakybucket.c config.c hub.c core_config.c hashlist.c user.c banlist.c banlistclient.c plugin.c commands.c builtincmd.c cap.c nmdc_token.c nmdc_protocol.c nmdc_utils.c nmdc.c pi_user.c pi_statistics.c pi_chatroom.c pi_trigger.c pi_chatlog.c pi_statbot.c pi_iplog.c pi_hublist.c $(LUA_SOURCES) main.c searchlist.c $(DEBUG_FILES) $(GETADDRINFO_SOURCES) banlist.h +aquila_SOURCES = buffer.c esocket.c stringlist.c rbt.c utils.c hash.c dllist.c leakybucket.c config.c hub.c core_config.c hashlist.c user.c banlist.c banlistclient.c plugin.c commands.c builtincmd.c cap.c nmdc_token.c nmdc_protocol.c nmdc_utils.c nmdc.c pi_forbid.c pi_user.c pi_statistics.c pi_chatroom.c pi_trigger.c pi_chatlog.c pi_statbot.c pi_iplog.c pi_hublist.c $(LUA_SOURCES) main.c searchlist.c $(DEBUG_FILES) $(GETADDRINFO_SOURCES) banlist.h aquila_LDADD = @ZLIB@ @LUALIB@ @CYGWIN_LDFLAGS@ indent: .indent diff -Naur /aquila-0.1.9-pre11/src/main.c aquila-0.1.9-pre11-forbid/src/main.c --- /aquila-0.1.9-pre11/src/main.c 2006-10-04 12:22:20.000000000 +0300 +++ aquila-0.1.9-pre11-forbid/src/main.c 2006-10-04 16:52:11.000000000 +0300 @@ -203,6 +203,7 @@ server_init (); nmdc_init (); + pi_forbid_init (); pi_iplog_init (); pi_user_init (); pi_chatroom_init (); diff -Naur /aquila-0.1.9-pre11/src/pi_forbid.c aquila-0.1.9-pre11-forbid/src/pi_forbid.c --- /aquila-0.1.9-pre11/src/pi_forbid.c 1970-01-01 02:00:00.000000000 +0200 +++ aquila-0.1.9-pre11-forbid/src/pi_forbid.c 2006-10-06 01:55:14.000000000 +0300 @@ -0,0 +1,472 @@ +/* + written by Vicentiu Rizan + based on pi_trigger.c by Johan Verrept +*/ + + + +#include +#include +#include +#include + +#include "../config.h" +#ifdef HAVE_LIBPCRE +# ifdef HAVE_PCRE_H +# define USE_PCRE 1 +# endif +#endif + +#ifdef USE_PCRE +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif +#include + +#include "defaults.h" +#include "plugin.h" +#include "commands.h" +#include "utils.h" + + +#define OVECCOUNT 30 /* should be a multiple of 3 */ +#define FORBID_NAME_LENGTH 32 /* should be enough */ + +typedef struct forbid { + struct forbid *next, *prev; + + unsigned char name[FORBID_NAME_LENGTH]; + buffer_t *text; + buffer_t *msg; + +#ifdef USE_PCRE + pcre *re; +#endif + + unsigned long usecnt; + unsigned long banperiod; +} forbid_t; + +forbid_t forbidList; + +plugin_t *plugin_forbid; + +unsigned char *pi_forbid_conffile; +unsigned char *reportto; + +#ifdef USE_PCRE + pcre *ire; +#endif + +/*************************************************************************************************************************/ + +forbid_t *check_message(buffer_t *message) +{ + int rc; + forbid_t *forbid; + + + for (forbid = forbidList.next; forbid != &forbidList; forbid = forbid->next) { +#ifdef USE_PCRE + rc = pcre_exec(forbid->re, NULL, message->s, bf_used(message), 0, 0, /*ovector*/NULL, /*OVECCOUNT*/0); + DPRINTF("MESSAGE: '%.*s' forbid(%lu,%i): '%.*s'\n", (int) bf_used (message), message->s, (unsigned long) forbid->re, rc, (int) bf_used (forbid->text), forbid->text->s); +#else + rc = strstr(message->s, forbid->text->s) ? 0 : -1; + DPRINTF("MESSAGE: '%.*s' forbid(%i): '%.*s'\n", (int) bf_used (message), message->s, rc, (int) bf_used (forbid->text), forbid->text->s); +#endif + if (rc >= 0) { + forbid->usecnt++; + return forbid; + } + } + + return NULL; +}; + +forbid_t *forbid_create (unsigned char *name, unsigned long usecnt, unsigned char *arg1, unsigned char *arg2, unsigned long banperiod) +{ + forbid_t *forbid; +#ifdef USE_PCRE + const char *error; + int erroffset; +#endif + + forbid = (forbid_t *) malloc (sizeof (forbid_t)); + if (!forbid) + return NULL; + + memset (forbid, 0, sizeof (forbid_t)); + +#ifdef USE_PCRE + forbid->re = pcre_compile(arg1, 0, &error, &erroffset, NULL); + if (forbid->re == NULL) { + free (forbid); + return NULL; //PCRE compilation failed + } +#endif + + strncpy (forbid->name, name, FORBID_NAME_LENGTH); + forbid->name[FORBID_NAME_LENGTH - 1] = 0; + forbid->text = bf_alloc (strlen (arg1) + 1); + bf_strcat (forbid->text, arg1); + forbid->msg = bf_alloc (strlen (arg2) + 1); + bf_strcat (forbid->msg, arg2); + forbid->usecnt = usecnt; + forbid->banperiod = banperiod; + +#ifdef USE_PCRE + DPRINTF("FORBID: (%lu): '%.*s'\n", (unsigned long) forbid->re, (int) bf_used (forbid->text), forbid->text->s); +#else + DPRINTF("FORBID: '%.*s'\n", (int) bf_used (forbid->text), forbid->text->s); +#endif + + forbid->next = &forbidList; + forbid->prev = forbidList.prev; + forbid->next->prev = forbid; + forbid->prev->next = forbid; + + return forbid; +} + +forbid_t *forbid_find (unsigned char *name) +{ + forbid_t *forbid; + + for (forbid = forbidList.next; forbid != &forbidList; forbid = forbid->next) + if (!strcmp (forbid->name, name)) + return forbid; + + return NULL; +} + +void forbid_delete (forbid_t * forbid) +{ + forbid->next->prev = forbid->prev; + forbid->prev->next = forbid->next; + + if (forbid->text) + bf_free (forbid->text); + + if (forbid->msg) + bf_free (forbid->msg); + +#ifdef USE_PCRE + if (forbid->re) + pcre_free (forbid->re); +#endif + + free (forbid); +} + +int forbid_save (unsigned char *file) +{ + FILE *fp; + forbid_t *forbid; + + fp = fopen (file, "w+"); + if (!fp) + return errno; + + for (forbid = forbidList.next; forbid != &forbidList; forbid = forbid->next) { + fprintf (fp, "forbid %s %lu %lu\n", forbid->name, forbid->usecnt, forbid->banperiod); + fprintf (fp, "%*s\n", (int) bf_used (forbid->text), forbid->text->s); + fprintf (fp, "%*s\n", (int) bf_used (forbid->msg), forbid->msg->s); + } + + fclose (fp); + + return 0; +} + +int forbid_load (unsigned char *file) +{ + FILE *fp; + unsigned char buffer[1024], buffer2[1024]; + unsigned char name[FORBID_NAME_LENGTH]; + unsigned long usecnt, banperiod; + unsigned int i; + + forbid_t *forbid; + + fp = fopen (file, "r+"); + if (!fp) + return -1; + + fgets (buffer, sizeof (buffer), fp); + while (!feof (fp)) { + for (i = 0; buffer[i] && (buffer[i] != '\n') && (i < sizeof (buffer)); i++); + if (i == sizeof (buffer)) + break; + sscanf (buffer, "forbid %s %lu %lu", name, &usecnt, &banperiod); + + fgets (buffer, sizeof (buffer), fp); + for (i = 0; buffer[i] && (buffer[i] != '\n') && (i < sizeof (buffer)); i++); + if (i == sizeof (buffer)) + break; + if (buffer[i] == '\n') + buffer[i] = '\0'; + + fgets (buffer2, sizeof (buffer2), fp); + for (i = 0; buffer2[i] && (buffer2[i] != '\n') && (i < sizeof (buffer2)); i++); + if (i == sizeof (buffer2)) + break; + if (buffer2[i] == '\n') + buffer2[i] = '\0'; + + if ((forbid = forbid_find (name))) + forbid_delete (forbid); + forbid = forbid_create (name, usecnt, buffer, buffer2, banperiod); + + fgets (buffer, sizeof (buffer), fp); + } + + fclose (fp); + + return 0; +} + +unsigned int forbid_show (buffer_t * buf, forbid_t * forbid) +{ + unsigned char *cleanxp, *origxp, *lastpc; + int arglen; + int i = 0; + + for (origxp = forbid->text->s; origxp < forbid->text->e; origxp++) + if (*origxp == '|' || *origxp == '$') i++; + arglen = bf_used (forbid->text); + cleanxp = malloc (arglen + 1 + i * 6); + memset (cleanxp, 0, arglen + 1 + i * 6); + lastpc = forbid->text->s; + for (origxp = forbid->text->s; origxp < forbid->text->e; origxp++) { + if (*origxp == '|' || *origxp == '$') { + strncat (cleanxp, lastpc, origxp-lastpc); + sprintf (cleanxp + strlen(cleanxp), "&#%i;", *origxp); + lastpc = origxp + 1; + } + } + strncat (cleanxp, lastpc, origxp-lastpc); + bf_printf (buf, "forbid \"%s\" regexp \"%*s\" message \"%*s\" time \"", + forbid->name, strlen(cleanxp), cleanxp, bf_used (forbid->msg), forbid->msg->s); + time_print (buf, forbid->banperiod); + bf_printf (buf, "\" (Hits %ld)\n", forbid->usecnt); + free (cleanxp); + return 1; +} + +/*************************************************************************************************************************/ + +unsigned long pi_forbid_handler_forbidadd (plugin_user_t * user, buffer_t * output, void *dummy, + unsigned int argc, unsigned char **argv) +{ + forbid_t *t; + + if (argc < 5) { + bf_printf (output, "\n Usage: %s