diff --git a/main/eggdrop/APKBUILD b/main/eggdrop/APKBUILD index 6d63c4fd8c1..4c2a964e2ba 100644 --- a/main/eggdrop/APKBUILD +++ b/main/eggdrop/APKBUILD @@ -1,18 +1,16 @@ # Maintainer: Carlo Landmeter pkgname=eggdrop -pkgver=1.8.4 -pkgrel=4 +pkgver=1.9.2 +pkgrel=0 pkgdesc="World's most popular Open Source IRC bot" url="https://eggheads.org/" arch="all" license='GPL-2.0-or-later' options="!check" # No test suite -makedepends="openssl1.1-compat-dev tcl-dev !bind-libs" -subpackages="$pkgname-doc $pkgname-logs2html $pkgname-gseen" -source="$pkgname-$pkgver.tar.gz::https://github.com/eggheads/eggdrop/archive/v$pkgver.tar.gz +makedepends="openssl-dev tcl-dev" +subpackages="$pkgname-doc" +source="https://github.com/eggheads/eggdrop/releases/download/v$pkgver/eggdrop-$pkgver.tar.gz eggdrop-langdir.patch - logs2html.mod.patch - gseen.mod.patch utf8.patch " @@ -30,7 +28,6 @@ build() { package() { # workaround for borked Makefile mkdir -p "$pkgdir"/usr/share/eggdrop/doc \ - "$pkgdir"/usr/share/eggdrop/scripts \ "$pkgdir"/usr/share/eggdrop/help/set/ make DEST="$pkgdir"/usr/share/eggdrop install @@ -61,7 +58,7 @@ package() { mkdir -p "$pkgdir"/usr/share/doc/eggdrop cp -a \ - COPYING FEATURES NEWS README doc/Changes1.8 eggdrop.conf \ + COPYING FEATURES NEWS README doc/Changes1.9 eggdrop.conf \ doc/ABOUT doc/BANS doc/BOTNET doc/BUG-REPORT doc/FIRST-SCRIPT \ doc/MODULES doc/PARTYLINE doc/TEXT-SUBSTITUTIONS doc/TRICKS \ doc/USERS doc/WEIRD-MESSAGES doc/tcl-commands.doc doc/settings \ @@ -69,46 +66,8 @@ package() { "$pkgdir"/usr/share/doc/eggdrop } -logs2html() { - pkgdesc="logs2html module for eggdrop" - install="" - cd "$builddir" - - for dir in language help; do - mkdir -p "$subpkgdir"/usr/share/eggdrop/$dir - mv "$pkgdir"/usr/share/eggdrop/$dir/logs2html.* "$subpkgdir"/usr/share/eggdrop/$dir/ - done - - mkdir -p "$subpkgdir"/usr/lib/eggdrop - mv "$pkgdir"/usr/lib/eggdrop/logs2html.so \ - "$subpkgdir"/usr/lib/eggdrop/ - - mkdir -p "$subpkgdir"/usr/share/eggdrop/log2html - - for files in logs2html.conf user.css readme.txt; do - cp src/mod/logs2html.mod/$files "$subpkgdir"/usr/share/eggdrop/log2html/ - done -} - -gseen() { - pkgdesc="gseen module for eggdrop" - install="" - cd "$builddir" - mkdir -p "$subpkgdir"/usr/share/eggdrop/language - mv "$pkgdir"/usr/share/eggdrop/language/gseen.* \ - "$subpkgdir"/usr/share/eggdrop/language/ - mkdir -p "$subpkgdir"/usr/lib/eggdrop - mv "$pkgdir"/usr/lib/eggdrop/gseen.so \ - "$subpkgdir"/usr/lib/eggdrop/ - mkdir -p "$subpkgdir"/usr/share/eggdrop/gseen - cp src/mod/gseen.mod/gseen.conf "$subpkgdir"/usr/share/eggdrop/gseen/ - cp src/mod/gseen.mod/README "$subpkgdir"/usr/share/eggdrop/gseen/ -} - sha512sums=" -80239a015f518cadc251bfc5edcf08715b9200a70eb0df7edf0efc113f320a7e407ab1fee96322fc6ec923781aa94f5a947c458e935e8a3714fb86cbcc02cb04 eggdrop-1.8.4.tar.gz +67c8053a79ab5c4c418164e4e12f89a6e111b06b4e6dfdc69c52913b2f3b9a58b065a7601165112071c9ca2a778269aeb95c749a9da787c1932e6471a23146ce eggdrop-1.9.2.tar.gz d8e8655fed028030bc3cfe28207a289d0efbc412c7e01170a4d0bb31200f7ea93df310f19e83b485013ca5d4264694b4956252663cb3a63c3d5e4cc31346e0fe eggdrop-langdir.patch -be173d94a953c4dc5b178950d06ce894deda60c3ddb8195c836797d45fbbcc9fba3bc3d3f34c96226464fdd327093a5d15bbc2b7924d18f845738c1a4dd64a3b logs2html.mod.patch -7879b998880deb1943c41569e243f9f1a50df23982d82d942af6c111e7fac0fb8a8444c84980645ba15b71dd69c8db2dab6f90bcb7a4292306011c7bcfc03d0d gseen.mod.patch 7966d4d42994e44a0e571b89f1c66cb41f672d75e6ced7051d1ece23d8c209059c3565b41de950bf9c907701ce7a5e33a215b637587075ed300a002a58eda503 utf8.patch " diff --git a/main/eggdrop/eggdrop.post-install b/main/eggdrop/eggdrop.post-install deleted file mode 100644 index 44b43cf34ef..00000000000 --- a/main/eggdrop/eggdrop.post-install +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -echo "*" -echo "* Please run /usr/bin/eggdrop-installer to install your eggdrop bot." -echo "*" -exit 0 - diff --git a/main/eggdrop/gseen.mod.patch b/main/eggdrop/gseen.mod.patch deleted file mode 100644 index dd49248c650..00000000000 --- a/main/eggdrop/gseen.mod.patch +++ /dev/null @@ -1,5133 +0,0 @@ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/addons/gseen.selectlang.1.0.0.tcl src/eggdrop-1.8.4/src/mod/gseen.mod/addons/gseen.selectlang.1.0.0.tcl ---- ./src/mod/gseen.mod/addons/gseen.selectlang.1.0.0.tcl 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/addons/gseen.selectlang.1.0.0.tcl 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,80 @@ -+##################################################################### -+# -+# gseen.selectlang v1.0.0 -+# -+# This is a simple script which selects a language based on the -+# user's host. -+# -+# It only works for /msg commands. -+# -+# If the user is in a channel which has a language defined, gseen's -+# internal functions will override this selection and use the language -+# of the channel instead. -+# -+##################################################################### -+ -+ -+# Here you can define which language to use for which host. -+# The first part is the mask for the host, and the second part -+# is the language which should be used for this host. -+ -+set tld-langs { -+ {"*.de" "de"} -+ {"*.at" "de"} -+ {"*.ch" "de"} -+ {"*.t-dialin.net" "de"} -+ {"*.t-ipconnect.net" "de"} -+ {"*.pl" "pl"} -+ {"*.jp" "ja"} -+} -+ -+################################################# -+ -+ -+proc selectlang:getlang {uhost} { -+ global tld-langs -+ -+ foreach tld ${tld-langs} { -+ if {[string match [lindex $tld 0] $uhost]} { -+ return [lindex $tld 1] -+ } -+ } -+ return "" -+} -+ -+proc sl:rebind {oldtarget newtarget} { -+ foreach binding [binds msg] { -+ if {[lindex $binding 4] == $oldtarget} { -+ unbind [lindex $binding 0] [lindex $binding 1] [lindex $binding 2] [lindex $binding 4] -+ bind [lindex $binding 0] [lindex $binding 1] [lindex $binding 2] $newtarget -+ } -+ } -+} -+ -+proc sl:msg:trigger {nick uhost hand rest target} { -+ global default-slang -+ -+ set lang [selectlang:getlang $uhost] -+ set old-slang ${default-slang} -+ if {$lang != ""} { -+ set default-slang $lang -+ putlog "using '$lang'..." -+ } -+ $target $nick $uhost $hand $rest -+ set default-slang ${old-slang} -+} -+ -+sl:rebind *msg:seen sl:msg:seen -+proc sl:msg:seen {nick uhost hand rest} { -+ sl:msg:trigger $nick $uhost $hand $rest *msg:seen -+} -+ -+sl:rebind *msg:seenstats sl:msg:seenstats -+proc sl:msg:seenstats {nick uhost hand rest} { -+ sl:msg:trigger $nick $uhost $hand $rest *msg:seenstats -+} -+ -+sl:rebind *msg:seennick sl:msg:seennick -+proc sl:msg:seennick {nick uhost hand rest} { -+ sl:msg:trigger $nick $uhost $hand $rest *msg:seennick -+} -\ No newline at end of file -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/ai.c src/eggdrop-1.8.4/src/mod/gseen.mod/ai.c ---- ./src/mod/gseen.mod/ai.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/ai.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static int quietaiseens(char *chan) -+{ -+ char buf[121], *b; -+ -+ Context; -+ strncpy(buf, quiet_ai_seen, 120); -+ buf[120] = 0; -+ b = buf; -+ while (b[0]) -+ if (!strcasecmp(chan, newsplit(&b))) -+ return 1; -+#if EGG_IS_MIN_VER(10503) -+ if (ngetudef("quietaiseens", chan)) -+ return 1; -+#endif -+ return 0; -+} -+ -+static int tcl_pubmseen STDVAR -+{ -+ char *nick, *uhost, *hand, *chan, *text; -+ char buf[1024]; -+ char *words, *word; -+ seendat *l; -+ int i; -+ -+ Context; -+ BADARGS(6, 6, " nick uhost hand chan text"); -+ nick = argv[1]; -+ uhost = argv[2]; -+ hand = argv[3]; -+ chan = argv[4]; -+ text = argv[5]; -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, chan)); -+ glob_nick = nick; -+ for (i = 0; i < strlen(text); i++) -+ if (strchr("!?.,\"", text[i])) -+ text[i] = ' '; -+ strncpy(buf, ignore_words, 1023); -+ buf[1023] = 0; -+ words = buf; -+ while (words[0]) -+ add_ignoredword(newsplit(&words)); -+ strncpy(buf, text, 1023); -+ buf[1023] = 0; -+ words = buf; -+ while (words[0]) { -+ word = newsplit(&words); -+ if (word_is_ignored(word)) -+ continue; -+ l = findseen(word); -+ if (l) { -+ if (quietaiseens(chan)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, -+ do_seen(word, nick, uhost, chan, 0)); -+ } else { -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", chan, reply_prefix, -+ do_seen(word, nick, uhost, chan, 0)); -+ } -+ add_seenreq(word, nick, uhost, chan, now); -+ free_ignoredwords(); -+ Tcl_AppendResult(irp, "1", NULL); -+ return TCL_OK; -+ } -+ } -+ free_ignoredwords(); -+ Tcl_AppendResult(irp, "0", NULL); -+ return TCL_OK; -+} -+ -+static tcl_cmds mytcls[] = -+{ -+ {"*pubm:seen", tcl_pubmseen}, -+ {"*chjn:gseen", gseen_chjn}, -+ {"*chpt:gseen", gseen_chpt}, -+ {0, 0} -+}; -+ -+static void add_ignoredword(char *word) -+{ -+ ignoredword *l, *nl; -+ -+ l = ignoredwords; -+ while (l && l->next) -+ l = l->next; -+ nl = nmalloc(sizeof(ignoredword)); -+ nl->word = nmalloc(strlen(word) + 1); -+ strcpy(nl->word, word); -+ nl->next = NULL; -+ if (ignoredwords) -+ l->next = nl; -+ else -+ ignoredwords = nl; -+} -+ -+static void free_ignoredwords() -+{ -+ ignoredword *l, *ll; -+ -+ l = ignoredwords; -+ while (l) { -+ ll = l->next; -+ nfree(l->word); -+ nfree(l); -+ l = ll; -+ } -+ ignoredwords = NULL; -+} -+ -+static int expmem_ignoredwords() -+{ -+ ignoredword *l; -+ int size = 0; -+ -+ for (l = ignoredwords; l; l = l->next) { -+ size += sizeof(ignoredword); -+ size += strlen(l->word) + 1; -+ } -+ return size; -+} -+ -+static int word_is_ignored(char *word) -+{ -+ ignoredword *l; -+ -+ for (l = ignoredwords; l; l = l->next) -+ if (!strcasecmp(l->word, word)) -+ return 1; -+ return 0; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/datahandling.c src/eggdrop-1.8.4/src/mod/gseen.mod/datahandling.c ---- ./src/mod/gseen.mod/datahandling.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/datahandling.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+ -+static void write_seens() -+{ -+ seenreq *r; -+ seenreq_by *b; -+ FILE *f; -+ char s[125]; -+ -+ Context; -+ /* putlog(LOG_MISC, "*", "Saving seen data..."); */ -+ if (!gseenfile[0]) -+ return; -+ sprintf(s, "%s~new", gseenfile); -+ f = fopen(s, "w"); -+ chmod(s, 0600); -+ if (f == NULL) { -+ putlog(LOG_MISC, "*", "ERROR writing gseen file."); -+ return; -+ } -+ fprintf(f, "# gseen data file v1.\n"); -+ write_seen_tree_target = f; -+ btree_getall(&seentree, write_seen_tree); -+ for (r = requests; r; r = r->next) -+ for (b = r->by; b; b = b->next) -+ /* @ nick by host chan when */ -+ fprintf(f, "@ %s %s %s %s %lu\n", r->nick, b->who, b->host, b->chan, -+ b->when); -+ fclose(f); -+ unlink(gseenfile); -+ movefile(s, gseenfile); -+ /* putlog(LOG_MISC, "*", "Done."); */ -+ return; -+} -+ -+static void read_seens() -+{ -+ FILE *f; -+ char buf[512], *s, *type, *nick, *host, *chan, *msg, *by; -+ time_t when; -+ int spent, iType, i; -+ -+ Context; -+ f = fopen(gseenfile, "r"); -+ if (f == NULL) { -+ putlog(LOG_MISC, "*", "Can't open gseen file, creating new database..."); -+ return; -+ } -+ while (!feof(f)) { -+ buf[0] = 0; -+ s = buf; -+ fgets(s, 511, f); -+ i = strlen(buf); -+ if (buf[i - 1] == '\n') -+ buf[i - 1] = 0; -+ if ((buf[0] == 0) || (buf[0] == '#')) -+ continue; -+ type = newsplit(&s); -+ if (!strcmp(type, "!")) { -+ nick = newsplit(&s); -+ host = newsplit(&s); -+ chan = newsplit(&s); -+ iType = atoi(newsplit(&s)); -+ when = (time_t) atoi(newsplit(&s)); -+ spent = atoi(newsplit(&s)); -+ msg = s; -+ add_seen(iType, nick, host, chan, msg, when, spent); -+ } else if (!strcmp(type, "@")) { -+ nick = newsplit(&s); -+ by = newsplit(&s); -+ host = newsplit(&s); -+ chan = newsplit(&s); -+ when = (time_t) atoi(newsplit(&s)); -+ add_seenreq(nick, by, host, chan, when); -+ } -+ } -+ fclose(f); -+ Context; -+ return; -+} -+ -+static void purge_seens() -+{ -+ seenreq *r, *rr; -+ seenreq_by *b, *bb; -+ -+ Context; -+ if (!expire_seens) -+ return; -+ btree_getall_expanded(&seentree, purge_seen_tree); -+ debug0("purge done"); -+ r = requests; -+ rr = NULL; -+ while (r) { -+ b = r->by; -+ bb = NULL; -+ while (b) { -+ if ((now - b->when) > (expire_seens * 86400)) { -+ debug2("request for %s from %s has expired.", r->nick, b->who); -+ nfree(b->who); -+ nfree(b->host); -+ nfree(b->chan); -+ if (bb) { -+ bb->next = b->next; -+ nfree(b); -+ b = bb->next; -+ } else { -+ r->by = b->next; -+ nfree(b); -+ b = r->by; -+ } -+ } else { -+ bb = b; -+ b = b->next; -+ } -+ } -+ if (!r->by) { -+ debug1("no further seen requests for %s, deleting", r->nick); -+ nfree(r->nick); -+ if (rr) { -+ rr->next = r->next; -+ nfree(r); -+ r = rr->next; -+ } else { -+ requests = r->next; -+ nfree(r); -+ r = requests; -+ } -+ } else { -+ rr = r; -+ r = r->next; -+ } -+ } -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/do_seen.c src/eggdrop-1.8.4/src/mod/gseen.mod/do_seen.c ---- ./src/mod/gseen.mod/do_seen.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/do_seen.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,840 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* do_seen(): Checks if someone matches the mask, and returns the reply -+ * mask : first paramater (e.g. "G`Quann", "G`Quann", "*!*@*.isp.de", ...) -+ * nick : nick of the one, who triggered the command -+ * uhost: user@host of nick -+ * chan : chan, where the command was triggered -+ * bns : -+ * 1 : do a botnet-seen if no matches are found -+ * 0 : don't do a botnet-seen -+ * -1 : return NULL instead of text, if no matches were found -+ * (necessary for botnet seen) -+ */ -+static char *do_seen(char *mask, char *nick, char *uhost, char *chan, int bns) -+{ -+ char hostbuf[UHOSTLEN + 1], *host, *newhost, *tmp, *dur; -+ seendat *l; -+ gseenres *r; -+ int wild, nr; -+ char bnquery[256]; -+ struct userrec *u; -+ struct laston_info *li; -+ struct chanset_t *ch; -+ -+ Context; -+ start_seentime_calc(); -+ if (seen_reply) { -+ nfree(seen_reply); -+ seen_reply = NULL; -+ } -+ l = NULL; -+ li = NULL; -+ host = hostbuf; -+ newhost = NULL; -+ mask = newsplit(&mask); -+ glob_query = mask; -+ while (mask[0] == ' ') -+ mask++; -+ if (!mask[0]) { -+ return SLNOPARAM; -+ } -+ if (strchr(mask, '?') || strchr(mask, '*')) { -+ // if wildcard-searches ares not allowed, then either return -+ // NULL (for botnet-seen), or a appropriate warning -+ if (!wildcard_search) { -+ if (bns == -1) -+ return NULL; -+ else -+ return SLNOWILDCARDS; -+ } else -+ wild = 1; -+ } else { -+ if (strlen(mask) > seen_nick_len) // don't process if requested nick is too long -+ return SLTOOLONGNICK; // (e.g. stop stupid jokes) -+ if (!strcasecmp(mask, nick)) { -+ return SLMIRROR; -+ } -+ // check if the nick is on the current channel -+ if (onchan(mask, chan)) -+ return SLONCHAN; -+ if ((glob_othernick = handonchan(mask, chan))) -+ return SLHANDONCHAN; -+ // check if it is on any other channel -+ if ((ch = onanychan(mask))) { -+#if EGG_IS_MIN_VER(10500) -+ if (!secretchan(ch->dname)) { -+ glob_otherchan = ch->dname; -+ return SLONOTHERCHAN; -+ } -+#else -+ if (!secretchan(ch->name)) { -+ glob_otherchan = ch->name; -+ return SLONOTHERCHAN; -+ } -+#endif -+ } -+ // check if the user who uses this handle is on the channel under -+ // a different nick -+ if ((ch = handonanychan(mask))) { -+#if EGG_IS_MIN_VER(10500) -+ if (!secretchan(ch->dname)) { -+ glob_otherchan = ch->dname; -+ return SLONOTHERCHAN; -+ } -+#else -+ if (!secretchan(ch->name)) { -+ glob_otherchan = ch->name; -+ return SLONOTHERCHAN; -+ } -+#endif -+ } -+ add_seenreq(mask, nick, uhost, chan, now); -+ wild = 0; -+ l = findseen(mask); -+ // if there's a result, and if we don't want to search for the same user -+ // under a different nick, just make a do_seennick on the result -+ if (l && !fuzzy_search) { -+ tmp = do_seennick(l); -+ end_seentime_calc(); -+ return tmp; -+ } -+ if (!l) { -+ u = get_user_by_handle(userlist, mask); -+ if (u) { -+ li = get_user(&USERENTRY_LASTON, u); -+ } -+ if (!u || !li) { -+ if (bns == -1) { // if bns is 0, then do_seen() was triggered by -+ end_seentime_calc(); // a botnet seen function, which needs a clear -+ return NULL; // NULL to detect if there was a result or not -+ } -+ tmp = SLNOTSEEN; -+ if (bns && ((strlen(mask) + strlen(nick) + strlen(uhost) -+ + strlen(chan) + 20) < 255)) { -+ debug0("trying botnet seen"); -+ if (bnsnick) -+ nfree(bnsnick); -+ if (bnschan) -+ nfree(bnschan); -+ bnsnick = nmalloc(strlen(nick) + 1); -+ strcpy(bnsnick, nick); -+ bnschan = nmalloc(strlen(chan) + 1); -+ strcpy(bnschan, chan); -+ sprintf(bnquery, "gseen_req %s %s %s %s", mask, nick, uhost, chan); -+ botnet_send_zapf_broad(-1, botnetnick, NULL, bnquery); -+ } -+ } else { -+ // we have a matching handle, no seen-entry, but a laston entry -+ // in the userbase, so let's just return that one. -+ dur = gseen_duration(now - li->laston); -+ glob_laston = dur; -+ tmp = SLPOORSEEN; -+ seen_reply = nmalloc(strlen(tmp) + 1); -+ strcpy(seen_reply, tmp); -+ end_seentime_calc(); -+ return seen_reply; -+ } -+ end_seentime_calc(); -+ return tmp; -+ } -+ // now prepare the host for fuzzy-search -+ if (strlen(l->host) < UHOSTLEN) { -+ maskstricthost(l->host, host); -+ host = strchr(host, '!') + 1; // strip nick from host for faster search -+ } else { -+ end_seentime_calc(); -+ return "error, too long host"; -+ } -+ } -+ if (l && (l->type == SEEN_CHPT)) { -+ tmp = do_seennick(l); -+ end_seentime_calc(); -+ return tmp; -+ } -+ numresults = 0; -+ // wildmatch_seens uses a global var to store hosts in it -+ // (to prevent massive nmalloc/nfree-usage), so don't forget -+ // to initialize and free it -+ temp_wildmatch_host = my_malloc(1); -+ wildmatch_seens(host, mask, wild); -+ my_free(temp_wildmatch_host); -+ temp_wildmatch_host = NULL; -+ if (!results) { -+ end_seentime_calc(); -+ if (bns == -1) -+ return NULL; // let the botnet seen function know, that seen failed -+ return SLNOMATCH; -+ } -+ if (numresults >= max_matches) { -+ end_seentime_calc(); -+ free_seenresults(); -+ return SLTOOMANYMATCHES; -+ } -+ sortresults(); -+ if (strcasecmp(results->seen->nick, mask)) { -+ // if the user's latest nick is not the nick for which we were searching, -+ // say that there were multiple matches and display the latest one -+ if (numresults == 1) -+ tmp = SLONEMATCH; -+ else if (numresults <= 5) -+ tmp = SLLITTLEMATCHES; -+ else -+ tmp = SLMANYMATCHES; -+ seen_reply = nmalloc(strlen(tmp) + 1); -+ strcpy(seen_reply, tmp); -+ nr = 0; -+ for (r = results; (r && (nr < 5)); r = r->next) { -+ nr++; -+ if (nr > 1) { -+ seen_reply = nrealloc(seen_reply, 1 + strlen(seen_reply) + 1 + strlen(r->seen->nick) + 1); -+ strcat(seen_reply, ", "); -+ } else { -+ seen_reply = nrealloc(seen_reply, 1 + strlen(seen_reply) + strlen(r->seen->nick) + 1); -+ strcat(seen_reply, " "); -+ } -+ strcat(seen_reply, r->seen->nick); -+ } -+ tmp = do_seennick(results->seen); -+ seen_reply = nrealloc(seen_reply, 2 + strlen(seen_reply) + strlen(tmp) + 1); -+ sprintf(seen_reply, "%s. %s", seen_reply, tmp); -+ } else { // first result is the nick which we were searching for -+ // just return the info for this nick and don't care about other results -+ tmp = do_seennick(results->seen); -+ seen_reply = nmalloc(strlen(tmp) + 1); -+ strcpy(seen_reply, tmp); -+ } -+ free_seenresults(); -+ end_seentime_calc(); -+ return seen_reply; -+} -+ -+/* do_seennick(): -+ * takes a seen-dataset and produces the corresponding reply basically -+ * by referencing to the lang entry with the same number as the seen-type. -+ */ -+static char *do_seennick(seendat *l) -+{ -+// char buf[256], *msg; -+ int stype; -+ -+ Context; -+ if (!l) { -+ debug0("ERROR! Tryed to do a seennick on a NULL pointer!"); -+ return "ERROR! seendat == NULL!!!"; -+ } -+ glob_seendat = l; -+ // l->type is the basic language-entry-number -+ stype = l->type + 100; -+ // in some cases, we might need a special reply, so modify the -+ // number if neccessary -+ switch (l->type) { -+ case SEEN_JOIN: -+ if (!onchan(l->nick, l->chan)) -+ stype += 20; -+ break; -+ case SEEN_PART: -+ /* nothing to do here */ -+ break; -+ case SEEN_SIGN: -+ /* nothing again */ -+ break; -+ case SEEN_NICK: -+ if (!onchan(l->msg, l->chan)) -+ stype += 20; -+ break; -+ case SEEN_NCKF: -+ if (!onchan(l->nick, l->chan)) -+ stype += 20; -+ break; -+ case SEEN_KICK: -+/* msg = buf; -+ strncpy(buf, l->msg, 255); -+ msg[255] = 0; -+ sglobpunisher = newsplit(&msg); -+ sglobreason = msg; */ -+ break; -+ case SEEN_SPLT: -+ /* nothing to do here */ -+ break; -+ case SEEN_REJN: -+ if (!onchan(l->nick, l->chan)) -+ stype += 20; -+ break; -+ case SEEN_CHJN: -+ case SEEN_CHPT: -+ if (!strcmp(l->chan, "0")) -+ stype += 20; -+ break; -+ default: -+ stype = 140; -+ } -+ return getslang(stype); -+} -+ -+/* findseens(): -+ * interface for webseen.mod -+ * find all results for a query and return a pointer to this list -+ * (basically the core of do_seen()) -+ */ -+static gseenres *findseens(char *mask, int *ret, int fuzzy) -+{ -+ char hostbuf[UHOSTLEN + 1], *host, *newhost; -+ seendat *l; -+ int wild; -+ -+ Context; -+ start_seentime_calc(); -+ *ret = WS_OK; -+ l = NULL; -+ host = hostbuf; -+ newhost = NULL; -+ mask = newsplit(&mask); -+ while (mask[0] == ' ') -+ mask++; -+ if (!mask[0]) { -+ *ret = WS_NOPARAM; -+ return NULL; -+ } -+ if (strchr(mask, '?') || strchr(mask, '*')) { -+ // if wildcard-searches ares not allowed, then either return -+ // NULL (for botnet-seen), or a appropriate warning -+ if (!wildcard_search) { -+ *ret = WS_NOWILDCARDS; -+ return NULL; -+ } -+ wild = 1; -+ } else { -+ if (strlen(mask) > seen_nick_len) { // don't process if requested nick is too long -+ *ret = WS_TOOLONGNICK; // (e.g. stop stupid jokes) -+ return NULL; -+ } -+ add_seenreq(mask, "www-user", "unknown_host", "webinterface", now); -+ wild = 0; -+ l = findseen(mask); -+ // if there's a result, and if we don't want to search for the same user -+ // under a different nick, just return this result -+ if (l && (!fuzzy_search || !fuzzy)) { -+ numresults = 1; -+ add_seenresult(l); -+ end_seentime_calc(); -+ return results; -+ } -+ if (!l) { -+ // no matching user was found :( -+ *ret = WS_NORESULT; -+ end_seentime_calc(); -+ return NULL; -+ } -+ // now prepare the host for fuzzy-search -+ if (strlen(l->host) < UHOSTLEN) { -+ maskstricthost(l->host, host); -+ host = strchr(host, '!') + 1; // strip nick from host for faster search -+ } else { -+ *ret = WS_TOOLONGHOST; -+ end_seentime_calc(); -+ return NULL; -+ } -+ } -+ if (l && (l->type == SEEN_CHPT)) { -+ numresults = 1; -+ add_seenresult(l); -+ end_seentime_calc(); -+ return results; -+ } -+ numresults = 0; -+ // wildmatch_seens uses a global var to store hosts in it -+ // (to prevent massive nmalloc/nfree-usage), so don't forget -+ // to initialize and free it -+ temp_wildmatch_host = my_malloc(1); -+ wildmatch_seens(host, mask, wild); -+ my_free(temp_wildmatch_host); -+ temp_wildmatch_host = NULL; -+ if (!results) { -+ // no match :( -+ *ret = WS_NORESULT; -+ end_seentime_calc(); -+ return NULL; -+ } -+ if (numresults >= max_matches) { -+ free_seenresults(); -+ *ret = WS_TOOMANYMATCHES; -+ end_seentime_calc(); -+ return NULL; -+ } -+ sortresults(); -+ *ret = 0; -+ end_seentime_calc(); -+ return results; -+} -+ -+ -+char seenstats_reply[512]; -+static char *do_seenstats() -+{ -+ glob_totalnicks = count_seens(); -+ glob_totalbytes = gseen_expmem(); -+ sprintf(seenstats_reply, "%s", SLSEENSTATS); -+ return seenstats_reply; -+} -+ -+// add an seen result (to the top of the list) -+static void add_seenresult(seendat *seen) -+{ -+ gseenres *nl; -+ -+ numresults++; -+ if (numresults > max_matches) -+ return; -+ nl = nmalloc(sizeof(gseenres)); -+ nl->seen = seen; -+ nl->next = results; -+ results = nl; -+} -+ -+static int expmem_seenresults() -+{ -+ int bytes = 0; -+ gseenres *l; -+ -+ for (l = results; l; l = l->next) -+ bytes += sizeof(gseenres); -+ return bytes; -+} -+ -+static void free_seenresults() -+{ -+ gseenres *l, *ll; -+ -+ l = results; -+ while (l) { -+ ll = l->next; -+ nfree(l); -+ l = ll; -+ } -+ results = NULL; -+} -+ -+static void sortresults() -+{ -+ int again = 1; -+ gseenres *last, *p, *c, *n; -+ int a, b; -+ -+ Context; -+ again = 1; -+ last = NULL; -+ while ((results != last) && (again)) { -+ p = NULL; -+ c = results; -+ n = c->next; -+ again = 0; -+ while (n != last) { -+ if (!c || !n) -+ a = b = 0; -+ else -+ a = c->seen->when; -+ b = n->seen->when; -+ if (a < b) { -+ again = 1; -+ c->next = n->next; -+ n->next = c; -+ if (p == NULL) -+ results = n; -+ else -+ p->next = n; -+ } -+ p = c; -+ c = n; -+ n = n->next; -+ } -+ last = c; -+ } -+ Context; -+ return; -+} -+ -+static void sortrequests(seenreq *l) -+{ -+ int again = 1; -+ seenreq_by *last, *p, *c, *n; -+ int a, b; -+ -+ Context; -+ again = 1; -+ last = NULL; -+ while ((l->by != last) && (again)) { -+ p = NULL; -+ c = l->by; -+ n = c->next; -+ again = 0; -+ while (n != last) { -+ if (!c || !n) -+ a = b = 0; -+ else -+ a = c->when; -+ b = n->when; -+ if (a < b) { -+ again = 1; -+ c->next = n->next; -+ n->next = c; -+ if (p == NULL) -+ l->by = n; -+ else -+ p->next = n; -+ } -+ p = c; -+ c = n; -+ n = n->next; -+ } -+ last = c; -+ } -+ Context; -+ return; -+} -+ -+/* stolen from tcl_duration in tclmisc.c */ -+char gs_duration_temp[256]; -+static char *gseen_duration(int seconds) -+{ -+ char s[256]; -+ time_t sec; -+ -+ sec = seconds; -+ s[0] = 0; -+ if (sec < 1) { -+ snprintf(gs_duration_temp, sizeof(gs_duration_temp), "%s", SLSOMETIME); -+ return gs_duration_temp; -+ } -+ if (sec < 60) { -+ sprintf(gs_duration_temp, "%d %s", (int) (sec / 1), -+ ((int) (sec / 1) > 1) ? SLSECONDS : SLSECOND); -+ return gs_duration_temp; -+ } -+ if (sec >= 31536000) { -+ sprintf(s, "%d %s ", (int) (sec / 31536000), -+ ((int) (sec / 31536000) > 1) ? SLYEARS : SLYEAR); -+ sec -= (((int) (sec / 31536000)) * 31536000); -+ } -+ if (sec >= 604800) { -+ sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 604800), -+ ((int) (sec / 604800) > 1) ? SLWEEKS : SLWEEK); -+ sec -= (((int) (sec / 604800)) * 604800); -+ } -+ if (sec >= 86400) { -+ sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 86400), -+ ((int) (sec / 86400) > 1) ? SLDAYS : SLDAY); -+ sec -= (((int) (sec / 86400)) * 86400); -+ } -+ if (sec >= 3600) { -+ sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 3600), -+ ((int) (sec / 3600) > 1) ? SLHOURS : SLHOUR); -+ sec -= (((int) (sec / 3600)) * 3600); -+ } -+ if (sec >= 60) { -+ sprintf(&s[strlen(s)], "%d %s ", (int) (sec / 60), -+ ((int) (sec / 60) > 1) ? SLMINUTES : SLMINUTE); -+ sec -= (((int) (sec / 60)) * 60); -+ } -+ strcpy(gs_duration_temp, s); -+ if (gs_duration_temp[strlen(gs_duration_temp) - 1] == ' ') -+ gs_duration_temp[strlen(gs_duration_temp) - 1] = 0; -+ return gs_duration_temp; -+} -+ -+static int onchan(char *nick, char *chan) -+{ -+ struct chanset_t *ch; -+ memberlist *m; -+ -+ ch = findchan_by_dname(chan); -+ if (!ch) -+ return 0; -+ m = ismember(ch, nick); -+ if (!m) -+ return 0; -+ else if (chan_issplit(m)) -+ return 0; -+ else -+ return 1; -+} -+ -+/* handonchan(): -+ * checks if the given user is on the channel and returns its nick -+ */ -+static char *handonchan(char *hand, char *chan) -+{ -+ struct chanset_t *ch; -+ memberlist *m; -+ -+ ch = findchan_by_dname(chan); -+ if (!ch) -+ return 0; -+ if (ch->channel.members > 0) { -+ for (m = ch->channel.member; m; m = m->next) { -+ if (m->user) { -+ if (m->user->handle && !rfc_casecmp(m->user->handle, hand)) -+ return m->nick; -+ } -+ } -+ } -+ return NULL; -+} -+ -+/* onanychan(): -+ * checks if the given nickname is on any of the bot's chans. -+ */ -+static struct chanset_t *onanychan(char *nick) -+{ -+ struct chanset_t *ch; -+ memberlist *m; -+ -+ for (ch = chanset; ch; ch = ch->next) { -+ m = ismember(ch, nick); -+ if (m && !chan_issplit(m)) -+ return ch; -+ } -+ return NULL; -+} -+ -+/* handonanychan(): -+ * checks if the given user is on any channel (no matter under which nick) -+ */ -+static struct chanset_t *handonanychan(char *hand) -+{ -+ struct chanset_t *ch; -+ memberlist *m; -+ -+ for (ch = chanset; ch; ch = ch->next) { -+ if (ch->channel.members > 0) { -+ for (m = ch->channel.member; m; m = m->next) { -+ if (m->user) { -+ if (m->user->handle && !rfc_casecmp(m->user->handle, hand)) -+ return ch; -+ } -+ } -+ } -+ } -+ return NULL; -+} -+ -+static void add_seenreq(char *nick, char *from, char *host, char *chan, -+ time_t when) -+{ -+ seenreq *l, *nl; -+ seenreq_by *b, *nb; -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (!tell_seens) -+ return; -+ if (strcmp(chan, "[partyline]") && secretchan(chan)) -+ chan = buf; -+ for (l = requests; l; l = l->next) { -+ if (!strcasecmp(nick, l->nick)) { -+ for (b = l->by; b; b = b->next) { -+ if (!strcasecmp(from, b->who)) { -+ nfree(b->chan); -+ b->chan = nmalloc(strlen(chan) + 1); -+ strcpy(b->chan, chan); -+ b->when = when; -+ return; -+ } -+ } -+ b = l->by; -+ while (b && b->next) -+ b = b->next; -+ nb = nmalloc(sizeof(seenreq_by)); -+ nb->who = nmalloc(strlen(from) + 1); -+ strcpy(nb->who, from); -+ nb->host = nmalloc(strlen(host) + 1); -+ strcpy(nb->host, host); -+ nb->chan = nmalloc(strlen(chan) + 1); -+ strcpy(nb->chan, chan); -+ nb->when = when; -+ nb->next = NULL; -+ if (l->by) -+ b->next = nb; -+ else -+ l->by = nb; -+ return; -+ } -+ } -+ nb = nmalloc(sizeof(seenreq_by)); -+ nb->who = nmalloc(strlen(from) + 1); -+ strcpy(nb->who, from); -+ nb->host = nmalloc(strlen(host) + 1); -+ strcpy(nb->host, host); -+ nb->chan = nmalloc(strlen(chan) + 1); -+ strcpy(nb->chan, chan); -+ nb->when = when; -+ nb->next = NULL; -+ l = requests; -+ while (l && l->next) -+ l = l->next; -+ nl = nmalloc(sizeof(seenreq)); -+ nl->nick = nmalloc(strlen(nick) + 1); -+ strcpy(nl->nick, nick); -+ nl->by = nb; -+ nl->next = NULL; -+ if (requests) -+ l->next = nl; -+ else -+ requests = nl; -+} -+ -+static int expmem_seenreq() -+{ -+ seenreq *l; -+ seenreq_by *b; -+ int size; -+ -+ size = 0; -+ for (l = requests; l; l = l->next) { -+ size += sizeof(seenreq); -+ size += strlen(l->nick) + 1; -+ for (b = l->by; b; b = b->next) { -+ size += sizeof(seenreq_by); -+ size += strlen(b->who) + 1; -+ size += strlen(b->host) + 1; -+ size += strlen(b->chan) + 1; -+ } -+ } -+ return size; -+} -+ -+static int count_seenreq(seenreq_by *b) -+{ -+ seenreq_by *l; -+ int nr; -+ -+ nr = 0; -+ for (l = b; l; l = l->next) -+ nr++; -+ return nr; -+} -+ -+static void free_seenreq() -+{ -+ seenreq *l, *ll; -+ seenreq_by *b, *bb; -+ -+ Context; -+ l = requests; -+ while (l) { -+ b = l->by; -+ while (b) { -+ bb = b->next; -+ nfree(b->who); -+ nfree(b->host); -+ nfree(b->chan); -+ nfree(b); -+ b = bb; -+ } -+ ll = l->next; -+ nfree(l->nick); -+ nfree(l); -+ l = ll; -+ } -+ requests = NULL; -+} -+ -+static void report_seenreq(char *channel, char *nick) -+{ -+ seenreq *l, *ll; -+ seenreq_by *b, *bb; -+ char *reply, *tmp; -+ int nr; -+ -+ if (!tell_seens) -+ return; -+ ll = NULL; -+ l = requests; -+ reply = NULL; -+ while (l) { -+ if (!strcasecmp(l->nick, nick)) { -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); -+ glob_nick = nick; -+ nr = count_seenreq(l->by); -+ if (nr == 1) { -+ glob_seenrequest = l; -+ dprintf(DP_HELP, "NOTICE %s :%s\n", l->nick, SLONELOOK); -+ } else { -+ sortrequests(l); -+ glob_seenrequest = l; -+ glob_seenrequests = nr; -+ tmp = SLMORELOOKS; -+ reply = nmalloc(strlen(tmp) + 1); -+ strcpy(reply, tmp); -+ nr = 0; -+ for (b = l->by; b; b = b->next) { -+ nr++; -+ reply = nrealloc(reply, strlen(reply) + ((nr == 1) ? 1 : 2) + strlen(b->who) + 1); -+ sprintf(reply, "%s%s%s", reply, (nr == 1) ? " " : ", ", b->who); -+ } -+ tmp = SLLASTLOOK; -+ reply = nrealloc(reply, strlen(reply) + 2 + strlen(tmp) + 1); -+ sprintf(reply, "%s. %s", reply, tmp); -+ dprintf(DP_HELP, "NOTICE %s :%s\n", l->nick, reply); -+ nfree(reply); -+ } -+ b = l->by; -+ while (b) { -+ bb = b->next; -+ nfree(b->who); -+ nfree(b->host); -+ nfree(b->chan); -+ nfree(b); -+ b = bb; -+ } -+ nfree(l->nick); -+ if (ll) -+ ll->next = l->next; -+ else -+ requests = l->next; -+ nfree(l); -+ if (ll) -+ l = ll->next; -+ else -+ l = requests; -+ } else { -+ ll = l; -+ l = l->next; -+ } -+ } -+} -+ -+static void start_seentime_calc() -+{ -+ struct timeval t; -+ -+ gettimeofday(&t, NULL); -+ glob_presearch = (float) t.tv_sec + (((float) t.tv_usec) / 1000000); -+} -+ -+static void end_seentime_calc() -+{ -+ struct timeval t; -+ -+ gettimeofday(&t, NULL); -+ glob_aftersearch = (float) t.tv_sec + (((float) t.tv_usec) / 1000000); -+ glob_total_searchtime += glob_aftersearch - glob_presearch; -+ glob_total_queries++; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/generic_binary_tree.c src/eggdrop-1.8.4/src/mod/gseen.mod/generic_binary_tree.c ---- ./src/mod/gseen.mod/generic_binary_tree.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/generic_binary_tree.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,311 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define GENERIC_BINARY_TREE 1 -+ -+struct generic_binary_tree { -+ void *root; -+ int (*comparedata) (void *data1, void *data2); -+ int (*expmemdata) (void *data); -+ void (*freedata) (void *data); -+}; -+ -+struct generic_binary_tree_node { -+ void *data; -+ void *left; -+ void *right; -+}; -+ -+static void btree_add(struct generic_binary_tree *, void *); -+static int btree_expmem(struct generic_binary_tree *); -+static int btree_recursive_expmem(struct generic_binary_tree *, struct generic_binary_tree_node *); -+static void *btree_get(struct generic_binary_tree *, void *t); -+static void btree_freetree(struct generic_binary_tree *); -+static void btree_recursive_free(struct generic_binary_tree *, -+ struct generic_binary_tree_node *); -+static void btree_getall(struct generic_binary_tree *, void (*) (void *)); -+static void btree_recursive_getall(struct generic_binary_tree_node *, -+ void (*) (void *)); -+static void btree_getall_expanded(struct generic_binary_tree *tree, void (*) (void *)); -+static void btree_recursive_getall_expanded(struct generic_binary_tree_node *, -+ void (*) (void *)); -+static void btree_remove(struct generic_binary_tree *, void *); -+ -+static void btree_add(struct generic_binary_tree *tree, void *data) -+{ -+ struct generic_binary_tree_node *node, *lastnode; -+ int cmp, lastcmp; -+ -+ Assert(tree); -+ Assert(data); -+ cmp = lastcmp = 0; -+ node = tree->root; -+ lastnode = NULL; -+ while (node) { -+ cmp = tree->comparedata(node->data, data); -+ if (!cmp) { -+ // item is identical -> free old data and insert new -+ tree->freedata(node->data); -+ node->data = data; -+ return; -+ } -+ lastnode = node; -+ lastcmp = cmp; -+ if (cmp < 0) -+ node = node->left; -+ else -+ node = node->right; -+ } -+ node = nmalloc(sizeof(struct generic_binary_tree_node)); -+ node->left = NULL; -+ node->right = NULL; -+ node->data = data; -+ if (!lastnode) -+ tree->root = node; -+ else { -+ Assert(lastcmp); -+ if (lastcmp < 0) { -+ Assert(!lastnode->left); -+ lastnode->left = node; -+ } else { -+ Assert(!lastnode->right); -+ lastnode->right = node; -+ } -+ } -+} -+ -+static int btree_expmem(struct generic_binary_tree *tree) -+{ -+ int size = 0; -+ -+ Assert(tree); -+ size += btree_recursive_expmem(tree, tree->root); -+ return size; -+} -+ -+static int btree_recursive_expmem(struct generic_binary_tree *tree, struct generic_binary_tree_node *node) -+{ -+ int size = 0; -+ -+ if (!node) -+ return 0; -+ size += sizeof(struct generic_binary_tree_node); -+ size += tree->expmemdata(node->data); -+ size += btree_recursive_expmem(tree, node->left); -+ size += btree_recursive_expmem(tree, node->right); -+ return size; -+} -+ -+static void *btree_get(struct generic_binary_tree *tree, void *what) -+{ -+ struct generic_binary_tree_node *node; -+ int cmp; -+ -+ node = tree->root; -+ while (node) { -+ cmp = tree->comparedata(node->data, what); -+ if (!cmp) -+ return node->data; -+ if (cmp < 0) -+ node = node->left; -+ else -+ node = node->right; -+ } -+ return NULL; -+} -+ -+static void btree_freetree(struct generic_binary_tree *tree) -+{ -+ btree_recursive_free(tree, tree->root); -+} -+ -+static void btree_recursive_free(struct generic_binary_tree *tree, -+ struct generic_binary_tree_node *node) -+{ -+ if (!node) -+ return; -+ btree_recursive_free(tree, node->left); -+ btree_recursive_free(tree, node->right); -+ tree->freedata(node->data); -+ nfree(node); -+} -+ -+/* btree_getall(): -+ * calls the specified function for each item in the tree. -+ * NOTE: getall() calls the proc _before_ it proceeds into recursion. This way, -+ * one can savely store the tree into a file without mixing up its form. -+ * But if you delete an item from the called prcedure, this function -+ * WILL crash. Use btree_getall() expanded instead. -+ */ -+static void btree_getall(struct generic_binary_tree *tree, void (*func) (void *)) -+{ -+ Assert(tree); -+ btree_recursive_getall(tree->root, func); -+} -+ -+static void btree_recursive_getall(struct generic_binary_tree_node *node, -+ void (*func) (void *)) -+{ -+ if (!node) -+ return; -+ // first call the function, then proceed into recursion -+ // this way, the tree keeps in form if its saved to a file, for example -+ Assert(func); -+ func(node->data); -+ -+ btree_recursive_getall(node->left, func); -+ btree_recursive_getall(node->right, func); -+} -+ -+/* btree_getall_expanded(): -+ * the same as btree_getall(), but calls the function after the greatest level of recursion -+ * has been reached. The node-pointers won't be accessed anymore when the first function -+ * gets called. You can savely use this to free items. -+ */ -+static void btree_getall_expanded(struct generic_binary_tree *tree, void (*func) (void *)) -+{ -+ Assert(tree); -+ btree_recursive_getall_expanded(tree->root, func); -+} -+ -+static void btree_recursive_getall_expanded(struct generic_binary_tree_node *node, -+ void (*func) (void *)) -+{ -+ if (!node) -+ return; -+ btree_recursive_getall_expanded(node->left, func); -+ btree_recursive_getall_expanded(node->right, func); -+ -+ Assert(func); -+ func(node->data); -+} -+ -+static void btree_remove(struct generic_binary_tree *tree, void *data) -+{ -+ struct generic_binary_tree_node *node, *last, *largenode, *lastlarge; -+ int ret, lastret; -+ -+ Assert(tree); -+ Assert(data); -+ last = NULL; -+ lastret = 0; -+ node = tree->root; -+ while (node) { -+ ret = tree->comparedata(node->data, data); -+ if (ret == 0) -+ break; -+ last = node; -+ lastret = ret; -+ if (ret < 0) -+ node = node->left; -+ else -+ node = node->right; -+ } -+ if (!node) // oops, item not found -+ return; -+ if (!node->left && !node->right) { -+ // *freu* no sub-branches! We can easily delete this item. -+ if (last) { -+ if (lastret < 0) -+ last->left = NULL; -+ else -+ last->right = NULL; -+ } else -+ tree->root = NULL; -+ } else if (!node->left) { -+ // also pretty easy. Just connect the child to the parent. -+ if (last) { -+ if (lastret < 0) -+ last->left = node->right; -+ else -+ last->right = node->right; -+ } else -+ tree->root = node->right; -+ } else if (!node->right) { -+ // same as above, but mirrored -+ if (last) { -+ if (lastret < 0) -+ last->left = node->left; -+ else -+ last->right = node->left; -+ } else -+ tree->root = node->left; -+ } else { -+ // aaargh... two sub-trees! The world is not fair... *sigh* -+ debug0("argl... worst case, two subtrees. :( Let's pray..."); -+ // now we take the largest item from the left subtree and replace the -+ // doomed node with it. -+ // since it is the largest val, the tree remains valid and doesn't -+ // get deformed too much. -+ -+ // at first, we have to find this node and cut it from the tree -+ largenode = node->left; -+ lastlarge = NULL; -+ while (largenode && largenode->right) { -+ lastlarge = largenode; -+ largenode = largenode->right; -+ } -+ -+ // only set largenode->left to node->left if largenode exists. -+ // otherwise node->left points to largenode, which would result -+ // in a nice short-circuit -+ // If it does not exist, just leave largenode->left as it is because we just -+ // move largenode one level up, so it can keep its left subtree. -+ if (lastlarge) { -+ lastlarge->right = largenode->left; -+ largenode->left = node->left; -+ } -+ -+ // now connect node's subtrees to it -+ largenode->right = node->right; -+ -+ // and finally replace node with largenode -+ if (last) { -+ if (lastret < 0) -+ last->left = largenode; -+ else -+ last->right = largenode; -+ } else -+ tree->root = largenode; -+ } -+ // finally kill the node... we shouldn't need it anymore -+ tree->freedata(node->data); -+ nfree(node); -+ node = NULL; -+} -+ -+#ifdef BTREE_WITHOPTIMIZE -+static void btree_optimize(struct generic_binary_tree *tree, -+ struct generic_binary_tree_node *node, -+ struct generic_binary_tree_node *last, -+ int limit) -+{ -+/* int leftdepth, rightdepth; -+ -+ if (!node) -+ return; -+ btree_optimize(tree, node->left, node, last, limit); -+ btree_optimize(tree, node->right, node, last, limit); -+ leftdepth = btree_depth(node->left); -+ rightdepth = btree_depth(node->right); -+ if ((leftdepth - rightdepth) > limit) { -+ -+ } -+*/ -+} -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/global_vars.c src/eggdrop-1.8.4/src/mod/gseen.mod/global_vars.c ---- ./src/mod/gseen.mod/global_vars.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/global_vars.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static char *glob_query, *glob_laston, *glob_otherchan, *glob_othernick; -+static char *glob_remotebot, *glob_nick; -+static struct slang_header *glob_slang; -+static seendat *glob_seendat; -+static seenreq *glob_seenrequest; -+static int glob_seenrequests, glob_totalnicks, glob_totalbytes; -+ -+static void reset_global_vars() -+{ -+ glob_query = glob_laston = glob_otherchan = glob_othernick = NULL; -+ glob_remotebot = glob_nick = NULL; -+ glob_seendat = NULL; -+ glob_slang = NULL; -+ glob_seenrequest = NULL; -+ glob_seenrequests = glob_totalnicks = glob_totalbytes = 0; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseen.c src/eggdrop-1.8.4/src/mod/gseen.mod/gseen.c ---- ./src/mod/gseen.mod/gseen.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/gseen.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,330 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define MAKING_GSEEN -+#define MODULE_NAME "gseen" -+#define MODULE_VERSION "1.1.2" -+#define MODULE_NUMVERSION 10100 -+#include "../module.h" -+#include "../irc.mod/irc.h" -+#include "../server.mod/server.h" -+#include "../channels.mod/channels.h" -+#include -+#include -+#include /* for time_t */ -+ -+#undef global -+static Function *global = NULL, *irc_funcs = NULL, *server_funcs = NULL, *channels_funcs = NULL; -+ -+#ifndef EGG_IS_MIN_VER -+#define EGG_IS_MIN_VER(ver) ((ver) <= 10400) -+#endif -+ -+#ifndef EGG_IS_MAX_VER -+#define EGG_IS_MAX_VER(ver) ((ver) >= 10400) -+#endif -+ -+#ifndef Context -+#define Context context -+#endif -+ -+#ifndef findchan_by_dname -+#define findchan_by_dname findchan -+#endif -+ -+#include "gseen.h" -+#include "seenlang.h" -+ -+static struct slang_header *coreslangs = NULL; -+static gseenres *results = NULL; -+static seenreq *requests = NULL; -+static ignoredword *ignoredwords = NULL; -+static char *bnsnick = NULL; -+static char *bnschan = NULL; -+static char *seen_reply = NULL; -+static char *temp_wildmatch_host; -+static int numresults = 0; -+static double glob_presearch, glob_aftersearch; -+int numseens, glob_total_queries; -+double glob_total_searchtime; -+ -+static char gseenfile[121] = "gseen.dat"; -+static char no_pub[121]; -+static char quiet_seen[121]; -+static char quiet_ai_seen[121]; -+static char no_log[121]; -+static char ignore_words[1024]; -+static char default_slang[21] = "eng"; -+static int gseen_numversion = MODULE_NUMVERSION; -+static int save_seens = 60; -+static int save_seens_temp = 1; -+static int expire_seens = 60; -+static int maxseen_thr = 0; -+static int maxseen_time = 0; -+static int seenflood_thr = 0; -+static time_t seenflood_time = 0; -+static int use_handles = 0; -+static int tell_seens = 1; -+static int botnet_seen = 1; -+int fuzzy_search = 1; // search for the same user under a differnt nick -+static int wildcard_search = 1;// allow wildcard seaching? ("*!*@*.isp.de") -+static int max_matches = 500; // break if there are more than X matches -+static int hide_secret_chans = 1; // #chan (+secret) => [secret] -+static int seen_nick_len = 9; -+ -+#include "global_vars.c" -+#define SLANG_NOTYPES 1 -+#define SLANG_NOFACTS 1 -+#define SLANG_NOGETALL 1 -+#define SLANG_NOVALIDATE 1 -+#include "slang.c" -+#include "slang_gseen_commands.c" -+#include "generic_binary_tree.c" -+#include "seentree.c" -+#include "datahandling.c" -+#include "sensors.c" -+#include "do_seen.c" -+#include "gseencmds.c" -+#include "ai.c" -+#include "misc.c" -+#include "tclcmds.c" -+ -+static int gseen_expmem() -+{ -+ int size = 0; -+ -+ size += seentree_expmem(); -+ size += expmem_seenresults(); -+ size += expmem_seenreq(); -+ size += expmem_ignoredwords(); -+ size += slang_expmem(coreslangs); -+ size += slang_glob_expmem(); -+ size += slang_chanlang_expmem(chanlangs); -+ if (bnsnick) -+ size += strlen(bnsnick) + 1; -+ if (bnschan) -+ size += strlen(bnschan) + 1; -+ if (seen_reply) { -+ size += strlen(seen_reply) + 1; -+ } -+ return size; -+} -+ -+static void free_gseen() -+{ -+ seentree_free(); -+ slang_free(coreslangs); -+ slang_chanlang_free(chanlangs); -+ if (seen_reply) -+ nfree(seen_reply); -+ return; -+} -+ -+/* a report on the module status */ -+static void gseen_report(int idx, int details) -+{ -+ int size = 0; -+ -+ Context; -+ if (details) { -+ size = gseen_expmem(); -+ dprintf(idx, " using %d bytes\n", size); -+ } -+} -+ -+static void gseen_minutely () -+{ -+ if (save_seens_temp >= save_seens) { -+ write_seens(); -+ save_seens_temp = 1; -+ } else -+ save_seens_temp++; -+} -+ -+static void gseen_daily () -+{ -+ Context; -+ purge_seens(); -+} -+ -+static tcl_strings my_tcl_strings[] = -+{ -+ {"gseenfile", gseenfile, 121, 0}, -+ {"ai-seen-ignore", ignore_words, 1024, 0}, -+ {"no-pub-seens", no_pub, 121, 0}, -+ {"quiet-seens", quiet_seen, 121, 0}, -+ {"quiet-ai-seens", quiet_ai_seen, 121, 0}, -+ {"no-log", no_log, 121, 0}, -+ {"no-seendata", no_log, 121, 0}, -+ {"default-slang", default_slang, 20, 0}, -+ {0, 0, 0, 0} -+}; -+ -+static tcl_ints my_tcl_ints[] = -+{ -+ {"save-seens", &save_seens, 0}, -+ {"expire-seens", &expire_seens, 0}, -+ {"use-handles", &use_handles, 0}, -+ {"tell-seens", &tell_seens, 0}, -+ {"botnet-seens", &botnet_seen, 0}, -+ {"max-matches", &max_matches, 0}, -+ {"fuzzy-search", &fuzzy_search, 0}, -+ {"wildcard-search", &wildcard_search, 0}, -+ {"hide-secret-chans", &hide_secret_chans, 0}, -+ {"seen-nick-len", &seen_nick_len, 0}, -+ {0, 0, 0} -+}; -+ -+static tcl_coups my_tcl_coups[] = -+{ -+ {"max-seens", &maxseen_thr, &maxseen_time}, -+ {0, 0, 0}, -+}; -+ -+static char *gseen_close() -+{ -+ Context; -+ write_seens(); -+ slang_glob_free(); -+ free_gseen(); -+ free_seenreq(); -+ free_seenresults(); -+ free_ignoredwords(); -+ if (bnsnick) -+ nfree(bnsnick); -+ if (bnschan) -+ nfree(bnschan); -+ rem_tcl_strings(my_tcl_strings); -+ rem_tcl_ints(my_tcl_ints); -+ rem_tcl_coups(my_tcl_coups); -+ rem_tcl_commands(mytcls); -+ rem_tcl_commands(gseentcls); -+ rem_tcl_commands(seendebugtcls); -+ rem_tcl_commands(gseentcls); -+ rem_builtins(H_dcc, mydcc); -+ rem_builtins(H_join, seen_join); -+ rem_builtins(H_kick, seen_kick); -+ rem_builtins(H_nick, seen_nick); -+ rem_builtins(H_part, seen_part); -+ rem_builtins(H_sign, seen_sign); -+ rem_builtins(H_splt, seen_splt); -+ rem_builtins(H_rejn, seen_rejn); -+ rem_builtins(H_pub, seen_pub); -+ rem_builtins(H_msg, seen_msg); -+ rem_builtins(H_bot, seen_bot); -+ del_hook(HOOK_MINUTELY, (Function) gseen_minutely); -+ del_hook(HOOK_DAILY, (Function) gseen_daily); -+ module_undepend(MODULE_NAME); -+ return NULL; -+} -+ -+char *gseen_start(); -+ -+static Function gseen_table[] = -+{ -+ (Function) gseen_start, -+ (Function) gseen_close, -+ (Function) gseen_expmem, -+ (Function) gseen_report, -+ /* 4 - 7 */ -+ (Function) findseens, -+ (Function) free_seenresults, -+ (Function) gseen_duration, -+ (Function) & glob_seendat, -+ (Function) & numresults, -+ (Function) & fuzzy_search, -+ (Function) & numseens, -+ (Function) & glob_total_queries, -+ (Function) & glob_total_searchtime, -+ (Function) & gseen_numversion, -+}; -+ -+char *gseen_start(Function * global_funcs) -+{ -+ global = global_funcs; -+ Context; -+ module_register(MODULE_NAME, gseen_table, 1, 1); -+ if (!(irc_funcs = module_depend(MODULE_NAME, "irc", 1, 0))) -+ return "You need the irc module to use the gseen module."; -+ if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0))) -+ return "You need the server module to use the gseen module."; -+ if (!(channels_funcs = module_depend(MODULE_NAME, "channels", 1, 0))) -+ return "You need the channels module to use the gseen module."; -+ if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) { -+ if (!module_depend(MODULE_NAME, "eggdrop", 107, 0)) { -+ if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { -+ if (!module_depend(MODULE_NAME, "eggdrop", 105, 0)) { -+ if (!module_depend(MODULE_NAME, "eggdrop", 104, 0)) { -+ module_undepend(MODULE_NAME); -+ return "This module requires eggdrop1.4.0 or later"; -+ } -+ } -+ } -+ } -+ } -+ chanlangs = NULL; -+ coreslangs = NULL; -+ slang_glob_init(); -+ -+ results = NULL; -+ requests = NULL; -+ ignoredwords = NULL; -+ bnsnick = NULL; -+ bnschan = NULL; -+ seen_reply = NULL; -+ -+ numresults = 0; -+ numseens = 0; -+ glob_total_queries = 0; -+ glob_total_searchtime = 0.0; -+ ignore_words[0] = 0; -+ no_pub[0] = 0; -+ quiet_seen[0] = 0; -+ no_log[0] = 0; -+ seentree_init(); -+ add_tcl_strings(my_tcl_strings); -+ add_tcl_ints(my_tcl_ints); -+ add_tcl_coups(my_tcl_coups); -+ add_tcl_commands(mytcls); -+ add_tcl_commands(seendebugtcls); -+ add_tcl_commands(gseentcls); -+ add_builtins(H_dcc, mydcc); -+ add_builtins(H_join, seen_join); -+ add_builtins(H_kick, seen_kick); -+ add_builtins(H_nick, seen_nick); -+ add_builtins(H_part, seen_part); -+ add_builtins(H_sign, seen_sign); -+ add_builtins(H_sign, seen_sign); -+ add_builtins(H_splt, seen_splt); -+ add_builtins(H_rejn, seen_rejn); -+ add_builtins(H_pub, seen_pub); -+ add_builtins(H_msg, seen_msg); -+ add_builtins(H_bot, seen_bot); -+ read_seens(); -+ add_hook(HOOK_MINUTELY, (Function) gseen_minutely); -+ add_hook(HOOK_DAILY, (Function) gseen_daily); -+#if EGG_IS_MIN_VER(10503) -+ initudef(1, "noseendata", 1); -+ initudef(1, "quietseens", 1); -+ initudef(1, "quietaiseens", 1); -+ initudef(1, "nopubseens", 1); -+#endif -+ glob_slang_cmd_list = slang_commands_list_add(glob_slang_cmd_list, slang_text_gseen_command_table); -+ putlog(LOG_MISC, "*", "gseen.mod v%s loaded.", MODULE_VERSION); -+ return NULL; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseencmds.c src/eggdrop-1.8.4/src/mod/gseen.mod/gseencmds.c ---- ./src/mod/gseen.mod/gseencmds.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/gseencmds.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,420 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define PREFIX_LENGTH 20 -+ -+static char reply_prefix[PREFIX_LENGTH + 1]; -+#define set_prefix(x) strncpy(reply_prefix, x, PREFIX_LENGTH); \ -+ reply_prefix[PREFIX_LENGTH] = 0; -+ -+static int seenflood() -+{ -+ if (!maxseen_thr || !maxseen_time) -+ return 0; -+ if ((now - seenflood_time) > maxseen_time) { -+ seenflood_time = now; -+ seenflood_thr = 0; -+ } -+ seenflood_thr++; -+ if (seenflood_thr > maxseen_thr) -+ return 1; -+ else -+ return 0; -+} -+ -+static int nopub(char *chan) -+{ -+ char buf[121], *b; -+ -+ Context; -+ strncpy(buf, no_pub, 120); -+ buf[120] = 0; -+ b = buf; -+ while (b[0]) -+ if (!strcasecmp(chan, newsplit(&b))) -+ return 1; -+#if EGG_IS_MIN_VER(10503) -+ if (ngetudef("nopubseens", chan)) -+ return 1; -+#endif -+ return 0; -+} -+ -+static int quietseen(char *chan) -+{ -+ char buf[121], *b; -+ -+ Context; -+ strncpy(buf, quiet_seen, 120); -+ buf[120] = 0; -+ b = buf; -+ while (b[0]) -+ if (!strcasecmp(chan, newsplit(&b))) -+ return 1; -+#if EGG_IS_MIN_VER(10503) -+ if (ngetudef("quietseens", chan)) -+ return 1; -+#endif -+ return 0; -+} -+ -+static int cmd_seen(struct userrec *u, int idx, char *par) -+{ -+ char *query; -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, default_slang); -+ glob_nick = dcc[idx].nick; -+ query = newsplit(&par); -+ glob_query = query; -+ set_prefix(SLDCCPREFIX); -+ putlog(LOG_CMDS, "*", "#%s# seen %s", dcc[idx].nick, par); -+ dprintf(idx, "%s%s\n", reply_prefix, do_seen(query, dcc[idx].nick, -+ dcc[idx].host, "[partyline]", botnet_seen)); -+ return 0; -+} -+ -+static int cmd_seenstats(struct userrec *u, int idx, char *par) -+{ -+ Context; -+ if (seenflood()) -+ return 0; -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, default_slang); -+ glob_nick = dcc[idx].nick; -+ set_prefix(SLDCCPREFIX); -+ putlog(LOG_CMDS, "*", "#%s# seenstats", dcc[idx].nick); -+ dprintf(idx, "%s%s\n", reply_prefix, do_seenstats()); -+ return 0; -+} -+ -+static int cmd_purgeseens(struct userrec *u, int idx, char *par) -+{ -+ Context; -+ purge_seens(); -+ putlog(LOG_CMDS, "*", "#%s# purgeseens", dcc[idx].nick); -+ return 0; -+} -+ -+static int pub_seen(char *nick, char *host, char *hand, -+ char *channel, char *text) -+{ -+ char *dest; -+#if EGG_IS_MIN_VER(10500) -+ struct chanset_t *chan; -+#endif -+ -+ Context; -+ if (seenflood() || nopub(channel)) -+ return 0; -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); -+ glob_nick = nick; -+ putlog(LOG_CMDS, "*", "<<%s>> !%s! seen %s", nick, hand, text); -+ if (quietseen(channel)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, -+ do_seen(newsplit(&text), nick, host, channel, botnet_seen)); -+ return 0; -+ } -+#if EGG_IS_MIN_VER(10500) -+ chan = findchan_by_dname(channel); -+ if (chan) -+ dest = chan->name; -+ else -+ dest = channel; -+#else -+ dest = channel; -+#endif -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, -+ do_seen(newsplit(&text), nick, host, channel, botnet_seen)); -+ return 0; -+} -+ -+static int pub_seenstats(char *nick, char *host, char *hand, -+ char *channel, char *text) -+{ -+ char *dest; -+#if EGG_IS_MIN_VER(10500) -+ struct chanset_t *chan; -+#endif -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ if (nopub(channel)) -+ return 0; -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); -+ glob_nick = nick; -+ putlog(LOG_CMDS, "*", "<<%s>> !%s! seenstats", nick, hand); -+ if (quietseen(channel)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, do_seenstats()); -+ return 0; -+ } -+#if EGG_IS_MIN_VER(10500) -+ chan = findchan_by_dname(channel); -+ if (chan) -+ dest = chan->name; -+ else -+ dest = channel; -+#else -+ dest = channel; -+#endif -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, do_seenstats()); -+ return 1; -+} -+ -+static int msg_seen(char *nick, char *uhost, struct userrec *u, char *text) -+{ -+ Context; -+ if (seenflood()) -+ return 0; -+ reset_global_vars(); -+ glob_slang = slang_getbynick(coreslangs, nick); -+ glob_nick = nick; -+ putlog(LOG_CMDS, "*", "(%s!%s) !%s! seen %s", nick, uhost, u ? u->handle : "*", text); -+ set_prefix(SLMSGPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", nick, reply_prefix, -+ do_seen(newsplit(&text), nick, uhost, "[/msg]", botnet_seen)); -+ return 1; -+} -+ -+static int pub_seennick(char *nick, char *host, char *hand, -+ char *channel, char *text) -+{ -+ seendat *l; -+ char *dest; -+#if EGG_IS_MIN_VER(10500) -+ struct chanset_t *chan; -+#endif -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ if (nopub(channel)) -+ return 0; -+ putlog(LOG_CMDS, "*", "<<%s>> !%s! seennick %s", nick, hand, text); -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); -+ glob_nick = nick; -+#if EGG_IS_MIN_VER(10500) -+ chan = findchan_by_dname(channel); -+ if (chan) -+ dest = chan->name; -+ else -+ dest = channel; -+#else -+ dest = channel; -+#endif -+ text = newsplit(&text); -+ l = findseen(text); -+ if (!l) { -+ glob_query = text; -+ if (quietseen(channel)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, SLNOTSEEN); -+ } else { -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, SLNOTSEEN); -+ } -+ return 0; -+ } -+ if (quietseen(channel)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, do_seennick(l)); -+ } else { -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, do_seennick(l)); -+ } -+ return 0; -+} -+ -+static int msg_seennick(char *nick, char *uhost, struct userrec *u, char *text) -+{ -+ seendat *l; -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ putlog(LOG_CMDS, "*", "(%s!%s) !%s! seennick %s", nick, uhost, u ? u->handle : "*", text); -+ reset_global_vars(); -+ glob_slang = slang_getbynick(coreslangs, nick); -+ glob_nick = nick; -+ set_prefix(SLMSGPREFIX); -+ text = newsplit(&text); -+ l = findseen(text); -+ if (!l) { -+ glob_query = text; -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", nick, reply_prefix, SLNOTSEEN); -+ return 0; -+ } -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", nick, reply_prefix, do_seennick(l)); -+ return 0; -+} -+ -+static int cmd_seennick(struct userrec *u, int idx, char *text) -+{ -+ seendat *l; -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ putlog(LOG_CMDS, "*", "#%s# seennick %s", dcc[idx].nick, text); -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, default_slang); -+ glob_nick = dcc[idx].nick; -+ set_prefix(SLMSGPREFIX); -+ text = newsplit(&text); -+ l = findseen(text); -+ if (!l) { -+ glob_query = text; -+ dprintf(idx, "%s%s\n", reply_prefix, SLNOTSEEN); -+ return 0; -+ } -+ dprintf(idx, "%s%s\n", reply_prefix, do_seennick(l)); -+ return 0; -+} -+ -+static int bot_gseen_req(char *bot, char *code, char *par) -+{ -+ char *mask, *nick, *uhost, *chan, *reply; -+ char tosend[256]; -+ int i; -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ i = nextbot(bot); -+ if (i < 0) { -+ debug1("Couldn't answer botnet-seen-request from %s: no such bot", bot); -+ return 0; -+ } -+ mask = newsplit(&par); -+ nick = newsplit(&par); -+ uhost = newsplit(&par); -+ chan = newsplit(&par); -+ reset_global_vars(); -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, chan)); -+ glob_nick = nick; -+ reply = do_seen(mask, nick, uhost, chan, -1); -+ if (!reply) -+ return 0; -+ if ((strlen(nick) + strlen(chan) + strlen(reply)) < 255) { -+ sprintf(tosend, "gseen_rep %s %s %s", nick, chan, reply); -+ botnet_send_zapf(i, botnetnick, bot, tosend); -+ } -+ return 0; -+} -+ -+static int bot_gseen_rep(char *bot, char *code, char *par) -+{ -+ char *nick, *chan, *reply; -+ int i; -+ -+ Context; -+ if (seenflood()) -+ return 0; -+ if (!bnsnick || !bnschan) { -+ if (bnsnick) -+ nfree(bnsnick); -+ if (bnschan) -+ nfree(bnschan); -+ bnsnick = bnschan = NULL; -+ return 0; -+ } -+ nick = newsplit(&par); -+ chan = newsplit(&par); -+ reset_global_vars(); -+ glob_remotebot = bot; -+ glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, chan)); -+ glob_nick = nick; -+ reply = par; -+ if (strcmp(nick, bnsnick) || strcmp(chan, bnschan)) -+ return 0; /* unwanted reply */ -+ if (findchan(chan)) { -+ if (nopub(chan)) { -+ nfree(bnsnick); -+ nfree(bnschan); -+ bnsnick = bnschan = NULL; -+ debug1("%s is nopub, bns-reply dropped", chan); -+ return 0; -+ } -+ if (quietseen(chan)) { -+ set_prefix(SLNOTPREFIX); -+ dprintf(DP_HELP, "NOTICE %s :%s%s%s\n", nick, reply_prefix, SLRBOTSAYS, reply); -+ } else { -+ set_prefix(SLPUBPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s%s\n", chan, reply_prefix, SLRBOTSAYS, reply); -+ } -+ } else if (!strcmp(chan, "[/msg]")) { -+ set_prefix(SLMSGPREFIX); -+ dprintf(DP_HELP, "PRIVMSG %s :%s%s%s\n", nick, reply_prefix, SLRBOTSAYS, reply); -+ } else if (!strcmp(chan, "[partyline]")) { -+ for (i = 0; i < dcc_total; i++) { -+ if ((!strcasecmp(nick, dcc[i].nick)) && -+ (dcc[i].type->flags & DCT_SIMUL)) { -+ set_prefix(SLDCCPREFIX); -+ dprintf(i, "%s%s%s\n", reply_prefix, SLRBOTSAYS, reply); -+ break; -+ } -+ } -+ } else -+ debug1("Couldn't send received bns answer, no such chan %s", chan); -+ nfree(bnsnick); -+ nfree(bnschan); -+ bnsnick = bnschan = NULL; -+ return 0; -+} -+ -+static cmd_t mydcc[] = -+{ -+ {"seen", "-|-", cmd_seen, NULL}, -+ {"seenstats", "-|-", cmd_seenstats, NULL}, -+ {"purgeseens", "m", cmd_purgeseens, NULL}, -+ {"seennick", "-|-", cmd_seennick, NULL}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_pub[] = -+{ -+ {"!seen", "", pub_seen, 0}, -+ {"!seenstats", "", pub_seenstats, 0}, -+ {"!seennick", "", pub_seennick, 0}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_msg[] = -+{ -+ {"seen", "", msg_seen, 0}, -+ {"seennick", "", msg_seennick, 0}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_bot[] = -+{ -+ {"gseen_req", "", bot_gseen_req, 0}, -+ {"gseen_rep", "", bot_gseen_rep, 0}, -+ {0, 0, 0, 0} -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseen.conf src/eggdrop-1.8.4/src/mod/gseen.mod/gseen.conf ---- ./src/mod/gseen.mod/gseen.conf 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/gseen.conf 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,151 @@ -+ -+###### -+##### -+### General Settings -+##### -+###### -+ -+# the file where the seen data will be backuped. -+# WARNING: set this _before_ the module is loaded. -+set gseenfile "gseen.dat" -+ -+# now load the module -+loadmodule gseen -+ -+# load the English language file -+loadseenslang "en" "English" language/gseen.en.lang -+ -+# load the German language file -+loadseenslang "de" "Deutsch" language/gseen.de.lang -+ -+# set the default language to english... -+set default-slang "en" -+ -+# ... but let #xwp use the german langfile -+setchanseenlang #xwp "de" -+ -+# the char that marks public commands (!seen, etc...) -+# "" is a valid option -+set cmdchar "!" -+ -+# delete data sets that are older than x days -+set expire-seens 60 -+ -+# only answer x seen requests in y seconds to prevent flooding -+set max-seens 7:60 -+ -+# tell users if someone was !seen'ing for them -+set tell-seens 1 -+ -+# check if the user was online under a different nick -+set fuzzy-search 1 -+ -+# allow user to include wildcards in the search? -+set wildcard-search 1 -+ -+# break search if there are more than x matches -+set max-matches 250 -+ -+# forward a request to other bots, if a !seen returned no result? -+set botnet-seens 1 -+ -+# store channels, which are +secret on the bot as [secret]? -+set hide-secret-chans 1 -+ -+# backup the seen data every x minutes -+set save-seens 60 -+ -+###### -+##### -+### AI Settings -+##### -+###### -+ -+# this setting configures on which sentences your bot should -+# attempt to do an ai-seen. Each of them is a simple wildcard -+# mask. Set this to "" if you want to deactivate ai-seens or -+# create more precise masks if the bots reacts too often. -+set ai-seen-binds { -+ "${nick}*seen*" -+ "${botnet-nick}*seen*" -+ "${nick}*gesehen*" -+ "${botnet-nick}*gesehen*" -+} -+ -+# this is just the same as above, but if triggered it will -+# not do an ai-seen, but display its seen-stats. -+set ai-seenstats-binds { -+ "${nick}*seenstats*" -+ "${botnet-nick}*seenstats*" -+} -+ -+# when doing an AI seen, ignore the following words (otherwise -+# the bot might give weird answers like " nick, bot was last seen..." :) -+set ai-seen-ignore "$nick ${botnet-nick} seen" -+ -+###### -+##### -+### special stuff (can be ignored in most cases) -+##### -+###### -+ -+# Maximum length of requested nick that will still be processed. -+# (by default this is eggdrop's configured nick-length) -+set seen-nick-len ${nick-len} -+ -+# if the user is known by the bot, log their handle instead of the nick -+# (not recommended, might cause confusion by the users) -+set use-handles 0 -+ -+###### -+##### -+### outdated settings (only important for eggdropv1.4 users) -+##### -+###### -+ -+# channels where you do not want your bot to reply to public queries -+set no-pub-seens "" -+ -+# channels where you want your bot to send replies via notice to the user and -+# not to the channel -+set quiet-seens "" -+ -+# same as quiet-seens but for AI seen -+set quiet-ai-seens "" -+ -+# channels where you do not want your bot to log seen data -+set no-seendata "" -+ -+ -+############################################################################### -+# end of configuration -+# just ignore everything below ^_^ -+############################################################################### -+ -+bind chjn - * *chjn:gseen -+bind chpt - * *chpt:gseen -+ -+catch "unbind pub - !seen *pub:!seen" -+catch "unbind pub - !seennick *pub:!seennick" -+catch "unbind pub - !seenstats *pub:!seenstats" -+bind pub - ${cmdchar}seen *pub:!seen -+bind pub - ${cmdchar}seennick *pub:!seennick -+bind pub - ${cmdchar}seenstats *pub:!seenstats -+ -+foreach bnd [binds pubm] { -+ if {([lindex $bnd 2] == "*pubm:seen") || ([lindex $bnd 2] == "*pub:!seenstats")} { -+ unbind [lindex $bnd 0] [lindex $bnd 1] [lindex $bnd 2] [lindex $bnd 4] -+ } -+} -+ -+if {${ai-seen-binds} != ""} { -+ foreach mask ${ai-seen-binds} { -+ bind pubm -|- "% [subst $mask]" *pubm:seen -+ } -+} -+ -+if {${ai-seenstats-binds} != ""} { -+ foreach mask ${ai-seenstats-binds} { -+ bind pubm -|- "% [subst $mask]" *pub:!seenstats -+ } -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseen.de.lang src/eggdrop-1.8.4/src/mod/gseen.mod/gseen.de.lang ---- ./src/mod/gseen.mod/language/gseen.de.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/language/gseen.de.lang 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,131 @@ -+##################################################################### -+# -+# Deutsche Sprachdatei f�r GSeen.Mod v1.1.0 -+# -+# Der Text in dieser Datei kann nach belieben ver�ndert werden. Du -+# kannst Tags hinzuf�gen oder entfernen, wie es Dir gef�llt. Die Tags -+# m�ssen nicht in einer bestimmten Reihenfolge oder Anzahl vorkommen. -+# -+# Wenn Du mehr als eine Zeile pro ID angibst, dann wird bei der -+# Antwort per Zufall eine daraus ausgew�hlt. (das funktioniert nicht -+# bei den Zeiteinheiten) -+# -+# Falls Du denkst, da� hier noch ein paar wichtige Tags fehlen, dann -+# schick mir einfach eine email. Vielleicht f�ge ich sie dann in der -+# n�chsten Version hinzu. -+# -+# Eine komplette Liste der Verf�gbaren Tags befindet sich am Ende von -+# slang_gseen_commands.c (leider ohne Erkl�hrungen) -+# -+##################################################################### -+ -+# -+## Zeiteinheiten -+# -+# jeweils in Singular und Plural -+# -+D 0 Jahr -+D 1 Jahre -+D 2 Woche -+D 3 Wochen -+D 4 Tag -+D 5 Tage -+D 6 Stunde -+D 7 Stunden -+D 8 Minute -+D 9 Minuten -+D 10 Sekunde -+D 11 Sekunden -+# falls ein �ng�ltiger Zeitwert angegeben war, dann wird dieser Text ausgegeben: -+D 12 einiger Zeit -+ -+ -+# -+## Pr�fixe -+# -+# Dieses Fragment wird jeweils vor eine Antwort gesetzt. Dadurch -+# ist beispielsweise bei �ffentlichen Anfragen ersichtlich, f�r -+# wen die Antwort ist. -+# Achtung: Die Nummer muss auf jeden Fall definiert werden. Sie muss -+# zwar keinen Text beinhalten, aber wenn sie nicht vorhanden -+# ist, dann gibt es eine Fehlermeldung -+ -+# f�r Antworten, die in den Channel geschrieben werden: -+10 , -+# f�r Antworten, die per NOTICE an den User geschickt werden: -+11 -+# f�r Antworten auf Anfragen, die per "/msg seen" erfolgt sind: -+12 -+# und f�r Antworten auf der Partyline: -+13 -+ -+# -+## Fehlermeldungen -+# -+54 wei�t Du was ein Parameter ist? ^_^ -+54 ich w�rde Dir ja gerne helfen, aber solange Du nicht sagst, nach wem Du suchst, kann ich nicht viel tun. -+54 meinst Du nicht, es w�re geschickter zu sagen, nach wem Du �berhaupt suchst? -+54 42. -+55 sehe ich etwa wie ein Spiegel aus? ^_^ -+55 Spieglein, Spieglein an der Wand... -+55 leidest Du etwa unter multiplen Pers�nlichkeiten? *eg* -+56 also wenn Du jetzt hier nicht sehen kannst, dann brauchst Du sicherlich eine neue Brille ^_^ -+56 ich muss mir unbedingt mal die Tarnkappe von ausleihen. Scheint ja prima zu funktioneren. -+56 schau Dir bitte nochmal ganz genau an, wer grade alles im Channel ist. -+57 Tut mir leid, aber Wildcards ('?', oder '*') sind bei der Suche nicht erlaubt. -+58 �hm... naja... etwas arg lang, dieser Nick... :) -+ -+# -+## Kein Ergebnis -+# -+65 Ich kann mich nicht daran erinnern, gesehen zu haben... -+65 ? Hmm... ich bin mir nicht sicher... vielleicht... eventuell... nein, kenne ich nicht. -+65 der Name sagt mir nichts. Hast Du Dich vielleicht vertippt? -+66 Ich hab' seit nicht mehr gesehen. -+67 Sorry, aber zu deiner Anfrage passt nichts in meiner Datenbank :( -+68 Autschi, das gab viel zu viele Ergebnisse. Bitte formuliere deine Suche etwas genauer. -+ -+73 ist grade unter dem Nick "" in diesem Channel zu finden. -+74 ist gerade in . -+75 Deine Anfrage f�hrte zu genau einem Ergebnis: -+76 Immerhin Treffer ergab deine Anfrage: -+77 Wow, auf deine Anfrage passen sogar Eintr�ge in meiner Datenbank! Dies sind die 5 aktuellsten: -+ -+# -+## falls ein anderer Bot etwas gefunden hat: -+# -+85 sagt: -+ -+# -+## die eigentliche Information -+# -+101 Ich habe () zuletzt vor betreten sehen (). ist noch immer da. -+121 Ich habe () zuletzt vor betreten sehen (), aber verschwand mysteri�serweise. -+102 Ich habe () zuletzt vor nach verchatteter Zeit verlassen sehen () -+103 Ich habe () zuletzt in gesehen, als er/sie vor () nach das IRC verlie� (""). -+104 Zuletzt habe ich () vor in gesehen, den Nick zu wechselnd. ist noch immer dort. -+124 () was last seen changing his/her nick to on ago (), but mysteriously dematerialized. -+105 Zuletzt habe ich () vor in gesehen, den Nick von wechselnd. ist noch immer dort. -+125 () was last seen changing his/her nick from on ago (), but mysteriously dematerialized. -+106 Zuletzt habe ich () gesehen, als er vor () von aus gejagt wurde. () -+107 () habe ich zuletzt vor gesehen, als er/sie von aus in einem Netsplit verschwand. -+108 () habe ich zuletzt vor gesehen, als er/sie nach einem Netsplit in zur�ck kam. ist noch immer dort. -+128 () habe ich zuletzt vor gesehen, als er/sie nach einem Netsplit in zur�ck kam. Allerdings konnte dem Gott der Netsplits nicht endg�ltig entkommen und ist wieder verschollen... -+109 was last seen joining the botnet channel on ago (). -+129 was last seen joining the partyline on ago (). -+110 was last seen leaving the botnet channel from ago (). -+130 was last seen leaving the partyline from ago (). -+140 () was last seen on ago (). -+ -+# -+## Seen-Mitteilungen -+# -+170 () scheint vor () in auf der Suche nach Dir gewesen zu sein. -+171 Leute haben sich nach Dir erkundigt: -+172 Der/die letzte war () in vor (). -+ -+# -+## Statistiken -+# -+180 Momentan sind Nicks in meiner Datenbank. Gesamter Speicherverbrauch: Bytes -+180 In meiner Datenbank befinden sich Nicks und verbrauchen Bytes Speicher. -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseen.en.lang src/eggdrop-1.8.4/src/mod/gseen.mod/gseen.en.lang ---- ./src/mod/gseen.mod/language/gseen.en.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/language/gseen.en.lang 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,131 @@ -+##################################################################### -+# -+# Default English langfile for GSeen.Mod v1.1.0 -+# -+# Just edit the text below to fit your needs. You can add or remove -+# any tag just like you want, they do not need to appear in a special -+# order (or number). -+# -+# If you enter more than one line per ID, then a random one will be -+# chosen for each reply. (this does not work for the time strings) -+# -+# If you think you need more tags, just email me and maybe I'll add -+# them in the next release. -+# -+# A complete list of available Tags can be found at the end of the -+# file slang_gseen_commands.c (unfortunately, it does not contain any -+# descriptions for the tags) -+# -+##################################################################### -+ -+# -+## time string -+# -+# each time string in singular and plural -+# -+D 0 year -+D 1 years -+D 2 week -+D 3 weeks -+D 4 day -+D 5 days -+D 6 hour -+D 7 hours -+D 8 minute -+D 9 minutes -+D 10 second -+D 11 seconds -+# if an invalid time value was supplied, output the following string -+D 12 some time -+ -+# -+## Prefixes -+# -+# These are the prefixes of the replies. By default, there's only -+# a prefix for public requests (so you know for whom the answer is), -+# but you can also define prefixes for other requests. -+ -+# for replies in the channel: -+10 , -+# for replies via notice: -+11 -+# for replies via PRIVMSG -+12 -+# for replies on the partyline -+13 -+ -+# -+## error messages -+# -+54 do you know what a parameter is? -+54 don't you think it would be more reasonable to say for whom you are searching? -+54 42. -+55 do I look like a mirror? ^_^ -+55 mirror mirror on the wall... -+55 do you have a split personality? *eg* -+56 if you can't see here right now, you probably need new glasses. ^_^ -+56 please look a bit closer at the memberlist of this channel. -+57 I'm sorry, but wildcards ('?' or '*') are not allowed in a search. -+58 Hum... don't you think this nick is a bit long? ^_^ -+58 you know that the length of nicks is limited, don't you? -+ -+# -+## no result -+# -+65 I don't remember seeing . -+65 ? hmm... I'm trying to remember... maybe... I'm not sure... no. I don't remember . -+66 I haven't seen for . -+67 I found no matches to your query. -+67 I'm sorry, but your search didn't return any results. -+68 Ouch, your search returned way too many matches. Please refine it. -+ -+# -+## victim is online -+# -+73 is , who is on this channel right now. -+74 is on right now. -+ -+# -+## results found -+# -+75 I found one match to your query: -+76 I found matches to your query: -+77 I found matches to your query. These are the 5 most recent ones: -+ -+# -+## results found by another bot in the botnet -+# -+85 says: -+ -+# -+## the core info -+# -+101 () was last seen joining ago (). is still there. -+121 () was last seen joining ago (), but mysteriously dematerialized. -+102 () was last seen parting ago (), after spending there. -+103 () was last seen quitting ago () stating "" after spending there. -+104 () was last seen changing his/her nick to on ago (). is still there. -+124 () was last seen changing his/her nick to on ago (), but mysteriously dematerialized. -+105 () was last seen changing his/her nick from on ago (). is still there. -+125 () was last seen changing his/her nick from on ago (), but mysteriously dematerialized. -+106 () was last seen being kicked from by () ago (), after spending there. -+107 () was last seen splitting from ago (), after spending there. -+108 () was last seen rejoining from a netsplit ago () is still there. -+128 () was last seen rejoining from a netsplit ago (), but the god of netsplits didn't let him escape, so he's not here now. -+109 was last seen joining the botnet channel on ago (). -+129 was last seen joining the partyline on ago (). -+110 was last seen leaving the botnet channel from ago (). -+130 was last seen leaving the partyline from ago (). -+140 () was last seen on ago (). -+ -+# -+## seen notification -+# -+170 () was looking for you on ago (). -+171 There have been users looking for you: -+172 The last one was () on ago (). -+ -+# -+## seen stats -+# -+180 I'm currently tracking nicks using bytes. -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/gseen.h src/eggdrop-1.8.4/src/mod/gseen.mod/gseen.h ---- ./src/mod/gseen.mod/gseen.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/gseen.h 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,157 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* #define USE_MEMDEBUG 1 */ -+ -+#define SEEN_JOIN 1 -+#define SEEN_PART 2 -+#define SEEN_SIGN 3 -+#define SEEN_NICK 4 -+#define SEEN_NCKF 5 -+#define SEEN_KICK 6 -+#define SEEN_SPLT 7 -+#define SEEN_REJN 8 -+#define SEEN_CHPT 9 -+#define SEEN_CHJN 10 -+ -+typedef struct gseen_data { -+ int type; -+ char *nick; -+ char *host; -+ char *chan; -+ char *msg; -+ time_t when; -+ int spent; -+} seendat; -+ -+typedef struct gseen_result { -+ struct gseen_result *next; -+ seendat *seen; -+} gseenres; -+ -+typedef struct gseen_requests { -+ struct gseen_requests *next; -+ char *who; -+ char *host; -+ char *chan; -+ time_t when; -+} seenreq_by; -+ -+typedef struct gseen_request { -+ struct gseen_request *next; -+ char *nick; -+ struct gseen_requests *by; -+} seenreq; -+ -+typedef struct gseen_ignorewords { -+ struct gseen_ignorewords *next; -+ char *word; -+} ignoredword; -+ -+#ifdef MAKING_GSEEN -+static int gseen_expmem(); -+static void free_gseen(); -+static int get_spent(char *, char *); -+static void write_seens(); -+static void read_seens(); -+static char *do_seen(char *, char *, char *, char *, int); -+static void add_seenresult(seendat *); -+static int expmem_seenresults(); -+static void free_seenresults(); -+static void sortresults(); -+static char *do_seennick(seendat *); -+static int onchan(char *, char *); -+static char *handonchan(char *, char *); -+static struct chanset_t *onanychan(char *); -+static struct chanset_t *handonanychan(char *); -+static char *do_seenstats(); -+static void add_seenreq(char *, char *, char *, char *, time_t); -+static int expmem_seenreq(); -+static void free_seenreq(); -+static void sortrequests(seenreq *); -+static void report_seenreq(char *, char *); -+static int count_seenreq(seenreq_by *b); -+static int expmem_ignoredwords(); -+static void free_ignoredwords(); -+static void add_ignoredword(char *word); -+static int word_is_ignored(char *word); -+static void purge_seens(); -+static int seenflood(); -+static int secretchan(char *); -+static int nopub(char *); -+static int quietseen(char *); -+static int quietaiseens(char *); -+static int nolog(char *); -+static void start_seentime_calc(); -+static void end_seentime_calc(); -+#endif -+ -+ -+#ifdef MAKING_GSEEN -+ -+// tree stuff -+static void maskstricthost(const char *, char *); -+#endif -+ -+// interface for webseen -+#define WS_OK 0 -+#define WS_NORESULT 1 -+#define WS_NOPARAM 2 -+#define WS_NOWILDCARDS 3 -+#define WS_TOOLONGNICK 4 -+#define WS_TOOMANYMATCHES 5 -+#define WS_TOOLONGHOST 6 -+ -+#ifndef MAKING_GSEEN -+#define findseens ((gseenres *(*)(char *, int *, int))gseen_funcs[4]) -+#define free_seenresults ((void (*)())gseen_funcs[5]) -+#define gseen_duration ((char *(*)(int))gseen_funcs[6]) -+#define numresults (*(int *)(gseen_funcs[12])) -+#define fuzzy_search (*(int *)(gseen_funcs[13])) -+#define numseens (*(int *)(gseen_funcs[15])) -+#define glob_total_queries (*(int *)(gseen_funcs[16])) -+#define glob_total_searchtime (*(double *)(gseen_funcs[17])) -+#define gseen_numversion (*(int *)(gseen_funcs[19])) -+#else -+static gseenres *findseens(char *, int *, int); -+static char *gseen_duration(int); -+#endif -+ -+#ifdef MAKING_GSEEN -+ -+#ifdef malloc -+#undef malloc -+#endif -+#ifdef free -+#undef free -+#endif -+#ifdef realloc -+#undef realloc -+#endif -+ -+#ifdef USE_MEMDEBUG -+#define my_malloc nmalloc -+#define my_free nfree -+#define my_realloc nrealloc -+#else -+#define my_malloc malloc -+#define my_free free -+#define my_realloc realloc -+#endif -+ -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/Makefile src/eggdrop-1.8.4/src/mod/gseen.mod/Makefile ---- ./src/mod/gseen.mod/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/Makefile 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,28 @@ -+# Makefile for src/mod/gseen.mod/ -+ -+doofus: -+ @echo "" -+ @echo "Let's try this from the right directory..." -+ @echo "" -+ @cd ../../../; make -+ -+clean: -+ @rm -f *.o *.$(MOD_EXT) *~ -+ -+static: ../gseen.o -+ -+modules: ../../../gseen.$(MOD_EXT) -+ -+../gseen.o: ../module.h ../modvals.h ../../eggdrop.h datahandling.c \ -+ gseen.c sensors.c gseencmds.c gseencmds.c do_seen.c ai.c tclcmds.c \ -+ misc.c seentree.c generic_binary_tree.c slang_gseen_commands.c \ -+ slang.c slang_text.c slang_ids.c slang_chanlang.c seenlang.h \ -+ slang_multitext.c gseen.h -+ $(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c gseen.c -+ rm -f ../gseen.o -+ mv gseen.o ../ -+ -+../../../gseen.$(MOD_EXT): ../gseen.o -+ $(LD) -o ../../../gseen.$(MOD_EXT) ../gseen.o $(XLIBS) -+ -+#safety hash -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/misc.c src/eggdrop-1.8.4/src/mod/gseen.mod/misc.c ---- ./src/mod/gseen.mod/misc.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/misc.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,116 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/* maskstricthost(): -+ * basically the same as maskhost() from src/misc.c, but _never_ stripts -+ * "~+-^=" off the host -+ * maskhost() version: * $Id: misc.c,v 1.1 2005/04/14 10:55:00 Administrator Exp $ -+ */ -+static void maskstricthost(const char *s, char *nw) -+{ -+ register const char *p, *q, *e, *f; -+ int i; -+ -+ *nw++ = '*'; -+ *nw++ = '!'; -+ p = (q = strchr(s, '!')) ? q + 1 : s; -+ /* Strip of any nick, if a username is found, use last 8 chars */ -+ if ((q = strchr(p, '@'))) { -+ int fl = 0; -+ -+ if ((q - p) > 9) { -+ nw[0] = '*'; -+ p = q - 7; -+ i = 1; -+ } else -+ i = 0; -+ while (*p != '@') { -+ if (!fl && strchr("~+-^=", *p)) { -+// if (strict_host) -+ nw[i] = '?'; -+// else -+// i--; -+ } else -+ nw[i] = *p; -+ fl++; -+ p++; -+ i++; -+ } -+ nw[i++] = '@'; -+ q++; -+ } else { -+ nw[0] = '*'; -+ nw[1] = '@'; -+ i = 2; -+ q = s; -+ } -+ nw += i; -+ e = NULL; -+ /* Now q points to the hostname, i point to where to put the mask */ -+ if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':')) -+ /* TLD or 2 part host */ -+ strcpy(nw, q); -+ else { -+ if (e == NULL) { /* IPv6 address? */ -+ const char *mask_str; -+ -+ f = strrchr(q, ':'); -+ if (strchr(f, '.')) { /* IPv4 wrapped in an IPv6? */ -+ f = strrchr(f, '.'); -+ mask_str = ".*"; -+ } else /* ... no, true IPv6. */ -+ mask_str = ":*"; -+ strncpy(nw, q, f - q); -+ /* No need to nw[f-q] = 0 here, as the strcpy below will -+ * terminate the string for us. -+ */ -+ nw += (f - q); -+ strcpy(nw, mask_str); -+ } else { -+ for (f = e; *f; f++); -+ f--; -+ if (*f >= '0' && *f <= '9') { /* Numeric IP address */ -+ while (*f != '.') -+ f--; -+ strncpy(nw, q, f - q); -+ /* No need to nw[f-q] = 0 here, as the strcpy below will -+ * terminate the string for us. -+ */ -+ nw += (f - q); -+ strcpy(nw, ".*"); -+ } else { /* Normal host >= 3 parts */ -+ /* a.b.c -> *.b.c -+ * a.b.c.d -> *.b.c.d if tld is a country (2 chars) -+ * OR *.c.d if tld is com/edu/etc (3 chars) -+ * a.b.c.d.e -> *.c.d.e etc -+ */ -+ const char *x = strchr(e + 1, '.'); -+ -+ if (!x) -+ x = p; -+ else if (strchr(x + 1, '.')) -+ x = e; -+ else if (strlen(x) == 3) -+ x = p; -+ else -+ x = e; -+ sprintf(nw, "*%s", x); -+ } -+ } -+ } -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/README src/eggdrop-1.8.4/src/mod/gseen.mod/README ---- ./src/mod/gseen.mod/README 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/README 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,139 @@ -+Description: -+------------ -+ -+gseen.mod is a seen module for eggdrop that tracks not only the users in the -+bot's userfile, but everyone who enters one of the bots channels. -+It does pretty much the same as the popular script bseen and has a few -+additional features like AI-seen and seen-notification. -+It's also way faster than any corresponding script because scripts are always -+much slower than modules. Especially scripts that deal with large amount of -+data often become incredible slow. -+ -+Installation: -+------------- -+ -+gseen.mod is written for eggdrop1.6, but it should also work with eggdrop 1.4. -+It has been reported to work with eggdrop 1.8, but I did not test it -+myself on that version. -+ -+You need the eggdrop source to compile the module. -+ -+The following instructions assume, ~/eggdrop1.6.2/ is the directory -+where you installed your eggdrop from. (of course, other source dirs -+will work as well) -+ -+Put gseen.mod.1.1.2.tar.gz in ~/eggdrop1.6.2/src/mod/, -+and unpack it (tar xfz gseen.mod.1.1.2.tar.gz). Change directory -+back to ~/eggdrop1.6.2/. -+ -+Now just do what you've done when you compiled your bot: -+"./configure" -+"make config" (you can skip this command on eggdrop 1.4) -+"make" -+"make install" -+ -+Don't forget to copy the langfiles from eggdrop1.6.2/src/mod/gseen.mod/ to -+eggdrop/language. -+ -+All settings can be found in ~/eggdrop1.6.2/src/mod/gseen.mod/gseen.conf -+Copy it to your eggdrop directory, edit it to fit your needs and put -+"source gseen.conf" at the end of your eggdrop config file. The last thing -+to do is to .rehash your bot. -+ -+ -+Public commands: -+---------------- -+ -+!seen -+ I think this command doesn't need an explanation. ^_^ -+!seen -+ Searches the database for entries that match -+ for example "!seen *!user@dialin-*.isp.com" -+!seennick -+ !seen also checks if a user was online later with a -+ different nick. !seennick only seens for -+!seenstats -+ just a little report on how many nicks are tracked -+ -+All commands are also accessible via /msg. -+("/msg seen ", for example) -+ -+ -+AI seen: -+-------- -+ -+This module has a simple built in AI routine. -+A short example: -+ -+ Argo: have you seen Fabian recently? -+<|Argo|> G`Quann, fabian (~fabian@dns.gifs.de) was last seen quitting -+from #eggdev 1 week 4 days 9 hours 40 minutes 56 seconds ago -+(20.02. 01:39) stating ".....zzzzZZZzzZZZzZZZZZZZZZZzzz..". -+ -+Well, it's not a very intelligent AI, it's rather brute-force. So don't -+forget to use the ai-seen-ignore setting. -+I know that's not coded very elegant, but if you configure it correctly, -+the failure-rate is way lower than with other AI scripts... -+ -+DCC commands: -+------------- -+ -+.seen -+.seennick -+.seenstats -+ just the same as the public versions -+.purgeseens -+ deletes expired data (this also happens automatically once a day) -+ (m) -+ -+Channel Settings: -+----------------- -+ -+ +noseendata -+ don't log any seen data in this channel -+ +quietseens -+ send answers directly via notice to the person who asked and -+ don't bother the rest of the channel with the reply -+ +quietaiseens -+ same as +quietseens, but for AI seens -+ +nopubseens -+ ignore every seen-command in this channel -+ -+TCL commands: -+------------- -+ -+There are no special tcl commands, only the usual bind procs. -+ -+The only one that should be mentioned is: -+ -+*pubm:seen -+ triggers the AI seen -+ returns: 1 if a reply was sent, 0 otherwise -+ -+So if you're using another AI script on your bot, you can modify it to -+use this proc and avoid doubled replies this way. -+ -+Other: -+------ -+ -+There is absolutely NO WARRANTY on this module. I do my best to make it -+work properly, but if anything gets screwed up, I'm not responsible. Use -+this module at your own risk. -+ -+Homepage: -+--------- -+ -+The newest gseen version can always be found at: -+http://www.kreativrauschen.com/gseen.mod/ -+ -+Thanks to: -+---------- -+ -+- Fabian for teaching me plenty of things -+- everyone who tested the many buggy development versions :) -+- the eggdev team for developing eggdrop -+ -+Most of all, I would like to thank Bass for writing bseen.tcl because alot -+of the ideas for this module came from using that tcl script. It's still the -+most powerful seen script, so if you want something that's easier to use than -+a module, get a copy of bseen.tcl. -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/seenlang.h src/eggdrop-1.8.4/src/mod/gseen.mod/seenlang.h ---- ./src/mod/gseen.mod/seenlang.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/seenlang.h 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define SLPUBPREFIX getslang(10) -+#define SLNOTPREFIX getslang(11) -+#define SLMSGPREFIX getslang(12) -+#define SLDCCPREFIX getslang(13) -+ -+#define SLNOPARAM getslang(54) -+#define SLMIRROR getslang(55) -+#define SLONCHAN getslang(56) -+#define SLNOWILDCARDS getslang(57) -+#define SLTOOLONGNICK getslang(58) -+ -+#define SLNOTSEEN getslang(65) -+#define SLPOORSEEN getslang(66) -+#define SLNOMATCH getslang(67) -+#define SLTOOMANYMATCHES getslang(68) -+ -+#define SLHANDONCHAN getslang(73) -+#define SLONOTHERCHAN getslang(74) -+#define SLONEMATCH getslang(75) -+#define SLLITTLEMATCHES getslang(76) -+#define SLMANYMATCHES getslang(77) -+ -+#define SLRBOTSAYS getslang(85) -+ -+#define SLYEAR getdur(0) -+#define SLYEARS getdur(1) -+#define SLWEEK getdur(2) -+#define SLWEEKS getdur(3) -+#define SLDAY getdur(4) -+#define SLDAYS getdur(5) -+#define SLHOUR getdur(6) -+#define SLHOURS getdur(7) -+#define SLMINUTE getdur(8) -+#define SLMINUTES getdur(9) -+#define SLSECOND getdur(10) -+#define SLSECONDS getdur(11) -+#define SLSOMETIME getdur(12) -+ -+#define SLONELOOK getslang(170) -+#define SLMORELOOKS getslang(171) -+#define SLLASTLOOK getslang(172) -+ -+#define SLSEENSTATS getslang(180) -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/seentree.c src/eggdrop-1.8.4/src/mod/gseen.mod/seentree.c ---- ./src/mod/gseen.mod/seentree.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/seentree.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,213 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static struct generic_binary_tree seentree; -+ -+static void seentree_init(); -+static int seentree_expmem(); -+static void seentree_free(); -+static int compareseens(void *, void *); -+static int expmemseen(void *); -+static void add_seen(int, char *, char *, char *, char *, -+ time_t, int); -+static void freeseen(void *); -+static seendat *findseen(char *); -+static void wildmatch_seens(char *, char *, int); -+static void process_wildmatch_seens(void *); -+static void write_seen_tree(void *); -+static void purge_seen_tree(void *); -+static int count_seens(); -+static void _count_seens(void *); -+ -+ -+static void seentree_init() -+{ -+ seentree.root = NULL; -+ seentree.comparedata = compareseens; -+ seentree.expmemdata = expmemseen; -+ seentree.freedata = freeseen; -+} -+ -+static int seentree_expmem() -+{ -+ return btree_expmem(&seentree); -+} -+ -+static void seentree_free() -+{ -+ btree_freetree(&seentree); -+ seentree.root = NULL; -+} -+ -+static int compareseens(void *first, void *second) -+{ -+ return rfc_casecmp(((seendat *) first)->nick, ((seendat *) second)->nick); -+} -+ -+// add another entry to the tree -+static void add_seen(int type, char *nick, char *host, char *chan, char *msg, -+ time_t when, int spent) -+{ -+ seendat *newseen; -+ -+ newseen = nmalloc(sizeof(seendat)); -+ newseen->type = type; -+ newseen->nick = nmalloc(strlen(nick) + 1); -+ strcpy(newseen->nick, nick); -+ newseen->host = nmalloc(strlen(host) + 1); -+ strcpy(newseen->host, host); -+ newseen->chan = nmalloc(strlen(chan) + 1); -+ strcpy(newseen->chan, chan); -+ newseen->msg = nmalloc(strlen(msg) + 1); -+ strcpy(newseen->msg, msg); -+ newseen->when = when; -+ newseen->spent = spent; -+ btree_add(&seentree, newseen); -+} -+ -+static void freeseen(void *what) -+{ -+ seendat *s = (seendat *) what; -+ -+ Assert(s); -+ Assert(s->nick); -+ Assert(s->host); -+ Assert(s->chan); -+ Assert(s->msg); -+ -+ nfree(s->nick); -+ nfree(s->host); -+ nfree(s->chan); -+ nfree(s->msg); -+ nfree(s); -+} -+ -+static int expmemseen(void *what) -+{ -+ int size = 0; -+ seendat *d = (seendat *) what; -+ -+ size += sizeof(seendat); -+ size += strlen(d->nick) + 1; -+ size += strlen(d->host) + 1; -+ size += strlen(d->chan) + 1; -+ size += strlen(d->msg) + 1; -+ return size; -+} -+ -+// finds a seen entry in the tree -+seendat findseen_temp; -+static seendat *findseen(char *nick) -+{ -+ findseen_temp.nick = nick; -+ return btree_get(&seentree, &findseen_temp); -+} -+ -+// function to find all nicks that match a host -+// (calls btree_getall() which calls a target function for each item) -+// host: user's hostmask (used if search query doesn't contain any wildcards) -+// mask: search mask -+// wild: defines if we want to use the mask, or host for the search -+static char *wildmatch_host, *wildmatch_mask; -+int wildmatch_wild; -+static void wildmatch_seens(char *host, char *mask, int wild) -+{ -+ wildmatch_host = host; -+ wildmatch_mask = mask; -+ wildmatch_wild = wild; -+ btree_getall(&seentree, process_wildmatch_seens); -+} -+ -+/* process_wildmatch_seens(): -+ * gets called from the binary tree for each existing item. -+ */ -+static void process_wildmatch_seens(void *data) -+{ -+ seendat *s = (seendat *) data; -+ -+ if ((numresults > max_matches) && (max_matches > 0)) // Don't return too many -+ return; // matches... -+ if (!wildmatch_wild) { -+ if (wild_match(wildmatch_host, s->host)) -+ add_seenresult(s); -+ } else { -+ temp_wildmatch_host = my_realloc(temp_wildmatch_host, strlen(s->nick) + 1 + strlen(s->host) + 1); -+ strcpy(temp_wildmatch_host, s->nick); -+ strcat(temp_wildmatch_host, "!"); -+ strcat(temp_wildmatch_host, s->host); -+ if (wild_match(wildmatch_mask, s->nick) || wild_match(wildmatch_mask, temp_wildmatch_host)) -+ add_seenresult(s); -+ } -+} -+ -+// write seendata in the datafile -+FILE *write_seen_tree_target; -+static void write_seen_tree(void *data) -+{ -+ seendat *node = (seendat *) data; -+ -+ /* format: "! nick host chan type when spent msg" */ -+ fprintf(write_seen_tree_target, "! %s %s %s %d %lu %d %s\n", node->nick, -+ node->host, node->chan, node->type, node->when, node->spent, -+ node->msg); -+} -+ -+// recursive function to remove old data -+// QUESTION: What happens if one of the nodes get moved by killseen()? -+// Possible bug/crash? -+// I think it should not be a problem. When killseen() is called the -+// first time, recursion already reached its end and no pointers -+// are accessed anymore. But I'm not sure... maybe I'm wrong. -+static void purge_seen_tree(void *data) -+{ -+ seendat *node = (seendat *) data; -+ -+ if ((now - node->when) > (expire_seens * 86400)) { -+ debug1("seen data for %s has expired.", node->nick); -+ btree_remove(&seentree, node); -+ } -+} -+ -+// counts the number of nicks in the database -+static int count_seens_temp; -+static int count_seens() -+{ -+ count_seens_temp = 0; -+ btree_getall(&seentree, _count_seens); -+ return count_seens_temp; -+} -+ -+static void _count_seens(void *node) -+{ -+ count_seens_temp++; -+} -+ -+static int tcl_killseen STDVAR -+{ -+ Context; -+ BADARGS(2, 2, " nick"); -+ findseen_temp.nick = argv[1]; -+ btree_remove(&seentree, &findseen_temp); -+ return TCL_OK; -+} -+ -+static tcl_cmds seendebugtcls[] = -+{ -+ {"killseen", tcl_killseen}, -+ {0, 0} -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/sensors.c src/eggdrop-1.8.4/src/mod/gseen.mod/sensors.c ---- ./src/mod/gseen.mod/sensors.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/sensors.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,273 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static int get_spent(char *nick, char *chan) -+{ -+ struct chanset_t *ch = NULL; -+ memberlist *m = NULL; -+ -+ int spent; -+ ch = findchan_by_dname(chan); -+ if (ch) -+ m = ismember(ch, nick); -+ if (m && m->joined) -+ spent = now - m->joined; -+ else -+ spent = -1; -+ return spent; -+} -+ -+static int secretchan(char *chan) -+{ -+ struct chanset_t *ch; -+ -+ ch = findchan_by_dname(chan); -+ if (!ch) -+ return 0; -+ if (ch->status & CHAN_SECRET) -+ return 1; -+ return 0; -+} -+ -+static int nolog(char *chan) -+{ -+ char buf[121], *b; -+ -+ Context; -+ strncpy(buf, no_log, 120); -+ buf[120] = 0; -+ b = buf; -+ while (b[0]) -+ if (!strcasecmp(chan, newsplit(&b))) -+ return 1; -+#if EGG_IS_MIN_VER(10503) -+ if (ngetudef("noseendata", chan)) -+ return 1; -+#endif -+ return 0; -+} -+ -+static int gseen_join(char *nick, char *uhost, char *hand, char *chan) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_JOIN, nick, uhost, chan, "", now, get_spent(nick, chan)); -+ report_seenreq(chan, nick); -+ if ((hand[0] == '*') && strcasecmp(nick, hand)) -+ report_seenreq(chan, hand); -+ return 0; -+} -+ -+static int gseen_kick(char *nick, char *uhost, char *hand, char *chan, -+ char *victim, char *reason) -+{ -+ struct chanset_t *ch = NULL; -+ memberlist *m = NULL; -+ char msg[1024], *s; -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ ch = findchan_by_dname(chan); -+ if (!ch) { -+ debug2("Unable to seen %s getting kicked from %s", victim, chan); -+ return 0; -+ } -+ if (secretchan(chan)) -+ chan = buf; -+ s = msg; -+ s[0] = 0; -+ m = ismember(ch, victim); -+ if (!m) { -+ debug2("Unable to seen %s getting kicked from %s", victim, chan); -+ return 0; -+ } -+ if ((strlen(nick) + strlen(reason) + 2) < 1024) -+ sprintf(s, "%s %s", nick, reason); -+ add_seen(SEEN_KICK, victim, m->userhost, chan, s, now, -+ get_spent(victim, chan)); -+ return 0; -+} -+ -+static int gseen_nick(char *nick, char *uhost, char *hand, char *chan, -+ char *newnick) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_NICK, nick, uhost, chan, newnick, now, get_spent(nick, chan)); -+ if (!(use_handles && (hand[0] != '*'))) -+ add_seen(SEEN_NCKF, newnick, uhost, chan, nick, now, get_spent(nick, chan)); -+ report_seenreq(chan, newnick); -+ if ((hand[0] != '*') && strcasecmp(newnick, hand)) -+ report_seenreq(chan, hand); -+ return 0; -+} -+ -+#if EGG_IS_MIN_VER(10502) -+static int gseen_part(char *nick, char *uhost, char *hand, char *chan, -+ char *reason) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_PART, nick, uhost, chan, reason, now, get_spent(nick, chan)); -+ return 0; -+} -+#else -+static int gseen_part(char *nick, char *uhost, char *hand, char *chan) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_PART, nick, uhost, chan, "", now, get_spent(nick, chan)); -+ return 0; -+} -+#endif -+ -+static int gseen_sign(char *nick, char *uhost, char *hand, char *chan, -+ char *reason) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_SIGN, nick, uhost, chan, reason, now, get_spent(nick, chan)); -+ return 0; -+} -+ -+static int gseen_splt(char *nick, char *uhost, char *hand, char *chan) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_SPLT, nick, uhost, chan, "", now, get_spent(nick, chan)); -+ return 0; -+} -+ -+static int gseen_rejn(char *nick, char *uhost, char *hand, char *chan) -+{ -+ char buf[10] = "[secret]"; -+ -+ Context; -+ if (nolog(chan)) -+ return 0; -+ if (use_handles && (hand[0] != '*')) -+ nick = hand; -+ if (secretchan(chan)) -+ chan = buf; -+ add_seen(SEEN_REJN, nick, uhost, chan, "", now, get_spent(nick, chan)); -+ return 0; -+} -+ -+static int gseen_chjn STDVAR -+{ -+ Context; -+ BADARGS(7, 7, " bot hand chan flag idx host"); -+ add_seen(SEEN_CHJN, argv[2], argv[6], argv[3], argv[1], now, -1); -+ return 0; -+} -+ -+static int gseen_chpt STDVAR -+{ -+ Context; -+ BADARGS(5, 5, " bot hand idx chan"); -+ add_seen(SEEN_CHPT, argv[2], "unknown", argv[4], argv[1], now, -1); -+ return 0; -+} -+ -+static cmd_t seen_kick[] = -+{ -+ {"*", "", (Function) gseen_kick, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_nick[] = -+{ -+ {"*", "", (Function) gseen_nick, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_join[] = -+{ -+ {"*", "", (Function) gseen_join, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_part[] = -+{ -+ {"*", "", (Function) gseen_part, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_sign[] = -+{ -+ {"*", "", (Function) gseen_sign, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_splt[] = -+{ -+ {"*", "", (Function) gseen_splt, "gseen"}, -+ {0, 0, 0, 0} -+}; -+ -+static cmd_t seen_rejn[] = -+{ -+ {"*", "", (Function) gseen_rejn, "gseen"}, -+ {0, 0, 0, 0} -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang.c ---- ./src/mod/gseen.mod/slang.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,309 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static struct slang_header *slang_find(struct slang_header *, char *); -+ -+#include "slang_text.c" -+#include "slang_multitext.c" -+#include "slang_ids.c" -+#ifndef SLANG_NOTYPES -+#include "slang_types.c" -+#endif -+#include "slang_duration.c" -+#ifndef SLANG_NOFACTS -+#include "slang_facts_places.c" -+#include "slang_facts.c" -+#endif -+#include "slang_chanlang.c" -+ -+ -+struct slang_header { -+ struct slang_header *next; -+ char *lang; -+ char *desc; -+ struct slang_id *ids; -+#ifndef SLANG_NOTYPES -+ struct slang_type *types; -+#endif -+ struct slang_duration *durations; -+}; -+ -+static void slang_glob_init() -+{ -+ glob_slang_cmd_list = NULL; -+} -+ -+static int slang_glob_expmem() -+{ -+ return slang_commands_list_expmem(glob_slang_cmd_list); -+} -+ -+static void slang_glob_free() -+{ -+ slang_commands_list_free(glob_slang_cmd_list); -+ glob_slang_cmd_list = NULL; -+} -+ -+static struct slang_header *slang_create(struct slang_header *list, char *lang, char *desc) -+{ -+ struct slang_header *nslang, *l; -+ -+ Assert(lang); -+ debug2("Creating language '%s' starting by %d", lang, (int) list); -+ for (nslang = list; nslang; nslang = nslang->next) -+ if (!strcasecmp(nslang->lang, lang)) -+ return list; -+ nslang = nmalloc(sizeof(struct slang_header)); -+ nslang->next = NULL; -+ nslang->desc = NULL; -+ nslang->lang = nmalloc(strlen(lang) + 1); -+ strcpy(nslang->lang, lang); -+ nslang->desc = nmalloc(strlen(desc) + 1); -+ strcpy(nslang->desc, desc); -+ nslang->ids = NULL; -+#ifndef SLANG_NOTYPES -+ nslang->types = NULL; -+#endif -+ nslang->durations = NULL; -+ for (l = list; l && l->next; l = l->next); -+ if (l) -+ l->next = nslang; -+ else { -+ Assert(!list); -+ list = nslang; -+ } -+ return list; -+} -+ -+static int slang_expmem(struct slang_header *what) -+{ -+ int size = 0; -+ -+ while (what) { -+ size += sizeof(struct slang_header); -+ size += strlen(what->lang) + 1; -+ size += strlen(what->desc) + 1; -+ size += slang_id_expmem(what->ids); -+#ifndef SLANG_NOTYPES -+ size += slang_type_expmem(what->types); -+#endif -+ size += slang_duration_expmem(what->durations); -+ what = what->next; -+ } -+ return size; -+} -+ -+static void slang_free(struct slang_header *what) -+{ -+ struct slang_header *next; -+ -+ while (what) { -+ next = what->next; -+ slang_id_free(what->ids); -+#ifndef SLANG_NOTYPES -+ slang_type_free(what->types); -+#endif -+ slang_duration_free(what->durations); -+ nfree(what->lang); -+ nfree(what->desc); -+ nfree(what); -+ what = next; -+ } -+} -+ -+static int slang_load(struct slang_header *slang, char *filename) -+{ -+ FILE *f; -+ char *buffer, *s; -+ char *cmd, *sid, *strtol_ret; -+#ifndef SLANG_NOTYPES -+ char *type; -+#endif -+ int line, id; -+ -+ Assert(slang); -+ putlog(LOG_MISC, "*", "Loading language \"%s\" from %s...", slang->lang, filename); -+ f = fopen(filename, "r"); -+ if (!f) { -+ putlog(LOG_MISC, "*", "Couldn't open slangfile \"%s\"!", filename); -+ return 0; -+ } -+ buffer = nmalloc(2000); -+ line = 0; -+ while (!feof(f)) { -+ s = buffer; -+ if (fgets(s, 2000, f)) { -+ line++; -+ // at first, kill those stupid line feeds and carriage returns... -+ if (s[strlen(s) - 1] == '\n') -+ s[strlen(s) - 1] = 0; -+ if (s[strlen(s) - 1] == '\r') -+ s[strlen(s) - 1] = 0; -+ if (!s[0]) -+ continue; -+ cmd = newsplit(&s); -+ -+ if (!strcasecmp(cmd, "T")) { -+#ifndef SLANG_NOTYPES -+ type = newsplit(&s); -+ slang->types = slang_type_add(slang->types, type, s); -+#endif -+ } else if (!strcasecmp(cmd, "D")) { -+ sid = newsplit(&s); -+ id = strtol(sid, &strtol_ret, 10); -+ if (strtol_ret == sid) { -+ putlog(LOG_MISC, "*", "ERROR in slangfile \"%s\", line %d: %s is not a valid " -+ "duration index!", filename, line, sid); -+ continue; -+ } -+ slang->durations = slang_duration_add(slang->durations, id, s); -+ } else { -+ id = strtol(cmd, &strtol_ret, 10); -+ if (strtol_ret == cmd) -+ continue; -+ slang->ids = slang_id_add(slang->ids, id, s); -+ } -+ } -+ } -+ fclose(f); -+ nfree(buffer); -+ return 1; -+} -+ -+static struct slang_header *slang_find(struct slang_header *where, char *language) -+{ -+ struct slang_header *slang = NULL; -+ -+ // at first, search for the specified language -+ for (slang = where; slang; slang = slang->next) -+ if (!strcasecmp(slang->lang, language)) -+ return slang; -+ // oops... language seems to be invalid. Let's find the default. -+ Assert(default_slang); -+ for (slang = where; slang; slang = slang->next) -+ if (!strcasecmp(slang->lang, default_slang)) -+ return slang; -+ // default_slang wasn't found either? *sigh* -+ // Let's return the first known language then. -+ return where; -+} -+ -+#ifndef SLANG_NOVALIDATE -+/* slang_valid(): -+ * check if the given language is a valid one -+ */ -+static int slang_valid(struct slang_header *where, char *language) -+{ -+ struct slang_header *slang = NULL; -+ -+ for (slang = where; slang; slang = slang->next) -+ if (!strcasecmp(slang->lang, language)) -+ return 1; -+ return 0; -+} -+#endif -+ -+static char getslang_error[12]; -+static char *getslang(int id) -+{ -+ char *text; -+ -+ if (!glob_slang) { -+ putlog(LOG_MISC, "*", "WARNING! No language selected! (getslang())"); -+ return "NOLANG"; -+ } -+ text = slang_id_get(glob_slang->ids, id); -+ if (!text) { -+ snprintf(getslang_error, sizeof(getslang_error), "SLANG%d", id); -+ return getslang_error; -+ } -+ return text; -+} -+ -+static char *getdur(int idx) -+{ -+ char *text; -+ -+ Assert((idx >= 0) && (idx < DURATIONS)); -+ if (!glob_slang) { -+ putlog(LOG_MISC, "*", "WARNING! No language selected! (getdur())"); -+ return "NOLANG"; -+ } -+ text = slang_duration_get(glob_slang->durations, idx); -+ if (!text) { -+ snprintf(getslang_error, sizeof(getslang_error), "DUR%d", idx); -+ return getslang_error; -+ } -+ return text; -+} -+ -+#ifndef SLANG_NOTYPES -+static char *getslangtype(char *type) -+{ -+ char *stype; -+ -+ if (!glob_slang) { -+ putlog(LOG_MISC, "*", "WARNING! No language selected! (getslangtype())"); -+ return "NOLANG"; -+ } -+ stype = slang_type_get(glob_slang->types, type); -+ if (stype) -+ return stype; -+ else -+ return type; -+} -+ -+static int slangtypetoi(char *slangtype) -+{ -+ char *type; -+ -+ if (!glob_slang) { -+ putlog(LOG_MISC, "*", "WARNING! No language selected! (slangtypetoi())"); -+ return T_ERROR; -+ } -+ type = slang_type_slang2type(glob_slang->types, slangtype); -+ if (type) { -+ debug1("type: %s", type); -+ return typetoi(type); -+ } else -+ return typetoi(slangtype); -+} -+#endif -+ -+#ifndef SLANG_NOGETALL -+static char *getslang_first(int id) -+{ -+ char *text; -+ -+ if (!glob_slang) { -+ putlog(LOG_MISC, "*", "WARNING! No language selected! (getslang())"); -+ return "NOLANG"; -+ } -+ text = slang_id_get_first(glob_slang->ids, id); -+ if (!text) { -+ snprintf(getslang_error, sizeof(getslang_error), "SLANG%d", id); -+ return getslang_error; -+ } -+ return text; -+} -+ -+static char *getslang_next() -+{ -+ return slang_id_get_next(); -+} -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_chanlang.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_chanlang.c ---- ./src/mod/gseen.mod/slang_chanlang.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_chanlang.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,113 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+struct slang_chanlang { -+ struct slang_chanlang *next; -+ char *chan; -+ char *lang; -+}; -+ -+static struct slang_chanlang *chanlangs = NULL; -+ -+static struct slang_chanlang *slang_chanlang_add(struct slang_chanlang *, char *, char *); -+static int slang_chanlang_expmem(struct slang_chanlang *); -+static void slang_chanlang_free(struct slang_chanlang *); -+static char *slang_chanlang_get(struct slang_chanlang *, char *); -+ -+static struct slang_chanlang *slang_chanlang_add(struct slang_chanlang *where, char *chan, char *lang) -+{ -+ struct slang_chanlang *item; -+ -+ for (item = where; item; item = item->next) -+ if (!rfc_casecmp(item->chan, chan)) -+ break; -+ if (!item) { -+ item = nmalloc(sizeof(struct slang_chanlang)); -+ item->chan = nmalloc(strlen(chan) + 1); -+ strcpy(item->chan, chan); -+ item->lang = nmalloc(strlen(lang) + 1); -+ strcpy(item->lang, lang); -+ item->next = where; -+ where = item; -+ } else { -+ Assert(item->lang); -+ item->lang = nrealloc(item->lang, strlen(lang) + 1); -+ strcpy(item->lang, lang); -+ } -+ return where; -+} -+ -+static int slang_chanlang_expmem(struct slang_chanlang *what) -+{ -+ int size = 0; -+ -+ while (what) { -+ Assert(what); -+ Assert(what->chan); -+ Assert(what->lang); -+ size += sizeof(struct slang_chanlang); -+ size += strlen(what->chan) + 1; -+ size += strlen(what->lang) + 1; -+ what = what->next; -+ } -+ return size; -+} -+ -+static void slang_chanlang_free(struct slang_chanlang *what) -+{ -+ struct slang_chanlang *next; -+ -+ while (what) { -+ Assert(what); -+ Assert(what->chan); -+ Assert(what->lang); -+ next = what->next; -+ nfree(what->chan); -+ nfree(what->lang); -+ nfree(what); -+ what = next; -+ } -+} -+ -+static char *slang_chanlang_get(struct slang_chanlang *where, char *chan) -+{ -+ while (where) { -+ if (!rfc_casecmp(where->chan, chan)) -+ return where->lang; -+ where = where->next; -+ } -+ return default_slang; -+} -+ -+/* slang_getbynick(): -+ * tries to find an appropriate language for nick by searching -+ * him on a channel and using the language of this channel. -+ */ -+static struct slang_header *slang_getbynick(struct slang_header *where, char *nick) -+{ -+ struct chanset_t *chan; -+ -+ for (chan = chanset; chan; chan = chan->next) -+ if (ismember(chan, nick)) -+#if EGG_IS_MIN_VER(10500) -+ return slang_find(where, slang_chanlang_get(chanlangs, chan->dname)); -+#else -+ return slang_find(where, slang_chanlang_get(chanlangs, chan->name)); -+#endif -+ return slang_find(where, default_slang); -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_duration.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_duration.c ---- ./src/mod/gseen.mod/slang_duration.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_duration.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define DURATIONS 13 -+ -+struct slang_duration { -+ char *durs[DURATIONS]; -+}; -+ -+static struct slang_duration *slang_duration_add(struct slang_duration *where, int idx, char *text) -+{ -+ int i; -+ -+ if ((idx < 0) || (idx >= DURATIONS)) { -+ putlog(LOG_MISC, "*", "Warning: Invalid duration index \"%d\".", idx); -+ return where; -+ } -+ debug2("Adding duration[%d]: %s", idx, text); -+ if (!where) { -+ where = nmalloc(sizeof(struct slang_duration)); -+ for (i = 0; i < DURATIONS; i++) -+ where->durs[i] = NULL; -+ } -+ if (where->durs[idx]) -+ nfree(where->durs[idx]); -+ where->durs[idx] = nmalloc(strlen(text) + 1); -+ strcpy(where->durs[idx], text); -+ return where; -+} -+ -+static int slang_duration_expmem(struct slang_duration *what) -+{ -+ int i, size = 0; -+ -+ if (!what) -+ return 0; -+ size += sizeof(struct slang_duration); -+ for (i = 0; i < DURATIONS; i++) -+ if (what->durs[i]) -+ size += strlen(what->durs[i]) + 1; -+ return size; -+} -+ -+static void slang_duration_free(struct slang_duration *what) -+{ -+ int i; -+ -+ if (what) { -+ for (i = 0; i < DURATIONS; i++) -+ if (what->durs[i]) -+ nfree(what->durs[i]); -+ nfree(what); -+ } -+} -+ -+static char *slang_duration_get(struct slang_duration *where, int idx) -+{ -+ if (!where) { -+ debug0("no where"); -+ return NULL; -+ } -+ if ((idx < 0) || (idx >= DURATIONS)) { -+ debug1("invalid duration index: %d", idx); -+ return NULL; -+ } -+ return where->durs[idx]; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_gseen_commands.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_gseen_commands.c ---- ./src/mod/gseen.mod/slang_gseen_commands.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_gseen_commands.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,235 @@ -+static void slang_send_botnick() -+{ -+ strncat(slang_text_buf, botname, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_query() -+{ -+ if (glob_query) -+ strncat(slang_text_buf, glob_query, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_laston() -+{ -+ if (glob_laston) -+ strncat(slang_text_buf, glob_laston, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_otherchan() -+{ -+ if (glob_otherchan) -+ strncat(slang_text_buf, glob_otherchan, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_othernick() -+{ -+ if (glob_othernick) -+ strncat(slang_text_buf, glob_othernick, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_remotebot() -+{ -+ if (glob_remotebot) -+ strncat(slang_text_buf, glob_remotebot, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_snick() -+{ -+ if (glob_seendat) -+ strncat(slang_text_buf, glob_seendat->nick, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_shost() -+{ -+ if (glob_seendat) -+ strncat(slang_text_buf, glob_seendat->host, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_schan() -+{ -+ if (glob_seendat) -+ strncat(slang_text_buf, glob_seendat->chan, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_swhen() -+{ -+ char *dur; -+ -+ if (glob_seendat) { -+ dur = gseen_duration(now - glob_seendat->when); -+ strncat(slang_text_buf, dur, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_stime() -+{ -+ time_t tt; -+ char t[20]; -+ -+ if (glob_seendat) { -+ tt = glob_seendat->when; -+ strftime(t, 19, "%d.%m. %H:%M", localtime(&tt)); -+ strncat(slang_text_buf, t, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_spent() -+{ -+ char *dur; -+ -+ if (glob_seendat) { -+ dur = gseen_duration(glob_seendat->spent); -+ strncat(slang_text_buf, dur, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_smsg() -+{ -+ if (glob_seendat) -+ strncat(slang_text_buf, glob_seendat->msg, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_numresults() -+{ -+ char buf[7]; -+ -+ snprintf(buf, sizeof(buf), "%d", numresults); -+ strncat(slang_text_buf, buf, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_punisher() -+{ -+ char *reason; -+ int len; -+ -+ if (glob_seendat) { -+ reason = strchr(glob_seendat->msg, ' '); -+ if (!reason) -+ strncat(slang_text_buf, glob_seendat->msg, sizeof(slang_text_buf)); -+ else { -+ len = (int) reason - (int) glob_seendat->msg; -+ strncat(slang_text_buf, glob_seendat->msg, (sizeof(slang_text_buf) < len) ? sizeof(slang_text_buf) : len); -+ } -+ } -+} -+ -+static void slang_send_kickreason() -+{ -+ char *reason; -+ -+ if (glob_seendat) { -+ reason = strchr(glob_seendat->msg, ' '); -+ if (reason) -+ strncat(slang_text_buf, reason, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_rnick() -+{ -+ if (glob_seenrequest) { -+ Assert(glob_seenrequest->by); -+ Assert(glob_seenrequest->by->who); -+ strncat(slang_text_buf, glob_seenrequest->by->who, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_rchan() -+{ -+ if (glob_seenrequest) { -+ Assert(glob_seenrequest->by); -+ Assert(glob_seenrequest->by->chan); -+ strncat(slang_text_buf, glob_seenrequest->by->chan, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_rhost() -+{ -+ if (glob_seenrequest) { -+ Assert(glob_seenrequest->by); -+ Assert(glob_seenrequest->by->host); -+ strncat(slang_text_buf, glob_seenrequest->by->host, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_rtime() -+{ -+ time_t tt; -+ char t[20]; -+ -+ if (glob_seenrequest) { -+ Assert(glob_seenrequest->by); -+ tt = glob_seenrequest->by->when; -+ strftime(t, sizeof(t), "%d.%m. %H:%M", localtime(&tt)); -+ strncat(slang_text_buf, t, sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_rwhen() -+{ -+ if (glob_seenrequest) { -+ Assert(glob_seenrequest->by); -+ strncat(slang_text_buf, gseen_duration(now - glob_seenrequest->by->when), sizeof(slang_text_buf)); -+ } -+} -+ -+static void slang_send_requests() -+{ -+ char buf[7]; -+ -+ snprintf(buf, sizeof(buf), "%d", glob_seenrequests); -+ strncat(slang_text_buf, buf, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_totalnicks() -+{ -+ char buf[7]; -+ -+ snprintf(buf, sizeof(buf), "%d", glob_totalnicks); -+ strncat(slang_text_buf, buf, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_totalbytes() -+{ -+ char buf[20]; -+ -+ snprintf(buf, sizeof(buf), "%d", glob_totalbytes); -+ strncat(slang_text_buf, buf, sizeof(slang_text_buf)); -+} -+ -+static void slang_send_nick() -+{ -+ if (glob_nick) -+ strncat(slang_text_buf, glob_nick, sizeof(slang_text_buf)); -+} -+ -+struct slang_text_commands slang_text_gseen_command_table[] = -+{ -+ {"botnick", slang_send_botnick}, -+ {"query", slang_send_query}, -+ {"laston", slang_send_laston}, -+ {"otherchan", slang_send_otherchan}, -+ {"othernick", slang_send_othernick}, -+ {"remotebot", slang_send_remotebot}, -+ {"snick", slang_send_snick}, -+ {"swhen", slang_send_swhen}, -+ {"stime", slang_send_stime}, -+ {"shost", slang_send_shost}, -+ {"schan", slang_send_schan}, -+ {"spent", slang_send_spent}, -+ {"smsg", slang_send_smsg}, -+ {"numresults", slang_send_numresults}, -+ {"snick2", slang_send_smsg}, -+ {"bnbot", slang_send_smsg}, -+ {"punisher", slang_send_punisher}, -+ {"kickreason", slang_send_kickreason}, -+ {"rnick", slang_send_rnick}, -+ {"rchan", slang_send_rchan}, -+ {"rhost", slang_send_rhost}, -+ {"rtime", slang_send_rtime}, -+ {"rwhen", slang_send_rwhen}, -+ {"requests", slang_send_requests}, -+ {"totalnicks", slang_send_totalnicks}, -+ {"totalbytes", slang_send_totalbytes}, -+ {"nick", slang_send_nick}, -+ {0, 0} -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_ids.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_ids.c ---- ./src/mod/gseen.mod/slang_ids.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_ids.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,104 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+struct slang_id { -+ struct slang_id *next; -+ int id; -+ struct slang_multitext *mtext; -+}; -+ -+static struct slang_id* slang_id_add(struct slang_id *, int, char *); -+static int slang_id_expmem(struct slang_id *); -+static void slang_id_free(struct slang_id *); -+static char *slang_id_get(struct slang_id *, int); -+ -+static struct slang_id* slang_id_add(struct slang_id *where, int id, char *text) -+{ -+ struct slang_id *newitem; -+ -+ newitem = NULL; -+ if (where) { -+ for (newitem = where; newitem; newitem = newitem->next) -+ if (newitem->id == id) -+ break; -+ } -+ if (!newitem) { -+ newitem = nmalloc(sizeof(struct slang_id)); -+ newitem->next = NULL; -+ newitem->id = id; -+ newitem->mtext = NULL; -+ if (where) -+ newitem->next = where; -+ else -+ newitem->next = NULL; -+ where = newitem; -+ } -+ newitem->mtext = slang_mtext_add(newitem->mtext, text); -+ return where; -+} -+ -+static int slang_id_expmem(struct slang_id *what) -+{ -+ int size = 0; -+ -+ for (; what; what = what->next) { -+ size += sizeof(struct slang_id); -+ size += slang_multitext_expmem(what->mtext); -+ } -+ return size; -+} -+ -+static void slang_id_free(struct slang_id *what) -+{ -+ struct slang_id *next; -+ -+ while (what) { -+ next = what->next; -+ slang_multitext_free(what->mtext); -+ nfree(what); -+ what = next; -+ } -+} -+ -+static char *slang_id_get(struct slang_id *where, int i) -+{ -+ while (where) { -+ if (where->id == i) -+ return slang_multitext_getrandomtext(where->mtext); -+ where = where->next; -+ } -+ return NULL; -+} -+ -+#ifndef SLANG_NOGETALL -+static char *slang_id_get_first(struct slang_id *where, int id) -+{ -+ while (where) { -+ if (where->id == id) { -+ return slang_multitext_get_first(where->mtext); -+ } -+ where = where->next; -+ } -+ return NULL; -+} -+ -+static char *slang_id_get_next() -+{ -+ return slang_multitext_get_next(); -+} -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_multitext.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_multitext.c ---- ./src/mod/gseen.mod/slang_multitext.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_multitext.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+struct slang_mt_content { -+ struct slang_mt_content *next; -+ struct slang_text *text; -+}; -+ -+struct slang_multitext { -+ int nr; -+ struct slang_mt_content *contents; -+}; -+ -+static struct slang_multitext *slang_mtext_add(struct slang_multitext *, char *); -+static int slang_multitext_expmem(struct slang_multitext *); -+static void slang_multitext_free(struct slang_multitext *); -+static char *slang_multitext_getrandomtext(struct slang_multitext *); -+#ifndef SLANG_NOTYPES -+static struct slang_text *slang_multitext_find(struct slang_multitext *, char *); -+#endif -+#ifndef SLANG_NOGETALL -+static char *slang_multitext_get_first(struct slang_multitext *); -+static char *slang_multitext_get_next(); -+#endif -+ -+static struct slang_multitext *slang_mtext_add(struct slang_multitext *where, char *text) -+{ -+ struct slang_mt_content *oc, *nc; -+ -+ if (!where) { -+ where = nmalloc(sizeof(struct slang_multitext)); -+ where->nr = 0; -+ where->contents = NULL; -+ } -+ nc = nmalloc(sizeof(struct slang_mt_content)); -+ nc->next = NULL; -+ nc->text = slang_text_parse(text); -+ for (oc = where->contents; oc && oc->next; oc = oc->next); -+ if (oc) { -+ Assert(!oc->next); -+ oc->next = nc; -+ } else -+ where->contents = nc; -+ where->nr++; -+ return where; -+} -+ -+static int slang_multitext_expmem(struct slang_multitext *what) -+{ -+ struct slang_mt_content *content; -+ int size = 0; -+ -+ if (!what) { -+ debug0("WARNING! slang_multitext_expmem() called with NULL pointer!"); -+ return 0; -+ } -+ size += sizeof(struct slang_multitext); -+ for (content = what->contents; content; content = content->next) { -+ size += sizeof(struct slang_mt_content); -+ size += slang_text_expmem(content->text); -+ } -+ return size; -+} -+ -+static void slang_multitext_free(struct slang_multitext *what) -+{ -+ struct slang_mt_content *content, *next; -+ -+ if (!what) { -+ debug0("WARNING! slang_multitext_free() called with NULL pointer!"); -+ return; -+ } -+ content = what->contents; -+ while (content) { -+ next = content->next; -+ slang_text_free(content->text); -+ nfree(content); -+ content = next; -+ } -+ nfree(what); -+} -+ -+static char *slang_multitext_getrandomtext(struct slang_multitext *where) -+{ -+ struct slang_mt_content *content; -+ unsigned long x; -+ -+ if (!where) -+ return NULL; -+ x = random() % where->nr; -+ for (content = where->contents; content; content = content->next) -+ if (!x) -+ return slang_text_get(content->text); -+ else -+ x--; -+ // we should never reach this part -+ debug0("warning: getrandomtext didn't find anything!"); -+ return NULL; -+} -+ -+#ifndef SLANG_NOTYPES -+static struct slang_text *slang_multitext_find(struct slang_multitext *where, char *what) -+{ -+ struct slang_mt_content *content; -+ -+ Assert(where); -+ for (content = where->contents; content; content = content->next) { -+ Assert(content->text); -+ if (!slang_text_strcasecmp(content->text, what)) -+ return content->text; -+ } -+ return NULL; -+} -+#endif -+ -+#ifndef SLANG_NOGETALL -+static struct slang_mt_content *glob_mtext_content; -+static char *slang_multitext_get_first(struct slang_multitext *where) -+{ -+ Assert(where); -+ glob_mtext_content = where->contents; -+ if (glob_mtext_content) -+ return slang_text_get(glob_mtext_content->text); -+ else -+ return NULL; -+} -+ -+static char *slang_multitext_get_next() -+{ -+ glob_mtext_content = glob_mtext_content->next; -+ if (glob_mtext_content) -+ return slang_text_get(glob_mtext_content->text); -+ else -+ return NULL; -+} -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/slang_text.c src/eggdrop-1.8.4/src/mod/gseen.mod/slang_text.c ---- ./src/mod/gseen.mod/slang_text.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/slang_text.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,200 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+struct slang_text { -+ struct slang_text *next; -+ char *string; -+ void (*command) (); -+}; -+ -+struct slang_text_commands { -+ char *command; -+ void (*targetfunc) (); -+}; -+ -+struct slang_command_list { -+ struct slang_command_list *next; -+ struct slang_text_commands *commands; -+}; -+ -+static struct slang_text *slang_text_parse(char *); -+static struct slang_text *slang_text_create(struct slang_text *); -+static void slang_text_add_string(struct slang_text *, char *); -+static void slang_text_add_command(struct slang_text *, char *); -+static void slang_text_free(struct slang_text *); -+static int slang_text_expmem(struct slang_text *); -+static char *slang_text_get(struct slang_text *); -+#ifndef SLANG_NOTYPES -+static int slang_text_strcasecmp(struct slang_text *, char *); -+#endif -+ -+static struct slang_text *slang_text_parse(char *text) -+{ -+ char *cmdstart, *cmdend; -+ struct slang_text *firstitem, *item; -+ -+ firstitem = slang_text_create(NULL); -+ item = firstitem; -+ while ((cmdstart = strstr(text, ""); -+ if (!cmdend) { -+ putlog(LOG_MISC, "*", "ERROR parsing slang text: unterminated command \"%s\"!", cmdstart); -+ break; -+ } -+ cmdend[0] = 0; -+ slang_text_add_command(item, cmdstart); -+ item = slang_text_create(item); -+ text = cmdend + 3; -+ } -+ slang_text_add_string(item, text); -+ return firstitem; -+} -+ -+static struct slang_text *slang_text_create(struct slang_text *where) -+{ -+ struct slang_text *newpart; -+ -+ newpart = nmalloc(sizeof(struct slang_text)); -+ newpart->next = NULL; -+ newpart->string = NULL; -+ newpart->command = NULL; -+ while (where && where->next) -+ where = where->next; -+ if (where) -+ where->next = newpart; -+ return newpart; -+} -+ -+static void slang_text_add_string(struct slang_text *item, char *s) -+{ -+ Assert(item); -+ Assert(!item->string); -+ item->string = nmalloc(strlen(s) + 1); -+ strcpy(item->string, s); -+} -+ -+static void slang_text_free(struct slang_text *item) -+{ -+ if (!item) -+ return; -+ slang_text_free(item->next); -+ if (item->string) -+ nfree(item->string); -+ nfree(item); -+} -+ -+static int slang_text_expmem(struct slang_text *item) -+{ -+ int size = 0; -+ -+ while (item) { -+ size += sizeof(struct slang_text); -+ if (item->string) -+ size += strlen(item->string) + 1; -+ item = item->next; -+ } -+ return size; -+} -+ -+#ifndef SLANG_NOTYPES -+static int slang_text_strcasecmp(struct slang_text *item, char *text) -+{ -+ Assert(item); -+ debug2("s_t_sc: '%s', '%s'", text, item->string); -+ if (item->command || item->next) -+ return 1; -+ return strcasecmp(item->string, text); -+} -+#endif -+ -+static char slang_text_buf[500]; -+static char *slang_text_get(struct slang_text *item) -+{ -+ slang_text_buf[0] = 0; -+ while (item) { -+ if (item->string) -+ strncat(slang_text_buf, item->string, sizeof(slang_text_buf)); -+ else if (item->command) -+ item->command(); -+ item = item->next; -+ } -+ return slang_text_buf; -+} -+ -+/*****************************************************/ -+ -+ -+static struct slang_command_list *glob_slang_cmd_list; -+ -+static struct slang_command_list *slang_commands_list_add(struct slang_command_list *where, struct slang_text_commands *what) -+{ -+ struct slang_command_list *newcommandlist; -+ -+ newcommandlist = nmalloc(sizeof(struct slang_command_list)); -+ newcommandlist->commands = what; -+ newcommandlist->next = where; -+ return newcommandlist; -+} -+ -+static int slang_commands_list_expmem(struct slang_command_list *what) -+{ -+ int size = 0; -+ -+ while (what) { -+ size += sizeof(struct slang_command_list); -+ what = what->next; -+ } -+ return size; -+} -+ -+static void slang_commands_list_free(struct slang_command_list *what) -+{ -+ struct slang_command_list *next; -+ -+ while (what) { -+ next = what->next; -+ nfree(what); -+ what = next; -+ } -+} -+ -+static void slang_text_add_command(struct slang_text *item, char *s) -+{ -+ struct slang_command_list *cmdlist; -+ char *cmd; -+ int i; -+ -+ cmd = newsplit(&s); -+ i = 0; -+ for (cmdlist = glob_slang_cmd_list; cmdlist; cmdlist = cmdlist->next) { -+ for (i = 0; 1; i++) { -+ if (!cmdlist->commands[i].command) -+ break; -+ if (!strcasecmp(cmdlist->commands[i].command, cmd)) { -+ item->command = cmdlist->commands[i].targetfunc; -+ return; -+ } -+ } -+ } -+ putlog(LOG_MISC, "*", "ERROR! Unknown slang-command: '%s'", cmd); -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/tclcmds.c src/eggdrop-1.8.4/src/mod/gseen.mod/tclcmds.c ---- ./src/mod/gseen.mod/tclcmds.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/tclcmds.c 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (C) 2000,2001 Florian Sander -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static int tcl_setchanseenlang STDVAR -+{ -+ Context; -+ BADARGS(3, 3, " channel language"); -+ chanlangs = slang_chanlang_add(chanlangs, argv[1], argv[2]); -+ return TCL_OK; -+} -+ -+static int tcl_loadseenslang STDVAR -+{ -+// int ret = 0; -+ char *shortname, *longname, *filename; -+ struct slang_header *slang; -+ -+ Context; -+ BADARGS(4, 4, " language description langfile"); -+ shortname = argv[1]; -+ longname = argv[2]; -+ filename = argv[3]; -+ coreslangs = slang_create(coreslangs, shortname, longname); -+ slang = slang_find(coreslangs, shortname); -+ Assert(slang); -+ if (!slang_load(slang, filename)) { -+ Tcl_AppendResult(irp, "Couldn't open seenslang file!!!", NULL); -+ return TCL_ERROR; -+ } -+ return TCL_OK; -+} -+ -+static tcl_cmds gseentcls[] = -+{ -+ {"loadseenslang", tcl_loadseenslang}, -+ {"setchanseenlang", tcl_setchanseenlang}, -+ {0, 0} -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/gseen.mod/UPDATES src/eggdrop-1.8.4/src/mod/gseen.mod/UPDATES ---- ./src/mod/gseen.mod/UPDATES 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/gseen.mod/UPDATES 2017-01-02 22:30:47.000000000 +0100 -@@ -0,0 +1,60 @@ -+Changes in gseen.mod: (since v1.0.0) -+-------------------- -+ -+1.1.2 (2017-01-02) -+- compatibility to eggdrop 1.8 -+ -+ -+1.1.1 -+- fixed "no newline" compilation warnings that appeared on some systems. -+- fixed uninitialized "li" variable in do_seen() -+- fixed lacking compatibility to eggdrop1.4 (confirmation anyone?) -+- new option: hide-secret-chans -+- new option: seen-nick-len -+ -+1.1.0 (15.6.2001) -+- added multilang support -+- removed static buffers -+- organized data in a binary search tree (much faster) -+- optimized a few other things -+- added settings: -+ - fuzzy-search -+ - max-matches -+ - wildcard-search -+ -+1.0.8 -+- quiet-seens wasn't working for !seennick -+- added quiet-ai-seens -+- renamed nopub to nopubseens and nolog to noseendata and -+ quietseen to quietseens -+ -+1.0.7 -+- added compatibility to !channels -+- fixed a bug relating strict-host 0 had some strange effects on -+ !seen requests for users with ~ in their ident -+ -+1.0.6 -+- fixed a very evil bug that allowed anyone to crash the bot, sorry -+ -+1.0.5 -+- quietseens wasn't working correctly -+- added support for egg1.5's udef chansets -+ -+1.0.4 -+- added GPL stuff -+- changed error msg that appears if no gseen file exists -+ -+1.0.3 -+- readme updates -+- fixed a grammatical error in do_seen -+ -+1.0.2 -+- bot wanted to free a NULL pointer sometimes -+ -+1.0.1 -+- !seen without parameter returned stupid results :) -+- fixed little typo in .purgeseens -+- "I found 1 matches..." -> "I found 1 match..." -+ -+1.0.0 -+- release :) diff --git a/main/eggdrop/logs2html.mod.patch b/main/eggdrop/logs2html.mod.patch deleted file mode 100644 index 36ed2361dcf..00000000000 --- a/main/eggdrop/logs2html.mod.patch +++ /dev/null @@ -1,3417 +0,0 @@ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/fileoperations.c src/eggdrop-1.8.4/src/mod/logs2html.mod/fileoperations.c ---- ./src/mod/logs2html.mod/fileoperations.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/fileoperations.c 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,134 @@ -+/* -+ * fileoperations.c -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Shmupsik aka shurikvz -+ * -+ * 2004-2009 year -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#include -+ -+/****************************************************************************/ -+/* -+ * function FILE *openfile(char *newfilename, const char *mode, bool silent) -+ * -+ * Input: -+ * newfilename - имя файла, который необходимо создать -+ * mode - режим открытия файла -+ * -+ * Output: -+ * указатель на файл -+ * -+ * Discription: -+ * функция осуществляет создание и открытие файла в указанном режиме -+ * и возвращает указатель на созданный файл -+ */ -+static FILE *openfile(char *filename, const char *mode, bool silent) { -+ FILE *file; -+ -+ if (filename == NULL) { -+ putlog(LOG_MISC, "*", "logs2html: ERROR! Can't allocate enough space for filename."); -+ return NULL; -+ } -+ -+ file = fopen(filename, mode); -+ if ((file == NULL) && (!silent)) { -+ putlog(LOG_MISC, "*", "logs2html: Warning! Can't open file \"%s\".", filename); -+ } -+ -+ return file; -+} /* openfile() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+/* -+ * function void writefromexfile(FILE *dst_file, char *exfilename) -+ * -+ * Input: -+ * -+ * -+ * -+ * -+ * Output: -+ * -+ * -+ * Discription: -+ * -+ * -+ */ -+static void writefromexfile(FILE *dst_file, char *exfilename) { -+ FILE *addfile; -+ char buffer[512]; -+ size_t n; -+ -+ if (strlen(exfilename) > 0) { -+ if ((addfile = openfile(exfilename, "r", false)) != NULL) { -+ while(!feof(addfile)) { -+ n = fread(buffer, sizeof(char), sizeof buffer, addfile); -+ fwrite(buffer, sizeof(char), n, dst_file); -+ } -+ fclose(addfile); -+ } -+ } -+ -+ return; -+} /* writefromexfile() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+/* -+ * function void str_write(FILE *file, char *fmt, ... ) -+ * -+ * Input: -+ * file - файл в который пишем данные -+ * fmt - строка для записи со спецификаторами формата -+ * ... - данные для записи в строку -+ * -+ * Output: -+ * ничего -+ * -+ * Discription: -+ * функция осуществляет запись переданной строки в указанный файл, -+ * производя соответствующее ее форматирование -+ */ -+static void str_write(FILE *file, char *fstr, ... ) { -+ va_list ap; -+ int nchars; -+ int size = 256; -+ static char *buffer = NULL; -+ -+ buffer = (char *)nmalloc(size); -+ -+ while (true) { -+ va_start(ap, fstr); -+ nchars = egg_vsnprintf(buffer, size, fstr, ap); -+ va_end(ap); -+ if (nchars < size) break; -+ size *= 2; -+ buffer = (char *)nrealloc(buffer, size); -+ } -+ -+ fwrite(buffer, sizeof(char), strlen(buffer), file); -+ nfree(buffer); buffer = NULL; -+ -+ return; -+} /* str_write() */ -+/****************************************************************************/ -+ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/help/logs2html.help src/eggdrop-1.8.4/src/mod/logs2html.mod/help/logs2html.help ---- ./src/mod/logs2html.mod/help/logs2html.help 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/help/logs2html.help 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,37 @@ -+%{help=convertalllogs}%{+n} -+### %bconvertalllogs%b -+ Reconverts all your logs. -+ -+See also: convertlogs, makemainpage -+%{help=convertlogs}%{+n} -+### %bconvertlogs [year [month [day]]]%b -+ %byear%b the year to reconvert logs -+ %bmonth%b the month to reconvert logs -+ %bmonth%b the day to reconvert logs -+ If year equals %ball%b the command reconverts all your logs (same as %b.convertalllogs%b). -+ If you do not specify a parameter, the command will convert the logs for the current day. -+ -+See also: convertalllogs, makemainpage -+%{help=makemainpage}%{+n} -+### %bmakemainpage%b -+ Redraws your mainpages. (same as %b.makeindexpage%b) -+ -+See also: makeindexpage -+%{help=makeindexpage}%{+n} -+### %bmakeindexpage%b -+ Redraws your mainpages. (same as %b.makemainpage%b) -+ -+See also: makemainpage -+%{help=logs2html module}%{+n} -+### %blogs2html module%b -+ This module convert all log files of your eggdrop in html format. -+ -+ The following commands are provided by the logs2html module: -+%{+n} -+ %bconvertalllogs makemainpage%b -+ %bconvertlogs makeindexpage%b -+%{help=all}%{+n} -+### %blogs2html module%b commands -+%{+n} -+ %bconvertalllogs makemainpage%b -+ %bconvertlogs makeindexpage%b -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/htmloperations.c src/eggdrop-1.8.4/src/mod/logs2html.mod/htmloperations.c ---- ./src/mod/logs2html.mod/htmloperations.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/htmloperations.c 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,349 @@ -+/* -+ * htmloperations.c -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Shmupsik aka shurikvz -+ * -+ * 2004-2009 year -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+/****************************************************************************/ -+/* -+* function void writecss -+* -+* Input: -+* -+* -+* -+* -+* Output: -+* -+* -+* Discription: -+* -+* -+*/ -+static void WriteCSSFile(FILE *dst_file) -+{ -+ str_write(dst_file, "@charset \"utf-8\";\n"); -+ str_write(dst_file, "/* CSS Document */\n\n"); -+ -+ str_write(dst_file, " \n\n"); -+ -+ return; -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.danish.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.danish.lang ---- ./src/mod/logs2html.mod/language/logs2html.danish.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.danish.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,38 @@ -+# logs2html.danish.lang -+# language messages for the logs2html module -+ -+# Year -+0xe000,�r -+ -+# Back to mainpage link -+0xe001,Hjem -+ -+# Up link -+0xe002,top -+ -+# Backward, forward link -+0xe003,forrige -+0xe004,n�ste -+ -+# Month names -+0xe005,Januar -+0xe006,Februar -+0xe007,Marts -+0xe008,April -+0xe009,M� -+0xe010,Juni -+0xe011,Juli -+0xe012,August -+0xe013,September -+0xe014,Oktober -+0xe015,November -+0xe016,December -+ -+# Days of week names -+0xe017,S�n. -+0xe018,Man. -+0xe019,Tir. -+0xe020,Ons. -+0xe021,Tor. -+0xe022,Fre. -+0xe023,L�r. -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.english.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.english.lang ---- ./src/mod/logs2html.mod/language/logs2html.english.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.english.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,38 @@ -+# logs2html.english.lang -+# language messages for the logs2html module -+ -+# Year -+0xe000,year -+ -+# Back to mainpage link -+0xe001,Main page -+ -+# Up link -+0xe002,up -+ -+# Backward, forward link -+0xe003,back -+0xe004,next -+ -+# Month names -+0xe005,January -+0xe006,February -+0xe007,March -+0xe008,April -+0xe009,May -+0xe010,June -+0xe011,July -+0xe012,August -+0xe013,September -+0xe014,October -+0xe015,November -+0xe016,December -+ -+# Days of week names -+0xe017,Su -+0xe018,Mo -+0xe019,Tu -+0xe020,Wn -+0xe021,Th -+0xe022,Fr -+0xe023,St -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.finnish.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.finnish.lang ---- ./src/mod/logs2html.mod/language/logs2html.finnish.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.finnish.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,38 @@ -+# logs2html.finnish.lang -+# language messages for the logs2html module -+ -+# Year -+0xe000,vuosi -+ -+# Back to mainpage link -+0xe001,Koti -+ -+# Up link -+0xe002,yl�s -+ -+# Backward, forward link -+0xe003,edellinen -+0xe004,seuraava -+ -+# Month names -+0xe005,Tammikuu -+0xe006,Helmikuu -+0xe007,Maaliskuu -+0xe008,Huhtikuu -+0xe009,Toukokuu -+0xe010,Kes�kuu -+0xe011,Hein�kuu -+0xe012,Elokuu -+0xe013,Syyskuu -+0xe014,Lokakuu -+0xe015,Marraskuu -+0xe016,Joulukuu -+ -+# Days of week names -+0xe017,Su -+0xe018,Ma -+0xe019,Ti -+0xe020,Ke -+0xe021,To -+0xe022,Pe -+0xe023,La -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.french.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.french.lang ---- ./src/mod/logs2html.mod/language/logs2html.french.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.french.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,40 @@ -+# logs2html.french.lang -+# language messages for the logs2html module -+# -+# Thanks to skiidoo patch (2007) -+ -+# Year -+0xe000,Ann�e -+ -+# Back to mainpage link -+0xe001,Page principale -+ -+# Up link -+0xe002,haut -+ -+# Backward, forward link -+0xe003,Pr�c�dente -+0xe004,Suivante -+ -+# Month names -+0xe005,Janvier -+0xe006,F�vrier -+0xe007,Mars -+0xe008,Avril -+0xe009,Mai -+0xe010,Juin -+0xe011,Juillet -+0xe012,Ao�t -+0xe013,Septembre -+0xe014,Octobre -+0xe015,Novembre -+0xe016,D�cembre -+ -+# Days of week names -+0xe017,Di -+0xe018,Lu -+0xe019,Ma -+0xe020,Me -+0xe021,Je -+0xe022,Ve -+0xe023,Sa -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.german.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.german.lang ---- ./src/mod/logs2html.mod/language/logs2html.german.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.german.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,38 @@ -+# logs2html.german.lang -+# language messages for the logs2html module -+ -+# Year -+0xe000,jahr -+ -+# Back to mainpage link -+0xe001,Heim -+ -+# Up link -+0xe002,Spitze -+ -+# Backward, forward link -+0xe003,zur�ck -+0xe004,n�chster -+ -+# Month names -+0xe005,Januar -+0xe006,Februar -+0xe007,M�rz -+0xe008,April -+0xe009,D�rfen -+0xe010,Juni -+0xe011,Juli -+0xe012,August -+0xe013,September -+0xe014,Oktober -+0xe015,November -+0xe016,Dezember -+ -+# Days of week names -+0xe017,So -+0xe018,Mo -+0xe019,Di -+0xe020,Mi -+0xe021,Do -+0xe022,Fr -+0xe023,Sa -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.russian.lang src/eggdrop-1.8.4/src/mod/logs2html.mod/language/logs2html.russian.lang ---- ./src/mod/logs2html.mod/language/logs2html.russian.lang 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language/logs2html.russian.lang 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,38 @@ -+# logs2html.ru.lang -+# language messages for the logs2html module -+ -+# Year -+0xe000,��� -+ -+# Back to mainpage link -+0xe001,�� ������� �������� -+ -+# Up link -+0xe002,������ -+ -+# Backward, forward link -+0xe003,���������� -+0xe004,��������� -+ -+# Month names -+0xe005,������ -+0xe006,������� -+0xe007,���� -+0xe008,������ -+0xe009,��� -+0xe010,���� -+0xe011,���� -+0xe012,������ -+0xe013,�������� -+0xe014,������� -+0xe015,������ -+0xe016,������� -+ -+# Days of week names -+0xe017,�� -+0xe018,�� -+0xe019,�� -+0xe020,�� -+0xe021,�� -+0xe022,�� -+0xe023,�� -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/language.h src/eggdrop-1.8.4/src/mod/logs2html.mod/language.h ---- ./src/mod/logs2html.mod/language.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/language.h 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,53 @@ -+/* -+ * language.h -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Gray_Angel aka Shmupsik -+ * -+ * 2004-2005 year -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+#ifndef _EGG_MOD_LOGS2HTML_LANGUAGE_H -+#define _EGG_MOD_LOGS2HTML_LANGUAGE_H -+ -+#define LOGS2HTML_YEAR get_language(0xe000) -+#define LOGS2HTML_MAINPAGE get_language(0xe001) -+#define LOGS2HTML_UP get_language(0xe002) -+#define LOGS2HTML_BACK get_language(0xe003) -+#define LOGS2HTML_NEXT get_language(0xe004) -+ -+#define LOGS2HTML_JANUARY get_language(0xe005) -+#define LOGS2HTML_FEBRIARY get_language(0xe006) -+#define LOGS2HTML_MARCH get_language(0xe007) -+#define LOGS2HTML_APRIL get_language(0xe008) -+#define LOGS2HTML_MAY get_language(0xe009) -+#define LOGS2HTML_JUNE get_language(0xe010) -+#define LOGS2HTML_JULY get_language(0xe011) -+#define LOGS2HTML_AUGUST get_language(0xe012) -+#define LOGS2HTML_SEPTEMBER get_language(0xe013) -+#define LOGS2HTML_OCTOBER get_language(0xe014) -+#define LOGS2HTML_NOVEMBER get_language(0xe015) -+#define LOGS2HTML_DECEMBER get_language(0xe016) -+ -+#define LOGS2HTML_SUNDAY get_language(0xe017) -+#define LOGS2HTML_MONDAY get_language(0xe018) -+#define LOGS2HTML_TUESDAY get_language(0xe019) -+#define LOGS2HTML_WEDNESDAY get_language(0xe020) -+#define LOGS2HTML_THURSDAY get_language(0xe021) -+#define LOGS2HTML_FRIDAY get_language(0xe022) -+#define LOGS2HTML_SATURDAY get_language(0xe023) -+ -+#endif -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.c src/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.c ---- ./src/mod/logs2html.mod/logs2html.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/logs2html.c 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,1679 @@ -+/* -+ * logs2html.c -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Shmupsik aka shurikvz -+ * -+ * 2004-2009 year -+ * -+ * Patch and some changes to v.2.3.4 by skiidoo (2007) -+ * -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+ -+#define MODULE_NAME "logs2html" -+#define MAKING_LOGS2HTML -+#include "src/mod/module.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "logs2html.h" -+#include "language.h" -+ -+#undef global -+ -+#define MODULE_MAJOR 2 -+#define MODULE_MINOR 4 -+#define MODULE_SUBMINOR 3 -+#define MODULE_BUILD "(ac100-ru fork)" -+ -+static Function *global = NULL; -+ -+static int shtime; -+static int keep_all_logs; -+static char logfile_suffix[21]; -+ -+static int lines_per_page; -+static int start_year; -+static int month_block_orientation; -+static int dont_print_time; -+static int dont_print_join; -+static int dont_print_left; -+static int dont_print_modechange; -+static int dont_print_nickchange; -+static int dont_print_kick; -+static int dont_print_else; -+ -+static int month_cols_count = 3; -+static int month_rows_count = 4; -+ -+static char mainpage_top_filename[257] = "\0"; -+static char mainpage_bottom_filename[257] = "\0"; -+static char logspage_top_filename[257] = "\0"; -+static char logspage_bottom_filename[257] = "\0"; -+static char userstyle_filename[257] = "\0"; -+static char encoding_string[31] = "\0"; -+ -+static l2hchan_t *logs2htmlchanlist = NULL; // Here we keep list of our logs -+ -+/* for language file */ -+static char month_names[12][MAX_MONTH_LENGTH]; -+static char days_names[7][MAX_DAY_LENGTH]; -+ -+static regex_t re_uri, re_uritrunc, re_email; -+ -+static void logs2html_hook_5minutely(void); -+static void logs2html_hook_hourly(void); -+static void logs2html_hook_rehash(void); -+static void logs2html_hook_pre_rehash(void); -+static void event_addlogs2htmlchan(void); -+ -+#ifndef _strlcpy -+#include "strlcpy.c" -+#endif -+#include "fileoperations.c" -+#include "htmloperations.c" -+#include "tcllogs2html.c" -+ -+ -+/* -+ * Code starts here -+ */ -+ -+/* -+ * getdayofweek() -+ * Input: -+ * year - год -+ * month - месяц -+ * day - день -+ * -+ * Output: -+ * 0 - Понедельник, 1 - Вторник, 2 - Среда и.т.д. -+ * -+ * Description: -+ * Функция вычисляет на какой день недели приходится переданная дата -+ */ -+static int getdayofweek(int year, int month, int day) -+{ -+ long int d1, d2, d3; -+ -+ long int tdays = year * 12 + month - 3; -+ month = tdays % 12; -+ year = (tdays - month) / 12; -+ -+ d1 = ((146097 * (year - (year % 100)) / 100) - ((146097 * (year - (year % 100)) / 100) % 4)) / 4; -+ d2 = ((1461 * (year % 100)) - ((1461 * (year % 100)) % 4)) / 4; -+ d3 = ((153 * month + 2) - ((153 * month + 2) % 5)) / 5 + day + 1721119; -+ -+ return (d1 + d2 + d3) % 7; -+} /* getdayofweek() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void makeindexpage(l2hchan_t *ch, int year) { -+ /* Compute how many rows we need */ -+ if (month_cols_count < 0) { month_cols_count = 3; } -+ if (month_cols_count > 12) { month_cols_count = 12; } -+ month_rows_count = (int)ceil(12.0 / (double)month_cols_count); -+ -+ time_t t = time(NULL); -+ struct tm tblock = *localtime(&t); -+ -+ FILE *file; -+ // calculate maximum possible filenamelength -+ int filenamelength = strlen(ch->outputpath) + strlen(SEP) + MAX(strlen(ch->mainpagename), strlen(ch->logspagename) + strlen("00") + strlen("00") + strlen("_pg000000")) + strlen("0000") + strlen(".html") + 1; -+ char *filename = nmalloc(filenamelength); -+ -+ egg_snprintf(filename, filenamelength, "%s%sdefault.css", ch->outputpath, SEP); -+ if ((file = openfile(filename, "wb", false)) == NULL) { -+ nfree(filename); -+ return; -+ } -+ WriteCSSFile(file); -+ fclose(file); -+ -+ if (tblock.tm_year + 1900 == year) { -+ egg_snprintf(filename, filenamelength, "%s%s%s.html", ch->outputpath, SEP, ch->mainpagename); -+ } else { -+ egg_snprintf(filename, filenamelength, "%s%s%s%d.html", ch->outputpath, SEP, ch->mainpagename, year); -+ } -+ if ((file = openfile(filename, "wb", false)) == NULL) { -+ nfree(filename); -+ return; -+ } -+ -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ if (strlen(encoding_string) > 0) {str_write(file, "\t\n", encoding_string); } -+ str_write(file, "\t\n", ch->mainpagetitle); -+ str_write(file, "\t\n", ch->mainpagetitle); -+ str_write(file, "\t\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ if (strlen(userstyle_filename) > 0) str_write(file, "\t\n"); -+ str_write(file, "\t%s %d %s\n", ch->mainpagetitle, year, LOGS2HTML_YEAR); -+ str_write(file, "\t\n"); -+ str_write(file, "\n\n"); -+ -+ str_write(file, "\n"); -+ str_write(file, "\t
\n"); -+ -+ if (strlen(mainpage_top_filename) > 0) { -+ str_write(file, "\t\t
\n"); -+ writefromexfile(file, mainpage_top_filename); -+ str_write(file, "\n\t\t
\n"); -+ } -+ -+ str_write(file, "\t\t
\n

%s
%d %s

\n\t\t
\n", ch->mainpagetitle, year, LOGS2HTML_YEAR); -+ str_write(file, "\t\t
\n"); -+ -+ int loopyear; -+ for(loopyear = start_year; loopyear <= tblock.tm_year + 1900; loopyear++) { -+ str_write(file, "\t\t\t
"); -+ if (loopyear == year) { -+ str_write(file, "%d", loopyear); -+ } else { -+ if (tblock.tm_year + 1900 == loopyear) { -+ egg_snprintf(filename, filenamelength, "%s.html", ch->mainpagename); -+ } else { -+ egg_snprintf(filename, filenamelength, "%s%d.html", ch->mainpagename, loopyear); -+ } -+ str_write(file, "%d", filename, loopyear); -+ } -+ str_write(file, "
\n"); -+ } -+ str_write(file, "\t\t
\n\n"); -+ str_write(file, "\t\t
\n"); -+ str_write(file, "\t\t\t\n"); -+ -+ int i, j, k; -+ str_write(file, "\t\t\t\t\n"); -+ for(k = 0; k < month_cols_count; k++) { -+ str_write(file, "\t\t\t\t\t\n", (int)(100 / month_cols_count)); -+ } -+ str_write(file, "\t\t\t\t\n"); -+ -+ for(i = 0; i < month_rows_count; i++) { -+ str_write(file, "\t\t\t\t\n"); -+ for(j = 0; j < month_cols_count; j++) { -+ int month = i * month_cols_count + j; -+ int row, col; -+ -+ str_write(file, "\t\t\t\t\t\n"); -+ } -+ str_write(file, "\t\t\t\t\n"); -+ } -+ -+ str_write(file, "\t\t\t
\n\t\t\t\t\t\t\n"); -+ str_write(file, "\t\t\t\t\t\t\t\n"); -+ for(k = 0; k < 7; k++) { -+ str_write(file, "\t\t\t\t\t\t\t\t\n", (int)(100 / 7)); -+ } -+ str_write(file, "\t\t\t\t\t\t\t\n"); -+ -+ if ((month >= 0) && (month <= 11)) { -+ -+ if (month_block_orientation != 0) { -+ /* -+ * Horisontal block orientation -+ * Each table has: 1 row: month name, 1 row: day of week names, 6 rows: days of month -+ * 7 columns: days of month. -+ * Total we must create 8x7 table -+ */ -+ str_write(file, "\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n", month_names[month]); -+ str_write(file, "\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n", -+ days_names[0], days_names[1], days_names[2], days_names[3], days_names[4], days_names[5], days_names[6]); -+ for(row = 0; row < 6; row++) { -+ str_write(file, "\t\t\t\t\t\t\t\n", (row % 2 == 0) ? "odd" : "even"); -+ for(col = 0; col < 7; col++) { -+ int day = row * 7 + (col + 1) - getdayofweek(year, month + 1, 1); -+ if ((day >= 1) && (day <= DAYS_IN_MONTH(year, month))) { -+ egg_snprintf(filename, filenamelength, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, year, month + 1, day, 1); -+ //Lets check if file exist and we can paste link to it. If not exist we try to make it. -+ if (!file_readable(filename)) { -+ convertfile(ch, year, month + 1, day); -+ } -+ if (file_readable(filename)) { -+ /* let write withount full path */ -+ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month + 1, day, 1); -+ str_write(file, "\t\t\t\t\t\t\t\t\n", filename, day); -+ } else { -+ str_write(file, "\t\t\t\t\t\t\t\t\n", day); -+ } -+ } else { -+ str_write(file, "\t\t\t\t\t\t\t\t\n"); -+ } -+ } -+ str_write(file, "\t\t\t\t\t\t\t\n"); -+ } -+ } else { -+ /* -+ * Vertical block orientation -+ * Each table has: 1 row: month name, 7 rows: (day of week + days of month) names, -+ * 1 column: day of week names, 6 columns: days of month. -+ * Total we must create 8x7 table -+ */ -+ str_write(file, "\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n", month_names[month]); -+ for(row = 0; row < 7; row++) { -+ str_write(file, "\t\t\t\t\t\t\t\n", (row % 2 == 0) ? "odd" : "even"); -+ for(col = 0; col < 7; col++) { -+ /* First column - day names. */ -+ if (col == 0) { -+ if (row == 6) { -+ str_write(file, "\t\t\t\t\t\t\t\t\n", days_names[row]); -+ } else { -+ str_write(file, "\t\t\t\t\t\t\t\t\n", days_names[row]); -+ } -+ continue; -+ } -+ int day = (col - 1) * 7 + (row + 1) - getdayofweek(year, month + 1, 1); -+ if ((day >= 1) && (day <= DAYS_IN_MONTH(year, month))) { -+ egg_snprintf(filename, filenamelength, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, year, month + 1, day, 1); -+ //Lets check if file exist and we can paste link to it. If not exist we try to make it. -+ if (!file_readable(filename)) { -+ convertfile(ch, year, month + 1, day); -+ } -+ if (file_readable(filename)) { -+ /* let write withount full path */ -+ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month + 1, day, 1); -+ str_write(file, "\t\t\t\t\t\t\t\t\n", filename, day); -+ } else { -+ str_write(file, "\t\t\t\t\t\t\t\t\n", day); -+ } -+ } else { -+ str_write(file, "\t\t\t\t\t\t\t\t\n"); -+ } -+ } -+ str_write(file, "\t\t\t\t\t\t\t\n"); -+ } -+ } -+ } else { -+ /* No more months :) Write empty month block */ -+ for(row = 0; row < 8; row++) { -+ str_write(file, "\t\t\t\t\t\t\t\n"); -+ } -+ } -+ str_write(file, "\t\t\t\t\t\t
%s
%s%s%s%s%s%s%s
%d%d 
%s
%s%s%d%d 
       
\n\t\t\t\t\t
\n"); -+ str_write(file, "\t\t
\n\n"); -+ -+ str_write(file, "\t\t
\n"); -+ str_write(file, "\t\t
\n

Generated by logs2html module for eggdrop v.%d.%d.%d%s
", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD); -+ str_write(file, "Find latest version at http://sourceforge.net/projects/logs2html or http://www.halftone.ru
"); -+ str_write(file, "Fork at https://github.com/ac100-ru/logs2html.mod

\n\t\t
\n"); -+ -+ if (strlen(mainpage_bottom_filename) > 0) { -+ str_write(file, "\t\t
\n"); -+ writefromexfile(file, mainpage_bottom_filename); -+ str_write(file, "\n\t\t
\n"); -+ } -+ -+ str_write(file, "\t
\n"); -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ -+ fclose(file); -+ nfree(filename); -+ -+ return; -+} /* makeindexpage() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+/* -+ * function void convertfile(l2hchan_t *ch, int year, int month, int day) -+ * -+ * Input: -+ * -+ * -+ * -+ * Output: -+ * -+ * -+ * Discription: -+ * переводит файлы из текстового вида в формат HTML -+ */ -+static void convertfile(l2hchan_t *ch, int year, int month, int day) { -+ -+ FILE *file, *src_file; -+ char buffer[LOGLINELEN], data[LOGLINELEN], ct[81], stamp[33]; -+ char *buf_ptr; -+ -+ struct tm tblock; -+ tblock.tm_year = year - 1900; -+ tblock.tm_mon = month - 1; -+ tblock.tm_mday = day; -+ tblock.tm_wday = getdayofweek(year, month, day); -+ tblock.tm_hour = 0; -+ tblock.tm_min = 0; -+ tblock.tm_sec = 1; -+ if (!logfile_suffix[0]) -+ egg_strftime(ct, 12, ".%d%b%Y", &tblock); -+ else -+ egg_strftime(ct, 80, logfile_suffix, &tblock); -+ ct[80] = '\0'; -+ -+ // calculate maximum possible filenamelength -+ int filenamelength = MAX(strlen(ch->outputpath), strlen(ch->inputpath)) + MAX(strlen(SEP) + strlen(ch->logspagename) + strlen("0000") + strlen("00") + strlen("00") + strlen("_pg000000") + strlen(".html"), strlen(ct)) + 1; -+ char *filename = nmalloc(filenamelength); -+ egg_snprintf(filename, filenamelength, "%s%s", ch->inputpath, ct); -+ if ((src_file = openfile(filename, "r", true)) == NULL) { -+ nfree(filename); -+ return; -+ } -+ -+ if (lines_per_page < 0) lines_per_page = 0; -+ -+ int lines_count, tsl; -+ int pages_count = 0; -+ while(!feof(src_file)) { -+ lines_count = lines_per_page; -+ pages_count++; -+ -+ egg_snprintf(filename, filenamelength, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, year, month, day, pages_count); -+ if ((file = openfile(filename, "wb", false)) == NULL) { -+ fclose(src_file); -+ putlog(LOG_MISC, "*", "logs2html: Error occured on converting %d page of file \"%s\"!", pages_count, filename); -+ nfree(filename); -+ return; -+ } -+ -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ if (strlen(encoding_string) > 0) {str_write(file, "\t\n", encoding_string); } -+ str_write(file, "\t\n", ch->logspagetitle); -+ str_write(file, "\t\n", ch->logspagetitle); -+ str_write(file, "\t\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ str_write(file, "\t\n"); -+ if (strlen(userstyle_filename) > 0) str_write(file, "\t\n"); -+ str_write(file, "\t%s. %d/%d/%d.\n", ch->logspagetitle, day, month, year); -+ str_write(file, "\t\n"); -+ str_write(file, "\n\n"); -+ -+ str_write(file, "\n"); -+ str_write(file, "\t
\n"); -+ -+ if (strlen(logspage_top_filename) > 0) { -+ str_write(file, "\t\t
\n"); -+ writefromexfile(file, logspage_top_filename); -+ str_write(file, "\n\t\t
\n"); -+ } -+ -+ str_write(file, "\t\t
\n", ch->mainpagetitle, year, LOGS2HTML_YEAR); -+ str_write(file, "\t\t\t\n"); -+ -+ str_write(file, "\t\t
\n"); -+ str_write(file, "\t\t
\n"); -+ -+ time_t t = time(NULL); -+ tblock = *localtime(&t); -+ if (tblock.tm_year + 1900 == year) { -+ str_write(file, "\t\t\t\n", ch->mainpagename, LOGS2HTML_MAINPAGE); -+ } else { -+ str_write(file, "\t\t\t\n", ch->mainpagename, year, LOGS2HTML_MAINPAGE); -+ } -+ -+ while ((lines_count > 0) || (lines_per_page == 0)) { -+ -+ buf_ptr = fgets(buffer, sizeof buffer, src_file); -+ if (buf_ptr == NULL) break; -+ -+ remove_crlf(&buf_ptr); -+ if (!buf_ptr[0]) continue; -+ -+ /* if timestamp exist cut time from string */ -+ data[0] = '\0'; -+ strcat(data, "\t\t\t
 "); -+ if (shtime) { -+ egg_strftime(stamp, sizeof(stamp) - 1, LOG_TS, &tblock); /* Print dummy time */ -+ tsl = strlen(stamp); -+ if (dont_print_time == 0) { -+ strcat(data, ""); -+ strncat(data, buf_ptr, tsl); -+ strcat(data, " "); -+ } -+ buf_ptr += (++tsl); -+ } -+ if (strncmp(buf_ptr, "--- ", 4) == 0) { /* we don't really need this string I think */ -+ continue; -+ } -+ -+ bool IsElseClass = false; -+ if (strncmp(buf_ptr, "Action: ", 8) == 0) { /* command: /me */ -+ str_write(file, "%s", data); -+ buf_ptr += 7; -+ str_write(file, " ***"); -+ } else { /* nick */ -+ char *p = strstr(buf_ptr, "> "); -+ if ((p != NULL) && (strncmp(buf_ptr, "<", 1) == 0)) { -+ str_write(file, "%s", data); -+ buf_ptr++; -+ data[0] = '\0'; -+ strncat(data, buf_ptr, p - buf_ptr); -+ str_write(file, "<%s> ", data); -+ buf_ptr += (p - buf_ptr + 1); -+ } else { -+ IsElseClass = true; -+ if (strstr(buf_ptr, " joined ") != NULL) { -+ if (dont_print_join != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else if (strstr(buf_ptr, " left irc: ") != NULL) { -+ if (dont_print_left != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else if (strstr(buf_ptr, " left ") != NULL) { -+ if (dont_print_left != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else if (strstr(buf_ptr, "Nick change: ") != NULL) { -+ if (dont_print_nickchange != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else if (strstr(buf_ptr, ": mode change '") != NULL) { -+ if (dont_print_modechange != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else if (strstr(buf_ptr, " kicked from ") != NULL) { -+ if (dont_print_kick != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } else { -+ if (dont_print_else != 0) {continue; } -+ str_write(file, "%s", data); -+ str_write(file, " "); -+ } -+ } -+ } -+ -+ lines_count--; -+ -+ char *realloc_buf = NULL; -+ replace_chars(buf_ptr, &realloc_buf); -+ // We have special chars that we replaced. Now point buf_ptr to the realloc_buf, -+ // strip_codes() will now work not with 'buffer' but with 'realloc_buf' -+ if (realloc_buf != NULL) { -+ buf_ptr = realloc_buf; -+ } -+ -+ l2hnode_t *tree = NULL; -+ strip_codes(buf_ptr, &tree); -+ l2hnode_t *ptree, *qtree; ptree = qtree = tree; -+ -+ data[0] = '\0'; -+ int last_tag = 0; -+ while (tree != NULL) { -+ if (tree->node_so != last_tag) { -+ data[0] = '\0'; -+ strncat(data, buf_ptr + last_tag, tree->node_so - last_tag); last_tag = tree->node_so; -+ str_write(file, "%s", data); -+ } -+ -+ switch (tree->node_type) { -+ case NODE_MIRCCOLOR: -+ { -+ if (tree->node_close) { -+ str_write(file, ""); -+ } -+ if (tree->node_data != NULL) { -+ str_write(file, "", tree->node_data); -+ } -+ } -+ break; -+ case NODE_FONTSTYLE: -+ { -+ if (tree->node_close) { -+ str_write(file, ""); -+ } else { -+ str_write(file, "", tree->node_data); -+ } -+ } -+ break; -+ case NODE_EMAIL: -+ { -+ if (!IsElseClass) { //Don't print emails on join/left, bans etc. Because client mask is look like email. -+ if (tree->node_close) { -+ str_write(file, ""); -+ } else { -+ str_write(file, "", tree->node_data); -+ } -+ } -+ } -+ break; -+ case NODE_URI: -+ { -+ if (tree->node_close) { -+ str_write(file, ""); -+ } else { -+ str_write(file, "", tree->node_data); -+ } -+ } -+ break; -+ case NODE_SPECIAL: -+ { -+ str_write(file, "%s", tree->node_data); -+ } -+ break; -+ } -+ -+ tree = tree->next; -+ } -+ str_write(file, "%s", buf_ptr + last_tag); -+ -+ str_write(file, "
\n"); -+ -+ // clear memory -+ while (qtree != NULL) { -+ qtree = ptree->next; -+ if (ptree->node_data != NULL) { nfree(ptree->node_data); } -+ nfree(ptree); -+ ptree = qtree; -+ } -+ if (realloc_buf != NULL) { -+ nfree(realloc_buf); -+ } -+ } -+ fclose(file); -+ } -+ fclose(src_file); -+ -+ /* -+ * Now, if log is splited to some number of lines (lines_per_page) we write links to other pages, and also final close tags for html files. -+ */ -+ int i, j; -+ for (i = 1; i <= pages_count; i++) { -+ egg_snprintf(filename, filenamelength, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, year, month, day, i); -+ if ((file = openfile(filename, "ab", false)) == NULL) { -+ putlog(LOG_MISC, "*", "logs2html: Error occured on converting %d page of file \"%s\"!", i, filename); -+ nfree(filename); -+ return; -+ } -+ -+ str_write(file, "\t\t
\n"); -+ if (pages_count > 1) { -+ str_write(file, "\t\t
"); -+ if (i == 1) { -+ str_write(file, LOGS2HTML_BACK); -+ } else { -+ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, i-1); -+ str_write(file, " %s", filename, LOGS2HTML_BACK); -+ } -+ str_write(file, " "); -+ if (i == pages_count) { -+ str_write(file, LOGS2HTML_NEXT); -+ } else { -+ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, i+1); -+ str_write(file, "%s ", filename, LOGS2HTML_NEXT); -+ } -+ str_write(file, "
"); -+ for (j = 1; j <= pages_count; j++) { -+ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, j); -+ if (j != i) { -+ str_write(file, "%d", filename, j); -+ } else { -+ str_write(file, "%d", j); -+ } -+ } -+ str_write(file, "
\n"); -+ } -+ str_write(file, "\t\t\n", LOGS2HTML_UP); -+ -+ str_write(file, "\t\t
\n"); -+ str_write(file, "\t\t
\n

Generated by logs2html module for eggdrop v.%d.%d.%d%s
", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD); -+ str_write(file, "Find latest version at http://sourceforge.net/projects/logs2html or http://www.halftone.ru
"); -+ str_write(file, "Fork at http://github.com/ac100-ru/logs2html.mod

\n\t\t
\n"); -+ -+ if (strlen(logspage_bottom_filename) > 0) { -+ str_write(file, "\t\t
\n"); -+ writefromexfile(file, logspage_bottom_filename); -+ str_write(file, "\n\t\t
\n"); -+ } -+ -+ str_write(file, "\t
\n"); -+ str_write(file, "\n"); -+ str_write(file, "\n"); -+ -+ fclose(file); -+ } -+ -+ nfree(filename); -+ -+ return; -+} /* convertfile() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void strip_codes(char *buf_ptr_copy, l2hnode_t **string_tree) { -+ /* -+ * void strip_mirc_codes(int flags, char *text) -+ * copied from src/dcc.c and modified -+ * -+ * Copyright (C) 1997 Robey Pointer -+ * Copyright (C) 1999 - 2006 Eggheads Development Team -+ */ -+ char *dd = buf_ptr_copy; -+ char *start = buf_ptr_copy; -+ bool t_0x02_opened, t_0x03_opened, t_0x07_opened, t_0x1f_opened; -+ t_0x02_opened = t_0x03_opened = t_0x07_opened = t_0x1f_opened = false; -+ -+ l2hnode_t *temp_tree = NULL; -+ l2hnode_t *newnode; -+ -+ char fg_color[3], bg_color[3]; -+ bg_color[0] = '\0'; -+ while (*buf_ptr_copy) { -+ switch (*buf_ptr_copy) { -+ case 0xf: /* close all open tags */ -+ { -+ buf_ptr_copy++; -+ if (t_0x02_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x02_opened = false; -+ } -+ if (t_0x07_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x07_opened = false; -+ } -+ if (t_0x1f_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x1f_opened = false; -+ } -+ if (t_0x03_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_MIRCCOLOR; -+ newnode->node_so = dd - start; -+ newnode->node_data = NULL; -+ newnode->node_close = true; -+ node_append(&temp_tree, newnode); -+ t_0x03_opened = false; -+ bg_color[0] = '\0'; -+ } -+ continue; -+ } -+ break; -+ case 3: /* mIRC colors? */ -+ { -+ buf_ptr_copy++; /* Skip over the ^C */ -+ fg_color[0] = '\0'; -+ if (egg_isdigit(*buf_ptr_copy)) { /* Is the first char a number? */ -+ fg_color[0] = *buf_ptr_copy; -+ fg_color[1] = '\0'; -+ buf_ptr_copy ++; /* Skip over the first digit */ -+ if (egg_isdigit(*buf_ptr_copy)) { /* Is this a double digit number? */ -+ fg_color[1] = *buf_ptr_copy; -+ fg_color[2] = '\0'; -+ buf_ptr_copy++; -+ } -+ // Even if we don't have background color in bg_color we have previous background, and we'll use it -+ if (*buf_ptr_copy == ',') { /* Do we have a background color next? */ -+ buf_ptr_copy++; /* Skip over the , */ -+ if (egg_isdigit(*buf_ptr_copy)) { -+ bg_color[0] = *buf_ptr_copy; -+ bg_color[1] = '\0'; -+ buf_ptr_copy ++; /* Skip over the first digit */ -+ } -+ if (egg_isdigit(*buf_ptr_copy)) { /* Is this a double digit number? */ -+ bg_color[1] = *buf_ptr_copy; -+ bg_color[2] = '\0'; -+ buf_ptr_copy++; /* Is it a double digit? */ -+ } -+ } -+ -+ if ((strlen(fg_color) > 0) && ((atoi(fg_color) < 0) || (atoi(fg_color) > 15))) { -+ fg_color[0] = '\0'; -+ } -+ if (((strlen(bg_color) > 0) && ((atoi(bg_color) < 0) || (atoi(bg_color) > 15))) || (strlen(fg_color) == 0)) { -+ bg_color[0] = '\0'; -+ } -+ -+ if (strlen(fg_color) > 0) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_MIRCCOLOR; -+ newnode->node_so = dd - start; -+ newnode->node_close = t_0x03_opened; -+ if (strlen(bg_color) > 0) { -+ newnode->node_data = nmalloc(6); -+ egg_snprintf(newnode->node_data, 6, "c%02.2d%02.2d", atoi(fg_color), atoi(bg_color)); -+ } else { -+ newnode->node_data = nmalloc(4); -+ egg_snprintf(newnode->node_data, 4, "f%02.2d", atoi(fg_color)); -+ } -+ node_append(&temp_tree, newnode); -+ t_0x03_opened = true; -+ } -+ } else { /* Single ^C char - it was a close tag */ -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_MIRCCOLOR; -+ newnode->node_so = dd - start; -+ newnode->node_data = NULL; -+ newnode->node_close = t_0x03_opened; -+ node_append(&temp_tree, newnode); -+ t_0x03_opened = false; -+ bg_color[0] = '\0'; -+ } -+ continue; -+ } -+ break; -+ case 2: /* Bold text */ -+ { -+ buf_ptr_copy++; -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = t_0x02_opened; -+ if (t_0x02_opened) { -+ newnode->node_data = NULL; -+ } else { -+ newnode->node_data = nmalloc(strlen("font-weight:bold") + 1); -+ strlcpy(newnode->node_data, "font-weight:bold", strlen("font-weight:bold") + 1); -+ } -+ t_0x02_opened = !t_0x02_opened; -+ node_append(&temp_tree, newnode); -+ continue; -+ } -+ break; -+ case 7: /* Italic text */ -+ { -+ buf_ptr_copy++; -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = t_0x07_opened; -+ if (t_0x07_opened) { -+ newnode->node_data = NULL; -+ } else { -+ newnode->node_data = nmalloc(strlen("font-style:italic") + 1); -+ strlcpy(newnode->node_data, "font-style:italic", strlen("font-style:italic") + 1); -+ } -+ t_0x07_opened = !t_0x07_opened; -+ node_append(&temp_tree, newnode); -+ continue; -+ } -+ break; -+ case 0x16: /* Reverse video */ -+ { -+ buf_ptr_copy++; -+ continue; -+ } -+ break; -+ case 0x1f: /* Underlined text */ -+ { -+ buf_ptr_copy++; -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = t_0x1f_opened; -+ if (t_0x1f_opened) { -+ newnode->node_data = NULL; -+ } else { -+ newnode->node_data = nmalloc(strlen("text-decoration:underline") + 1); -+ strlcpy(newnode->node_data, "text-decoration:underline", strlen("text-decoration:underline") + 1); -+ } -+ t_0x1f_opened = !t_0x1f_opened; -+ node_append(&temp_tree, newnode); -+ continue; -+ } -+ break; -+ case 033: -+ { -+ buf_ptr_copy++; -+ if (*buf_ptr_copy == '[') { -+ buf_ptr_copy++; -+ while ((*buf_ptr_copy == ';') || egg_isdigit(*buf_ptr_copy)) { -+ buf_ptr_copy++; -+ } -+ if (*buf_ptr_copy) { -+ buf_ptr_copy++; /* also kill the following char */ -+ } -+ } -+ continue; -+ } -+ break; -+ } -+ *dd++ = *buf_ptr_copy++; /* Move on to the next char */ -+ } -+ *dd = 0; -+ /* -+ * strip_mirc_codes() ends here. -+ */ -+ -+ //At that point we have temp_tree which points to the linked list of mirc codes and special chars (bold, italic) positions. -+ // Now close any unclose tag -+ -+ if (t_0x02_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x02_opened = false; -+ } -+ if (t_0x07_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x07_opened = false; -+ } -+ if (t_0x1f_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_FONTSTYLE; -+ newnode->node_so = dd - start; -+ newnode->node_close = true; -+ newnode->node_data = NULL; -+ node_append(&temp_tree, newnode); -+ t_0x1f_opened = false; -+ } -+ if (t_0x03_opened) { -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_MIRCCOLOR; -+ newnode->node_so = dd - start; -+ newnode->node_data = NULL; -+ newnode->node_close = true; -+ node_append(&temp_tree, newnode); -+ t_0x03_opened = false; -+ bg_color[0] = '\0'; -+ } -+ -+ -+ // rewind to the start of the string -+ dd = start; -+ -+ int status_uri, status_email; -+ regmatch_t pmatch_uri, pmatch_email; -+ -+ do { -+ status_uri = regexec(&re_uri, dd, (size_t) 1, &pmatch_uri, 0); -+ status_email = regexec(&re_email, dd, (size_t) 1, &pmatch_email, 0); -+ -+ int method; -+ if ((status_email == 0) && (status_uri == 0)) { // We have uri & email in string -+ if (pmatch_uri.rm_so == pmatch_email.rm_so) { // I think that it never must be so, but if it is - better lets write it as simple text -+ method = 3; -+ } else if (pmatch_uri.rm_so > pmatch_email.rm_so) { -+ method = 1; -+ } else { -+ method = 2; -+ } -+ } else if ((status_email == 0) && (status_uri != 0)) { // We have only email in string -+ method = 1; -+ } else if ((status_email != 0) && (status_uri == 0)) { // We have only uri in string -+ method = 2; -+ } else { // No uri or email in string, simply assign temp_tree to result -+ method = 3; -+ } -+ -+ l2hnode_t *temp; -+ if (method == 1) { -+ while ((temp_tree != NULL) && (temp_tree->node_so < pmatch_email.rm_so + (dd - start))) { -+ temp = temp_tree; -+ temp_tree = temp_tree->next; -+ temp->next = NULL; -+ node_append(string_tree, temp); -+ } -+ -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_EMAIL; -+ newnode->node_so = pmatch_email.rm_so + (dd - start); -+ newnode->node_data = nmalloc(pmatch_email.rm_eo - pmatch_email.rm_so + 1); -+ newnode->node_data[0] = '\0'; -+ strncat(newnode->node_data, dd + pmatch_email.rm_so, pmatch_email.rm_eo - pmatch_email.rm_so); -+ newnode->node_close = false; -+ node_append(string_tree, newnode); -+ -+ while ((temp_tree != NULL) && ((temp_tree->node_so < pmatch_email.rm_eo + (dd - start)) || ((temp_tree->node_so == pmatch_email.rm_eo + (dd - start)) && (temp_tree->node_close == true)))) { -+ temp = temp_tree; -+ temp_tree = temp_tree->next; -+ temp->next = NULL; -+ node_append(string_tree, temp); -+ } -+ -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_EMAIL; -+ newnode->node_so = pmatch_email.rm_eo + (dd - start); -+ newnode->node_data = NULL; -+ newnode->node_close = true; -+ node_append(string_tree, newnode); -+ dd += pmatch_email.rm_eo; -+ continue; -+ } else if (method == 2) { -+ while ((temp_tree != NULL) && (temp_tree->node_so < pmatch_uri.rm_so + (dd - start))) { -+ temp = temp_tree; -+ temp_tree = temp_tree->next; -+ temp->next = NULL; -+ node_append(string_tree, temp); -+ } -+ -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_URI; -+ newnode->node_so = pmatch_uri.rm_so + (dd - start); -+ // if uri begins with protocol name - simply output our uri, else we must add protocol name to our uri -+ if (regexec(&re_uritrunc, dd + pmatch_uri.rm_so, (size_t) 0, NULL, 0) == 0) { -+ newnode->node_data = nmalloc(pmatch_uri.rm_eo - pmatch_uri.rm_so + 1); -+ newnode->node_data[0] = '\0'; -+ } else { -+ // if uri look like 'ftp.eggheads.org' we add 'ftp://' protocol, else let it be 'http://' -+ if (strncmp(dd + pmatch_uri.rm_so, "ftp.", 4) == 0) { -+ newnode->node_data = nmalloc(strlen("ftp://") + pmatch_uri.rm_eo - pmatch_uri.rm_so + 1); -+ newnode->node_data[0] = '\0'; -+ strncat(newnode->node_data, "ftp://", strlen("ftp://")); -+ } else { -+ newnode->node_data = nmalloc(strlen("http://") + pmatch_uri.rm_eo - pmatch_uri.rm_so + 1); -+ newnode->node_data[0] = '\0'; -+ strncat(newnode->node_data, "http://", strlen("http://")); -+ } -+ } -+ strncat(newnode->node_data, dd + pmatch_uri.rm_so, pmatch_uri.rm_eo - pmatch_uri.rm_so); -+ newnode->node_close = false; -+ node_append(string_tree, newnode); -+ -+ while ((temp_tree != NULL) && ((temp_tree->node_so < pmatch_uri.rm_eo + (dd - start)) || ((temp_tree->node_so == pmatch_uri.rm_eo + (dd - start)) && (temp_tree->node_close == true)))) { -+ temp = temp_tree; -+ temp_tree = temp_tree->next; -+ temp->next = NULL; -+ node_append(string_tree, temp); -+ } -+ -+ newnode = nmalloc(sizeof(struct l2hnode_struct)); -+ newnode->next = NULL; -+ newnode->node_type = NODE_URI; -+ newnode->node_so = pmatch_uri.rm_eo + (dd - start); -+ newnode->node_data = NULL; -+ newnode->node_close = true; -+ node_append(string_tree, newnode); -+ dd += pmatch_uri.rm_eo; -+ continue; -+ } else if (method == 3) { -+ while (temp_tree != NULL) { -+ temp = temp_tree; -+ temp_tree = temp_tree->next; -+ temp->next = NULL; -+ node_append(string_tree, temp); -+ } -+ break; -+ } -+ -+ } while ((status_email == 0) || (status_uri == 0)); -+ -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/* -+ * int list_append(struct list_type **h, struct list_type *i) -+ * copied from src/userent.c and modified -+ * -+ * Copyright (C) 1997 Robey Pointer -+ * Copyright (C) 1999 - 2006 Eggheads Development Team -+ */ -+static void node_append(struct l2hnode_struct **h, struct l2hnode_struct *i) -+{ -+ for (; *h; h = &((*h)->next)); -+ *h = i; -+ return; -+} -+/* -+ * list_append() ends here. -+ */ -+ -+ -+/****************************************************************************/ -+static void replace_chars(char *buf_ptr_copy, char **realloc_buf) -+{ -+ // Loop through string if there are chars, which we can safely replace with their xhtml analog, -+ // if there are - count number of bytes we need our string to grow -+ int realloc_size = 0; -+ char *dd = buf_ptr_copy; -+ -+ while (*dd) { -+ switch (*dd) { -+ case 0x3c: /* < */ -+ { -+ realloc_size += strlen("<") - strlen("<"); -+ } -+ break; -+ case 0x3e: /* > */ -+ { -+ realloc_size += strlen(">") - strlen(">"); -+ } -+ break; -+ case 0x22: /* " */ -+ { -+ realloc_size += strlen(""") - strlen(""""); -+ } -+ break; -+ case 0x26: /* & */ -+ { -+ realloc_size += strlen("&") - strlen("&"); -+ } -+ break; -+ } -+ dd++; /* Move on to the next char */ -+ } -+ -+ if (realloc_size > 0) { -+ (*realloc_buf) = nmalloc(strlen(buf_ptr_copy) + realloc_size + 1); -+ dd = (*realloc_buf); *dd = '\0'; -+ -+ while (*buf_ptr_copy) { -+ switch (*buf_ptr_copy) { -+ case 0x3c: /* < */ -+ { -+ strncat(dd, "<", strlen("<")); -+ buf_ptr_copy++; dd += strlen("<"); -+ continue; -+ } -+ break; -+ case 0x3e: /* > */ -+ { -+ strncat(dd, ">", strlen(">")); -+ buf_ptr_copy++; dd += strlen(">"); -+ continue; -+ } -+ break; -+ case 0x22: /* " */ -+ { -+ strncat(dd, """, strlen(""")); -+ buf_ptr_copy++; dd += strlen("""); -+ continue; -+ } -+ break; -+ case 0x26: /* & */ -+ { -+ strncat(dd, "&", strlen("&")); -+ buf_ptr_copy++; dd += strlen("&"); -+ continue; -+ } -+ break; -+ } -+ *dd++ = *buf_ptr_copy++; /* Move on to the next char */ -+ *dd = '\0'; /* for strncat(), cause string must be null terminated or we'll get buffer overflow */ -+ } -+ *dd = 0; -+ } -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+/* -+ * function int cmd_makemainpage(struct userrec *u, int idx, char *par) -+ * -+ * Input: -+ * -+ * -+ * -+ * Output: -+ * -+ * -+ * Discription: -+ * -+ */ -+static int cmd_makemainpage(struct userrec *u, int idx, char *par) { -+ -+ time_t start, finish; -+ time(&start); -+ putlog(LOG_CMDS, "*", "#%s# begin creation of index pages.", dcc[idx].nick); -+ -+ time_t t = time(NULL); -+ struct tm tblock = *localtime(&t); -+ -+ l2hchan_t *p = logs2htmlchanlist; -+ while (p != NULL) { -+ int i; -+ -+ start_year = MIN(MAX(start_year, 2000), tblock.tm_year + 1900); -+ -+ for (i = start_year; i <= tblock.tm_year + 1900; i++) { -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, i); -+ makeindexpage(p, i); -+ } -+ p = p->next; -+ } -+ -+ putlog(LOG_CMDS, "*", "#%s# creation of index pages finished.", dcc[idx].nick); -+ time(&finish); -+ double elapsed_time = difftime(finish, start); -+ if (elapsed_time == 0.0) { -+ putlog(LOG_CMDS, "*", "#%s# It takes < 1 second.", dcc[idx].nick); -+ } -+ else { -+ putlog(LOG_CMDS, "*", "#%s# It takes %f second%s.", dcc[idx].nick, elapsed_time, (elapsed_time != 1.0) ? "s" : ""); -+ } -+ -+ return 0; -+} /* cmd_makemainpage() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+/* -+ * function int convertalllogs(struct userrec *u, int idx, char *par) -+ * -+ * Input: -+ * -+ * -+ * -+ * Output: -+ * -+ * -+ * Discription: -+ * -+ */ -+static int cmd_convertalllogs(struct userrec *u, int idx, char *par) { -+ -+ return cmd_convertlogs(u, idx, "all"); -+} /* convertalllogs() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static int cmd_convertlogs(struct userrec *u, int idx, char *par) { -+ -+ time_t start, finish; -+ time(&start); -+ putlog(LOG_CMDS, "*", "#%s# begin creation of logfiles.", dcc[idx].nick); -+ -+ time_t t = time(NULL); -+ struct tm tblock = *localtime(&t); -+ -+ l2hchan_t *p = logs2htmlchanlist; -+ -+ if (!par[0]) { -+ -+ //no parameter. Convert log for all channels for current day. -+ while (p != NULL) { -+ dprintf(idx, " Converting log for channel '%s' for current day.\n", p->channame); -+ convertfile(p, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday); -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, tblock.tm_year + 1900); -+ makeindexpage(p, tblock.tm_year + 1900); -+ p = p->next; -+ } -+ -+ } else { -+ -+ int i, j, k; -+ start_year = MIN(MAX(start_year, 2000), tblock.tm_year + 1900); -+ char *part; -+ -+ part = newsplit(&par); -+ if (!egg_strncasecmp(part, "all", 3)) { // "all". Convert logs for all channels for all years. -+ -+ while (p != NULL) { -+ for (i = start_year; i <= tblock.tm_year + 1900; i++) { -+ dprintf(idx, " Creating logs for channel '%s' for %d year.\n", p->channame, i); -+ for (j = 0; j < 12; j++) { -+ for (k = 1; k <= DAYS_IN_MONTH(i, j); k++) { -+ convertfile(p, i, j + 1, k); -+ } -+ } -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, i); -+ makeindexpage(p, i); -+ } -+ p = p->next; -+ } -+ } else { // Check for year, month, day -+ -+ int year, month, day; -+ year = atoi(part); -+ if ((year < start_year) || (year > tblock.tm_year + 1900)) { // Check if parameter is valid year -+ dprintf(idx, " Invalid parameter. 'year' must be between %d and %d.\n", start_year, tblock.tm_year + 1900); -+ return 1; -+ } -+ part = newsplit(&par); -+ if (!part[0]) { // Is there second parameter? -+ -+ while (p != NULL) { -+ dprintf(idx, " Creating logs for channel '%s' for %d year.\n", p->channame, year); -+ for (j = 0; j < 12; j++) { -+ for (k = 1; k <= DAYS_IN_MONTH(year, j); k++) { -+ convertfile(p, year, j + 1, k); -+ } -+ } -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, year); -+ makeindexpage(p, year); -+ p = p->next; -+ } -+ -+ } else { // No second parameter. We have only year -+ -+ month = atoi(part); -+ if ((month < 1) || (month > 12)) { // Check if parameter is valid month -+ dprintf(idx, " Invalid parameter. 'month' must be between %d and %d.\n", 1, 12); -+ return 1; -+ } -+ part = newsplit(&par); -+ if (!part[0]) { // Is there third parameter? -+ -+ while (p != NULL) { -+ dprintf(idx, " Creating logs for channel '%s' for %d year, for %d month.\n", p->channame, year, month); -+ for (k = 1; k <= DAYS_IN_MONTH(year, month - 1); k++) { -+ convertfile(p, year, month, k); -+ } -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, year); -+ makeindexpage(p, year); -+ p = p->next; -+ } -+ -+ } else { // No third parameter, we have year and month -+ -+ day = atoi(part); -+ if ((day < 1) || (day > DAYS_IN_MONTH(year, month - 1))) { // Check if parameter is valid day -+ dprintf(idx, " Invalid parameter. 'day' must be between %d and %d.\n", 1, DAYS_IN_MONTH(year, month - 1)); -+ return 1; -+ } -+ -+ while (p != NULL) { -+ dprintf(idx, " Creating log for channel '%s' for %d year, for %d month, for %d day.\n", p->channame, year, month, day); -+ convertfile(p, year, month, day); -+ dprintf(idx, " Creating index page for channel '%s' for %d year.\n", p->channame, year); -+ makeindexpage(p, year); -+ p = p->next; -+ } -+ -+ } -+ -+ } -+ } -+ -+ } -+ -+ putlog(LOG_CMDS, "*", "#%s# creation of logfiles finished.", dcc[idx].nick); -+ time(&finish); -+ double elapsed_time = difftime(finish, start); -+ if (elapsed_time == 0.0) { -+ putlog(LOG_CMDS, "*", "#%s# It takes < 1 second.", dcc[idx].nick); -+ } -+ else { -+ putlog(LOG_CMDS, "*", "#%s# It takes %f second%s.", dcc[idx].nick, elapsed_time, (elapsed_time != 1.0) ? "s" : ""); -+ } -+ return 0; -+} /* convertlogs() */ -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void initialize(void) -+{ -+ strlcpy(month_names[0], LOGS2HTML_JANUARY, MAX_MONTH_LENGTH); -+ strlcpy(month_names[1], LOGS2HTML_FEBRIARY, MAX_MONTH_LENGTH); -+ strlcpy(month_names[2], LOGS2HTML_MARCH, MAX_MONTH_LENGTH); -+ strlcpy(month_names[3], LOGS2HTML_APRIL, MAX_MONTH_LENGTH); -+ strlcpy(month_names[4], LOGS2HTML_MAY, MAX_MONTH_LENGTH); -+ strlcpy(month_names[5], LOGS2HTML_JUNE, MAX_MONTH_LENGTH); -+ strlcpy(month_names[6], LOGS2HTML_JULY, MAX_MONTH_LENGTH); -+ strlcpy(month_names[7], LOGS2HTML_AUGUST, MAX_MONTH_LENGTH); -+ strlcpy(month_names[8], LOGS2HTML_SEPTEMBER, MAX_MONTH_LENGTH); -+ strlcpy(month_names[9], LOGS2HTML_OCTOBER, MAX_MONTH_LENGTH); -+ strlcpy(month_names[10],LOGS2HTML_NOVEMBER, MAX_MONTH_LENGTH); -+ strlcpy(month_names[11],LOGS2HTML_DECEMBER, MAX_MONTH_LENGTH); -+ strlcpy(days_names[0], LOGS2HTML_MONDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[1], LOGS2HTML_TUESDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[2], LOGS2HTML_WEDNESDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[3], LOGS2HTML_THURSDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[4], LOGS2HTML_FRIDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[5], LOGS2HTML_SATURDAY, MAX_DAY_LENGTH); -+ strlcpy(days_names[6], LOGS2HTML_SUNDAY, MAX_DAY_LENGTH); -+ -+ // Precompile our regular expressions -+ if (regcomp(&re_uri, "((file|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://|www\\.|ftp\\.)+(([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(/(([a-zA-Z0-9%_#:\\./=?-]|\\&)*([a-zA-Z0-9%_#:\\/=?-]|\\&))*)?", REG_EXTENDED|REG_ICASE) != 0) { -+ putlog(LOG_CMDS, "*", "logs2html: Error while making regular expression for uri."); -+ } -+ if (regcomp(&re_uritrunc, "^((file|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://){1}", REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) { -+ putlog(LOG_CMDS, "*", "logs2html: Error while making regular expression for truncate uri."); -+ } -+ if (regcomp(&re_email, "([a-zA-Z]([a-zA-Z0-9_\\-\\.]*[a-zA-Z0-9])*)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)", REG_EXTENDED|REG_ICASE) != 0) { -+ putlog(LOG_CMDS, "*", "logs2html: Error while making regular expression for email."); -+ } -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void finalize(void) -+{ -+ l2hchan_t *p, *q; -+ -+ p = q = logs2htmlchanlist; -+ while (q != NULL) { -+ q = p->next; -+ if (p->channame != NULL) nfree(p->channame); -+ if (p->inputpath != NULL) nfree(p->inputpath); -+ if (p->outputpath != NULL) nfree(p->outputpath); -+ if (p->mainpagename != NULL) nfree(p->mainpagename); -+ if (p->mainpagetitle != NULL) nfree(p->mainpagetitle); -+ if (p->logspagename != NULL) nfree(p->logspagename); -+ if (p->logspagetitle != NULL) nfree(p->logspagetitle); -+ nfree(p); -+ p = q; -+ } -+ logs2htmlchanlist = p = q = NULL; -+ -+ regfree(&re_email); -+ regfree(&re_uritrunc); -+ regfree(&re_uri); -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void logs2html_hook_5minutely(void) -+{ -+ time_t t = time(NULL); -+ struct tm tblock = *localtime(&t); -+ tblock.tm_hour = 0; -+ tblock.tm_min = 0; -+ tblock.tm_sec = 1; -+ -+ l2hchan_t *p = logs2htmlchanlist; -+ while (p != NULL) { -+ convertfile(p, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday); -+ makeindexpage(p, tblock.tm_year + 1900); -+ p = p->next; -+ } -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void logs2html_hook_hourly(void) -+{ -+ time_t t = time(NULL); -+ -+ struct tm tnow = *localtime(&t); -+ -+ t -= (time_t)(60); -+ -+ struct tm tblock = *localtime(&t); -+ tblock.tm_hour = 0; -+ tblock.tm_min = 0; -+ tblock.tm_sec = 1; -+ -+ //Let's convert log for previous day, because last 5 minutes of that log was not converted -+ //by logs2html_hook_5minutely(void) procedure. -+ if (tnow.tm_mday != tblock.tm_mday) { -+ l2hchan_t *p = logs2htmlchanlist; -+ while (p != NULL) { -+ convertfile(p, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday); -+ makeindexpage(p, tblock.tm_year + 1900); -+ p = p->next; -+ } -+ } -+ -+ //Let's convert logs for previous year, because name of the index page change from prefix.html to prefixPASTYEAR.html -+ if (tnow.tm_year != tblock.tm_year) { -+ int j, k; -+ -+ l2hchan_t *p = logs2htmlchanlist; -+ while (p != NULL) { -+ for (j = 0; j < 12; j++) { -+ for (k = 1; k <= DAYS_IN_MONTH(tblock.tm_year + 1900, j); k++) { -+ convertfile(p, tblock.tm_year + 1900, j + 1, k); -+ } -+ } -+ makeindexpage(p, tblock.tm_year + 1900); -+ p = p->next; -+ } -+ } -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void logs2html_hook_pre_rehash(void) -+{ -+ finalize(); -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+/****************************************************************************/ -+static void logs2html_hook_rehash(void) -+{ -+ initialize(); -+ -+ return; -+} -+/****************************************************************************/ -+ -+ -+static void event_addlogs2htmlchan(void) -+{ -+ check_tcl_event("addlogs2htmlchan"); -+ -+ return; -+} -+ -+ -+/* -+ * Calculate the memory we keep allocated. -+ */ -+static int logs2html_expmem() -+{ -+ int size = 0; -+ l2hchan_t *p = logs2htmlchanlist; -+ while (p != NULL) { -+ size += sizeof(struct l2hchan_struct); -+ if (p->channame != NULL) size += strlen(p->channame) + 1; -+ if (p->inputpath != NULL) size += strlen(p->inputpath) + 1; -+ if (p->outputpath != NULL) size += strlen(p->outputpath) + 1; -+ if (p->mainpagename != NULL) size += strlen(p->mainpagename) + 1; -+ if (p->mainpagetitle != NULL) size += strlen(p->mainpagetitle) + 1; -+ if (p->logspagename != NULL) size += strlen(p->logspagename) + 1; -+ if (p->logspagetitle != NULL) size += strlen(p->logspagetitle) + 1; -+ p = p->next; -+ } -+ -+ size += MAX_MONTH_LENGTH * 12; -+ size += MAX_DAY_LENGTH * 7; -+ -+ return size; -+} -+ -+/* A report on the module status. -+ * -+ * details is either 0 or 1: -+ * 0 - `.status' -+ * 1 - `.status all' or `.module logs2html' -+ */ -+static void logs2html_report(int idx, int details) -+{ -+ if (logs2htmlchanlist != NULL) { -+ l2hchan_t *p = logs2htmlchanlist; -+ -+ dprintf(idx, " logs2html channels list:\n"); -+ while (p != NULL) { -+ dprintf(idx, " Channel: '%s'.\n", p->channame); -+ dprintf(idx, " path to logfiles: '%s'\n", p->inputpath); -+ dprintf(idx, " path to generated html pages: '%s'.\n", p->outputpath); -+ p = p->next; -+ } -+ } -+ -+ if (details) { -+ int size = logs2html_expmem(); -+ dprintf(idx, " Using %d byte%s of memory\n", size, (size != 1) ? "s" : ""); -+ } -+ -+ return; -+} -+ -+static cmd_t mydcc[] = { -+ {"convertalllogs", "n", cmd_convertalllogs, NULL}, -+ {"makemainpage", "n", cmd_makemainpage, NULL}, -+ {"makeindexpage", "n", cmd_makemainpage, NULL}, -+ {"convertlogs", "n", cmd_convertlogs, NULL}, -+ {NULL, NULL, NULL, NULL} /* Mark end. */ -+}; -+ -+static tcl_strings my_tcl_strings[] = { -+ {"logfile-suffix", logfile_suffix, 20, 0}, -+ {"mainpage-top", mainpage_top_filename, 256, 0}, -+ {"mainpage-bottom", mainpage_bottom_filename, 256, 0}, -+ {"logspage-top", logspage_top_filename, 256, 0}, -+ {"logspage-bottom", logspage_bottom_filename, 256, 0}, -+ {"user-style", userstyle_filename, 256, 0}, -+ {"insert-encoding-str", encoding_string, 30, 0}, -+ {NULL, NULL, 0, 0} /* Mark end. */ -+}; -+ -+static tcl_ints my_tcl_ints[] = { -+ {"col-count", &month_cols_count, 0}, -+ {"lines-per-page", &lines_per_page, 0}, -+ {"start-year", &start_year, 0}, -+ {"month-block-orientation", &month_block_orientation, 0}, -+ {"dont-print-time", &dont_print_time, 0}, -+ {"dont-print-join", &dont_print_join, 0}, -+ {"dont-print-left", &dont_print_left, 0}, -+ {"dont-print-modechange", &dont_print_modechange, 0}, -+ {"dont-print-nickchange", &dont_print_nickchange, 0}, -+ {"dont-print-kick", &dont_print_kick, 0}, -+ {"dont-print-else", &dont_print_else, 0}, -+ {"log-time", &shtime, 1}, -+ {"keep-all-logs", &keep_all_logs, 1}, -+ {NULL, NULL, 0} /* Mark end. */ -+}; -+ -+ -+static char *logs2html_close() -+{ -+ -+ del_hook(HOOK_LOADED, (Function) event_addlogs2htmlchan); -+ del_hook(HOOK_REHASH, (Function) event_addlogs2htmlchan); -+ del_hook(HOOK_REHASH, (Function) logs2html_hook_rehash); -+ del_hook(HOOK_PRE_REHASH, (Function) logs2html_hook_pre_rehash); -+ del_hook(HOOK_HOURLY, (Function) logs2html_hook_hourly); -+ del_hook(HOOK_5MINUTELY, (Function) logs2html_hook_5minutely); -+ -+ finalize(); -+ -+ rem_help_reference(MODULE_NAME".help"); -+ del_lang_section(MODULE_NAME); -+ rem_builtins(H_dcc, mydcc); -+ rem_tcl_commands(my_tcl_cmds); -+ rem_tcl_strings(my_tcl_strings); -+ rem_tcl_ints(my_tcl_ints); -+ -+ module_undepend(MODULE_NAME); -+ -+ return NULL; -+} -+ -+EXPORT_SCOPE char *logs2html_start(); -+ -+static Function logs2html_table[] = { -+ (Function) logs2html_start, -+ (Function) logs2html_close, -+ (Function) logs2html_expmem, -+ (Function) logs2html_report, -+}; -+ -+char *logs2html_start(Function *global_funcs) -+{ -+ global = global_funcs; -+ -+ /* Register the module. */ -+ module_register(MODULE_NAME, logs2html_table, MODULE_MAJOR, MODULE_MINOR); -+ -+ if (!module_depend(MODULE_NAME, "eggdrop", 108, 0)) { -+ module_undepend(MODULE_NAME); -+ return "This module requires Eggdrop 1.6.18 or later."; -+ } -+ -+ add_tcl_ints(my_tcl_ints); -+ add_tcl_strings(my_tcl_strings); -+ add_tcl_commands(my_tcl_cmds); -+ add_builtins(H_dcc, mydcc); -+ add_lang_section(MODULE_NAME); -+ add_help_reference(MODULE_NAME".help"); -+ -+ initialize(); -+ -+ add_hook(HOOK_5MINUTELY, (Function) logs2html_hook_5minutely); -+ add_hook(HOOK_HOURLY, (Function) logs2html_hook_hourly); -+ add_hook(HOOK_PRE_REHASH, (Function) logs2html_hook_pre_rehash); -+ add_hook(HOOK_REHASH, (Function) logs2html_hook_rehash); -+ add_hook(HOOK_REHASH, (Function) event_addlogs2htmlchan); -+ add_hook(HOOK_LOADED, (Function) event_addlogs2htmlchan); -+ -+ return NULL; -+} -+ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.conf src/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.conf ---- ./src/mod/logs2html.mod/logs2html.conf 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/logs2html.conf 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,105 @@ -+###### -+##### -+### General Settings -+##### -+###### -+ -+# number of rows the month'll put out -+set col-count 3 -+ -+ -+# set how many lines there'll be on the one page of created html page. If it -+# set to 0 then all lines will be in one html page -+set lines-per-page 200 -+ -+ -+# Uncomment line if you want specify file with your own css settings for -+# generated pages -+#set user-style user.css -+ -+ -+# This setting allows you to insert meta tag -+# in your -+# html files. You can comment next line, that will mean that this tag'll not -+# be insert in the resulting page. -+set insert-encoding-str "windows-1251" -+ -+ -+# The start year, from which logs will be converted. The minimum is 2000 year. -+# (I think that should be enought) -+set start-year 2003 -+ -+ -+# set it to 1 not to print time in the html page, even if eggdrop's logfile has it -+set dont-print-time 0 -+ -+ -+# set it to 1 not to print join messages in the html page -+set dont-print-join 0 -+ -+ -+# set it to 1 not to print left messages in the html page -+set dont-print-left 0 -+ -+ -+# set it to 1 not to print mode changed messages in the html page -+set dont-print-modechange 0 -+ -+ -+# set it to 1 not to print nick change messages in the html page -+set dont-print-nickchange 0 -+ -+ -+# set it to 1 not to print kick messages in the html page -+set dont-print-kick 0 -+ -+ -+# set it to 1 not to print other irc messages in the html page -+set dont-print-else 0 -+ -+ -+# Orientation of the month blocks on index page. 0 - vertical, 1 - horizontal -+# Chose one you like more. -+set month-block-orientation 0 -+ -+ -+# Here you can specify path to files which content will be put to converted -+# logfile (or mainpage). For example you can add code for your counter -+# or banner. Uncomment the line you need and put there filename with path, -+# for example: set mainpage-top "mycounter.tpl" -+# Note: the content of specified file puts to the resulting file "as is", -+# without any transformation -+#set mainpage-top "" -+#set mainpage-bottom "" -+#set logspage-top "" -+#set logspage-bottom "" -+ -+ -+# now load the module -+loadmodule logs2html -+ -+ -+# Add your channels here. The format is: -+# addlogs2htmlchan channel output-path main-page-name main-page-title logs-page-prefix logs-page-title -+# channel - your channel which logs you want to convert -+# output-path - your ftp path, where converted files will be put -+# (don't forget to check settings to be sure bot have -+# permision write to the path you specify) -+# main-page-name - name of your mainpage (i.e. page with calendar) for -+# this channel. The "Main page" for current year name will be -+# "main-page-name.html", for the past years it will look like -+# "main-page-nameYY.html". For example if we set main-page-name -+# to "index", then main page for current year'll be "index.html", -+# and for 2008 year it will look like "index2008.html" -+# main-page-title - your mainpage title for this channel (will be shown -+# as the caption of the web page in your browser and as -+# the title of calendar) -+# logs-page-prefix - your logs page name (prefix) for this channel. -+# Resulting name will be "logs-page-prefixYYmmdd_pgN.html". -+# For example if we set "logs-page-prefix" to "mychan", then the -+# first page of logfile for the 1st january 2009 will look -+# like "mychan20090101_pg1.html" -+# logs-page-title - your logs page title for this channel (will be shown -+# as the caption of the web page in your browser) -+# Example: -+# addlogs2htmlchan #MyChannel "/home/www/logs" index "Logs of MyChannel" mychan "Log of MyChannel" -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.h src/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.h ---- ./src/mod/logs2html.mod/logs2html.h 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/logs2html.h 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,92 @@ -+/* -+ * logs2html.h -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Gray_Angel aka Shmupsik -+ * -+ * 2004-2009 year -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#ifndef _EGG_MOD_LOGS2HTML_LOGS2HTML_H -+#define _EGG_MOD_LOGS2HTML_LOGS2HTML_H -+ -+#include "src/lang.h" -+ -+#define SEP "/" -+ -+#ifndef MAX -+#define MAX(a,b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a > _b ? _a : _b; }) -+#endif -+ -+#ifndef MIN -+#define MIN(a,b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a < _b ? _a : _b; }) -+#endif -+ -+ -+typedef struct l2hchan_struct { -+ struct l2hchan_struct *next; -+ char *channame; /* Имя канала для которого конвертировать логи */ -+ char *inputpath; /* Имя (префикс) данного канала (вычисляется из выражения logfile в конфиге бота) */ -+ char *outputpath; /* Куда выводить конвертированные логи */ -+ char *mainpagename; /* Имя главной страницы */ -+ char *mainpagetitle; /* Заголовок на главной странице */ -+ char *logspagename; /* Имя (префикс) страницы переконвертированного логфайла */ -+ char *logspagetitle; /* Заголовок страницы логфайла */ -+} l2hchan_t; -+ -+typedef enum {NODE_MIRCCOLOR, NODE_FONTSTYLE, NODE_EMAIL, NODE_URI, NODE_SPECIAL} l2h_node; -+ -+typedef struct l2hnode_struct { -+ struct l2hnode_struct *next; -+ l2h_node node_type; -+ int node_so; // Start of special char -+ char *node_data; // Class fo mirc colors -+ bool node_close; -+} l2hnode_t; -+ -+/* -+ * For language files. Lets define max number of chars in month and days of week names -+ */ -+#define MAX_MONTH_LENGTH 15 -+#define MAX_DAY_LENGTH 6 -+ -+static int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -+ -+#define DAYS_IN_MONTH(year, month) (days_in_month[month] + (((month == 1) && ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))) ? 1 : 0)) -+ -+ -+static int cmd_convertalllogs(struct userrec *u, int idx, char *par); -+static int cmd_makemainpage(struct userrec *u, int idx, char *par); -+static int cmd_convertlogs(struct userrec *u, int idx, char *par); -+static int getdayofweek(int year, int month, int day); -+static FILE *openfile(char *newfilename, const char *mode, bool silent); -+static void str_write(FILE *file, char *fstr, ... ); -+static void writefromexfile(FILE *dst_file, char *exfilename); -+static void makeindexpage(l2hchan_t *ch, int year); -+static void convertfile(l2hchan_t *ch, int year, int month, int day); -+static void strip_codes(char *buf_ptr_copy, l2hnode_t **tree); -+static void node_append(struct l2hnode_struct **h, struct l2hnode_struct *i); -+static void replace_chars(char *buf_ptr_copy, char **realloc_buf); -+ -+ -+#endif /* _EGG_MOD_LOGS2HTML_LOGS2HTML_H */ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.mod.desc src/eggdrop-1.8.4/src/mod/logs2html.mod/logs2html.mod.desc ---- ./src/mod/logs2html.mod/logs2html.mod.desc 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/logs2html.mod.desc 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1 @@ -+This module converts the log files of your eggdrop to the html format. It also creates a page-calendar with links to that created files. -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/Makefile src/eggdrop-1.8.4/src/mod/logs2html.mod/Makefile ---- ./src/mod/logs2html.mod/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/Makefile 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,44 @@ -+# Makefile for src/mod/logs2html.mod/ -+ -+srcdir = . -+ -+ -+doofus: -+ @echo "" -+ @echo "Let's try this from the right directory..." -+ @echo "" -+ @cd ../../../ && make -+ -+static: ../logs2html.o -+ -+modules: ../../../logs2html.$(MOD_EXT) -+ -+../logs2html.o: -+ $(CC) $(CFLAGS) $(CPPFLAGS) -DMAKING_MODS -c $(srcdir)/logs2html.c -+ @rm -f ../logs2html.o -+ mv logs2html.o ../ -+ -+../../../logs2html.$(MOD_EXT): ../logs2html.o -+ $(LD) -o ../../../logs2html.$(MOD_EXT) ../logs2html.o $(XLIBS) $(MODULE_XLIBS) -+ $(STRIP) ../../../logs2html.$(MOD_EXT) -+ -+depend: -+ $(CC) $(CFLAGS) -MM $(srcdir)/logs2html.c -MT ../logs2html.o > .depend -+ -+clean: -+ @rm -f .depend *.o *.$(MOD_EXT) *~ -+distclean: clean -+ -+#safety hash -+../logs2html.o: .././logs2html.mod/logs2html.c \ -+ ../../../src/mod/module.h ../../../src/main.h ../../../src/lang.h \ -+ ../../../src/eggdrop.h ../../../src/flags.h ../../../src/proto.h \ -+ ../../../lush.h ../../../src/misc_file.h ../../../src/cmdt.h \ -+ ../../../src/tclegg.h ../../../src/tclhash.h ../../../src/chan.h \ -+ ../../../src/users.h ../../../src/compat/compat.h \ -+ ../../../src/compat/inet_aton.h \ -+ ../../../src/compat/snprintf.h \ -+ ../../../src/compat/strcasecmp.h \ -+ ../../../src/compat/strftime.h ../../../src/mod/modvals.h \ -+ .././logs2html.mod/language.h .././logs2html.mod/tcllogs2html.c \ -+ .././logs2html.mod/htmloperations.c .././logs2html.mod/fileoperations.c -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/modinfo src/eggdrop-1.8.4/src/mod/logs2html.mod/modinfo ---- ./src/mod/logs2html.mod/modinfo 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/modinfo 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,3 @@ -+DESC:This module converts the log files of your eggdrop -+DESC:to the html format. It also creates a page-calendar -+DESC:with links to that created files. -diff -urpN "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/Contents" "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/Contents" ---- "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/Contents" 1970-01-01 01:00:00.000000000 +0100 -+++ "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/Contents" 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1 @@ -+Precompiled on CYGWIN_NT-5.1 1.5.25(0.156/4/2) for eggdrop 1.6.18 -Binary files src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/logs2html.dll and src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.18/logs2html.dll differ -diff -urpN "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/Contents" "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/Contents" ---- "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/Contents" 1970-01-01 01:00:00.000000000 +0100 -+++ "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/Contents" 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1 @@ -+Precompiled on CYGWIN_NT-5.1 1.5.25(0.156/4/2) for eggdrop 1.6.19 -Binary files src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/logs2html.dll and src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19/logs2html.dll differ -diff -urpN "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/Contents" "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/Contents" ---- "src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/Contents" 1970-01-01 01:00:00.000000000 +0100 -+++ "src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/Contents" 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1 @@ -+Precompiled on CYGWIN_NT-5.1 1.5.25(0.156/4/2) for eggdrop 1.6.19 with Suzi patch sp.0009 -Binary files src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/logs2html.dll and src/eggdrop-1.8.4/src/mod/logs2html.mod/precompiled/windrop 1.6.19 Suzi/logs2html.dll differ -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/readme.txt src/eggdrop-1.8.4/src/mod/logs2html.mod/readme.txt ---- ./src/mod/logs2html.mod/readme.txt 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/readme.txt 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,105 @@ -+logs2html.mod v.2.4.3 by Alexander Fedotov aka Shmupsik aka shurikvz -+e-mail: shurikvz@mail.ru -+ -+This module converts the log files of your eggdrop to the html format. It also creates a page-calendar with links to that created files. -+ -+******************************************************************************* -+To install this module: -+ - edit and copy logs2html.conf file to your eggdrop directory -+ - for (*nix) copy logs2html.mod to the source directory of your eggdrop (src/mod), then as usual: make iconfig && make && make install) -+ - for windows: -+ - copy the contents of "language" directory to your windrop "language" directory -+ - copy the contents of "help" directory to your windrop "help" directory -+ - copy *.dll (/precompiled) to windrop "modules" directory -+ - if you decide to use your own style for pages edit and copy user.css file to your logs output directory -+ - put string "source logs2html.conf" into your eggdrop config file and restart your bot -+ -+Module has 4 commands, which you can use from dcc chat: -+ - convertalllogs - reconverts all your logs -+ - convertlogs [year [month [day]]] - reconverts your logs -+ - makemainpage - redraws mainpages -+ - makeindexpage - same as ".makemainpage" -+******************************************************************************* -+ -+ -+ -+******************************************************************************* -+You can try to find latest version on http://sourceforge.net/projects/logs2html or http://www.halftone.ru/projects -+******************************************************************************* -+ -+ -+ -+******************************************************************************* -+Version history: -+28.05.09 - version 2.4.3 -+ - now correctly output '"' and '&' char to html -+ - improved search of uri and email -+ - added css classes for join/left, mode change, nick change and kick events -+ - added an option to not display these events in the resulting html file -+ -+ -+12.05.09 - version 2.4.2 -+ - fixed error with compilation on eggdrop 1.6.19 with Suzi-patch sp.0009 -+ - now automaticly reconvert logs for previous year, when the year changed (i.e. on december, 31) -+ -+ -+08.05.09 - version 2.4.1 -+ - fixed display bug with firefox browser -+ -+ -+24.04.09 - version 2.4.0 -+ - now module can convert and show logs for several years (new command added, see '.help logs2html module') -+ - the output pages is now in xhtml format (see "known problems" for details) -+ - added dont-print-time parameter -+ - added month-block-orientation parameter -+ - some color-names fixed in default css file -+ -+ -+15.10.05 - version 2.3.4 -+ - added setting in config file, which allow to change value of meta tag in generated HTML files. -+ -+ -+04.10.05 - version 2.3.3 -+ - fixed bug with broken e-mail (strings with broken e-mails were truncated) -+ -+ -+ 24.09.05 - version 2.3.2 -+ - added support for and tags -+ - fixed bug with [%H:%M:%S] timestamp (I hope.. :-)) -+ -+ -+ 26.07.05 - version 2.3.1 -+ - bug fixed -+ -+ -+ 24.07.05 - version 2.3.0 -+ - page style discriptions moved to CSS file -+ - no need for tcl now -+ - small bugs fixed -+ -+ -+ 25.04.05 - version 2.1.0 -+ - added support for http links and e-mail. -+ -+ -+ 27.02.05 - version 2.0 -+ - converting logs for multiply channels -+ - possibility to change colors of HTML pages -+ - now you can aim number of lines on the one generated HTML page -+ -+ -+ 16.12.04 - version 1.0 -+ - initial realise -+******************************************************************************* -+ -+ -+ -+******************************************************************************* -+KNOWN PROBLEMS -+ -+ -+******************************************************************************* -+ -+ -+ -+P.S. Sorry for my bad english -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/strlcpy.c src/eggdrop-1.8.4/src/mod/logs2html.mod/strlcpy.c ---- ./src/mod/logs2html.mod/strlcpy.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/strlcpy.c 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,51 @@ -+/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ -+ -+/* -+ * Copyright (c) 1998 Todd C. Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+ -+/* -+ * Copy src to string dst of size siz. At most siz-1 characters -+ * will be copied. Always NUL terminates (unless siz == 0). -+ * Returns strlen(src); if retval >= siz, truncation occurred. -+ */ -+size_t -+strlcpy(char *dst, const char *src, size_t siz) -+{ -+ char *d = dst; -+ const char *s = src; -+ size_t n = siz; -+ -+ /* Copy as many bytes as will fit */ -+ if (n != 0) { -+ while (--n != 0) { -+ if ((*d++ = *s++) == '\0') -+ break; -+ } -+ } -+ -+ /* Not enough room in dst, add NUL and traverse rest of src */ -+ if (n == 0) { -+ if (siz != 0) -+ *d = '\0'; /* NUL-terminate dst */ -+ while (*s++) -+ ; -+ } -+ -+ return(s - src - 1); /* count does not include NUL */ -+} -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/tcllogs2html.c src/eggdrop-1.8.4/src/mod/logs2html.mod/tcllogs2html.c ---- ./src/mod/logs2html.mod/tcllogs2html.c 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/tcllogs2html.c 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,130 @@ -+/* -+ * tcllogs2html.c -- part of logs2html.mod -+ * -+ * Written by Fedotov Alexander aka Shmupsik aka shurikvz -+ * -+ * 2004-2009 year -+ */ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+static void get_log_path(char *channel, char **inputpath) { -+ if (Tcl_VarEval(interp, "logfile", (char *)NULL) != TCL_OK || !Tcl_GetStringResult(interp)[0]) { -+ putlog(LOG_MISC, "*", "Error finding logfiles! Please check settings in your config file to be sure statement \"logfile\" present."); -+ return; -+ } -+ -+ int len = strlen(Tcl_GetStringResult(interp)) + 1; -+ char *logslist = nmalloc(len); -+ strlcpy(logslist, Tcl_GetStringResult(interp), len); -+ -+ char *p = logslist, *q, *r; -+ while ((q = strchr(p, '{')) != NULL) { -+ p = strchr(++q, '}'); -+ (*p) = '\0'; -+ p++; // now points to next chan in list -+ r = newsplit(&q); -+ // r = channel modes, check if it has +p flag -+ if (logmodes(r) & LOG_PUBLIC) { -+ r = newsplit(&q); -+ // r = channel name, is it our channel? -+ if ((*r == '*') || (!rfc_casecmp(channel, r))) { -+ r = newsplit(&q); -+ // r = log file name -+ int len = strlen(r) + 1; -+ (*inputpath) = nmalloc(len); -+ strlcpy((*inputpath), r, len); -+ break; -+ } -+ } -+ } -+ -+ nfree(logslist); -+ return; -+} -+ -+ -+static int tcl_addlogs2htmlchan STDVAR -+{ -+ BADARGS(7, 7, " channel output-path main-page-name main-page-title logs-page-prefix logs-page-title"); -+ -+ l2hchan_t *newchan = nmalloc(sizeof(struct l2hchan_struct)); -+ if (newchan == NULL) { -+ putlog(LOG_MISC, "*", "Can't allocate enough space to add new channel!"); -+ Tcl_AppendResult(irp, "Can't allocate enough space to add new channel!", NULL); -+ return TCL_ERROR; -+ } -+ -+ int len; -+ newchan->next = NULL; -+ -+ newchan->inputpath = NULL; -+ get_log_path(argv[1], &(newchan->inputpath)); -+ if (newchan->inputpath == NULL) { -+ putlog(LOG_MISC, "*", "Can't find expression \"logfile\" for channel \'%s\' with mode \'+p\'.", argv[1]); -+ Tcl_AppendResult(irp, "Can't find expression \"logfile\" for channel \'", argv[1], "\' with mode \'+p\'.", NULL); -+ nfree(newchan); -+ return TCL_OK; //Silently ignore this -+ } -+ -+ len = strlen(argv[1]) + 1; -+ newchan->channame = nmalloc(len); -+ strlcpy(newchan->channame, argv[1], len); -+ -+ len = strlen(argv[2]) + 1; -+ newchan->outputpath = nmalloc(len); -+ strlcpy(newchan->outputpath, argv[2], len); -+ -+ len = strlen(argv[3]) + 1; -+ newchan->mainpagename = nmalloc(len); -+ strlcpy(newchan->mainpagename, argv[3], len); -+ -+ len = strlen(argv[4]) + 1; -+ newchan->mainpagetitle = nmalloc(len); -+ strlcpy(newchan->mainpagetitle, argv[4], len); -+ -+ len = strlen(argv[5]) + 1; -+ newchan->logspagename = nmalloc(len); -+ strlcpy(newchan->logspagename, argv[5], len); -+ -+ len = strlen(argv[6]) + 1; -+ newchan->logspagetitle = nmalloc(len); -+ strlcpy(newchan->logspagetitle, argv[6], len); -+ -+ int count = 0; -+ l2hchan_t *chan = logs2htmlchanlist; -+ if (chan == NULL) { -+ logs2htmlchanlist = newchan; -+ } else { -+ count++; -+ while (chan->next != NULL) { -+ chan = chan->next; -+ count++; -+ } -+ chan->next = newchan; -+ } -+ count++; -+ -+ putlog(LOG_MISC, "*", " logs2html module: added channel '%s'. Total channels added: %d.", newchan->channame, count); -+ Tcl_AppendResult(irp, "Channel added: ", argv[1], ".", NULL); -+ -+ return TCL_OK; -+} -+ -+static tcl_cmds my_tcl_cmds[] = { -+ {"addlogs2htmlchan", tcl_addlogs2htmlchan}, -+ {NULL, NULL} /* Mark end. */ -+}; -diff -urpN src-orig/eggdrop-1.8.4/src/mod/logs2html.mod/user.css src/eggdrop-1.8.4/src/mod/logs2html.mod/user.css ---- ./src/mod/logs2html.mod/user.css 1970-01-01 01:00:00.000000000 +0100 -+++ ./src/mod/logs2html.mod/user.css 2018-07-29 03:18:35.000000000 +0200 -@@ -0,0 +1,306 @@ -+@charset "utf-8"; -+/* CSS Document */ -+ -+ -+