From 8d262c175c014612fd75f8eff3496dd6f0fc7ae8 Mon Sep 17 00:00:00 2001 From: rubicon <5662-rubicon@users.gitlab.alpinelinux.org> Date: Tue, 28 Jun 2022 22:20:19 +0800 Subject: [PATCH] main/eggdrop: upgrade to 1.9.2 removed eggdrop.post-install, /usr/bin/eggdrop-installer does not exist, and there is no install= line in the APKBUILD, so the post-install was not being used anyway. removed gseen.mod.patch and logs2html.mod.patch as they are very old and not part of the official release tarball, they are not really patches anyway, but full source files, so if anyone needs them, it's probably better to add them to source= instead. --- main/eggdrop/APKBUILD | 55 +- main/eggdrop/eggdrop.post-install | 6 - main/eggdrop/gseen.mod.patch | 5133 ----------------------------- main/eggdrop/logs2html.mod.patch | 3417 ------------------- 4 files changed, 7 insertions(+), 8604 deletions(-) delete mode 100644 main/eggdrop/eggdrop.post-install delete mode 100644 main/eggdrop/gseen.mod.patch delete mode 100644 main/eggdrop/logs2html.mod.patch 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 */ -+ -+ -+