aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTBK <tbk@jjtc.eu>2020-03-09 10:47:41 +0100
committerLeo <thinkabit.ukim@gmail.com>2020-03-25 17:13:42 +0000
commitbe4e9928d9fbeb45a36b8601def0782732fb0a98 (patch)
tree0beb07b5796f84ca6351a659ff71633a4f259eb7
parent936220e3a5ca223ed285e6b9ad8d37fd8c64218e (diff)
downloadaports-be4e9928d9fbeb45a36b8601def0782732fb0a98.tar.bz2
aports-be4e9928d9fbeb45a36b8601def0782732fb0a98.tar.xz
main/eggdrop: upgrade to 1.8.4
-rw-r--r--main/eggdrop/APKBUILD93
-rw-r--r--main/eggdrop/eggdrop-langdir.patch2
-rw-r--r--main/eggdrop/fix-inline-functions.patch70
-rw-r--r--main/eggdrop/gseen.mod.patch1624
-rw-r--r--main/eggdrop/logs2html.mod.patch4417
-rw-r--r--main/eggdrop/utf8.patch12
6 files changed, 3585 insertions, 2633 deletions
diff --git a/main/eggdrop/APKBUILD b/main/eggdrop/APKBUILD
index f6907b8cf0..f342c82428 100644
--- a/main/eggdrop/APKBUILD
+++ b/main/eggdrop/APKBUILD
@@ -1,66 +1,56 @@
# Maintainer: Carlo Landmeter <clandmeter@gmail.com>
pkgname=eggdrop
-pkgver=1.6.21
-pkgrel=2
+pkgver=1.8.4
+pkgrel=0
pkgdesc="World's most popular Open Source IRC bot"
-url="http://www.eggheads.org/"
+url="https://eggheads.org/"
arch="all"
-license='GPL2'
+license='GPL-2.0-or-later'
+options="!check" # No test suite
depends="tcl"
-makedepends="tcl-dev !bind-libs"
-install=
+makedepends="openssl-dev tcl-dev !bind-libs"
subpackages="$pkgname-doc $pkgname-logs2html $pkgname-gseen"
-source="ftp://ftp.eggheads.org/pub/eggdrop/GNU/1.6/${pkgname}${pkgver}.tar.bz2
+source="$pkgname-$pkgver.tar.gz::https://github.com/eggheads/eggdrop/archive/v$pkgver.tar.gz
eggdrop-langdir.patch
- gseen.mod.patch
logs2html.mod.patch
- fix-inline-functions.patch"
-
-_builddir="$srcdir/${pkgname}${pkgver}"
-
-prepare() {
- cd "$_builddir"
- update_config_sub || return 1
- for i in $source; do
- case $i in
- *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
- esac
- done
-}
+ gseen.mod.patch
+ utf8.patch
+ "
build() {
- cd "$_builddir"
./configure \
--build=$CBUILD \
--host=$CHOST \
--prefix=/usr \
--with-tcllib=/usr/lib/libtcl8.6.so \
- --with-tclinc=/usr/include/tcl.h \
- || return 1
- make config || return 1
- make -j1 || return 1
+ --with-tclinc=/usr/include/tcl.h
+ make config
+ make
}
package() {
- cd "$_builddir"
- make -j1 INSTALL="install -p" DEST="$pkgdir"/usr/share/eggdrop install \
- || return 1
+ # 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
rm -rf "$pkgdir"/usr/share/eggdrop/README \
"$pkgdir"/usr/share/eggdrop/doc \
"$pkgdir"/usr/share/eggdrop/eggdrop* \
"$pkgdir"/usr/share/eggdrop/filesys \
"$pkgdir"/usr/share/eggdrop/logs \
"$pkgdir"/usr/share/eggdrop/modules \
- "$pkgdir"/usr/share/eggdrop/scripts/CONTENTS \
- || return 1
- install -D -m 755 eggdrop "$pkgdir"/usr/bin/eggdrop || return 1
+ "$pkgdir"/usr/share/eggdrop/scripts/CONTENTS
+
+ install -D -m 755 eggdrop "$pkgdir"/usr/bin/eggdrop
install -D -m 644 doc/man1/eggdrop.1 \
- "$pkgdir"/usr/share/man/man1/eggdrop.1 || return 1
+ "$pkgdir"/usr/share/man/man1/eggdrop.1
#move modules to /usr/lib
mkdir "$pkgdir"/usr/lib
mv "$pkgdir"/usr/share/eggdrop/modules-* \
- "$pkgdir"/usr/lib/eggdrop || return 1
+ "$pkgdir"/usr/lib/eggdrop
# Fix paths of example eggdrop.conf
@@ -72,7 +62,7 @@ package() {
mkdir -p "$pkgdir"/usr/share/doc/eggdrop
cp -a \
- COPYING FEATURES NEWS README doc/Changes1.6 eggdrop.conf \
+ COPYING FEATURES NEWS README doc/Changes1.8 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 \
@@ -83,44 +73,41 @@ package() {
logs2html() {
pkgdesc="logs2html module for eggdrop"
install=""
- cd "$_builddir"
+ 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/ || return 1
+ 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/ || return 1
+ "$subpkgdir"/usr/lib/eggdrop/
mkdir -p "$subpkgdir"/usr/share/eggdrop/log2html
- for files in logs2html.conf top100.tpl user.css readme.txt chan.list; do
- cp src/mod/logs2html.mod/${files} "$subpkgdir"/usr/share/eggdrop/log2html/ || return 1
+ 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"
+ cd "$builddir"
mkdir -p "$subpkgdir"/usr/share/eggdrop/language
mv "$pkgdir"/usr/share/eggdrop/language/gseen.* \
- "$subpkgdir"/usr/share/eggdrop/language/ || return 1
+ "$subpkgdir"/usr/share/eggdrop/language/
mkdir -p "$subpkgdir"/usr/lib/eggdrop
mv "$pkgdir"/usr/lib/eggdrop/gseen.so \
- "$subpkgdir"/usr/lib/eggdrop/ || return 1
+ "$subpkgdir"/usr/lib/eggdrop/
mkdir -p "$subpkgdir"/usr/share/eggdrop/gseen
- cp src/mod/gseen.mod/gseen.conf "$subpkgdir"/usr/share/eggdrop/gseen/ \
- || return 1
- cp src/mod/gseen.mod/README "$subpkgdir"/usr/share/eggdrop/gseen/ \
- || return 1
+ cp src/mod/gseen.mod/gseen.conf "$subpkgdir"/usr/share/eggdrop/gseen/
+ cp src/mod/gseen.mod/README "$subpkgdir"/usr/share/eggdrop/gseen/
}
-sha512sums="9fd9a86c1c4b59a47a5eed4e2306e829a01bac2ad29e990ca9c0ec630d5814fd649a9216dae9ce49f734e3ac1728beb4f479ca10af583bd513f43bbbea23a653 eggdrop1.6.21.tar.bz2
-e8b36fb3c444bd884def46082f2c4f0683d1ba8bf05015344e1a2cf634955c8f1e8ccef62c3c2d93958151cf2ce1595adc352c0de3c76ceed7b89c28f48ea96f eggdrop-langdir.patch
-b7bc853b73a9a86ed19dae2cb9edaededbeaa0c163034dc8106239818b8d1fb7c7381fa933fda786cb1c5026283821ec6e3a85a1bbc73db736668f1615dfe2f7 gseen.mod.patch
-8380c414d5193f7a48b5b91384c0181b472dd6cd541a3e9921453b945af3a959d6f58e6bfdcc311ba7b1ed15a44b2225c1d0f1a00526da75cacd4b8650591229 logs2html.mod.patch
-bbe12761c35298604ffeb90a1dfb1c928fa7b83e6366578e8f1b298dda72dea19931812c70b6f9475b7b0449b0e799fd9cbee52e8d40be04eb33484274589340 fix-inline-functions.patch"
+sha512sums="80239a015f518cadc251bfc5edcf08715b9200a70eb0df7edf0efc113f320a7e407ab1fee96322fc6ec923781aa94f5a947c458e935e8a3714fb86cbcc02cb04 eggdrop-1.8.4.tar.gz
+d8e8655fed028030bc3cfe28207a289d0efbc412c7e01170a4d0bb31200f7ea93df310f19e83b485013ca5d4264694b4956252663cb3a63c3d5e4cc31346e0fe eggdrop-langdir.patch
+be173d94a953c4dc5b178950d06ce894deda60c3ddb8195c836797d45fbbcc9fba3bc3d3f34c96226464fdd327093a5d15bbc2b7924d18f845738c1a4dd64a3b logs2html.mod.patch
+7879b998880deb1943c41569e243f9f1a50df23982d82d942af6c111e7fac0fb8a8444c84980645ba15b71dd69c8db2dab6f90bcb7a4292306011c7bcfc03d0d gseen.mod.patch
+7966d4d42994e44a0e571b89f1c66cb41f672d75e6ced7051d1ece23d8c209059c3565b41de950bf9c907701ce7a5e33a215b637587075ed300a002a58eda503 utf8.patch"
diff --git a/main/eggdrop/eggdrop-langdir.patch b/main/eggdrop/eggdrop-langdir.patch
index 5f2db86626..f19b4afc7d 100644
--- a/main/eggdrop/eggdrop-langdir.patch
+++ b/main/eggdrop/eggdrop-langdir.patch
@@ -4,7 +4,7 @@ EGG_LANGDIR environment variable per default (#194481 #c6-c9).
--- eggdrop1.6.17/src/eggdrop.h 2004-07-25 13:17:34.000000000 +0200
+++ eggdrop1.6.17/src/eggdrop.h.langdir 2006-06-18 01:19:23.000000000 +0200
-@@ -75,7 +75,7 @@
+@@ -63,7 +63,7 @@
/* Language stuff */
diff --git a/main/eggdrop/fix-inline-functions.patch b/main/eggdrop/fix-inline-functions.patch
deleted file mode 100644
index 3856be1f48..0000000000
--- a/main/eggdrop/fix-inline-functions.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-Description: fix inline functions to build with clang-3.5. See
- http://clang.llvm.org/compatibility.html#inline
-Author: Arthur Marble <arthur@info9.net>
-
---- a/src/match.c
-+++ b/src/match.c
-@@ -367,7 +367,7 @@
- /* Inline for cron_match (obviously).
- * Matches a single field of a crontab expression.
- */
--inline int cron_matchfld(char *mask, int match)
-+static inline int cron_matchfld(char *mask, int match)
- {
- int skip = 0, f, t;
- char *p, *q;
---- a/src/tclhash.c
-+++ b/src/tclhash.c
-@@ -109,7 +109,7 @@
- nfree(tl);
- }
-
--inline void garbage_collect_tclhash(void)
-+void garbage_collect_tclhash(void)
- {
- tcl_bind_list_t *tl, *tl_next, *tl_prev;
- tcl_bind_mask_t *tm, *tm_next, *tm_prev;
---- a/src/tclhash.h
-+++ b/src/tclhash.h
-@@ -75,7 +75,7 @@
-
- #ifndef MAKING_MODS
-
--inline void garbage_collect_tclhash(void);
-+void garbage_collect_tclhash(void);
-
- void init_bind(void);
- void kill_bind(void);
---- a/src/net.c
-+++ b/src/net.c
-@@ -564,7 +564,7 @@
- /* Returns a socket number for a listening socket that will accept any
- * connection -- port # is returned in port
- */
--inline int open_listen(int *port)
-+int open_listen(int *port)
- {
- return open_address_listen(myip[0] ? getmyip() : INADDR_ANY, port);
- }
---- a/src/proto.h
-+++ b/src/proto.h
-@@ -271,7 +271,7 @@
- void killsock(int);
- void killtclsock(int);
- int answer(int, char *, unsigned long *, unsigned short *, int);
--inline int open_listen(int *);
-+int open_listen(int *);
- int open_address_listen(IP addr, int *);
- int open_telnet(char *, int);
- int open_telnet_dcc(int, char *, char *);
---- a/src/userrec.c
-+++ b/src/userrec.c
-@@ -77,7 +77,7 @@
- #endif
- }
-
--inline int expmem_mask(struct maskrec *m)
-+static inline int expmem_mask(struct maskrec *m)
- {
- int result = 0;
-
diff --git a/main/eggdrop/gseen.mod.patch b/main/eggdrop/gseen.mod.patch
index 9f3beda356..dd49248c65 100644
--- a/main/eggdrop/gseen.mod.patch
+++ b/main/eggdrop/gseen.mod.patch
@@ -1,326 +1,91 @@
-diff -Nur src/mod/gseen.mod/Makefile src/mod/gseen.mod/Makefile
---- ./src/mod/gseen.mod/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ ./src/mod/gseen.mod/Makefile 2002-10-26 13:17:44.000000000 +0200
-@@ -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 -Nur src/mod/gseen.mod/README src/mod/gseen.mod/README
---- ./src/mod/gseen.mod/README 1970-01-01 01:00:00.000000000 +0100
-+++ ./src/mod/gseen.mod/README 2002-10-26 13:17:45.000000000 +0200
-@@ -0,0 +1,140 @@
-+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.
-+
-+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.0.tar.gz in ~/eggdrop1.6.2/src/mod/,
-+and unpack it (tar xfz gseen.mod.1.1.0.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 <nick>
-+ I think this command doesn't need an explanation. ^_^
-+!seen <mask>
-+ Searches the database for entries that match <mask>
-+ for example "!seen *!user@dialin-*.isp.com"
-+!seennick <nick>
-+ !seen also checks if a user was online later with a
-+ different nick. !seennick only seens for <nick>
-+!seenstats
-+ just a little report on how many nicks are tracked
-+
-+All commands are also accessible via /msg.
-+("/msg <bot> seen <nick>", for example)
-+
-+
-+AI seen:
-+--------
-+
-+This module has a simple built in AI routine.
-+A short example:
-+
-+<G`Quann> 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 <nick> <uhost> <hand> <chan> <text>
-+ 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.
-+
-+Feedback:
-+---------
-+
-+Feel free to send feedback and bugreports (I hope there won't be any<g>) to
-+gseen.mod@visions-of-fantasy.de
-+
-+The newest gseen version can always be found at:
-+http://www.visions-of-fantasy.de/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 -Nur src/mod/gseen.mod/UPDATES src/mod/gseen.mod/UPDATES
---- ./src/mod/gseen.mod/UPDATES 1970-01-01 01:00:00.000000000 +0100
-+++ ./src/mod/gseen.mod/UPDATES 2002-10-26 13:17:46.000000000 +0200
-@@ -0,0 +1,55 @@
-+Changes in gseen.mod: (since v1.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.
++#
++#####################################################################
+
-+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
+
-+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
++# 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.
+
-+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
++set tld-langs {
++ {"*.de" "de"}
++ {"*.at" "de"}
++ {"*.ch" "de"}
++ {"*.t-dialin.net" "de"}
++ {"*.t-ipconnect.net" "de"}
++ {"*.pl" "pl"}
++ {"*.jp" "ja"}
++}
+
-+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
++proc selectlang:getlang {uhost} {
++ global tld-langs
++
++ foreach tld ${tld-langs} {
++ if {[string match [lindex $tld 0] $uhost]} {
++ return [lindex $tld 1]
++ }
++ }
++ return ""
++}
+
-+1.0.4
-+- added GPL stuff
-+- changed error msg that appears if no gseen file exists
++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
++ }
++ }
++}
+
-+1.0.3
-+- readme updates
-+- fixed a grammatical error in do_seen
++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}
++}
+
-+1.0.2
-+- bot wanted to free a NULL pointer sometimes
++sl:rebind *msg:seen sl:msg:seen
++proc sl:msg:seen {nick uhost hand rest} {
++ sl:msg:trigger $nick $uhost $hand $rest *msg:seen
++}
+
-+1.0.1
-+- !seen without parameter returned stupid results :)
-+- fixed little typo in .purgeseens
-+- "I found 1 matches..." -> "I found 1 match..."
++sl:rebind *msg:seenstats sl:msg:seenstats
++proc sl:msg:seenstats {nick uhost hand rest} {
++ sl:msg:trigger $nick $uhost $hand $rest *msg:seenstats
++}
+
-+1.0.0
-+- release :)
-diff -Nur src/mod/gseen.mod/addons/gseen.selectlang.1.0.0.tcl 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 2002-10-26 13:18:14.000000000 +0200
-@@ -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
++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 -Nur src/mod/gseen.mod/ai.c src/mod/gseen.mod/ai.c
+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 2002-10-26 13:17:47.000000000 +0200
++++ ./src/mod/gseen.mod/ai.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -473,9 +238,9 @@ diff -Nur src/mod/gseen.mod/ai.c src/mod/gseen.mod/ai.c
+ return 1;
+ return 0;
+}
-diff -Nur src/mod/gseen.mod/datahandling.c src/mod/gseen.mod/datahandling.c
+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 2002-10-26 13:17:48.000000000 +0200
++++ ./src/mod/gseen.mod/datahandling.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -628,9 +393,9 @@ diff -Nur src/mod/gseen.mod/datahandling.c src/mod/gseen.mod/datahandling.c
+ }
+ }
+}
-diff -Nur src/mod/gseen.mod/do_seen.c src/mod/gseen.mod/do_seen.c
+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 2002-10-26 13:17:50.000000000 +0200
++++ ./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
@@ -1472,9 +1237,9 @@ diff -Nur src/mod/gseen.mod/do_seen.c src/mod/gseen.mod/do_seen.c
+ glob_total_searchtime += glob_aftersearch - glob_presearch;
+ glob_total_queries++;
+}
-diff -Nur src/mod/gseen.mod/generic_binary_tree.c src/mod/gseen.mod/generic_binary_tree.c
+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 2002-10-26 13:17:51.000000000 +0200
++++ ./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
@@ -1787,9 +1552,9 @@ diff -Nur src/mod/gseen.mod/generic_binary_tree.c src/mod/gseen.mod/generic_bina
+*/
+}
+#endif
-diff -Nur src/mod/gseen.mod/global_vars.c src/mod/gseen.mod/global_vars.c
+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 2002-10-26 13:18:09.000000000 +0200
++++ ./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
@@ -1825,10 +1590,10 @@ diff -Nur src/mod/gseen.mod/global_vars.c src/mod/gseen.mod/global_vars.c
+ glob_seenrequest = NULL;
+ glob_seenrequests = glob_totalnicks = glob_totalbytes = 0;
+}
-diff -Nur src/mod/gseen.mod/gseen.c src/mod/gseen.mod/gseen.c
+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 2002-10-26 14:24:48.000000000 +0200
-@@ -0,0 +1,328 @@
++++ ./src/mod/gseen.mod/gseen.c 2017-01-02 22:30:47.000000000 +0100
+@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
+ *
@@ -1849,7 +1614,7 @@ diff -Nur src/mod/gseen.mod/gseen.c src/mod/gseen.mod/gseen.c
+
+#define MAKING_GSEEN
+#define MODULE_NAME "gseen"
-+#define MODULE_VERSION "1.1.1 dev3"
++#define MODULE_VERSION "1.1.2"
+#define MODULE_NUMVERSION 10100
+#include "../module.h"
+#include "../irc.mod/irc.h"
@@ -1916,7 +1681,7 @@ diff -Nur src/mod/gseen.mod/gseen.c src/mod/gseen.mod/gseen.c
+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 = 32;
++static int seen_nick_len = 9;
+
+#include "global_vars.c"
+#define SLANG_NOTYPES 1
@@ -2096,12 +1861,14 @@ diff -Nur src/mod/gseen.mod/gseen.c src/mod/gseen.mod/gseen.c
+ 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", 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";
++ 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";
++ }
+ }
+ }
+ }
@@ -2157,10 +1924,434 @@ diff -Nur src/mod/gseen.mod/gseen.c src/mod/gseen.mod/gseen.c
+ putlog(LOG_MISC, "*", "gseen.mod v%s loaded.", MODULE_VERSION);
+ return NULL;
+}
-diff -Nur src/mod/gseen.mod/gseen.conf src/mod/gseen.mod/gseen.conf
+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 2002-10-26 13:17:54.000000000 +0200
-@@ -0,0 +1,147 @@
++++ ./src/mod/gseen.mod/gseen.conf 2017-01-02 22:30:47.000000000 +0100
+@@ -0,0 +1,151 @@
+
+######
+#####
@@ -2252,6 +2443,10 @@ diff -Nur src/mod/gseen.mod/gseen.conf src/mod/gseen.mod/gseen.conf
+#####
+######
+
++# 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
@@ -2308,28 +2503,28 @@ diff -Nur src/mod/gseen.mod/gseen.conf src/mod/gseen.mod/gseen.conf
+ bind pubm -|- "% [subst $mask]" *pub:!seenstats
+ }
+}
-diff -Nur src/mod/gseen.mod/language/gseen.de.lang src/mod/gseen.mod/language/gseen.de.lang
+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 2002-10-26 13:18:12.000000000 +0200
++++ ./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
++# 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.
++# 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
++# 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.
++# 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)
++# Eine komplette Liste der VerfпїЅgbaren Tags befindet sich am Ende von
++# slang_gseen_commands.c (leider ohne ErklпїЅhrungen)
+#
+#####################################################################
+
@@ -2350,44 +2545,44 @@ diff -Nur src/mod/gseen.mod/language/gseen.de.lang src/mod/gseen.mod/language/gs
+D 9 Minuten
+D 10 Sekunde
+D 11 Sekunden
-+# falls ein ьngьltiger Zeitwert angegeben war, dann wird dieser Text ausgegeben:
++# falls ein пїЅngпїЅltiger Zeitwert angegeben war, dann wird dieser Text ausgegeben:
+D 12 einiger Zeit
+
+
+#
-+## Prдfixe
++## PrпїЅfixe
+#
+# Dieses Fragment wird jeweils vor eine Antwort gesetzt. Dadurch
-+# ist beispielsweise bei цffentlichen Anfragen ersichtlich, fьr
++# 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:
++# fпїЅr Antworten, die in den Channel geschrieben werden:
+10 <?nick/?>,
-+# fьr Antworten, die per NOTICE an den User geschickt werden:
++# fпїЅr Antworten, die per NOTICE an den User geschickt werden:
+11
-+# fьr Antworten auf Anfragen, die per "/msg <bot> seen" erfolgt sind:
++# fпїЅr Antworten auf Anfragen, die per "/msg <bot> seen" erfolgt sind:
+12
-+# und fьr Antworten auf der Partyline:
++# 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 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*
++55 leidest Du etwa unter multiplen PersпїЅnlichkeiten? *eg*
+56 also wenn Du <?query/?> jetzt hier nicht sehen kannst, dann brauchst Du sicherlich eine neue Brille ^_^
+56 ich muss mir unbedingt mal die Tarnkappe von <?query/?> 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... :)
++58 пїЅhm... naja... etwas arg lang, dieser Nick... :)
+
+#
+## Kein Ergebnis
@@ -2401,9 +2596,9 @@ diff -Nur src/mod/gseen.mod/language/gseen.de.lang src/mod/gseen.mod/language/gs
+
+73 <?query/?> ist grade unter dem Nick "<?othernick/?>" in diesem Channel zu finden.
+74 <?query/?> ist gerade in <?otherchan/?>.
-+75 Deine Anfrage fьhrte zu genau einem Ergebnis:
++75 Deine Anfrage fпїЅhrte zu genau einem Ergebnis:
+76 Immerhin <?numresults/?> Treffer ergab deine Anfrage:
-+77 Wow, auf deine Anfrage passen sogar <?numresults/?> Eintrдge in meiner Datenbank! Dies sind die 5 aktuellsten:
++77 Wow, auf deine Anfrage passen sogar <?numresults/?> EintrпїЅge in meiner Datenbank! Dies sind die 5 aktuellsten:
+
+#
+## falls ein anderer Bot etwas gefunden hat:
@@ -2414,17 +2609,17 @@ diff -Nur src/mod/gseen.mod/language/gseen.de.lang src/mod/gseen.mod/language/gs
+## die eigentliche Information
+#
+101 Ich habe <?snick/?> (<?shost/?>) zuletzt <?schan/?> vor <?swhen/?> betreten sehen (<?stime/?>). <?snick/?> ist noch immer da.
-+121 Ich habe <?snick/?> (<?shost/?>) zuletzt <?schan/?> vor <?swhen/?> betreten sehen (<?stime/?>), aber <?snick/?> verschwand mysteriцserweise.
++121 Ich habe <?snick/?> (<?shost/?>) zuletzt <?schan/?> vor <?swhen/?> betreten sehen (<?stime/?>), aber <?snick/?> verschwand mysteriпїЅserweise.
+102 Ich habe <?snick/?> (<?shost/?>) zuletzt <?schan/?> vor <?swhen/?> nach <?spent/?> verchatteter Zeit verlassen sehen (<?stime/?>)
-+103 Ich habe <?snick/?> (<?shost/?>) zuletzt in <?schan/?> gesehen, als er/sie vor <?swhen/?> (<?stime/?>) nach <?spent/?> das IRC verlieЯ ("<?smsg/?>").
++103 Ich habe <?snick/?> (<?shost/?>) zuletzt in <?schan/?> gesehen, als er/sie vor <?swhen/?> (<?stime/?>) nach <?spent/?> das IRC verlieпїЅ ("<?smsg/?>").
+104 Zuletzt habe ich <?snick/?> (<?shost/?>) vor <?swhen/?> in <?schan/?> gesehen, den Nick zu <?snick2/?> wechselnd. <?snick2/?> ist noch immer dort.
+124 <?snick/?> (<?shost/?>) was last seen changing his/her nick to <?snick2/?> on <?schan/?> <?swhen/?> ago (<?stime/?>), but <?snick2/?> mysteriously dematerialized.
+105 Zuletzt habe ich <?snick/?> (<?shost/?>) vor <?swhen/?> in <?schan/?> gesehen, den Nick von <?snick2/?> wechselnd. <?snick/?> ist noch immer dort.
+125 <?snick/?> (<?shost/?>) was last seen changing his/her nick from <?snick2/?> on <?schan/?> <?swhen/?> ago (<?stime/?>), but <?snick/?> mysteriously dematerialized.
+106 Zuletzt habe ich <?snick/?> (<?shost/?>) gesehen, als er vor <?swhen/?> (<?stime/?>) von <?punisher/?> aus <?schan/?> gejagt wurde. (<?kickreason/?>)
+107 <?snick/?> (<?shost/?>) habe ich zuletzt vor <?swhen/?> gesehen, als er/sie von <?schan/?> aus in einem Netsplit verschwand.
-+108 <?snick/?> (<?shost/?>) habe ich zuletzt vor <?swhen/?> gesehen, als er/sie nach einem Netsplit in <?schan/?> zurьck kam. <?snick/?> ist noch immer dort.
-+128 <?snick/?> (<?shost/?>) habe ich zuletzt vor <?swhen/?> gesehen, als er/sie nach einem Netsplit in <?schan/?> zurьck kam. Allerdings konnte <?snick/?> dem Gott der Netsplits nicht endgьltig entkommen und ist wieder verschollen...
++108 <?snick/?> (<?shost/?>) habe ich zuletzt vor <?swhen/?> gesehen, als er/sie nach einem Netsplit in <?schan/?> zurпїЅck kam. <?snick/?> ist noch immer dort.
++128 <?snick/?> (<?shost/?>) habe ich zuletzt vor <?swhen/?> gesehen, als er/sie nach einem Netsplit in <?schan/?> zurпїЅck kam. Allerdings konnte <?snick/?> dem Gott der Netsplits nicht endgпїЅltig entkommen und ist wieder verschollen...
+109 <?snick/?> was last seen joining the botnet channel <?schan/?> on <?bnbot/?> <?swhen/?> ago (<?stime/?>).
+129 <?snick/?> was last seen joining the partyline on <?bnbot/?> <?swhen/?> ago (<?stime/?>).
+110 <?snick/?> was last seen leaving the botnet channel <?schan/?> from <?bnbot/?> <?swhen/?> ago (<?stime/?>).
@@ -2443,9 +2638,9 @@ diff -Nur src/mod/gseen.mod/language/gseen.de.lang src/mod/gseen.mod/language/gs
+#
+180 Momentan sind <?totalnicks/?> Nicks in meiner Datenbank. Gesamter Speicherverbrauch: <?totalbytes/?> Bytes
+180 In meiner Datenbank befinden sich <?totalnicks/?> Nicks und verbrauchen <?totalbytes/?> Bytes Speicher.
-diff -Nur src/mod/gseen.mod/language/gseen.en.lang src/mod/gseen.mod/language/gseen.en.lang
+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 2002-10-26 13:18:13.000000000 +0200
++++ ./src/mod/gseen.mod/language/gseen.en.lang 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,131 @@
+#####################################################################
+#
@@ -2578,9 +2773,9 @@ diff -Nur src/mod/gseen.mod/language/gseen.en.lang src/mod/gseen.mod/language/gs
+## seen stats
+#
+180 I'm currently tracking <?totalnicks/?> nicks using <?totalbytes/?> bytes.
-diff -Nur src/mod/gseen.mod/gseen.h src/mod/gseen.mod/gseen.h
+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 2002-10-26 13:17:55.000000000 +0200
++++ ./src/mod/gseen.mod/gseen.h 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -2739,433 +2934,41 @@ diff -Nur src/mod/gseen.mod/gseen.h src/mod/gseen.mod/gseen.h
+#endif
+
+#endif
-diff -Nur src/mod/gseen.mod/gseencmds.c 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 2002-10-26 13:17:56.000000000 +0200
-@@ -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;
+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/
+
-+ 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;
-+}
++doofus:
++ @echo ""
++ @echo "Let's try this from the right directory..."
++ @echo ""
++ @cd ../../../; make
+
-+static int bot_gseen_rep(char *bot, char *code, char *par)
-+{
-+ char *nick, *chan, *reply;
-+ int i;
++clean:
++ @rm -f *.o *.$(MOD_EXT) *~
+
-+ 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: ../gseen.o
+
-+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}
-+};
++modules: ../../../gseen.$(MOD_EXT)
+
-+static cmd_t seen_pub[] =
-+{
-+ {"!seen", "", pub_seen, 0},
-+ {"!seenstats", "", pub_seenstats, 0},
-+ {"!seennick", "", pub_seennick, 0},
-+ {0, 0, 0, 0}
-+};
++../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 ../
+
-+static cmd_t seen_msg[] =
-+{
-+ {"seen", "", msg_seen, 0},
-+ {"seennick", "", msg_seennick, 0},
-+ {0, 0, 0, 0}
-+};
++../../../gseen.$(MOD_EXT): ../gseen.o
++ $(LD) -o ../../../gseen.$(MOD_EXT) ../gseen.o $(XLIBS)
+
-+static cmd_t seen_bot[] =
-+{
-+ {"gseen_req", "", bot_gseen_req, 0},
-+ {"gseen_rep", "", bot_gseen_rep, 0},
-+ {0, 0, 0, 0}
-+};
-diff -Nur src/mod/gseen.mod/misc.c src/mod/gseen.mod/misc.c
++#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 2002-10-26 13:17:57.000000000 +0200
++++ ./src/mod/gseen.mod/misc.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -3188,7 +2991,7 @@ diff -Nur src/mod/gseen.mod/misc.c src/mod/gseen.mod/misc.c
+/* maskstricthost():
+ * basically the same as maskhost() from src/misc.c, but _never_ stripts
+ * "~+-^=" off the host
-+ * maskhost() version: * $Id: misc.c,v 1.30 2000/10/27 19:27:32 fabian Exp $
++ * maskhost() version: * $Id: misc.c,v 1.1 2005/04/14 10:55:00 Administrator Exp $
+ */
+static void maskstricthost(const char *s, char *nw)
+{
@@ -3283,9 +3086,152 @@ diff -Nur src/mod/gseen.mod/misc.c src/mod/gseen.mod/misc.c
+ }
+ }
+}
-diff -Nur src/mod/gseen.mod/seenlang.h src/mod/gseen.mod/seenlang.h
+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 <nick>
++ I think this command doesn't need an explanation. ^_^
++!seen <mask>
++ Searches the database for entries that match <mask>
++ for example "!seen *!user@dialin-*.isp.com"
++!seennick <nick>
++ !seen also checks if a user was online later with a
++ different nick. !seennick only seens for <nick>
++!seenstats
++ just a little report on how many nicks are tracked
++
++All commands are also accessible via /msg.
++("/msg <bot> seen <nick>", for example)
++
++
++AI seen:
++--------
++
++This module has a simple built in AI routine.
++A short example:
++
++<G`Quann> 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 <nick> <uhost> <hand> <chan> <text>
++ 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 2002-10-26 13:17:58.000000000 +0200
++++ ./src/mod/gseen.mod/seenlang.h 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -3348,9 +3294,9 @@ diff -Nur src/mod/gseen.mod/seenlang.h src/mod/gseen.mod/seenlang.h
+#define SLLASTLOOK getslang(172)
+
+#define SLSEENSTATS getslang(180)
-diff -Nur src/mod/gseen.mod/seentree.c src/mod/gseen.mod/seentree.c
+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 2002-10-26 13:18:10.000000000 +0200
++++ ./src/mod/gseen.mod/seentree.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -3565,9 +3511,9 @@ diff -Nur src/mod/gseen.mod/seentree.c src/mod/gseen.mod/seentree.c
+ {"killseen", tcl_killseen},
+ {0, 0}
+};
-diff -Nur src/mod/gseen.mod/sensors.c src/mod/gseen.mod/sensors.c
+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 2002-10-26 13:18:00.000000000 +0200
++++ ./src/mod/gseen.mod/sensors.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -3842,9 +3788,9 @@ diff -Nur src/mod/gseen.mod/sensors.c src/mod/gseen.mod/sensors.c
+ {"*", "", (Function) gseen_rejn, "gseen"},
+ {0, 0, 0, 0}
+};
-diff -Nur src/mod/gseen.mod/slang.c src/mod/gseen.mod/slang.c
+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 2002-10-26 13:18:03.000000000 +0200
++++ ./src/mod/gseen.mod/slang.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -4155,9 +4101,9 @@ diff -Nur src/mod/gseen.mod/slang.c src/mod/gseen.mod/slang.c
+ return slang_id_get_next();
+}
+#endif
-diff -Nur src/mod/gseen.mod/slang_chanlang.c src/mod/gseen.mod/slang_chanlang.c
+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 2002-10-26 13:18:02.000000000 +0200
++++ ./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
@@ -4272,9 +4218,9 @@ diff -Nur src/mod/gseen.mod/slang_chanlang.c src/mod/gseen.mod/slang_chanlang.c
+#endif
+ return slang_find(where, default_slang);
+}
-diff -Nur src/mod/gseen.mod/slang_duration.c src/mod/gseen.mod/slang_duration.c
+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 2002-10-26 13:18:01.000000000 +0200
++++ ./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
@@ -4358,9 +4304,9 @@ diff -Nur src/mod/gseen.mod/slang_duration.c src/mod/gseen.mod/slang_duration.c
+ }
+ return where->durs[idx];
+}
-diff -Nur src/mod/gseen.mod/slang_gseen_commands.c src/mod/gseen.mod/slang_gseen_commands.c
+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 2002-10-26 13:18:06.000000000 +0200
++++ ./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()
+{
@@ -4597,9 +4543,9 @@ diff -Nur src/mod/gseen.mod/slang_gseen_commands.c src/mod/gseen.mod/slang_gseen
+ {"nick", slang_send_nick},
+ {0, 0}
+};
-diff -Nur src/mod/gseen.mod/slang_ids.c src/mod/gseen.mod/slang_ids.c
+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 2002-10-26 13:18:04.000000000 +0200
++++ ./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
@@ -4705,9 +4651,9 @@ diff -Nur src/mod/gseen.mod/slang_ids.c src/mod/gseen.mod/slang_ids.c
+ return slang_multitext_get_next();
+}
+#endif
-diff -Nur src/mod/gseen.mod/slang_multitext.c src/mod/gseen.mod/slang_multitext.c
+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 2002-10-26 13:18:05.000000000 +0200
++++ ./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
@@ -4860,9 +4806,9 @@ diff -Nur src/mod/gseen.mod/slang_multitext.c src/mod/gseen.mod/slang_multitext.
+ return NULL;
+}
+#endif
-diff -Nur src/mod/gseen.mod/slang_text.c src/mod/gseen.mod/slang_text.c
+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 2002-10-26 13:18:07.000000000 +0200
++++ ./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
@@ -5064,9 +5010,9 @@ diff -Nur src/mod/gseen.mod/slang_text.c src/mod/gseen.mod/slang_text.c
+ }
+ putlog(LOG_MISC, "*", "ERROR! Unknown slang-command: '%s'", cmd);
+}
-diff -Nur src/mod/gseen.mod/tclcmds.c src/mod/gseen.mod/tclcmds.c
+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 2002-10-26 13:18:08.000000000 +0200
++++ ./src/mod/gseen.mod/tclcmds.c 2017-01-02 22:30:47.000000000 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000,2001 Florian Sander
@@ -5121,3 +5067,67 @@ diff -Nur src/mod/gseen.mod/tclcmds.c src/mod/gseen.mod/tclcmds.c
+ {"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
index 25ad9366c6..36ed2361dc 100644
--- a/main/eggdrop/logs2html.mod.patch
+++ b/main/eggdrop/logs2html.mod.patch
@@ -1,85 +1,13 @@
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/Makefile eggdrop1.6.19/src/mod/logs2html.mod/Makefile
---- ./src/mod/logs2html.mod/Makefile 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/Makefile 2009-03-28 01:32:21.000000000 +0000
-@@ -0,0 +1,42 @@
-+# 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
-+ $(STRIP) ../../../logs2html.$(MOD_EXT)
-+
-+depend:
-+ $(CC) $(CFLAGS) $(CPPFLAGS) -MM $(srcdir)/logs2html.c > .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/memset.h \
-+ ../../../src/compat/memcpy.h ../../../src/compat/strcasecmp.h \
-+ ../../../src/compat/strftime.h ../../../src/mod/modvals.h
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/chan.list eggdrop1.6.19/src/mod/logs2html.mod/chan.list
---- ./src/mod/logs2html.mod/chan.list 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/chan.list 2009-03-28 01:43:40.000000000 +0000
-@@ -0,0 +1,22 @@
-+# 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
-+# 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'll be 'logs-page-prefixYYmmdd'
-+# 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 "#MyChan" "logs" "index" "Logs of MyChan" "mychan" "Log of MyChan"
-+#
-+# Note: expression "logs2html" MUST be one line (i.e. without linefeeds
-+# and carrige returns) and every parameter in the expression MUST be enclosed
-+# with ".
-+
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.19/src/mod/logs2html.mod/fileoperations.c
---- ./src/mod/logs2html.mod/fileoperations.c 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/fileoperations.c 2009-03-28 01:45:19.000000000 +0000
-@@ -0,0 +1,142 @@
+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 Gray_Angel aka Shmupsik <shurikvz@mail.ru>
++ * Written by Fedotov Alexander aka Shmupsik aka shurikvz <shurikvz@mail.ru>
+ *
-+ * 2004-2005 year
++ * 2004-2009 year
+ */
+/*
+ * This program is free software; you can redistribute it and/or
@@ -104,37 +32,29 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.
+ * function FILE *openfile(char *newfilename, const char *mode, bool silent)
+ *
+ * Input:
-+ * newfilename - имя файла, который необходимо создать
-+ * mode - режим открытия файла
++ * newfilename - имя файла, который необходимо создать
++ * mode - режим открытия файла
+ *
+ * Output:
-+ * указатель на файл
++ * указатель на файл
+ *
+ * Discription:
-+ * функция осуществляет создание и открытие файла в указанном режиме
-+ * и возвращает указатель на созданный файл
++ * функция осуществляет создание и открытие файла в указанном режиме
++ * и возвращает указатель на созданный файл
+ */
-+static FILE *openfile(char *newfilename, const char *mode, bool silent) {
++static FILE *openfile(char *filename, const char *mode, bool silent) {
+ FILE *file;
-+ static char *filename = NULL;
-+
-+ Context;
-+
-+ filename = (char *)nmalloc(sizeof(char) * (strlen(newfilename) + 1));
+
+ if (filename == NULL) {
+ putlog(LOG_MISC, "*", "logs2html: ERROR! Can't allocate enough space for filename.");
+ return NULL;
+ }
+
-+ sprintf(filename, "%s", newfilename);
+ file = fopen(filename, mode);
+ if ((file == NULL) && (!silent)) {
+ putlog(LOG_MISC, "*", "logs2html: Warning! Can't open file \"%s\".", filename);
+ }
+
-+ nfree(filename); filename = NULL;
-+
+ return file;
+} /* openfile() */
+/****************************************************************************/
@@ -145,16 +65,16 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.
+ * function void writefromexfile(FILE *dst_file, char *exfilename)
+ *
+ * Input:
-+ *
-+ *
-+ *
++ *
++ *
++ *
+ *
+ * Output:
-+ *
++ *
+ *
+ * Discription:
-+ *
-+ *
++ *
++ *
+ */
+static void writefromexfile(FILE *dst_file, char *exfilename) {
+ FILE *addfile;
@@ -181,16 +101,16 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.
+ * function void str_write(FILE *file, char *fmt, ... )
+ *
+ * Input:
-+ * file - файл в который пишем данные
-+ * fmt - строка для записи со спецификаторами формата
-+ * ... - данные для записи в строку
++ * file - файл в который пишем данные
++ * fmt - строка для записи со спецификаторами формата
++ * ... - данные для записи в строку
+ *
+ * Output:
-+ * ничего
++ * ничего
+ *
+ * Discription:
-+ * функция осуществляет запись переданной строки в указанный файл,
-+ * производя соответствующее ее форматирование
++ * функция осуществляет запись переданной строки в указанный файл,
++ * производя соответствующее ее форматирование
+ */
+static void str_write(FILE *file, char *fstr, ... ) {
+ va_list ap;
@@ -198,17 +118,17 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.
+ int size = 256;
+ static char *buffer = NULL;
+
-+ Context;
+ buffer = (char *)nmalloc(size);
+
-+ va_start(ap, fstr);
+ 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);
+ }
-+ va_end(ap);
++
+ fwrite(buffer, sizeof(char), strlen(buffer), file);
+ nfree(buffer); buffer = NULL;
+
@@ -216,35 +136,445 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/fileoperations.c eggdrop1.6.
+} /* str_write() */
+/****************************************************************************/
+
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/help/logs2html.help eggdrop1.6.19/src/mod/logs2html.mod/help/logs2html.help
---- ./src/mod/logs2html.mod/help/logs2html.help 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/help/logs2html.help 2009-03-28 01:32:21.000000000 +0000
-@@ -0,0 +1,22 @@
+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: makemainpage
++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.
++ Redraws your mainpages. (same as %b.makeindexpage%b)
+
-+See also: convertalllogs
++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 existing log files of your eggdrop for giving
-+ channels to their html representation.
++ 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
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.english.lang eggdrop1.6.19/src/mod/logs2html.mod/language/logs2html.english.lang
---- ./src/mod/logs2html.mod/language/logs2html.english.lang 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/language/logs2html.english.lang 2009-03-28 01:32:53.000000000 +0000
++ %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 <shurikvz@mail.ru>
++ *
++ * 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");
++ str_write(dst_file, "body {\n");
++ str_write(dst_file, "font-family:\"Times New Roman\", Times, serif;\n");
++ str_write(dst_file, "background: #666666;\n");
++ str_write(dst_file, "margin: 0;\n");
++ str_write(dst_file, "padding: 0;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "color: #000000;\n");
++ str_write(dst_file, "}\n\n");
++
++ str_write(dst_file, "/* mainpage styles */\n");
++ str_write(dst_file, ".l2hMainPage #container {\n");
++ str_write(dst_file, "width: 99%%;\n");
++ str_write(dst_file, "background:#FFFF99;\n");
++ str_write(dst_file, "margin: 0 auto;\n");
++ str_write(dst_file, "border: 1px solid #000000;\n");
++ str_write(dst_file, "text-align: left;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container #monthtable tr {\n");
++ str_write(dst_file, "background: Orange;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container .monthblock .monthname {\n");
++ str_write(dst_file, "font-family:\"Comic Sans MS\", \"Brush Script Std\", Verdana, Arial, Helvetica, sans-serif;\n");
++ str_write(dst_file, "font-size: 1.3em;\n");
++ str_write(dst_file, "height: 1.8em;\n");
++ str_write(dst_file, "background:#FF6600;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "color: white;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container #monthtable .monthblock .dayname {\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "height: 1.8em;\n");
++ str_write(dst_file, "background: Silver;\n");
++ str_write(dst_file, "text-align: left;\n");
++ str_write(dst_file, "padding: 0 5px;\n");
++ str_write(dst_file, "color:#333333;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container #monthtable .monthblock .weekend {\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "height: 1.8em;\n");
++ str_write(dst_file, "background: #FF6633;\n");
++ str_write(dst_file, "text-align: left;\n");
++ str_write(dst_file, "padding: 0 5px;\n");
++ str_write(dst_file, "color:#333333;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container #monthtable .monthblock .emptycell {\n");
++ str_write(dst_file, "height: 1.8em;\n");
++ str_write(dst_file, "background:#DDDDDD;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #container #monthtable .monthblock .day {\n");
++ str_write(dst_file, "font-family:\"Courier New\", Courier, monospace;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "height: 1.8em;\n");
++ str_write(dst_file, "background:#FFCC00;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "color:#FF0000;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #header {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #header h2 {\n");
++ str_write(dst_file, "font-style:italic;\n");
++ str_write(dst_file, "margin: 0;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #mp_top {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #mp_bottom {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "}\n\n");
++
++ str_write(dst_file, "/* leftsidebar styles */\n");
++ str_write(dst_file, ".l2hMainPage #leftsidebar {\n");
++ str_write(dst_file, "float: left;\n");
++ str_write(dst_file, "width: 7em;\n");
++ str_write(dst_file, "background: #EBEBEB;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #leftsidebar div.indexlink {\n");
++ str_write(dst_file, "background-color: #EBEBEB;\n");
++ str_write(dst_file, "margin-left: 5px;\n");
++ str_write(dst_file, "margin-right: 5px;\n");
++ str_write(dst_file, "text-align:center;\n");
++ str_write(dst_file, "border-bottom-width: thin;\n");
++ str_write(dst_file, "border-bottom-style: dotted;\n");
++ str_write(dst_file, "border-bottom-color: #CCCCCC;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #leftsidebar div.indexlink a {\n");
++ str_write(dst_file, "display:block;\n");
++ str_write(dst_file, "letter-spacing:.1em;\n");
++ str_write(dst_file, "line-height:1.5em;\n");
++ str_write(dst_file, "text-decoration: none;\n");
++ str_write(dst_file, "vertical-align:baseline;\n");
++ str_write(dst_file, "color:#333333;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #leftsidebar div.indexlink a:hover {\n");
++ str_write(dst_file, "background:#FF6600;\n");
++ str_write(dst_file, "letter-spacing:.3em;\n");
++ str_write(dst_file, "line-height:1.5em;\n");
++ str_write(dst_file, "color:#FFFFFF;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #mainblock {\n");
++ str_write(dst_file, "margin: 0 20px 0 8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #footer {\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "background:#DDDDDD;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hMainPage #footer p {\n");
++ str_write(dst_file, "margin: 0;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "font-size: 0.9em;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "color: #333333;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #lp_top {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #lp_bottom {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "}\n\n");
++
++ str_write(dst_file, "/* Log Page styles */\n");
++ str_write(dst_file, ".l2hLogPage #header {\n");
++ str_write(dst_file, "background: #DDDDDD;\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container {\n");
++ str_write(dst_file, "width: 99%%;\n");
++ str_write(dst_file, "background: #FFFF99;\n");
++ str_write(dst_file, "margin: 0 auto;\n");
++ str_write(dst_file, "border: 1px solid #000000;\n");
++ str_write(dst_file, "text-align: left;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #navtop {\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "border-bottom: 1px solid Orange;\n");
++ str_write(dst_file, "margin-bottom: 10px;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #navtop a {\n");
++ str_write(dst_file, "color:#FF0000;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #totoplink {\n");
++ str_write(dst_file, "color:#FF0000;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "border-top: 1px solid Orange;\n");
++ str_write(dst_file, "margin-top: 10px;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #totoplink a {\n");
++ str_write(dst_file, "color:#FF0000;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #navbottom {\n");
++ str_write(dst_file, "color:#FF0000;\n");
++ str_write(dst_file, "text-align: center;\n");
++ str_write(dst_file, "padding: 10px;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #navbottom span {\n");
++ str_write(dst_file, "padding-left:5px;\n");
++ str_write(dst_file, "padding-right:5px;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #container #navbottom #navbottom_currentpg {\n");
++ str_write(dst_file, "font-size:1.1em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #footer {\n");
++ str_write(dst_file, "padding: 0 10px;\n");
++ str_write(dst_file, "background:#DDDDDD;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #footer p {\n");
++ str_write(dst_file, "margin: 0;\n");
++ str_write(dst_file, "padding: 10px 0;\n");
++ str_write(dst_file, "font-size: 0.9em;\n");
++ str_write(dst_file, "font-weight:bold;\n");
++ str_write(dst_file, "color: #333333;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock div {\n");
++ str_write(dst_file, "white-space: pre-wrap; /* css-3 */\n");
++ str_write(dst_file, "white-space: pre-line; /* css-3, css-2.1 */\n");
++ str_write(dst_file, "white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */\n");
++ str_write(dst_file, "white-space: -hp-pre-wrap; /* HP printers */\n");
++ str_write(dst_file, "white-space: -pre-wrap; /* Opera 4-6 */\n");
++ str_write(dst_file, "white-space: -o-pre-wrap; /* Opera 7 */\n");
++ str_write(dst_file, "word-wrap: break-word; /* Internet Explorer 5.5+ */\n");
++ str_write(dst_file, "overflow:hidden;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.time {\n");
++ str_write(dst_file, "color: #D0D0D0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.nick {\n");
++ str_write(dst_file, "color: #0040C0;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.text {\n");
++ str_write(dst_file, "color: #111111;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_j {\n");
++ str_write(dst_file, "color: #99CC00;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_li {\n");
++ str_write(dst_file, "color: #99CC00;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_l {\n");
++ str_write(dst_file, "color: #99CC00;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_n {\n");
++ str_write(dst_file, "color: #FF6666;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_m {\n");
++ str_write(dst_file, "color: #00CCFF;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else_k {\n");
++ str_write(dst_file, "color: #FF0066;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.else {\n");
++ str_write(dst_file, "color: #40C000;\n");
++ str_write(dst_file, "font-size: 0.8em;\n");
++ str_write(dst_file, "}\n");
++ str_write(dst_file, ".l2hLogPage #mainblock span.action {\n");
++ str_write(dst_file, "color: #FF99FF;\n");
++ str_write(dst_file, "}\n\n");
++
++ str_write(dst_file, "/* mirc colors */\n");
++ str_write(dst_file, ".l2hLogPage span.c0000, .l2hLogPage span.c0100, .l2hLogPage span.c0200, .l2hLogPage span.c0300, .l2hLogPage span.c0400, .l2hLogPage span.c0500, .l2hLogPage span.c0600, .l2hLogPage span.c0700, .l2hLogPage span.c0800, .l2hLogPage span.c0900, .l2hLogPage span.c1000, .l2hLogPage span.c1100, .l2hLogPage span.c1200, .l2hLogPage span.c1300, .l2hLogPage span.c1400, .l2hLogPage span.c1500 {background-color: white;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0001, .l2hLogPage span.c0101, .l2hLogPage span.c0201, .l2hLogPage span.c0301, .l2hLogPage span.c0401, .l2hLogPage span.c0501, .l2hLogPage span.c0601, .l2hLogPage span.c0701, .l2hLogPage span.c0801, .l2hLogPage span.c0901, .l2hLogPage span.c1001, .l2hLogPage span.c1101, .l2hLogPage span.c1201, .l2hLogPage span.c1301, .l2hLogPage span.c1401, .l2hLogPage span.c1501 {background-color: black;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0002, .l2hLogPage span.c0102, .l2hLogPage span.c0202, .l2hLogPage span.c0302, .l2hLogPage span.c0402, .l2hLogPage span.c0502, .l2hLogPage span.c0602, .l2hLogPage span.c0702, .l2hLogPage span.c0802, .l2hLogPage span.c0902, .l2hLogPage span.c1002, .l2hLogPage span.c1102, .l2hLogPage span.c1202, .l2hLogPage span.c1302, .l2hLogPage span.c1402, .l2hLogPage span.c1502 {background-color: navy;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0003, .l2hLogPage span.c0103, .l2hLogPage span.c0203, .l2hLogPage span.c0303, .l2hLogPage span.c0403, .l2hLogPage span.c0503, .l2hLogPage span.c0603, .l2hLogPage span.c0703, .l2hLogPage span.c0803, .l2hLogPage span.c0903, .l2hLogPage span.c1003, .l2hLogPage span.c1103, .l2hLogPage span.c1203, .l2hLogPage span.c1303, .l2hLogPage span.c1403, .l2hLogPage span.c1503 {background-color: green;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0004, .l2hLogPage span.c0104, .l2hLogPage span.c0204, .l2hLogPage span.c0304, .l2hLogPage span.c0404, .l2hLogPage span.c0504, .l2hLogPage span.c0604, .l2hLogPage span.c0704, .l2hLogPage span.c0804, .l2hLogPage span.c0904, .l2hLogPage span.c1004, .l2hLogPage span.c1104, .l2hLogPage span.c1204, .l2hLogPage span.c1304, .l2hLogPage span.c1404, .l2hLogPage span.c1504 {background-color: red;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0005, .l2hLogPage span.c0105, .l2hLogPage span.c0205, .l2hLogPage span.c0305, .l2hLogPage span.c0405, .l2hLogPage span.c0505, .l2hLogPage span.c0605, .l2hLogPage span.c0705, .l2hLogPage span.c0805, .l2hLogPage span.c0905, .l2hLogPage span.c1005, .l2hLogPage span.c1105, .l2hLogPage span.c1205, .l2hLogPage span.c1305, .l2hLogPage span.c1405, .l2hLogPage span.c1505 {background-color: maroon;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0006, .l2hLogPage span.c0106, .l2hLogPage span.c0206, .l2hLogPage span.c0306, .l2hLogPage span.c0406, .l2hLogPage span.c0506, .l2hLogPage span.c0606, .l2hLogPage span.c0706, .l2hLogPage span.c0806, .l2hLogPage span.c0906, .l2hLogPage span.c1006, .l2hLogPage span.c1106, .l2hLogPage span.c1206, .l2hLogPage span.c1306, .l2hLogPage span.c1406, .l2hLogPage span.c1506 {background-color: purple;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0007, .l2hLogPage span.c0107, .l2hLogPage span.c0207, .l2hLogPage span.c0307, .l2hLogPage span.c0407, .l2hLogPage span.c0507, .l2hLogPage span.c0607, .l2hLogPage span.c0707, .l2hLogPage span.c0807, .l2hLogPage span.c0907, .l2hLogPage span.c1007, .l2hLogPage span.c1107, .l2hLogPage span.c1207, .l2hLogPage span.c1307, .l2hLogPage span.c1407, .l2hLogPage span.c1507 {background-color: orange;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0008, .l2hLogPage span.c0108, .l2hLogPage span.c0208, .l2hLogPage span.c0308, .l2hLogPage span.c0408, .l2hLogPage span.c0508, .l2hLogPage span.c0608, .l2hLogPage span.c0708, .l2hLogPage span.c0808, .l2hLogPage span.c0908, .l2hLogPage span.c1008, .l2hLogPage span.c1108, .l2hLogPage span.c1208, .l2hLogPage span.c1308, .l2hLogPage span.c1408, .l2hLogPage span.c1508 {background-color: yellow;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0009, .l2hLogPage span.c0109, .l2hLogPage span.c0209, .l2hLogPage span.c0309, .l2hLogPage span.c0409, .l2hLogPage span.c0509, .l2hLogPage span.c0609, .l2hLogPage span.c0709, .l2hLogPage span.c0809, .l2hLogPage span.c0909, .l2hLogPage span.c1009, .l2hLogPage span.c1109, .l2hLogPage span.c1209, .l2hLogPage span.c1309, .l2hLogPage span.c1409, .l2hLogPage span.c1509 {background-color: lime;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0010, .l2hLogPage span.c0110, .l2hLogPage span.c0210, .l2hLogPage span.c0310, .l2hLogPage span.c0410, .l2hLogPage span.c0510, .l2hLogPage span.c0610, .l2hLogPage span.c0710, .l2hLogPage span.c0810, .l2hLogPage span.c0910, .l2hLogPage span.c1010, .l2hLogPage span.c1110, .l2hLogPage span.c1210, .l2hLogPage span.c1310, .l2hLogPage span.c1410, .l2hLogPage span.c1510 {background-color: teal;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0011, .l2hLogPage span.c0111, .l2hLogPage span.c0211, .l2hLogPage span.c0311, .l2hLogPage span.c0411, .l2hLogPage span.c0511, .l2hLogPage span.c0611, .l2hLogPage span.c0711, .l2hLogPage span.c0811, .l2hLogPage span.c0911, .l2hLogPage span.c1011, .l2hLogPage span.c1111, .l2hLogPage span.c1211, .l2hLogPage span.c1311, .l2hLogPage span.c1411, .l2hLogPage span.c1511 {background-color: aqua;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0012, .l2hLogPage span.c0112, .l2hLogPage span.c0212, .l2hLogPage span.c0312, .l2hLogPage span.c0412, .l2hLogPage span.c0512, .l2hLogPage span.c0612, .l2hLogPage span.c0712, .l2hLogPage span.c0812, .l2hLogPage span.c0912, .l2hLogPage span.c1012, .l2hLogPage span.c1112, .l2hLogPage span.c1212, .l2hLogPage span.c1312, .l2hLogPage span.c1412, .l2hLogPage span.c1512 {background-color: blue;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0013, .l2hLogPage span.c0113, .l2hLogPage span.c0213, .l2hLogPage span.c0313, .l2hLogPage span.c0413, .l2hLogPage span.c0513, .l2hLogPage span.c0613, .l2hLogPage span.c0713, .l2hLogPage span.c0813, .l2hLogPage span.c0913, .l2hLogPage span.c1013, .l2hLogPage span.c1113, .l2hLogPage span.c1213, .l2hLogPage span.c1313, .l2hLogPage span.c1413, .l2hLogPage span.c1513 {background-color: fuchsia;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0014, .l2hLogPage span.c0114, .l2hLogPage span.c0214, .l2hLogPage span.c0314, .l2hLogPage span.c0414, .l2hLogPage span.c0514, .l2hLogPage span.c0614, .l2hLogPage span.c0714, .l2hLogPage span.c0814, .l2hLogPage span.c0914, .l2hLogPage span.c1014, .l2hLogPage span.c1114, .l2hLogPage span.c1214, .l2hLogPage span.c1314, .l2hLogPage span.c1414, .l2hLogPage span.c1514 {background-color: silver;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0015, .l2hLogPage span.c0115, .l2hLogPage span.c0215, .l2hLogPage span.c0315, .l2hLogPage span.c0415, .l2hLogPage span.c0515, .l2hLogPage span.c0615, .l2hLogPage span.c0715, .l2hLogPage span.c0815, .l2hLogPage span.c0915, .l2hLogPage span.c1015, .l2hLogPage span.c1114, .l2hLogPage span.c1215, .l2hLogPage span.c1315, .l2hLogPage span.c1415, .l2hLogPage span.c1515 {background-color: gray;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0000, .l2hLogPage span.c0001, .l2hLogPage span.c0002, .l2hLogPage span.c0003, .l2hLogPage span.c0004, .l2hLogPage span.c0005, .l2hLogPage span.c0006, .l2hLogPage span.c0007, .l2hLogPage span.c0008, .l2hLogPage span.c0009, .l2hLogPage span.c0010, .l2hLogPage span.c0011, .l2hLogPage span.c0012, .l2hLogPage span.c0013, .l2hLogPage span.c0014, .l2hLogPage span.c0015 {color: white;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0100, .l2hLogPage span.c0101, .l2hLogPage span.c0102, .l2hLogPage span.c0103, .l2hLogPage span.c0104, .l2hLogPage span.c0105, .l2hLogPage span.c0106, .l2hLogPage span.c0107, .l2hLogPage span.c0108, .l2hLogPage span.c0109, .l2hLogPage span.c0110, .l2hLogPage span.c0111, .l2hLogPage span.c0112, .l2hLogPage span.c0113, .l2hLogPage span.c0114, .l2hLogPage span.c0115 {color: black;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0200, .l2hLogPage span.c0201, .l2hLogPage span.c0202, .l2hLogPage span.c0203, .l2hLogPage span.c0204, .l2hLogPage span.c0205, .l2hLogPage span.c0206, .l2hLogPage span.c0207, .l2hLogPage span.c0208, .l2hLogPage span.c0209, .l2hLogPage span.c0210, .l2hLogPage span.c0211, .l2hLogPage span.c0212, .l2hLogPage span.c0213, .l2hLogPage span.c0214, .l2hLogPage span.c0215 {color: navy;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0300, .l2hLogPage span.c0301, .l2hLogPage span.c0302, .l2hLogPage span.c0303, .l2hLogPage span.c0304, .l2hLogPage span.c0305, .l2hLogPage span.c0306, .l2hLogPage span.c0307, .l2hLogPage span.c0308, .l2hLogPage span.c0309, .l2hLogPage span.c0310, .l2hLogPage span.c0311, .l2hLogPage span.c0312, .l2hLogPage span.c0313, .l2hLogPage span.c0314, .l2hLogPage span.c0315 {color: green;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0400, .l2hLogPage span.c0401, .l2hLogPage span.c0402, .l2hLogPage span.c0403, .l2hLogPage span.c0404, .l2hLogPage span.c0405, .l2hLogPage span.c0406, .l2hLogPage span.c0407, .l2hLogPage span.c0408, .l2hLogPage span.c0409, .l2hLogPage span.c0410, .l2hLogPage span.c0411, .l2hLogPage span.c0412, .l2hLogPage span.c0413, .l2hLogPage span.c0414, .l2hLogPage span.c0415 {color: red;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0500, .l2hLogPage span.c0501, .l2hLogPage span.c0502, .l2hLogPage span.c0503, .l2hLogPage span.c0504, .l2hLogPage span.c0505, .l2hLogPage span.c0506, .l2hLogPage span.c0507, .l2hLogPage span.c0508, .l2hLogPage span.c0509, .l2hLogPage span.c0510, .l2hLogPage span.c0511, .l2hLogPage span.c0512, .l2hLogPage span.c0513, .l2hLogPage span.c0514, .l2hLogPage span.c0515 {color: maroon;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0600, .l2hLogPage span.c0601, .l2hLogPage span.c0602, .l2hLogPage span.c0603, .l2hLogPage span.c0604, .l2hLogPage span.c0605, .l2hLogPage span.c0606, .l2hLogPage span.c0607, .l2hLogPage span.c0608, .l2hLogPage span.c0609, .l2hLogPage span.c0610, .l2hLogPage span.c0611, .l2hLogPage span.c0612, .l2hLogPage span.c0613, .l2hLogPage span.c0614, .l2hLogPage span.c0615 {color: purple;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0700, .l2hLogPage span.c0701, .l2hLogPage span.c0702, .l2hLogPage span.c0703, .l2hLogPage span.c0704, .l2hLogPage span.c0705, .l2hLogPage span.c0706, .l2hLogPage span.c0707, .l2hLogPage span.c0708, .l2hLogPage span.c0709, .l2hLogPage span.c0710, .l2hLogPage span.c0711, .l2hLogPage span.c0712, .l2hLogPage span.c0713, .l2hLogPage span.c0714, .l2hLogPage span.c0715 {color: orange;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0800, .l2hLogPage span.c0801, .l2hLogPage span.c0802, .l2hLogPage span.c0803, .l2hLogPage span.c0804, .l2hLogPage span.c0805, .l2hLogPage span.c0806, .l2hLogPage span.c0807, .l2hLogPage span.c0808, .l2hLogPage span.c0809, .l2hLogPage span.c0810, .l2hLogPage span.c0811, .l2hLogPage span.c0812, .l2hLogPage span.c0813, .l2hLogPage span.c0814, .l2hLogPage span.c0815 {color: yellow;}\n");
++ str_write(dst_file, ".l2hLogPage span.c0900, .l2hLogPage span.c0901, .l2hLogPage span.c0902, .l2hLogPage span.c0903, .l2hLogPage span.c0904, .l2hLogPage span.c0905, .l2hLogPage span.c0906, .l2hLogPage span.c0907, .l2hLogPage span.c0908, .l2hLogPage span.c0909, .l2hLogPage span.c0910, .l2hLogPage span.c0911, .l2hLogPage span.c0912, .l2hLogPage span.c0913, .l2hLogPage span.c0914, .l2hLogPage span.c0915 {color: lime;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1000, .l2hLogPage span.c1001, .l2hLogPage span.c1002, .l2hLogPage span.c1003, .l2hLogPage span.c1004, .l2hLogPage span.c1005, .l2hLogPage span.c1006, .l2hLogPage span.c1007, .l2hLogPage span.c1008, .l2hLogPage span.c1009, .l2hLogPage span.c1010, .l2hLogPage span.c1011, .l2hLogPage span.c1012, .l2hLogPage span.c1013, .l2hLogPage span.c1014, .l2hLogPage span.c1015 {color: teal;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1100, .l2hLogPage span.c1101, .l2hLogPage span.c1102, .l2hLogPage span.c1103, .l2hLogPage span.c1104, .l2hLogPage span.c1105, .l2hLogPage span.c1106, .l2hLogPage span.c1107, .l2hLogPage span.c1108, .l2hLogPage span.c1109, .l2hLogPage span.c1110, .l2hLogPage span.c1111, .l2hLogPage span.c1112, .l2hLogPage span.c1113, .l2hLogPage span.c1114, .l2hLogPage span.c1115 {color: aqua;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1200, .l2hLogPage span.c1201, .l2hLogPage span.c1202, .l2hLogPage span.c1203, .l2hLogPage span.c1204, .l2hLogPage span.c1205, .l2hLogPage span.c1206, .l2hLogPage span.c1207, .l2hLogPage span.c1208, .l2hLogPage span.c1209, .l2hLogPage span.c1210, .l2hLogPage span.c1211, .l2hLogPage span.c1212, .l2hLogPage span.c1213, .l2hLogPage span.c1214, .l2hLogPage span.c1215 {color: blue;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1300, .l2hLogPage span.c1301, .l2hLogPage span.c1302, .l2hLogPage span.c1303, .l2hLogPage span.c1304, .l2hLogPage span.c1305, .l2hLogPage span.c1306, .l2hLogPage span.c1307, .l2hLogPage span.c1308, .l2hLogPage span.c1309, .l2hLogPage span.c1310, .l2hLogPage span.c1311, .l2hLogPage span.c1312, .l2hLogPage span.c1313, .l2hLogPage span.c1314, .l2hLogPage span.c1315 {color: fuchsia;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1400, .l2hLogPage span.c1401, .l2hLogPage span.c1402, .l2hLogPage span.c1403, .l2hLogPage span.c1404, .l2hLogPage span.c1405, .l2hLogPage span.c1406, .l2hLogPage span.c1407, .l2hLogPage span.c1408, .l2hLogPage span.c1409, .l2hLogPage span.c1410, .l2hLogPage span.c1411, .l2hLogPage span.c1412, .l2hLogPage span.c1413, .l2hLogPage span.c1414, .l2hLogPage span.c1415 {color: silver;}\n");
++ str_write(dst_file, ".l2hLogPage span.c1500, .l2hLogPage span.c1501, .l2hLogPage span.c1502, .l2hLogPage span.c1503, .l2hLogPage span.c1504, .l2hLogPage span.c1505, .l2hLogPage span.c1506, .l2hLogPage span.c1507, .l2hLogPage span.c1508, .l2hLogPage span.c1509, .l2hLogPage span.c1510, .l2hLogPage span.c1511, .l2hLogPage span.c1512, .l2hLogPage span.c1513, .l2hLogPage span.c1514, .l2hLogPage span.c1515 {color: gray;}\n");
++ str_write(dst_file, ".l2hLogPage span.f00 {color: white;}\n");
++ str_write(dst_file, ".l2hLogPage span.f01 {color: black;}\n");
++ str_write(dst_file, ".l2hLogPage span.f02 {color: navy;}\n");
++ str_write(dst_file, ".l2hLogPage span.f03 {color: green;}\n");
++ str_write(dst_file, ".l2hLogPage span.f04 {color: red;}\n");
++ str_write(dst_file, ".l2hLogPage span.f05 {color: maroon;}\n");
++ str_write(dst_file, ".l2hLogPage span.f06 {color: purple;}\n");
++ str_write(dst_file, ".l2hLogPage span.f07 {color: orange;}\n");
++ str_write(dst_file, ".l2hLogPage span.f08 {color: yellow;}\n");
++ str_write(dst_file, ".l2hLogPage span.f09 {color: lime;}\n");
++ str_write(dst_file, ".l2hLogPage span.f10 {color: teal;}\n");
++ str_write(dst_file, ".l2hLogPage span.f11 {color: aqua;}\n");
++ str_write(dst_file, ".l2hLogPage span.f12 {color: blue;}\n");
++ str_write(dst_file, ".l2hLogPage span.f13 {color: fuchsia;}\n");
++ str_write(dst_file, ".l2hLogPage span.f14 {color: silver;}\n");
++ str_write(dst_file, ".l2hLogPage span.f15 {color: gray;}\n\n");
++
++ str_write(dst_file, "/* Miscellaneous classes for reuse */\n");
++ str_write(dst_file, ".clearfloat {\n");
++ str_write(dst_file, "/* this class should be placed on a div or break element and should be the final element before\n");
++ str_write(dst_file, "the close of a container that should fully contain a float */\n");
++ str_write(dst_file, "clear:both;\n");
++ str_write(dst_file, "height:0;\n");
++ str_write(dst_file, "font-size: 1px;\n");
++ str_write(dst_file, "line-height: 0px;\n");
++ str_write(dst_file, "}\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
@@ -284,15 +614,59 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.english.l
+0xe021,Th
+0xe022,Fr
+0xe023,St
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.french.lang eggdrop1.6.19/src/mod/logs2html.mod/language/logs2html.french.lang
---- ./src/mod/logs2html.mod/language/logs2html.french.lang 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/language/logs2html.french.lang 2009-03-28 01:32:53.000000000 +0000
+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
++0xe000,AnnпїЅe
+
+# Back to mainpage link
+0xe001,Page principale
@@ -301,22 +675,22 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.french.la
+0xe002,haut
+
+# Backward, forward link
-+0xe003,Prйcйdente
++0xe003,PrпїЅcпїЅdente
+0xe004,Suivante
+
+# Month names
+0xe005,Janvier
-+0xe006,Fйvrier
++0xe006,FпїЅvrier
+0xe007,Mars
+0xe008,Avril
+0xe009,Mai
+0xe010,Juin
+0xe011,Juillet
-+0xe012,Aoыt
++0xe012,AoпїЅt
+0xe013,Septembre
+0xe014,Octobre
+0xe015,Novembre
-+0xe016,Dйcembre
++0xe016,DпїЅcembre
+
+# Days of week names
+0xe017,Di
@@ -326,52 +700,94 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.french.la
+0xe021,Je
+0xe022,Ve
+0xe023,Sa
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language/logs2html.russian.lang eggdrop1.6.19/src/mod/logs2html.mod/language/logs2html.russian.lang
---- ./src/mod/logs2html.mod/language/logs2html.russian.lang 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/language/logs2html.russian.lang 2009-03-28 01:32:21.000000000 +0000
+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,год
++0xe000,пїЅпїЅпїЅ
+
+# Back to mainpage link
-+0xe001,На главную страницу
++0xe001,пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
+
+# Up link
-+0xe002,наверх
++0xe002,пїЅпїЅпїЅпїЅпїЅпїЅ
+
+# Backward, forward link
-+0xe003,предыдущая
-+0xe004,следующая
++0xe003,пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
++0xe004,пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
+
+# Month names
-+0xe005,Январь
-+0xe006,Февраль
-+0xe007,Март
-+0xe008,Апрель
-+0xe009,Май
-+0xe010,Июнь
-+0xe011,Июль
-+0xe012,Август
-+0xe013,Сентябрь
-+0xe014,Октябрь
-+0xe015,Ноябрь
-+0xe016,Декабрь
++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 eggdrop1.6.19-orig/src/mod/logs2html.mod/language.h eggdrop1.6.19/src/mod/logs2html.mod/language.h
---- ./src/mod/logs2html.mod/language.h 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/language.h 2009-03-28 01:32:21.000000000 +0000
-@@ -0,0 +1,51 @@
++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
+ *
@@ -394,7 +810,8 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language.h eggdrop1.6.19/src
+ * 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)
@@ -423,16 +840,20 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/language.h eggdrop1.6.19/src
+#define LOGS2HTML_FRIDAY get_language(0xe022)
+#define LOGS2HTML_SATURDAY get_language(0xe023)
+
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/src/mod/logs2html.mod/logs2html.c
---- ./src/mod/logs2html.mod/logs2html.c 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/logs2html.c 2009-03-28 01:32:53.000000000 +0000
-@@ -0,0 +1,1572 @@
++#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 Gray_Angel aka Shmupsik <shurikvz@mail.ru>
++ * Written by Fedotov Alexander aka Shmupsik aka shurikvz <shurikvz@mail.ru>
++ *
++ * 2004-2009 year
++ *
++ * Patch and some changes to v.2.3.4 by skiidoo (2007)
+ *
-+ * 2004-2005 year
+ */
+/*
+ * This program is free software; you can redistribute it and/or
@@ -456,33 +877,40 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+#include "src/mod/module.h"
+
+#include <stdlib.h>
++#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
-+#include <sys/types.h>
-+#include <math.h>
++#include <sys/types.h>
++#include <math.h>
++#include <regex.h>
+#include "logs2html.h"
+#include "language.h"
-+
++
+#undef global
+
+#define MODULE_MAJOR 2
-+#define MODULE_MINOR 3
-+#define MODULE_SUBMINOR 4
++#define MODULE_MINOR 4
++#define MODULE_SUBMINOR 3
++#define MODULE_BUILD "(ac100-ru fork)"
+
+static Function *global = NULL;
+
-+#include "fileoperations.c"
-+
-+
+static int shtime;
+static int keep_all_logs;
+static char logfile_suffix[21];
-+static char configfile[121];
-+static int lines_per_page;
+
-+static int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
++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;
@@ -491,370 +919,30 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+static char mainpage_bottom_filename[257] = "\0";
+static char logspage_top_filename[257] = "\0";
+static char logspage_bottom_filename[257] = "\0";
-+static char chanlist_filename[257] = "\0";
-+static char userstyle_filename[257] = "\0";
-+static char encoding_string[31] = "\0";
++static char userstyle_filename[257] = "\0";
++static char encoding_string[31] = "\0";
+
-+static logs2htmlchan *logs2htmlchanlist = NULL;
++static l2hchan_t *logs2htmlchanlist = NULL; // Here we keep list of our logs
+
+/* for language file */
-+static char month_names[12][21];
-+static char days_names[7][21];
++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_daily(void);
-+static void logs2html_hook_pre_rehash(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"
+
-+/* Calculate the memory we keep allocated.
-+ */
-+static int logs2html_expmem()
-+{
-+ logs2htmlchan *p;
-+ int size = 0;
-+
-+ Context;
-+ p = logs2htmlchanlist;
-+ while (p != NULL) {
-+ size++;
-+ p = p->next;
-+ }
-+
-+ size *= sizeof(struct logs2html_data);
-+
-+ return size;
-+}
-+
-+
-+/****************************************************************************/
-+/*
-+ * function int convertalllogs(struct userrec *u, int idx, char *par)
-+ *
-+ * Input:
-+ *
-+ *
-+ *
-+ * Output:
-+ *
-+ *
-+ * Discription:
-+ *
-+ */
-+static int cmd_convertalllogs(struct userrec *u, int idx, char *par) {
-+ int add_day;
-+ logs2htmlchan *p;
-+ int i, j, k;
-+ struct tm tblock;
-+ time_t t = time(NULL);
-+ struct tm *st = localtime(&t);
-+
-+ tblock.tm_year = st->tm_year;
-+ tblock.tm_isdst = st->tm_isdst;
-+ tblock.tm_hour = 0;
-+ tblock.tm_min = 0;
-+ tblock.tm_sec = 1;
-+ /* Other fields not necessary here
-+ tblock.tm_mday = st->tm_mday;
-+ tblock.tm_mon = st->tm_mon;
-+ tblock.tm_wday = st->tm_wday;
-+ tblock.tm_yday = st->tm_yday;
-+ */
-+
-+ putlog(LOG_CMDS, "*", "#%s# start converting all log files.", dcc[idx].nick);
-+ for (i = 0; i < 12; i++) {
-+ add_day = ((i == 1) && isleap(tblock.tm_year)) ? 1 : 0;
-+ for (j = 0; j < ((days_in_month[i]) + add_day); j++) {
-+ tblock.tm_mon = i; tblock.tm_mday = j + 1;
-+
-+ tblock.tm_wday = (getdayofweek(tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday) + 1) % 7;
-+ tblock.tm_yday = 0;
-+ for (k = 0; k < tblock.tm_mon; k++) tblock.tm_yday += days_in_month[k];
-+ tblock.tm_yday += tblock.tm_mday - 1;
-+
-+ p = logs2htmlchanlist;
-+ while (p != NULL) {
-+ convertfile(&tblock, p);
-+ p = p->next;
-+ }
-+ }
-+ }
-+ putlog(LOG_CMDS, "*", "#%s# converting of all log files done.", dcc[idx].nick);
-+
-+ return 0;
-+} /* convertalllogs() */
-+/****************************************************************************/
-+
-+
-+/****************************************************************************/
-+/*
-+ * 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) {
-+ logs2htmlchan *p;
-+
-+ putlog(LOG_CMDS, "*", "#%s# starting making mainpages.", dcc[idx].nick);
-+ p = logs2htmlchanlist;
-+ while (p != NULL) {
-+ dprintf(idx, "Making mainpage for channel '%s'...\n", p->channame);
-+ makemainpage(p);
-+ p = p->next;
-+ }
-+ putlog(LOG_CMDS, "*", "#%s# making of mainpages done.", dcc[idx].nick);
-+
-+ return 0;
-+} /* convertalllogs() */
-+/****************************************************************************/
-+
-+
-+/****************************************************************************/
-+/*
-+ * function bool isvalidlink(char *link)
-+ *
-+ * Input:
-+ * link - строка указывающая на ссылку
-+ *
-+ *
-+ * Output:
-+ *
-+ *
-+ * Discription:
-+ * Функция проверяет являются ли переданные в строке символы - символами
-+ * допустимыми в ссылках
-+ */
-+static patternkind whatisit(char *pattern) {
-+ char alpha_common[] = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789._-";
-+ char alpha_http[] = "=?&/:%";
-+ char *p;
-+
-+ if (strstr(pattern, "..") != NULL) {
-+ return ITS_NOTHING;
-+ }
-+
-+ p = strchr(pattern, '@');
-+ if (p) {
-+ /* it's can't be www link */
-+
-+ /* well, i can't imagine e-mail shorter than i@m.ru */
-+ /* let's check it */
-+ *p = '\0';
-+ if (strlen(pattern) < 1) {
-+ *p = '@';
-+ return ITS_NOTHING;
-+ }
-+ while (*pattern) {
-+ if (strchr(alpha_common, *pattern) == NULL) {
-+ *p = '@';
-+ return ITS_NOTHING;
-+ }
-+ pattern++;
-+ }
-+ *p = '@';
-+ p++;
-+ if (strlen(p) < 4) {
-+ return ITS_NOTHING;
-+ }
-+ while (*p) {
-+ if (strchr(alpha_common, *p) == NULL) return ITS_NOTHING;
-+ p++;
-+ }
-+
-+ return ITS_EMAIL;
-+ } else {
-+ if ((strncmp(pattern, "http://", 7) != 0) && (strncmp(pattern, "ftp://", 6) != 0)) {
-+ if (strncmp(pattern, "www.", 4) != 0) {
-+ return ITS_NOTHING;
-+ } else {
-+ while (*pattern) {
-+ if ((strchr(alpha_common, *pattern) == NULL) && (strchr(alpha_http, *pattern) == NULL)) return ITS_NOTHING;
-+ pattern++;
-+ }
-+
-+ return ITS_TRUNKLINK;
-+ }
-+ }
-+
-+ while (*pattern) {
-+ if ((strchr(alpha_common, *pattern) == NULL) && (strchr(alpha_http, *pattern) == NULL)) return ITS_NOTHING;
-+ pattern++;
-+ }
-+
-+ return ITS_LINK;
-+ }
-+
-+ return ITS_NOTHING;
-+} /* whatisit() */
-+/****************************************************************************/
-+
-+
-+/* A report on the module status.
-+ *
-+ * details is either 0 or 1:
-+ * 0 - `.status'
-+ * 1 - `.status all' or `.module woobie'
-+ */
-+static void logs2html_report(int idx, int details)
-+{
-+ if (details) {
-+ int size = logs2html_expmem();
-+
-+ dprintf(idx, " Using %d byte%s of memory\n", size,
-+ (size != 1) ? "s" : "");
-+ }
-+}
-+
-+static cmd_t mydcc[] = {
-+ {"convertalllogs", "n", cmd_convertalllogs, NULL},
-+ {"makemainpage", "n", cmd_makemainpage, NULL},
-+ {NULL, NULL, NULL, NULL} /* Mark end. */
-+};
-+
-+static tcl_strings my_tcl_strings[] = {
-+ {"logfile-suffix", logfile_suffix, 20, STR_PROTECT},
-+ {"config", configfile, 121, STR_PROTECT},
-+ {"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},
-+ {"channels-list", chanlist_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},
-+ {"log-time", &shtime, 1},
-+ {"keep-all-logs", &keep_all_logs, 1},
-+ {NULL, NULL, 0} /* Mark end. */
-+};
-+
-+static char *logs2html_close()
-+{
-+ logs2htmlchan *p, *q;
-+
-+ Context;
-+ q = p = logs2htmlchanlist;
-+ while (q != NULL) {
-+ q = p->next;
-+ nfree(p);
-+ p = q;
-+ }
-+ logs2htmlchanlist = p = q = NULL;
-+
-+ del_lang_section(MODULE_NAME);
-+ rem_help_reference(MODULE_NAME ".help");
-+
-+ del_hook(HOOK_DAILY, (Function)logs2html_hook_daily);
-+ del_hook(HOOK_5MINUTELY, (Function)logs2html_hook_5minutely);
-+ del_hook(HOOK_PRE_REHASH, (Function)logs2html_hook_pre_rehash);
-+ del_hook(HOOK_REHASH, (Function)logs2html_hook_rehash);
-+
-+ rem_builtins(H_dcc, mydcc);
-+ rem_tcl_ints(my_tcl_ints);
-+ rem_tcl_strings(my_tcl_strings);
-+
-+ 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)
-+{
-+ logs2htmlchan *ptr;
-+
-+ global = global_funcs;
-+
-+ Context;
-+ /* Register the module. */
-+ module_register(MODULE_NAME, logs2html_table, MODULE_MAJOR, MODULE_MINOR);
-+
-+ if (!module_depend(MODULE_NAME, "eggdrop", 106, 15)) {
-+ module_undepend(MODULE_NAME);
-+ return "This module requires Eggdrop 1.6.15 or later.";
-+ }
-+
-+ add_tcl_ints(my_tcl_ints);
-+
-+ if (!keep_all_logs) {
-+ rem_tcl_ints(my_tcl_ints);
-+ module_undepend(MODULE_NAME);
-+ return "This module requires \"keep-all-logs\" set to \"1\". Please check settings in your config file.";
-+ }
-+ logs2htmlchanlist = NULL; if (lines_per_page < 0) lines_per_page = 0;
-+
-+ add_tcl_strings(my_tcl_strings);
-+
-+ if (addchannels()) {
-+ ptr = logs2htmlchanlist;
-+ while (ptr != NULL) {
-+ putlog(LOG_CMDS, "*", "logs2html: added channel %s, with path to logfiles \"%s\"...\n", ptr->channame, ptr->logfilename);
-+ ptr = ptr->next;
-+ }
-+ } else {
-+ rem_tcl_strings(my_tcl_strings);
-+ rem_tcl_ints(my_tcl_ints);
-+ module_undepend(MODULE_NAME);
-+ return "No channels added. Please check settings in your eggdrop config file to be sure there is logfiles with mode set to \"p\".";
-+ }
-+
-+ add_builtins(H_dcc, mydcc);
-+
-+ add_hook(HOOK_5MINUTELY, (Function)logs2html_hook_5minutely); //Для обновления лога за текущий день
-+ add_hook(HOOK_DAILY, (Function)logs2html_hook_daily); //Последние 5 минут за прошлый день
-+ add_hook(HOOK_PRE_REHASH, (Function)logs2html_hook_pre_rehash);
-+ add_hook(HOOK_REHASH, (Function)logs2html_hook_rehash);
-+
-+ add_lang_section(MODULE_NAME);
-+ add_help_reference(MODULE_NAME ".help");
-+
-+ month_names[0][0] = month_names[1][0] = month_names[2][0] = month_names[3][0] =
-+ month_names[4][0] = month_names[5][0] = month_names[6][0] = month_names[7][0] =
-+ month_names[8][0] = month_names[9][0] = month_names[10][0] = month_names[11][0] =
-+ days_names[0][0] = days_names[1][0] = days_names[2][0] = days_names[3][0] =
-+ days_names[4][0] = days_names[5][0] = days_names[6][0] = '\0';
-+
-+ strncpyz(month_names[0], LOGS2HTML_JANUARY, sizeof month_names[0]);
-+ strncpyz(month_names[1], LOGS2HTML_FEBRIARY, sizeof month_names[1]);
-+ strncpyz(month_names[2], LOGS2HTML_MARCH, sizeof month_names[2]);
-+ strncpyz(month_names[3], LOGS2HTML_APRIL, sizeof month_names[3]);
-+ strncpyz(month_names[4], LOGS2HTML_MAY, sizeof month_names[4]);
-+ strncpyz(month_names[5], LOGS2HTML_JUNE, sizeof month_names[5]);
-+ strncpyz(month_names[6], LOGS2HTML_JULY, sizeof month_names[6]);
-+ strncpyz(month_names[7], LOGS2HTML_AUGUST, sizeof month_names[7]);
-+ strncpyz(month_names[8], LOGS2HTML_SEPTEMBER, sizeof month_names[8]);
-+ strncpyz(month_names[9], LOGS2HTML_OCTOBER, sizeof month_names[9]);
-+ strncpyz(month_names[10], LOGS2HTML_NOVEMBER, sizeof month_names[10]);
-+ strncpyz(month_names[11], LOGS2HTML_DECEMBER, sizeof month_names[11]);
-+ strncpyz(days_names[0], LOGS2HTML_MONDAY, sizeof days_names[0]);
-+ strncpyz(days_names[1], LOGS2HTML_TUESDAY, sizeof days_names[1]);
-+ strncpyz(days_names[2], LOGS2HTML_WEDNESDAY, sizeof days_names[2]);
-+ strncpyz(days_names[3], LOGS2HTML_THURSDAY, sizeof days_names[3]);
-+ strncpyz(days_names[4], LOGS2HTML_FRIDAY, sizeof days_names[4]);
-+ strncpyz(days_names[5], LOGS2HTML_SATURDAY, sizeof days_names[5]);
-+ strncpyz(days_names[6], LOGS2HTML_SUNDAY, sizeof days_names[6]);
-+
-+ return NULL;
-+}
+
+/*
+ * Code starts here
@@ -863,15 +951,15 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+/*
+ * getdayofweek()
+ * Input:
-+ * year - год
-+ * month - месяц
-+ * day - день
++ * year - РіРѕРґ
++ * month - месяц
++ * day - день
+ *
+ * Output:
-+ * 0 - Понедельник, 1 - Вторник, 2 - Среда и.т.д.
++ * 0 - Понедельник, 1 - Вторник, 2 - Среда и.т.д.
+ *
+ * Description:
-+ * Функция вычисляет на какой день недели приходится переданная дата
++ * Функция вычисляет на какой день недели приходится переданная дата
+ */
+static int getdayofweek(int year, int month, int day)
+{
@@ -891,1035 +979,1315 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+
+
+/****************************************************************************/
-+/*
-+ * function static int addchannels() {
-+ *
-+ * Input:
-+ *
-+ *
-+ *
-+ *
-+ * Output:
-+ *
-+ *
-+ * Discription:
-+ *
-+ *
-+ */
-+static int addchannels() {
-+ char buffer[512];
-+ char *buf_ptr, *p;
-+ logs2htmlchan *newchan, *ptr;
-+ FILE *src_file;
-+ int field_num;
-+ int filelineread;
-+ int channels_count = 0;
-+
-+
-+ Context;
-+ filelineread = 0;
-+ if ((src_file = openfile(chanlist_filename, "r", true)) == NULL) return 0;
-+ while (!feof(src_file)) {
-+ buf_ptr = fgets(buffer, sizeof(buffer)-1, src_file);
-+ if (buf_ptr == NULL) break;
-+ filelineread++;
-+
-+ p = strrchr(buf_ptr, '\n');
-+ if (p) *p = '\0';
-+ p = strrchr(buf_ptr, '\r');
-+ if (p) *p = '\0';
-+ if (strlen(buf_ptr) == 0) continue;
-+ while (isspace(*buf_ptr)) buf_ptr++;
-+/* while (egg_isspace(*buf_ptr)) buf_ptr++; */
-+ if (strncmp(buf_ptr, "addlogs2htmlchan", 16) == 0) p = buf_ptr += 16; else continue;
-+ while (*p++) if (isspace(*p)) *p = ' ';
-+/* while (*p++) if (egg_isspace(*p)) *p = ' '; */
-+ if (!isspace(*buf_ptr)) continue;
-+/* if (!egg_isspace(*buf_ptr)) continue; */
-+ /*
-+ At that point we have string of params of command "addlogs2htmlchan"
-+ pointed by buf_ptr, with leading ' ';
-+ */
-+
-+ newchan = (logs2htmlchan *)nmalloc(sizeof(logs2htmlchan) * 1);
-+ if (newchan == NULL) {
-+ nfree(newchan); newchan = NULL;
-+ fclose(src_file);
-+ putlog(LOG_MISC, "*", "Can't allocate enough space to add new channel!");
-+ break;
-+ }
++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);
+
-+ newchan->next = NULL;
-+ newchan->logfilename[0] = '\0';
-+ newchan->channame[0] = '\0';
-+ newchan->outputpath[0] = '\0';
-+ newchan->mainpagename[0] = '\0';
-+ newchan->mainpagetitle[0] = '\0';
-+ newchan->logspagename[0] = '\0';
-+ newchan->logspagetitle[0] = '\0';
-+
-+ field_num = 0;
-+ while (*buf_ptr) {
-+ while ((*buf_ptr) && (*buf_ptr == ' ')) buf_ptr++;
-+ p = ++buf_ptr;
-+ while ((*p) && (*p != '"')) p++;
-+ *p = '\0';
-+ switch (field_num) {
-+ case 0: /* newchan->channame */
-+ strncpyz(newchan->channame, buf_ptr, sizeof newchan->channame);
-+ field_num = 1;
-+ break;
-+ case 1: /* newchan->outputpath */
-+ strncpyz(newchan->outputpath, buf_ptr, sizeof newchan->outputpath);
-+ field_num = 2;
-+ break;
-+ case 2: /* newchan->mainpagename */
-+ strncpyz(newchan->mainpagename, buf_ptr, sizeof newchan->mainpagename);
-+ field_num = 3;
-+ break;
-+ case 3: /* newchan->mainpagetitle */
-+ strncpyz(newchan->mainpagetitle, buf_ptr, sizeof newchan->mainpagetitle);
-+ field_num = 4;
-+ break;
-+ case 4: /* newchan->logspagename */
-+ strncpyz(newchan->logspagename, buf_ptr, sizeof newchan->logspagename);
-+ field_num = 5;
-+ break;
-+ case 5: /* newchan->logspagetitle */
-+ strncpyz(newchan->logspagetitle, buf_ptr, sizeof newchan->logspagetitle);
-+ field_num = 6;
-+ break;
-+ }
-+ buf_ptr = ++p;
-+ }
++ 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 (field_num != 6) {
-+ nfree(newchan); newchan = NULL;
-+ putlog(LOG_MISC, "*", "Error in file %s. String %d. Invalid expression \"addlogs2htmlchan\".", chanlist_filename, filelineread);
-+ continue;
-+ }
++ 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;
++ }
+
-+ ptr = logs2htmlchanlist;
-+ if (ptr == NULL) {
-+ logs2htmlchanlist = newchan;
++ str_write(file, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
++ str_write(file, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");
++ str_write(file, "<head>\n");
++ if (strlen(encoding_string) > 0) {str_write(file, "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n", encoding_string); }
++ str_write(file, "\t<meta name=\"title\" content=\"%s\" />\n", ch->mainpagetitle);
++ str_write(file, "\t<meta name=\"description\" content=\"%s\" />\n", ch->mainpagetitle);
++ str_write(file, "\t<meta name=\"generator\" content=\"logs2html module for Eggdrop v.%d.%d.%d%s\" />\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD);
++ str_write(file, "\t<meta name=\"author\" content=\"Fedotov Alexander aka shurikvz aka shmupsik\" />\n");
++ str_write(file, "\t<meta name=\"keywords\" content=\"logs2html, logs, logging, channel, irc, bot, eggdrop, windrop, mirc, module, convert\" />\n");
++ str_write(file, "\t<meta name=\"robots\" content= \"index,all\" />\n");
++ str_write(file, "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"default.css\" />\n");
++ if (strlen(userstyle_filename) > 0) str_write(file, "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"user.css\" />\n");
++ str_write(file, "\t<title>%s %d %s</title>\n", ch->mainpagetitle, year, LOGS2HTML_YEAR);
++ str_write(file, "\t<!--[if IE]>\n\t<style type=\"text/css\">\n\t.l2hMainPage #leftsidebar { padding-top: 30px; }\n\t.l2hMainPage #mainblock { zoom: 1; padding-top: 15px; }\n\t/* the above proprietary zoom property gives IE the hasLayout it may need to avoid several bugs */\n\t</style>\n\t<![endif]-->\n");
++ str_write(file, "</head>\n\n");
++
++ str_write(file, "<body class=\"l2hMainPage\">\n");
++ str_write(file, "\t<div id=\"container\">\n");
++
++ if (strlen(mainpage_top_filename) > 0) {
++ str_write(file, "\t\t<div id=\"mp_top\">\n");
++ writefromexfile(file, mainpage_top_filename);
++ str_write(file, "\n\t\t</div>\n");
++ }
++
++ str_write(file, "\t\t<div id=\"header\">\n<h2>%s<br />%d %s</h2>\n\t\t</div>\n", ch->mainpagetitle, year, LOGS2HTML_YEAR);
++ str_write(file, "\t\t<div id=\"leftsidebar\">\n");
++
++ int loopyear;
++ for(loopyear = start_year; loopyear <= tblock.tm_year + 1900; loopyear++) {
++ str_write(file, "\t\t\t<div class=\"indexlink\">");
++ if (loopyear == year) {
++ str_write(file, "<a href=\"JavaScript:void(0);\">%d</a>", loopyear);
+ } else {
-+ while (ptr->next != NULL) {
-+ ptr = ptr->next;
++ 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);
+ }
-+ ptr->next = newchan;
++ str_write(file, "<a href=\"%s\">%d</a>", filename, loopyear);
+ }
-+ newchan = NULL;
++ str_write(file, "</div>\n");
++ }
++ str_write(file, "\t\t</div>\n\n");
++ str_write(file, "\t\t<div id=\"mainblock\">\n");
++ str_write(file, "\t\t\t<table id=\"monthtable\" width=\"100%%\" border=\"0\">\n");
+
++ int i, j, k;
++ str_write(file, "\t\t\t\t<colgroup>\n");
++ for(k = 0; k < month_cols_count; k++) {
++ str_write(file, "\t\t\t\t\t<col width=\"%d%%\" />\n", (int)(100 / month_cols_count));
+ }
-+ fclose(src_file);
++ str_write(file, "\t\t\t\t</colgroup>\n");
+
-+ if ((src_file = openfile(configfile, "r", true)) == NULL) return 0;
-+ while (!feof(src_file)) {
-+ buf_ptr = fgets(buffer, sizeof(buffer)-1, src_file);
-+ if (buf_ptr == NULL) break;
-+
-+ p = strrchr(buf_ptr, '\n');
-+ if (p) *p = '\0';
-+ p = strrchr(buf_ptr, '\r');
-+ if (p) *p = '\0';
-+ if (strlen(buf_ptr) == 0) continue;
-+ while (isspace(*buf_ptr)) buf_ptr++;
-+/* while (egg_isspace(*buf_ptr)) buf_ptr++; */
-+ if (strncmp(buf_ptr, "logfile", 7) == 0) p = buf_ptr += 7; else continue;
-+ while (*p++) if (isspace(*p)) *p = ' ';
-+/* while (*p++) if (egg_isspace(*p)) *p = ' '; */
-+ if (!isspace(*buf_ptr)) continue;
-+/* if (!egg_isspace(*buf_ptr)) continue; */
-+ /*
-+ At that point we have string of params of command "logfile"
-+ pointed by buf_ptr, with leading ' ';
-+ */
-+
-+ p = newsplit(&buf_ptr);
-+ if (logmodes(p) & LOG_PUBLIC) {
-+ p = newsplit(&buf_ptr);
-+ /*
-+ At that point we have channel of command "logfile" pointed by p,
-+ and the rest of the string (path to file), pointed by buf_ptr and enclosed with "
-+ */
-+ buf_ptr++; buf_ptr[strlen(buf_ptr)-1] = '\0';
-+
-+ ptr = logs2htmlchanlist;
-+ while (ptr != NULL) {
-+ if ((*p == '*') || (!rfc_casecmp(ptr->channame, p))) {
-+ egg_snprintf(ptr->logfilename, sizeof ptr->logfilename, "%s", buf_ptr);
-+ }
-+ ptr = ptr->next;
++ for(i = 0; i < month_rows_count; i++) {
++ str_write(file, "\t\t\t\t<tr>\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<td>\n\t\t\t\t\t\t<table class=\"monthblock\" width=\"100%%\">\n");
++ str_write(file, "\t\t\t\t\t\t\t<colgroup>\n");
++ for(k = 0; k < 7; k++) {
++ str_write(file, "\t\t\t\t\t\t\t\t<col width=\"%d%%\" />\n", (int)(100 / 7));
+ }
-+ }
-+
-+
-+ }
-+ fclose(src_file);
++ str_write(file, "\t\t\t\t\t\t\t</colgroup>\n");
+
++ if ((month >= 0) && (month <= 11)) {
+
-+ while (logs2htmlchanlist != NULL) {
-+ if (strlen(logs2htmlchanlist->logfilename) == 0) {
-+ ptr = logs2htmlchanlist;
-+ logs2htmlchanlist = logs2htmlchanlist->next;
-+ nfree(ptr);
-+ } else {
-+ ptr = logs2htmlchanlist;
-+ while (ptr->next != NULL) {
-+ if (strlen(ptr->next->logfilename) == 0) {
-+ newchan = ptr->next;
-+ ptr->next = ptr->next->next;
-+ nfree(newchan);
++ 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<tr>\n\t\t\t\t\t\t\t\t<th class=\"monthname\" colspan=\"7\">%s</th>\n\t\t\t\t\t\t\t</tr>\n", month_names[month]);
++ str_write(file, "\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\n\t\t\t\t\t\t\t\t<td class=\"weekend\">%s</td>\n\t\t\t\t\t\t\t</tr>\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<tr class=\"%s\">\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<td class=\"day\"><a href=\"%s\">%d</a></td>\n", filename, day);
++ } else {
++ str_write(file, "\t\t\t\t\t\t\t\t<td class=\"day\">%d</td>\n", day);
++ }
++ } else {
++ str_write(file, "\t\t\t\t\t\t\t\t<td class=\"emptycell\">&nbsp;</td>\n");
++ }
++ }
++ str_write(file, "\t\t\t\t\t\t\t</tr>\n");
++ }
+ } else {
-+ ptr = ptr->next;
++ /*
++ * 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<tr>\n\t\t\t\t\t\t\t\t<th class=\"monthname\" colspan=\"7\">%s</th>\n\t\t\t\t\t\t\t</tr>\n", month_names[month]);
++ for(row = 0; row < 7; row++) {
++ str_write(file, "\t\t\t\t\t\t\t<tr class=\"%s\">\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<td class=\"weekend\">%s</td>\n", days_names[row]);
++ } else {
++ str_write(file, "\t\t\t\t\t\t\t\t<td class=\"dayname\">%s</td>\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<td class=\"day\"><a href=\"%s\">%d</a></td>\n", filename, day);
++ } else {
++ str_write(file, "\t\t\t\t\t\t\t\t<td class=\"day\">%d</td>\n", day);
++ }
++ } else {
++ str_write(file, "\t\t\t\t\t\t\t\t<td class=\"emptycell\">&nbsp;</td>\n");
++ }
++ }
++ str_write(file, "\t\t\t\t\t\t\t</tr>\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<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>\n");
+ }
+ }
-+ break;
++ str_write(file, "\t\t\t\t\t\t</table>\n\t\t\t\t\t</td>\n");
+ }
++ str_write(file, "\t\t\t\t</tr>\n");
+ }
+
-+ ptr = logs2htmlchanlist;
-+ while (ptr != NULL) {
-+ channels_count++;
-+ ptr = ptr->next;
++ str_write(file, "\t\t\t</table>\n");
++ str_write(file, "\t\t</div>\n\n");
++
++ str_write(file, "\t\t<br class=\"clearfloat\" />\n");
++ str_write(file, "\t\t<div id=\"footer\">\n<p>Generated by logs2html module for eggdrop v.%d.%d.%d%s<br />", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD);
++ str_write(file, "Find latest version at <a href=\"http://sourceforge.net/projects/logs2html\">http://sourceforge.net/projects/logs2html</a> or <a href=\"http://www.halftone.ru/projects\">http://www.halftone.ru</a><br />");
++ str_write(file, "Fork at <a href=\"https://github.com/ac100-ru/logs2html.mod\">https://github.com/ac100-ru/logs2html.mod</a></p>\n\t\t</div>\n");
++
++ if (strlen(mainpage_bottom_filename) > 0) {
++ str_write(file, "\t\t<div id=\"mp_bottom\">\n");
++ writefromexfile(file, mainpage_bottom_filename);
++ str_write(file, "\n\t\t</div>\n");
+ }
+
-+ ptr = newchan = NULL;
++ str_write(file, "\t</div>\n");
++ str_write(file, "</body>\n");
++ str_write(file, "</html>\n");
++
++ fclose(file);
++ nfree(filename);
+
-+ return channels_count;
-+} /* addchannels() */
++ return;
++} /* makeindexpage() */
+/****************************************************************************/
+
+
+/****************************************************************************/
+/*
-+ * function int convertfile(int year, int month, int day, bool convertifexists)
++ * function void convertfile(l2hchan_t *ch, int year, int month, int day)
+ *
+ * Input:
-+ *
-+ *
++ *
++ *
+ *
+ * Output:
-+ *
++ *
+ *
+ * Discription:
-+ * переводит файлы из текстового вида в формат HTML
++ * переводит файлы из текстового вида в формат HTML
+ */
-+static void convertfile(struct tm *t, logs2htmlchan *ch) {
-+ char *buf_ptr, *p, *q, *r;
++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 f_color[3], bg_color[3], text_style[6];
-+ int mc_openteg_count = 0, pages_count = 0;
-+ int i, j, k, lines_count, tsl;
-+ char src_filename[257], dst_filename[257];
-+ FILE *src_file, *dst_file;
-+ bool bold_isopen, underline_isopen;
-+ bool noneedtoclose, skipemail, linkfound;
-+ char openspace[3] = " ( ";
-+ char closespace[3] = " ),";
-+ char *cuted_string = NULL;
-+ int cuted_string_len, old_cuted_string_len, delta_cuted_string_len;
-+ int r_offset, q_offset;
-+ int *original_idx = NULL;
-+
-+ Context;
-+ /* Let first write our default CSS file */
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%sdefault.css", ch->outputpath, SEP);
-+ if ((dst_file = openfile(dst_filename, "wb", false)) != NULL) {
-+ str_write(dst_file, "BODY {\n");
-+ str_write(dst_file, "font-family: serif;\n");
-+ str_write(dst_file, "font-style: normal\n");
-+ str_write(dst_file, "font-variant: normal;\n");
-+ str_write(dst_file, "font-weight: normal;\n");
-+ str_write(dst_file, "font-stretch: normal;\n");
-+ str_write(dst_file, "font-size: 12pt;\n");
-+ str_write(dst_file, "text-align: left;\n");
-+ str_write(dst_file, "color: rgb(0,0,0);\n");
-+ str_write(dst_file, "background-color: transparent;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "BODY.mainpage {\n");
-+ str_write(dst_file, "background-color: whitesmoke;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "BODY.logspage {\n");
-+ str_write(dst_file, "background-color: lightyellow;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "TD {\n");
-+ str_write(dst_file, "width: %d%%;\n", (int)floor(100.0/((double)month_cols_count * 8)));
-+ str_write(dst_file, "background-color: lavender;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "TD.space {\n");
-+ str_write(dst_file, "width: auto;\n");
-+ str_write(dst_file, "background-color: whitesmoke;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "TD.dayname {\n");
-+ str_write(dst_file, "width: auto;\n");
-+ str_write(dst_file, "font-weight: bold;\n");
-+ str_write(dst_file, "text-align: right;\n");
-+ str_write(dst_file, "background-color: lightskyblue;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "TD.weekend {\n");
-+ str_write(dst_file, "width: auto;\n");
-+ str_write(dst_file, "font-weight: bold;\n");
-+ str_write(dst_file, "text-align: right;\n");
-+ str_write(dst_file, "color: red;\n");
-+ str_write(dst_file, "background-color: lightskyblue;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "TH {\n");
-+ str_write(dst_file, "font-weight: bold;\n");
-+ str_write(dst_file, "text-align: center;\n");
-+ str_write(dst_file, "background-color: lavender;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "SPAN.time {\n");
-+ str_write(dst_file, "color: silver;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "SPAN.nick {\n");
-+ str_write(dst_file, "color: mediumblue;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "SPAN.else {\n");
-+ str_write(dst_file, "color: green;\n");
-+ str_write(dst_file, "font-style: italic;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "SPAN.action {\n");
-+ str_write(dst_file, "color: violet;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#footer {\n");
-+ str_write(dst_file, " font-size: 10px;\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, " border-top-width: 1px;\n");
-+ str_write(dst_file, " border-top-style: solid;\n");
-+ str_write(dst_file, " border-color: #CCCCCC;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "h1 {\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#calendar {\n");
-+ str_write(dst_file, " margin-right: auto;\n");
-+ str_write(dst_file, " margin-left: auto;\n");
-+ str_write(dst_file, " width: 90%;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#navtop {\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, " margin-top: 10px;\n");
-+ str_write(dst_file, " margin-bottom: 10px;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#navbottom {\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, " margin-top: 10px;\n");
-+ str_write(dst_file, " margin-bottom: 5px;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#totop {\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, " margin-top: 5px;\n");
-+ str_write(dst_file, " margin-bottom: 10px;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "#log {\n");
-+ str_write(dst_file, " margin-top: 10px;\n");
-+ str_write(dst_file, " margin-bottom: 10px;\n");
-+ str_write(dst_file, " padding-top: 10px;\n");
-+ str_write(dst_file, " padding-bottom: 10px;\n");
-+ str_write(dst_file, " border-width: thin;\n");
-+ str_write(dst_file, " border-top-style: solid;\n");
-+ str_write(dst_file, " border-bottom-style: solid;\n");
-+ str_write(dst_file, " border-color: #CCCCCC;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, ".mainpage #title {\n");
-+ str_write(dst_file, " font-size: 36px;\n");
-+ str_write(dst_file, " text-align: center;\n");
-+ str_write(dst_file, " margin-bottom: 20px;\n");
-+ str_write(dst_file, " border-width: thin;\n");
-+ str_write(dst_file, " border-color: #CCCCCC;\n");
-+ str_write(dst_file, " border-bottom-style: solid;\n");
-+ str_write(dst_file, "}\n");
-+ str_write(dst_file, "SPAN.c0000, SPAN.c0100, SPAN.c0200, SPAN.c0300, SPAN.c0400, SPAN.c0500, SPAN.c0600, SPAN.c0700, SPAN.c0800, SPAN.c0900, SPAN.c1000, SPAN.c1100, SPAN.c1200, SPAN.c1300, SPAN.c1400, SPAN.c1500 {background-color: white;}\n");
-+ str_write(dst_file, "SPAN.c0001, SPAN.c0101, SPAN.c0201, SPAN.c0301, SPAN.c0401, SPAN.c0501, SPAN.c0601, SPAN.c0701, SPAN.c0801, SPAN.c0901, SPAN.c1001, SPAN.c1101, SPAN.c1201, SPAN.c1301, SPAN.c1401, SPAN.c1501 {background-color: black;}\n");
-+ str_write(dst_file, "SPAN.c0002, SPAN.c0102, SPAN.c0202, SPAN.c0302, SPAN.c0402, SPAN.c0502, SPAN.c0602, SPAN.c0702, SPAN.c0802, SPAN.c0902, SPAN.c1002, SPAN.c1102, SPAN.c1202, SPAN.c1302, SPAN.c1402, SPAN.c1502 {background-color: navy;}\n");
-+ str_write(dst_file, "SPAN.c0003, SPAN.c0103, SPAN.c0203, SPAN.c0303, SPAN.c0403, SPAN.c0503, SPAN.c0603, SPAN.c0703, SPAN.c0803, SPAN.c0903, SPAN.c1003, SPAN.c1103, SPAN.c1203, SPAN.c1303, SPAN.c1403, SPAN.c1503 {background-color: green;}\n");
-+ str_write(dst_file, "SPAN.c0004, SPAN.c0104, SPAN.c0204, SPAN.c0304, SPAN.c0404, SPAN.c0504, SPAN.c0604, SPAN.c0704, SPAN.c0804, SPAN.c0904, SPAN.c1004, SPAN.c1104, SPAN.c1204, SPAN.c1304, SPAN.c1404, SPAN.c1504 {background-color: red;}\n");
-+ str_write(dst_file, "SPAN.c0005, SPAN.c0105, SPAN.c0205, SPAN.c0305, SPAN.c0405, SPAN.c0505, SPAN.c0605, SPAN.c0705, SPAN.c0805, SPAN.c0905, SPAN.c1005, SPAN.c1105, SPAN.c1205, SPAN.c1305, SPAN.c1405, SPAN.c1505 {background-color: maroon;}\n");
-+ str_write(dst_file, "SPAN.c0006, SPAN.c0106, SPAN.c0206, SPAN.c0306, SPAN.c0406, SPAN.c0506, SPAN.c0606, SPAN.c0706, SPAN.c0806, SPAN.c0906, SPAN.c1006, SPAN.c1106, SPAN.c1206, SPAN.c1306, SPAN.c1406, SPAN.c1506 {background-color: purple;}\n");
-+ str_write(dst_file, "SPAN.c0007, SPAN.c0107, SPAN.c0207, SPAN.c0307, SPAN.c0407, SPAN.c0507, SPAN.c0607, SPAN.c0707, SPAN.c0807, SPAN.c0907, SPAN.c1007, SPAN.c1107, SPAN.c1207, SPAN.c1307, SPAN.c1407, SPAN.c1507 {background-color: orange;}\n");
-+ str_write(dst_file, "SPAN.c0008, SPAN.c0108, SPAN.c0208, SPAN.c0308, SPAN.c0408, SPAN.c0508, SPAN.c0608, SPAN.c0708, SPAN.c0808, SPAN.c0908, SPAN.c1008, SPAN.c1108, SPAN.c1208, SPAN.c1308, SPAN.c1408, SPAN.c1508 {background-color: yellow;}\n");
-+ str_write(dst_file, "SPAN.c0009, SPAN.c0109, SPAN.c0209, SPAN.c0309, SPAN.c0409, SPAN.c0509, SPAN.c0609, SPAN.c0709, SPAN.c0809, SPAN.c0909, SPAN.c1009, SPAN.c1109, SPAN.c1209, SPAN.c1309, SPAN.c1409, SPAN.c1509 {background-color: lime;}\n");
-+ str_write(dst_file, "SPAN.c0010, SPAN.c0110, SPAN.c0210, SPAN.c0310, SPAN.c0410, SPAN.c0510, SPAN.c0610, SPAN.c0710, SPAN.c0810, SPAN.c0910, SPAN.c1010, SPAN.c1110, SPAN.c1210, SPAN.c1310, SPAN.c1410, SPAN.c1510 {background-color: teal;}\n");
-+ str_write(dst_file, "SPAN.c0011, SPAN.c0111, SPAN.c0211, SPAN.c0311, SPAN.c0411, SPAN.c0511, SPAN.c0611, SPAN.c0711, SPAN.c0811, SPAN.c0911, SPAN.c1011, SPAN.c1111, SPAN.c1211, SPAN.c1311, SPAN.c1411, SPAN.c1511 {background-color: cyan;}\n");
-+ str_write(dst_file, "SPAN.c0012, SPAN.c0112, SPAN.c0212, SPAN.c0312, SPAN.c0412, SPAN.c0512, SPAN.c0612, SPAN.c0712, SPAN.c0812, SPAN.c0912, SPAN.c1012, SPAN.c1112, SPAN.c1212, SPAN.c1312, SPAN.c1412, SPAN.c1512 {background-color: blue;}\n");
-+ str_write(dst_file, "SPAN.c0013, SPAN.c0113, SPAN.c0213, SPAN.c0313, SPAN.c0413, SPAN.c0513, SPAN.c0613, SPAN.c0713, SPAN.c0813, SPAN.c0913, SPAN.c1013, SPAN.c1113, SPAN.c1213, SPAN.c1313, SPAN.c1413, SPAN.c1513 {background-color: magenta;}\n");
-+ str_write(dst_file, "SPAN.c0014, SPAN.c0114, SPAN.c0214, SPAN.c0314, SPAN.c0414, SPAN.c0514, SPAN.c0614, SPAN.c0714, SPAN.c0814, SPAN.c0914, SPAN.c1014, SPAN.c1114, SPAN.c1214, SPAN.c1314, SPAN.c1414, SPAN.c1514 {background-color: silver;}\n");
-+ str_write(dst_file, "SPAN.c0015, SPAN.c0115, SPAN.c0215, SPAN.c0315, SPAN.c0415, SPAN.c0515, SPAN.c0615, SPAN.c0715, SPAN.c0815, SPAN.c0915, SPAN.c1015, SPAN.c1114, SPAN.c1215, SPAN.c1315, SPAN.c1415, SPAN.c1515 {background-color: gray;}\n");
-+ str_write(dst_file, "SPAN.c0000, SPAN.c0001, SPAN.c0002, SPAN.c0003, SPAN.c0004, SPAN.c0005, SPAN.c0006, SPAN.c0007, SPAN.c0008, SPAN.c0009, SPAN.c0010, SPAN.c0011, SPAN.c0012, SPAN.c0013, SPAN.c0014, SPAN.c0015 {color: white;}\n");
-+ str_write(dst_file, "SPAN.c0100, SPAN.c0101, SPAN.c0102, SPAN.c0103, SPAN.c0104, SPAN.c0105, SPAN.c0106, SPAN.c0107, SPAN.c0108, SPAN.c0109, SPAN.c0110, SPAN.c0111, SPAN.c0112, SPAN.c0113, SPAN.c0114, SPAN.c0115 {color: black;}\n");
-+ str_write(dst_file, "SPAN.c0200, SPAN.c0201, SPAN.c0202, SPAN.c0203, SPAN.c0204, SPAN.c0205, SPAN.c0206, SPAN.c0207, SPAN.c0208, SPAN.c0209, SPAN.c0210, SPAN.c0211, SPAN.c0212, SPAN.c0213, SPAN.c0214, SPAN.c0215 {color: navy;}\n");
-+ str_write(dst_file, "SPAN.c0300, SPAN.c0301, SPAN.c0302, SPAN.c0303, SPAN.c0304, SPAN.c0305, SPAN.c0306, SPAN.c0307, SPAN.c0308, SPAN.c0309, SPAN.c0310, SPAN.c0311, SPAN.c0312, SPAN.c0313, SPAN.c0314, SPAN.c0315 {color: green;}\n");
-+ str_write(dst_file, "SPAN.c0400, SPAN.c0401, SPAN.c0402, SPAN.c0403, SPAN.c0404, SPAN.c0405, SPAN.c0406, SPAN.c0407, SPAN.c0408, SPAN.c0409, SPAN.c0410, SPAN.c0411, SPAN.c0412, SPAN.c0413, SPAN.c0414, SPAN.c0415 {color: red;}\n");
-+ str_write(dst_file, "SPAN.c0500, SPAN.c0501, SPAN.c0502, SPAN.c0503, SPAN.c0504, SPAN.c0505, SPAN.c0506, SPAN.c0507, SPAN.c0508, SPAN.c0509, SPAN.c0510, SPAN.c0511, SPAN.c0512, SPAN.c0513, SPAN.c0514, SPAN.c0515 {color: maroon;}\n");
-+ str_write(dst_file, "SPAN.c0600, SPAN.c0601, SPAN.c0602, SPAN.c0603, SPAN.c0604, SPAN.c0605, SPAN.c0606, SPAN.c0607, SPAN.c0608, SPAN.c0609, SPAN.c0610, SPAN.c0611, SPAN.c0612, SPAN.c0613, SPAN.c0614, SPAN.c0615 {color: purple;}\n");
-+ str_write(dst_file, "SPAN.c0700, SPAN.c0701, SPAN.c0702, SPAN.c0703, SPAN.c0704, SPAN.c0705, SPAN.c0706, SPAN.c0707, SPAN.c0708, SPAN.c0709, SPAN.c0710, SPAN.c0711, SPAN.c0712, SPAN.c0713, SPAN.c0714, SPAN.c0715 {color: orange;}\n");
-+ str_write(dst_file, "SPAN.c0800, SPAN.c0801, SPAN.c0802, SPAN.c0803, SPAN.c0804, SPAN.c0805, SPAN.c0806, SPAN.c0807, SPAN.c0808, SPAN.c0809, SPAN.c0810, SPAN.c0811, SPAN.c0812, SPAN.c0813, SPAN.c0814, SPAN.c0815 {color: yellow;}\n");
-+ str_write(dst_file, "SPAN.c0900, SPAN.c0901, SPAN.c0902, SPAN.c0903, SPAN.c0904, SPAN.c0905, SPAN.c0906, SPAN.c0907, SPAN.c0908, SPAN.c0909, SPAN.c0910, SPAN.c0911, SPAN.c0912, SPAN.c0913, SPAN.c0914, SPAN.c0915 {color: lime;}\n");
-+ str_write(dst_file, "SPAN.c1000, SPAN.c1001, SPAN.c1002, SPAN.c1003, SPAN.c1004, SPAN.c1005, SPAN.c1006, SPAN.c1007, SPAN.c1008, SPAN.c1009, SPAN.c1010, SPAN.c1011, SPAN.c1012, SPAN.c1013, SPAN.c1014, SPAN.c1015 {color: teal;}\n");
-+ str_write(dst_file, "SPAN.c1100, SPAN.c1101, SPAN.c1102, SPAN.c1103, SPAN.c1104, SPAN.c1105, SPAN.c1106, SPAN.c1107, SPAN.c1108, SPAN.c1109, SPAN.c1110, SPAN.c1111, SPAN.c1112, SPAN.c1113, SPAN.c1114, SPAN.c1115 {color: cyan;}\n");
-+ str_write(dst_file, "SPAN.c1200, SPAN.c1201, SPAN.c1202, SPAN.c1203, SPAN.c1204, SPAN.c1205, SPAN.c1206, SPAN.c1207, SPAN.c1208, SPAN.c1209, SPAN.c1210, SPAN.c1211, SPAN.c1212, SPAN.c1213, SPAN.c1214, SPAN.c1215 {color: blue;}\n");
-+ str_write(dst_file, "SPAN.c1300, SPAN.c1301, SPAN.c1302, SPAN.c1303, SPAN.c1304, SPAN.c1305, SPAN.c1306, SPAN.c1307, SPAN.c1308, SPAN.c1309, SPAN.c1310, SPAN.c1311, SPAN.c1312, SPAN.c1313, SPAN.c1314, SPAN.c1315 {color: magenta;}\n");
-+ str_write(dst_file, "SPAN.c1400, SPAN.c1401, SPAN.c1402, SPAN.c1403, SPAN.c1404, SPAN.c1405, SPAN.c1406, SPAN.c1407, SPAN.c1408, SPAN.c1409, SPAN.c1410, SPAN.c1411, SPAN.c1412, SPAN.c1413, SPAN.c1414, SPAN.c1415 {color: silver;}\n");
-+ str_write(dst_file, "SPAN.c1500, SPAN.c1501, SPAN.c1502, SPAN.c1503, SPAN.c1504, SPAN.c1505, SPAN.c1506, SPAN.c1507, SPAN.c1508, SPAN.c1509, SPAN.c1510, SPAN.c1511, SPAN.c1512, SPAN.c1513, SPAN.c1514, SPAN.c1515 {color: gray;}\n");
-+ str_write(dst_file, "SPAN.f00 {color: white;}\n");
-+ str_write(dst_file, "SPAN.f01 {color: black;}\n");
-+ str_write(dst_file, "SPAN.f02 {color: navy;}\n");
-+ str_write(dst_file, "SPAN.f03 {color: green;}\n");
-+ str_write(dst_file, "SPAN.f04 {color: red;}\n");
-+ str_write(dst_file, "SPAN.f05 {color: maroon;}\n");
-+ str_write(dst_file, "SPAN.f06 {color: purple;}\n");
-+ str_write(dst_file, "SPAN.f07 {color: orange;}\n");
-+ str_write(dst_file, "SPAN.f08 {color: yellow;}\n");
-+ str_write(dst_file, "SPAN.f09 {color: lime;}\n");
-+ str_write(dst_file, "SPAN.f10 {color: teal;}\n");
-+ str_write(dst_file, "SPAN.f11 {color: cyan;}\n");
-+ str_write(dst_file, "SPAN.f12 {color: blue;}\n");
-+ str_write(dst_file, "SPAN.f13 {color: magenta;}\n");
-+ str_write(dst_file, "SPAN.f14 {color: silver;}\n");
-+ str_write(dst_file, "SPAN.f15 {color: gray;}\n");
-+ str_write(dst_file, "SPAN.b00 {background-color: white;}\n");
-+ str_write(dst_file, "SPAN.b01 {background-color: black;}\n");
-+ str_write(dst_file, "SPAN.b02 {background-color: navy;}\n");
-+ str_write(dst_file, "SPAN.b03 {background-color: green;}\n");
-+ str_write(dst_file, "SPAN.b04 {background-color: red;}\n");
-+ str_write(dst_file, "SPAN.b05 {background-color: maroon;}\n");
-+ str_write(dst_file, "SPAN.b06 {background-color: purple;}\n");
-+ str_write(dst_file, "SPAN.b07 {background-color: orange;}\n");
-+ str_write(dst_file, "SPAN.b08 {background-color: yellow;}\n");
-+ str_write(dst_file, "SPAN.b09 {background-color: lime;}\n");
-+ str_write(dst_file, "SPAN.b10 {background-color: teal;}\n");
-+ str_write(dst_file, "SPAN.b11 {background-color: cyan;}\n");
-+ str_write(dst_file, "SPAN.b12 {background-color: blue;}\n");
-+ str_write(dst_file, "SPAN.b13 {background-color: magenta;}\n");
-+ str_write(dst_file, "SPAN.b14 {background-color: silver;}\n");
-+ str_write(dst_file, "SPAN.b15 {background-color: gray;}\n");
-+ fclose(dst_file);
-+ }
-+ /* Now write user CSS file */
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%suser.css", ch->outputpath, SEP);
-+ if ((dst_file = openfile(dst_filename, "wb", false)) != NULL) {
-+ writefromexfile(dst_file, userstyle_filename);
-+ fclose(dst_file);
-+ }
-+
++ 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", t);
++ egg_strftime(ct, 12, ".%d%b%Y", &tblock);
+ else
-+ egg_strftime(ct, 80, logfile_suffix, t);
++ egg_strftime(ct, 80, logfile_suffix, &tblock);
+ ct[80] = '\0';
-+
-+ egg_snprintf(src_filename, sizeof src_filename, "%s%s", ch->logfilename, ct);
-+ if ((src_file = openfile(src_filename, "r", true)) == NULL) return;
+
++ // 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++;
++ lines_count = lines_per_page;
++ pages_count++;
+
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, pages_count);
-+ if ((dst_file = openfile(dst_filename, "wb", false)) == NULL) {
++ 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, dst_filename);
++ putlog(LOG_MISC, "*", "logs2html: Error occured on converting %d page of file \"%s\"!", pages_count, filename);
++ nfree(filename);
+ return;
+ }
+
-+ str_write(dst_file, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
-+ str_write(dst_file, "<html>\n");
-+ str_write(dst_file, "<head>\n");
-+ if (strlen(encoding_string) > 0) {
-+ str_write(dst_file, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n", encoding_string);
++ str_write(file, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
++ str_write(file, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n");
++ str_write(file, "<head>\n");
++ if (strlen(encoding_string) > 0) {str_write(file, "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n", encoding_string); }
++ str_write(file, "\t<meta name=\"title\" content=\"%s\" />\n", ch->logspagetitle);
++ str_write(file, "\t<meta name=\"description\" content=\"%s\" />\n", ch->logspagetitle);
++ str_write(file, "\t<meta name=\"generator\" content=\"logs2html module for Eggdrop v.%d.%d.%d%s\" />\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD);
++ str_write(file, "\t<meta name=\"author\" content=\"Fedotov Alexander aka shurikvz aka shmupsik\" />\n");
++ str_write(file, "\t<meta name=\"keywords\" content=\"logs2html, logs, logging, channel, irc, bot, eggdrop, windrop, mirc, module, convert\" />\n");
++ str_write(file, "\t<meta name=\"robots\" content= \"index,all\" />\n");
++ str_write(file, "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"default.css\" />\n");
++ if (strlen(userstyle_filename) > 0) str_write(file, "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"user.css\" />\n");
++ str_write(file, "\t<title>%s. %d/%d/%d.</title>\n", ch->logspagetitle, day, month, year);
++ str_write(file, "\t<!--[if IE]>\n\t<style type=\"text/css\">\n\t.l2hLogPage #mainblock { zoom: 1; padding-top: 15px; }\n\t/* the above proprietary zoom property gives IE the hasLayout it may need to avoid several bugs */\n\t</style>\n\t<![endif]-->\n");
++ str_write(file, "</head>\n\n");
++
++ str_write(file, "<body class=\"l2hLogPage\">\n");
++ str_write(file, "\t<div id=\"container\">\n");
++
++ if (strlen(logspage_top_filename) > 0) {
++ str_write(file, "\t\t<div id=\"lp_top\">\n");
++ writefromexfile(file, logspage_top_filename);
++ str_write(file, "\n\t\t</div>\n");
++ }
++
++ str_write(file, "\t\t<div id=\"header\">\n", ch->mainpagetitle, year, LOGS2HTML_YEAR);
++ str_write(file, "\t\t\t<a name=\"top\" id=\"top\"></a>\n");
++
++ str_write(file, "\t\t</div>\n");
++ str_write(file, "\t\t<div id=\"mainblock\">\n");
++
++ time_t t = time(NULL);
++ tblock = *localtime(&t);
++ if (tblock.tm_year + 1900 == year) {
++ str_write(file, "\t\t\t<div id=\"navtop\"><a href=\"%s.html\">%s</a></div>\n", ch->mainpagename, LOGS2HTML_MAINPAGE);
++ } else {
++ str_write(file, "\t\t\t<div id=\"navtop\"><a href=\"%s%d.html\">%s</a></div>\n", ch->mainpagename, year, LOGS2HTML_MAINPAGE);
+ }
-+ str_write(dst_file, "<meta name=\"title\" content=\"%s\">\n", ch->logspagetitle);
-+ str_write(dst_file, "<meta name=\"Description\" content=\"%s\">\n", ch->logspagetitle);
-+ str_write(dst_file, "<meta name=\"Generator\" content=\"logs2html module for Eggdrop v.%d.%d.%d\">\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR);
-+ str_write(dst_file, "<meta name=\"Author\" content=\"Fedotov Alexander aka Gray_Angel\">\n");
-+ str_write(dst_file, "<meta name=\"Keywords\" content=\"logs, logging, channel, irc, bot, eggdrop, windrop, module, logs2html\">\n");
-+ str_write(dst_file, "<meta name=\"robots\" content= \"index,all\">\n");
-+ str_write(dst_file, "<link rel=stylesheet type=\"text/css\" href=\"default.css\">\n");
-+ if (strlen(userstyle_filename) > 0) str_write(dst_file, "<link rel=stylesheet type=\"text/css\" href=\"user.css\">\n");
-+ str_write(dst_file, "<title>%s. %d/%d/%d</title>\n", ch->logspagetitle, t->tm_mday, t->tm_mon + 1, t->tm_year + 1900);
-+ str_write(dst_file, "</head>\n");
-+ str_write(dst_file, "<body class=\"logspage\">\n");
-+
-+ writefromexfile(dst_file, logspage_top_filename);
-+
-+ str_write(dst_file, "<a name=\"top\"></a>\n");
-+ str_write(dst_file, "<div id=\"navtop\"><a href=\"%s.html\">%s</a></div>\n", ch->mainpagename, LOGS2HTML_MAINPAGE);
-+ str_write(dst_file, "<div id=\"log\">\n");
+
+ while ((lines_count > 0) || (lines_per_page == 0)) {
-+ lines_count--;
+
+ buf_ptr = fgets(buffer, sizeof buffer, src_file);
+ if (buf_ptr == NULL) break;
+
-+ p = strrchr(buf_ptr, '\n');
-+ if (p) *p = '\0';
-+ p = strrchr(buf_ptr, '\r');
-+ if (p) *p = '\0';
++ remove_crlf(&buf_ptr);
+ if (!buf_ptr[0]) continue;
+
+ /* if timestamp exist cut time from string */
+ data[0] = '\0';
++ strcat(data, "\t\t\t<div>&nbsp;");
+ if (shtime) {
-+ egg_strftime(stamp, sizeof(stamp) - 1, LOG_TS, t); /* Print dummy time */
++ egg_strftime(stamp, sizeof(stamp) - 1, LOG_TS, &tblock); /* Print dummy time */
+ tsl = strlen(stamp);
-+ strncat(data, buf_ptr, tsl);
++ if (dont_print_time == 0) {
++ strcat(data, "<span class=\"time\">");
++ strncat(data, buf_ptr, tsl);
++ strcat(data, "</span>&nbsp;");
++ }
+ buf_ptr += (++tsl);
+ }
+ if (strncmp(buf_ptr, "--- ", 4) == 0) { /* we don't really need this string I think */
+ continue;
+ }
-+ if (data && data[0]) {
-+ str_write(dst_file, "<span class=\"time\">%s</span>", data);
-+ }
+
-+ data[0] = '\0'; noneedtoclose = false; skipemail = false;
++ bool IsElseClass = false;
+ if (strncmp(buf_ptr, "Action: ", 8) == 0) { /* command: /me */
++ str_write(file, "%s", data);
+ buf_ptr += 7;
-+ str_write(dst_file, "<span class=\"action\"> ***");
++ str_write(file, "<span class=\"action\">&nbsp;***");
+ } else { /* nick */
-+ p = strstr(buf_ptr, "> ");
-+ if ((strncmp(buf_ptr, "<", 1) == 0) && (p != NULL)) {
++ 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(dst_file, "<span class=\"nick\"> &lt;%s&gt;</span>", data);
++ str_write(file, "<span class=\"nick\">&lt;%s&gt;</span><span class=\"text\">&nbsp;", data);
+ buf_ptr += (p - buf_ptr + 1);
-+ noneedtoclose = true;
+ } else {
-+ str_write(dst_file, "<span class=\"else\"> ");
-+ skipemail = true;
++ IsElseClass = true;
++ if (strstr(buf_ptr, " joined ") != NULL) {
++ if (dont_print_join != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_j\">&nbsp;");
++ } else if (strstr(buf_ptr, " left irc: ") != NULL) {
++ if (dont_print_left != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_li\">&nbsp;");
++ } else if (strstr(buf_ptr, " left ") != NULL) {
++ if (dont_print_left != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_l\">&nbsp;");
++ } else if (strstr(buf_ptr, "Nick change: ") != NULL) {
++ if (dont_print_nickchange != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_n\">&nbsp;");
++ } else if (strstr(buf_ptr, ": mode change '") != NULL) {
++ if (dont_print_modechange != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_m\">&nbsp;");
++ } else if (strstr(buf_ptr, " kicked from ") != NULL) {
++ if (dont_print_kick != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else_k\">&nbsp;");
++ } else {
++ if (dont_print_else != 0) {continue; }
++ str_write(file, "%s", data);
++ str_write(file, "<span class=\"else\">&nbsp;");
++ }
+ }
+ }
+
-+ cuted_string_len = strlen(buf_ptr) + 2;
-+ original_idx = (int *)nmalloc(sizeof(int) * (cuted_string_len + 1));
-+ for (i = 0; i < cuted_string_len; i++) original_idx[i] = i - 1; original_idx[cuted_string_len] = -1;
++ lines_count--;
+
-+ cuted_string = (char *)nmalloc(cuted_string_len + 1);
-+ egg_memset(cuted_string, 0, cuted_string_len + 1);
-+ snprintf(cuted_string, cuted_string_len + 1, " %s ", buf_ptr);
-+ q = r = cuted_string + 1;
-+ /*
-+ * Code copied from Eggdrop's src/dcc.c and then modified...
-+ * Copyright (C) 1997 Robey Pointer
-+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
-+ */
-+ while (*r) {
-+ switch (*r) {
-+ case 0xf:
-+ case 3: /* mIRC colors? */
-+ if (isdigit(r[1])) { /* Is the first char a number? */
-+ r += 2; /* Skip over the ^C and the first digit */
-+ if (isdigit(*r)) r++; /* Is this a double digit number? */
-+ if (*r == ',') { /* Do we have a background color next? */
-+ if (isdigit(r[1])) r += 2; /* Skip over the first background digit */
-+ if (isdigit(*r)) r++; /* Is it a double digit? */
-+ }
-+ } else {
-+ r++;
-+ }
-+ continue;
-+ case 2: /* Bold text */
-+ case 7:
-+ case 0x16: /* Reverse video */
-+ case 0x1f: /* Underlined text */
-+ case 0x3c: /* < */
-+ case 0x3e: /* > */
-+ r++;
-+ continue;
-+ case 033:
-+ r++;
-+ if (*r == '[') {
-+ r++;
-+ while ((*r == ';') || isdigit(*r)) r++;
-+ if (*r) r++; /* also kill the following char */
-+ }
-+ continue;
-+ }
-+ original_idx[q - cuted_string] = r - cuted_string - 1;
-+ *q++ = *r++; /* Move on to the next char */
++ 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;
+ }
-+ *q = '\0';
-+ /*
-+ * Ends here...
-+ */
+
-+ linkfound = false;
-+ q = cuted_string;
-+ while (*q) {
-+ for (k = 0; k < MIN(sizeof openspace, sizeof closespace); k++) {
-+ if (openspace[k] == *q) {
-+ r = q + 1;
-+ while (*r) {
-+ if (closespace[k] == *r) {
-+ *r = '\0';
-+ p = q + 1;
-+ switch (whatisit(p)) {
-+ case ITS_NOTHING:
-+ break;
-+ case ITS_EMAIL:
-+ if (!skipemail) { /* If class = "else", lets skip mail, because it ident@host */
-+ egg_memset(data, 0, sizeof data);
-+ sprintf(data, "<a href=\"mailto:%s\">", p);
-+ linkfound = true;
-+ }
-+ break;
-+ case ITS_LINK:
-+ egg_memset(data, 0, sizeof data);
-+ sprintf(data, "<a href=\"%s\">", p);
-+ linkfound = true;
-+ break;
-+ case ITS_TRUNKLINK:
-+ egg_memset(data, 0, sizeof data);
-+ sprintf(data, "<a href=\"http://%s\">", p);
-+ linkfound = true;
-+ break;
-+ }
-+ *r = closespace[k];
-+ if (linkfound) {
-+ /* will after reallocation r & q pointers be aviable?
-+ * i.e. will cuted_string begin with the same adress?
-+ * to make them aviable let's count offset.
-+ */
-+ r_offset = r - cuted_string; q_offset = q - cuted_string;
-+ old_cuted_string_len = strlen(cuted_string); delta_cuted_string_len = strlen(data) + strlen(T_LINKC);
-+ cuted_string = (char *)nrealloc(cuted_string, old_cuted_string_len + delta_cuted_string_len + 1);
-+ original_idx = (int *)nrealloc(original_idx, sizeof(int) * (old_cuted_string_len + delta_cuted_string_len + 1));
-+ r = cuted_string + r_offset; q = cuted_string + q_offset;
-+ for (i = old_cuted_string_len; i < (old_cuted_string_len + delta_cuted_string_len + 1); i++) {
-+ original_idx[i] = -1; cuted_string[i] = '\0';
-+ }
-+ for (i = old_cuted_string_len - 1; i >= r_offset; i--) {
-+ cuted_string[i + delta_cuted_string_len] = cuted_string[i];
-+ original_idx[i + delta_cuted_string_len] = original_idx[i]; original_idx[i] = -1;
-+ }
-+ for (i = strlen(T_LINKC); i--; ) {
-+ cuted_string[r_offset + delta_cuted_string_len - strlen(T_LINKC) + i] = T_LINKC[i];
-+ }
-+ for (i = r_offset - 1; i > q_offset; i--) {
-+ cuted_string[i + delta_cuted_string_len - strlen(T_LINKC)] = cuted_string[i];
-+ original_idx[i + delta_cuted_string_len - strlen(T_LINKC)] = original_idx[i]; original_idx[i] = -1;
-+ }
-+ for (i = 0; i < strlen(data); i++) {
-+ cuted_string[q_offset + i + 1] = data[i];
-+ original_idx[q_offset + i + 1] = -1;
-+ }
-+ }
-+ if (linkfound) q = r - 1;
-+ break;
++ 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, "</span>");
++ }
++ if (tree->node_data != NULL) {
++ str_write(file, "<span class=\"%s\">", tree->node_data);
+ }
-+ r++;
+ }
-+ }
-+ if (linkfound) {
-+ linkfound = false;
+ break;
-+ }
-+ }
-+ q++;
-+ }
-+
-+ cuted_string[strlen(cuted_string) - 1] = '\0';
-+ egg_memset(data, 0, sizeof data);
-+ bold_isopen = false; underline_isopen = false;
-+ p = cuted_string + 1; /* Don't need first char cause it = ' ' */
-+ q = buf_ptr;
-+ while (*p) {
-+ if ((original_idx[p - cuted_string] == -1) || (original_idx[p - cuted_string] == (q - buf_ptr))) {
-+ if ((strlen(data) + 1) > (sizeof data - 1)) {
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+ strncat(data, p, 1);
-+ p++;
-+ if (original_idx[p - cuted_string] != -1) q++;
-+ } else {
-+ /*
-+ * Code copied from Eggdrop's src/dcc.c and then modified...
-+ * Copyright (C) 1997 Robey Pointer
-+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Eggheads Development Team
-+ */
-+ switch (*q) {
-+ case 2: /* Bold text */
-+ if (bold_isopen) {
-+ bold_isopen = false;
-+ str_write(dst_file, "%s%s", data, T_BOLDC);
-+ egg_memset(data, 0, sizeof data);
++ case NODE_FONTSTYLE:
++ {
++ if (tree->node_close) {
++ str_write(file, "</span>");
+ } else {
-+ bold_isopen = true;
-+ str_write(dst_file, "%s%s", data, T_BOLDO);
-+ egg_memset(data, 0, sizeof data);
++ str_write(file, "<span style=\"%s\">", tree->node_data);
+ }
-+ q++;
-+ break;
-+ case 3: /* mIRC colors? */
-+ case 0xf: /* don't know, maybe broken client? but also mIRC colors */
-+ egg_memset(f_color, 0, sizeof f_color); egg_memset(bg_color, 0, sizeof bg_color);
-+ if (isdigit(q[1])) { /* Is the first char a number? */
-+ f_color[0] = q[1];
-+ if (isdigit(q[2])) {f_color[1] = q[2]; q++;}
-+ q += 2;
-+ if (*q == ',') {
-+ if (isdigit(q[1])) { /* Is the first char a number? */
-+ bg_color[0] = q[1];
-+ if (isdigit(q[2])) {bg_color[1] = q[2]; q++;}
-+ q += 2;
-+ }
-+ }
-+ if (strlen(bg_color) > 0) {
-+ /* If we have background color - let's close all previous "SPAN" */
-+ for (mc_openteg_count++; --mc_openteg_count; ) {
-+ if ((strlen(data) + strlen(T_SPANC)) > (sizeof data - 1)) {
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+ strncat(data, T_SPANC, strlen(T_SPANC));
-+ }
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+
-+ if ((strlen(f_color) > 0) && ((atoi(f_color) < 0) || (atoi(f_color) > 15))) {
-+ egg_memset(f_color, 0, sizeof f_color);
-+ }
-+ if ((strlen(bg_color) > 0) && ((atoi(bg_color) < 0) || (atoi(bg_color) > 15))) {
-+ egg_memset(bg_color, 0, sizeof bg_color);
-+ }
-+ if ((strlen(f_color) > 0) || (strlen(bg_color) > 0)) {
-+ mc_openteg_count++;
-+ text_style[0] = '\0';
-+ if ((strlen(f_color) > 0) && (strlen(bg_color) > 0)) egg_snprintf(text_style, sizeof text_style, "c%02.2d%02.2d", atoi(f_color), atoi(bg_color));
-+ if (strlen(bg_color) == 0) egg_snprintf(text_style, sizeof text_style, "f%02.2d", atoi(f_color));
-+ if (strlen(f_color) == 0) egg_snprintf(text_style, sizeof text_style, "b%02.2d", atoi(bg_color));
-+ str_write(dst_file, "%s<span class=\"%s\">", data, text_style);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+ } else {
-+ /* It was "close-color" tag -> let's close all "SPAN" */
-+ for (mc_openteg_count++; --mc_openteg_count; ) {
-+ if ((strlen(data) + strlen(T_SPANC)) > (sizeof data - 1)) {
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+ strncat(data, T_SPANC, strlen(T_SPANC));
++ }
++ 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, "</a>");
++ } else {
++ str_write(file, "<a href=\"mailto:%s\">", tree->node_data);
+ }
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ q++;
+ }
-+ break;
-+ case 7: /* Bells */
-+ q++;
-+ break;
-+ case 0x16: /* Reverse video */
-+ q++;
-+ break;
-+ case 0x1f: /* Underlined text */
-+ if (underline_isopen) {
-+ underline_isopen = false;
-+ str_write(dst_file, "%s%s", data, T_UNDERLINEC);
-+ egg_memset(data, 0, sizeof data);
++ }
++ break;
++ case NODE_URI:
++ {
++ if (tree->node_close) {
++ str_write(file, "</a>");
+ } else {
-+ underline_isopen = true;
-+ str_write(dst_file, "%s%s", data, T_UNDERLINEO);
-+ egg_memset(data, 0, sizeof data);
-+ }
-+ q++;
-+ break;
-+ case 0x3c: /* < */
-+ str_write(dst_file, "%s%s", data, T_LT);
-+ egg_memset(data, 0, sizeof data);
-+ q++;
-+ break;
-+ case 0x3e: /* > */
-+ str_write(dst_file, "%s%s", data, T_GT);
-+ egg_memset(data, 0, sizeof data);
-+ q++;
-+ break;
-+ case 033:
-+ q++;
-+ if (*q == '[') {
-+ q++;
-+ while ((*q == ';') || isdigit(*q)) q++;
-+ if (*q) q++; /* also kill the following char */
++ str_write(file, "<a href=\"%s\">", tree->node_data);
+ }
-+ break;
-+ default:
-+ /* I think we should never get here, but if so... */
-+ strncat(data, q, 1);
-+ q++;
-+ break;
-+ }
-+ /*
-+ * Ends here...
-+ */
-+ }
-+ }
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
-+ if (bold_isopen) str_write(dst_file, "%s", T_BOLDC);
-+ if (underline_isopen) str_write(dst_file, "%s", T_UNDERLINEC);
-+ for (mc_openteg_count++; --mc_openteg_count; ) {
-+ if ((strlen(data) + strlen(T_SPANC)) > (sizeof data - 1)) {
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
++ }
++ break;
++ case NODE_SPECIAL:
++ {
++ str_write(file, "%s", tree->node_data);
++ }
++ break;
+ }
-+ strncat(data, T_SPANC, strlen(T_SPANC));
++
++ tree = tree->next;
+ }
-+ str_write(dst_file, "%s", data);
-+ egg_memset(data, 0, sizeof data);
++ str_write(file, "%s</span>", buf_ptr + last_tag);
+
-+ nfree(original_idx); original_idx = NULL;
-+ nfree(cuted_string); cuted_string = NULL;
++ str_write(file, "</div>\n");
+
-+ str_write(dst_file, "%s", data); data[0] = '\0';
-+ str_write(dst_file, noneedtoclose ? "<br />\n":"</span><br />\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(dst_file);
++ 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(dst_filename, sizeof dst_filename, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, i);
-+ if ((dst_file = openfile(dst_filename, "ab", false)) == NULL) {
-+ putlog(LOG_MISC, "*", "logs2html: Error occured on converting %d page of file \"%s\"!", i, dst_filename);
++ 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(dst_file, "</div>\n");
++
++ str_write(file, "\t\t</div>\n");
+ if (pages_count > 1) {
-+ str_write(dst_file, "<div id=\"navbottom\">");
++ str_write(file, "\t\t<div id=\"navbottom\">");
+ if (i == 1) {
-+ str_write(dst_file, LOGS2HTML_BACK);
++ str_write(file, LOGS2HTML_BACK);
+ } else {
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%d%02d%02d_pg%d.html", ch->logspagename, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, i-1);
-+ str_write(dst_file, "<span>&larr;</span>&nbsp;<a href=\"%s\">%s</a>", dst_filename, LOGS2HTML_BACK);
++ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, i-1);
++ str_write(file, "<span>&larr;</span>&nbsp;<a href=\"%s\">%s</a>", filename, LOGS2HTML_BACK);
+ }
-+ str_write(dst_file, "&nbsp;");
++ str_write(file, "&nbsp;");
+ if (i == pages_count) {
-+ str_write(dst_file, LOGS2HTML_NEXT);
++ str_write(file, LOGS2HTML_NEXT);
+ } else {
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%d%02d%02d_pg%d.html", ch->logspagename, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, i+1);
-+ str_write(dst_file, "<a href=\"%s\">%s</a>&nbsp;<span>&rarr;</span>", dst_filename, LOGS2HTML_NEXT);
++ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, i+1);
++ str_write(file, "<a href=\"%s\">%s</a>&nbsp;<span>&rarr;</span>", filename, LOGS2HTML_NEXT);
+ }
-+ str_write(dst_file, "<br />");
++ str_write(file, "<br />");
+ for (j = 1; j <= pages_count; j++) {
-+ egg_snprintf(dst_filename, sizeof dst_filename, "%s%d%02d%02d_pg%d.html", ch->logspagename, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, j);
++ egg_snprintf(filename, filenamelength, "%s%d%02d%02d_pg%d.html", ch->logspagename, year, month, day, j);
+ if (j != i) {
-+ str_write(dst_file, "<span> <a href=\"%s\">%d</a> </span>", dst_filename, j);
++ str_write(file, "<span><a href=\"%s\">%d</a></span>", filename, j);
+ } else {
-+ str_write(dst_file, "<b>%d</b>", j);
++ str_write(file, "<span id=\"navbottom_currentpg\">%d</span>", j);
+ }
+ }
-+ str_write(dst_file, "</div>\n");
++ str_write(file, "</div>\n");
+ }
++ str_write(file, "\t\t<div id=\"totoplink\"><a href=\"#top\">%s</a></div>\n", LOGS2HTML_UP);
+
-+ str_write(dst_file, "<div id=\"totop\"><a href=\"#top\">%s</a></div>\n", LOGS2HTML_UP);
++ str_write(file, "\t\t<br class=\"clearfloat\" />\n");
++ str_write(file, "\t\t<div id=\"footer\">\n<p>Generated by logs2html module for eggdrop v.%d.%d.%d%s<br />", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR, MODULE_BUILD);
++ str_write(file, "Find latest version at <a href=\"http://sourceforge.net/projects/logs2html\">http://sourceforge.net/projects/logs2html</a> or <a href=\"http://www.halftone.ru/projects\">http://www.halftone.ru</a><br />");
++ str_write(file, "Fork at <a href=\"http://github.com/ac100-ru/logs2html.mod\">http://github.com/ac100-ru/logs2html.mod</a></p>\n\t\t</div>\n");
+
-+ writefromexfile(dst_file, logspage_bottom_filename);
-+
-+ str_write(dst_file, "<div id=\"footer\">\nGenerated by logs2html module for eggdrop v.%d.%d.%d<br />\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR);
-+ str_write(dst_file, "Find latest version at <a href=\"http://sourceforge.net/projects/logs2html\">http://sourceforge.net/projects/logs2html</a> or <a href=\"http://shmupsik.osetia.org\">http://shmupsik.osetia.org</a>\n</div>\n");
++ if (strlen(logspage_bottom_filename) > 0) {
++ str_write(file, "\t\t<div id=\"lp_bottom\">\n");
++ writefromexfile(file, logspage_bottom_filename);
++ str_write(file, "\n\t\t</div>\n");
++ }
+
-+ str_write(dst_file, "</body>\n");
-+ str_write(dst_file, "</html>");
++ str_write(file, "\t</div>\n");
++ str_write(file, "</body>\n");
++ str_write(file, "</html>\n");
+
-+ fclose(dst_file);
++ 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("&lt;") - strlen("<");
++ }
++ break;
++ case 0x3e: /* > */
++ {
++ realloc_size += strlen("&gt;") - strlen(">");
++ }
++ break;
++ case 0x22: /* " */
++ {
++ realloc_size += strlen("&quot;") - strlen("""");
++ }
++ break;
++ case 0x26: /* & */
++ {
++ realloc_size += strlen("&amp;") - 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, "&lt;", strlen("&lt;"));
++ buf_ptr_copy++; dd += strlen("&lt;");
++ continue;
++ }
++ break;
++ case 0x3e: /* > */
++ {
++ strncat(dd, "&gt;", strlen("&gt;"));
++ buf_ptr_copy++; dd += strlen("&gt;");
++ continue;
++ }
++ break;
++ case 0x22: /* " */
++ {
++ strncat(dd, "&quot;", strlen("&quot;"));
++ buf_ptr_copy++; dd += strlen("&quot;");
++ continue;
++ }
++ break;
++ case 0x26: /* & */
++ {
++ strncat(dd, "&amp;", strlen("&amp;"));
++ buf_ptr_copy++; dd += strlen("&amp;");
++ 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 void makemainpage(logs2htmlchan *ch)
++ * function int cmd_makemainpage(struct userrec *u, int idx, char *par)
+ *
+ * Input:
-+ * ничего
++ *
++ *
+ *
+ * Output:
-+ * ничего
++ *
+ *
+ * Discription:
-+ * Генерация основной страницы (календаря)
-+ * + вызывается процедура для конвертирования логов в формат HTML
++ *
+ */
-+static void makemainpage(logs2htmlchan *ch) {
-+ int i, j, k, m, l;
-+ int add_day;
-+ FILE *file;
-+ char filename[256];
-+ bool endofyear;
-+ struct tm tblock;
-+ int delta_day = 0;
++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 *st = localtime(&t);
++ struct tm tblock = *localtime(&t);
+
-+ tblock.tm_year = st->tm_year;
-+ tblock.tm_isdst = st->tm_isdst;
-+ tblock.tm_hour = 0;
-+ tblock.tm_min = 0;
-+ tblock.tm_sec = 1;
-+ /* Other fields not necessary here
-+ tblock.tm_mday = st->tm_mday;
-+ tblock.tm_mon = st->tm_mon;
-+ tblock.tm_wday = st->tm_wday;
-+ tblock.tm_yday = st->tm_yday;
-+ */
-+
-+ egg_snprintf(filename, sizeof filename, "%s%s%s.html", ch->outputpath, SEP, ch->mainpagename);
-+ if ((file = openfile(filename, "wb", false)) == NULL) return;
-+
-+ str_write(file, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
-+ str_write(file, "<html>\n");
-+ str_write(file, "<head>\n");
-+ if (strlen(encoding_string) > 0) {
-+ str_write(file, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">\n", encoding_string);
++ 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;
+ }
-+ str_write(file, "<meta name=\"title\" content=\"%s\">\n", ch->mainpagetitle);
-+ str_write(file, "<meta name=\"Description\" content=\"%s\">\n", ch->mainpagetitle);
-+ str_write(file, "<meta name=\"Generator\" content=\"logs2html module for Eggdrop v.%d.%d.%d\">\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR);
-+ str_write(file, "<meta name=\"Author\" content=\"Fedotov Alexander aka Gray_Angel\">\n");
-+ str_write(file, "<meta name=\"Keywords\" content=\"logs, logging, channel, irc, bot, eggdrop, windrop, module, logs2html\">\n");
-+ str_write(file, "<meta name=\"robots\" content= \"index,all\">\n");
-+ str_write(file, "<link rel=stylesheet type=\"text/css\" href=\"default.css\">\n");
-+ if (strlen(userstyle_filename) > 0) str_write(file, "<link rel=stylesheet type=\"text/css\" href=\"user.css\">\n");
-+ str_write(file, "<title>%s %d %s</title>\n", ch->mainpagetitle, tblock.tm_year + 1900, LOGS2HTML_YEAR);
-+ str_write(file, "</head>\n");
-+ str_write(file, "<body class=\"mainpage\">\n");
+
-+ writefromexfile(file, mainpage_top_filename);
++ 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" : "");
++ }
+
-+ str_write(file, "<div id=\"title\">%s<br />%d %s</div>\n", ch->mainpagetitle, tblock.tm_year + 1900, LOGS2HTML_YEAR);
-+ str_write(file, "<div id=\"calendar\">\n");
++ return 0;
++} /* cmd_makemainpage() */
++/****************************************************************************/
+
+
-+ /* Вычисляем сколько рядов потребуется для размещения 12 месяцев при заданном числе столбцов */
-+ month_rows_count = (int)ceil(12.0 / (double)month_cols_count);
++/****************************************************************************/
++/*
++ * function int convertalllogs(struct userrec *u, int idx, char *par)
++ *
++ * Input:
++ *
++ *
++ *
++ * Output:
++ *
++ *
++ * Discription:
++ *
++ */
++static int cmd_convertalllogs(struct userrec *u, int idx, char *par) {
+
-+ str_write(file, "<table width=\"100%%\" cellspacing=\"2\" cellpadding=\"1\" border=\"0\">\n");
++ return cmd_convertlogs(u, idx, "all");
++} /* convertalllogs() */
++/****************************************************************************/
+
-+ /* цикл по рядам месяцев */
-+ for(i = 0; i < month_rows_count; i++) {
+
-+ /* в каждом ряду: 1 строка (название месяца) + 7 строк (дни недели) */
-+ for (j = 0; j < 8; j++) {
-+ str_write(file, "<tr align=center>\n");
++/****************************************************************************/
++static int cmd_convertlogs(struct userrec *u, int idx, char *par) {
+
-+ /* цикл по столбцам месяцев */
-+ for (k = 0; k < month_cols_count; k++) {
-+ tblock.tm_mon = i * month_cols_count + k;
-+ endofyear = (tblock.tm_mon > 11 ) ? true : false;
++ time_t start, finish;
++ time(&start);
++ putlog(LOG_CMDS, "*", "#%s# begin creation of logfiles.", dcc[idx].nick);
+
-+ if (j == 0) {
-+ str_write(file, "<td class=\"space\"></td>");
-+ str_write(file, "<th colspan=7>%s</th>\n", endofyear ? "&nbsp;": month_names[tblock.tm_mon]);
-+ continue;
-+ }
++ time_t t = time(NULL);
++ struct tm tblock = *localtime(&t);
+
-+ /* Если год високосный, то добавляем к февралю 1 день */
-+ add_day = ((tblock.tm_mon == 1) && isleap(tblock.tm_year)) ? 1 : 0;
++ l2hchan_t *p = logs2htmlchanlist;
+
-+ /* Для данного месяца данного года вычисляем на какой день недели приходится 1 число */
-+ if (!endofyear) {
-+ delta_day = getdayofweek(tblock.tm_year + 1900, tblock.tm_mon + 1, 1);
-+ }
++ if (!par[0]) {
+
-+ /* в каждом месяце: 2 столбца (название дней недели) + 6 столбцов (недели) */
-+ for (m = 0; m < 7; m++) {
-+ if (endofyear) {
-+ str_write(file, "<td>&nbsp;</td>\n");
-+ continue;
++ //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);
++ }
+ }
-+ if (m == 0) {
-+ str_write(file, "<td class=\"space\"></td>");
-+ switch (j)
-+ {
-+ case 1:
-+ case 2:
-+ case 3:
-+ case 4:
-+ case 5:
-+ case 6:
-+ str_write(file, "<td class=\"dayname\">%s</td>\n", days_names[j-1]);
-+ break;
-+ case 7:
-+ str_write(file, "<td class=\"weekend\">%s</td>\n", days_names[j-1]);
-+ break;
-+ default:
-+ /* Uuups.. We should never get to this point.. and if it so, that mean's something wrong...:( */
-+ str_write(file, "<td>&nbsp;</td>\n");
++ 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);
+ }
-+ continue;
+ }
-+ tblock.tm_mday = (m - 1) * 7 + j - delta_day;
-+ if ((tblock.tm_mday >= 1) && (tblock.tm_mday <= (days_in_month[tblock.tm_mon] + add_day))) {
-+ tblock.tm_wday = (getdayofweek(tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday) + 1) % 7;
-+ tblock.tm_yday = 0;
-+ for (l = 0; l < tblock.tm_mon; l++) tblock.tm_yday += days_in_month[l];
-+ tblock.tm_yday += tblock.tm_mday - 1;
-+
-+ egg_snprintf(filename, sizeof filename, "%s%s%s%d%02d%02d_pg%d.html", ch->outputpath, SEP, ch->logspagename, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday, 1);
-+ if (!file_readable(filename)) convertfile(&tblock, ch);
-+ if (file_readable(filename)) {
-+ /* let write withount full path */
-+ egg_snprintf(filename, sizeof filename, "%s%d%02d%02d_pg%d.html", ch->logspagename, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday, 1);
-+ str_write(file, "<td><a href=\"%s\">%d</A></td>\n", filename, tblock.tm_mday);
-+ } else {
-+ str_write(file, "<td>%d</td>\n", tblock.tm_mday);
++ 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);
+ }
-+ } else {
-+ str_write(file, "<td>&nbsp;</td>\n");
++ 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;
++ }
++
+ }
++
+ }
-+ str_write(file, "</tr>\n");
+ }
-+ str_write(file, "<tr><td class=\"space\" colspan=%d>&nbsp;</td></tr>\n", month_cols_count * 8);
++
+ }
+
-+ str_write(file, "</table>\n");
-+ str_write(file, "</div>\n");
++ 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() */
++/****************************************************************************/
+
-+ writefromexfile(file, mainpage_bottom_filename);
+
-+ str_write(file, "<div id=\"footer\">\nGenerated by logs2html module for eggdrop v.%d.%d.%d<br />\n", MODULE_MAJOR, MODULE_MINOR, MODULE_SUBMINOR);
-+ str_write(file, "Find latest version at <a href=\"http://sourceforge.net/projects/logs2html\">http://sourceforge.net/projects/logs2html</a> or <a href=\"http://shmupsik.osetia.org\">http://shmupsik.osetia.org</a>\n</div>\n");
++/****************************************************************************/
++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%_#:\\./=?-]|\\&amp;)*([a-zA-Z0-9%_#:\\/=?-]|\\&amp;))*)?", 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.");
++ }
+
-+ str_write(file, "</body>\n");
-+ str_write(file, "</html>");
++ return;
++}
++/****************************************************************************/
+
-+ fclose(file);
++
++/****************************************************************************/
++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;
-+} /* makemainpage() */
++}
+/****************************************************************************/
+
+
+/****************************************************************************/
+static void logs2html_hook_5minutely(void)
+{
-+ logs2htmlchan *p;
-+ struct tm tblock;
+ time_t t = time(NULL);
-+ struct tm *st = localtime(&t);
-+
-+ tblock.tm_year = st->tm_year;
-+ tblock.tm_isdst = st->tm_isdst;
-+ tblock.tm_mday = st->tm_mday;
-+ tblock.tm_mon = st->tm_mon;
-+ tblock.tm_wday = st->tm_wday;
-+ tblock.tm_yday = st->tm_yday;
++ struct tm tblock = *localtime(&t);
+ tblock.tm_hour = 0;
+ tblock.tm_min = 0;
+ tblock.tm_sec = 1;
+
-+ p = logs2htmlchanlist;
++ l2hchan_t *p = logs2htmlchanlist;
+ while (p != NULL) {
-+ convertfile(&tblock, p);
-+ makemainpage(p);
++ convertfile(p, tblock.tm_year + 1900, tblock.tm_mon + 1, tblock.tm_mday);
++ makeindexpage(p, tblock.tm_year + 1900);
+ p = p->next;
+ }
+
@@ -1927,46 +2295,46 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+}
+/****************************************************************************/
+
++
+/****************************************************************************/
-+static void logs2html_hook_daily(void)
++static void logs2html_hook_hourly(void)
+{
-+ logs2htmlchan *p;
-+ struct tm tblock;
+ time_t t = time(NULL);
-+ struct tm *st = localtime(&t);
-+
-+ tblock.tm_year = st->tm_year;
-+ tblock.tm_isdst = st->tm_isdst;
-+ tblock.tm_mday = st->tm_mday;
-+ tblock.tm_mon = st->tm_mon;
-+ tblock.tm_wday = st->tm_wday;
-+ tblock.tm_yday = st->tm_yday;
++
++ 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;
+
-+ if (!--tblock.tm_mday) {
-+ if (!tblock.tm_mon) {
-+ /* it's 1st January; lets go one day before */
-+ tblock.tm_year--;
-+ tblock.tm_mon = 11;
-+ tblock.tm_mday = 31;
-+ tblock.tm_yday = 364 + isleap(tblock.tm_year) ? 1 : 0;
-+ } else {
-+ tblock.tm_mon--;
-+ tblock.tm_mday = days_in_month[tblock.tm_mon] + ((tblock.tm_mon == 1) && isleap(tblock.tm_year)) ? 1 : 0;
-+ tblock.tm_yday--;
++ //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;
+ }
-+ } else {
-+ tblock.tm_yday--;
+ }
-+ tblock.tm_wday = (tblock.tm_wday + 6) % 7;
+
-+ p = logs2htmlchanlist;
-+ while (p != NULL) {
-+ convertfile(&tblock, p);
-+ makemainpage(p);
-+ 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;
@@ -1977,80 +2345,304 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.c eggdrop1.6.19/sr
+/****************************************************************************/
+static void logs2html_hook_pre_rehash(void)
+{
-+ logs2htmlchan *p, *q;
-+
-+ q = p = logs2htmlchanlist;
-+ while (q != NULL) {
-+ q = p->next;
-+ nfree(p);
-+ p = q;
-+ }
-+ logs2htmlchanlist = p = q = NULL;
++ finalize();
+
+ return;
+}
+/****************************************************************************/
+
++
+/****************************************************************************/
+static void logs2html_hook_rehash(void)
+{
-+ if (lines_per_page < 0) lines_per_page = 0;
++ initialize();
+
+ return;
+}
+/****************************************************************************/
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.conf eggdrop1.6.19/src/mod/logs2html.mod/logs2html.conf
---- ./src/mod/logs2html.mod/logs2html.conf 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/logs2html.conf 2009-03-28 01:43:58.000000000 +0000
-@@ -0,0 +1,38 @@
++
++
++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
++# number of rows the month'll put out
+set col-count 3
+
-+# set how many lines there'll be on one page of converted logfile. If it
-+# set to 0 then all converted log will dispalay as one page.
++
++# 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
+
-+# Here specify file with "addlogs2html" expressions.
-+set channels-list chan.list
+
-+# Uncomment line if you want specify file with your color settings for
-+# generated pages
++# 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
-+# <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=..."> in your
-+# HTML files. You can comment next line, that will mean that this tag'll not
-+# be insert in the resulting page.
++
++# This setting allows you to insert meta tag
++# <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=..."> 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"
+
-+# Here you can specify path to files which content will be put to converted
-+# logfile (or mainpage). Uncomment the line you need and put there
-+# filename with path for example: set mainpage-top "top100.tpl"
-+# Note: the content of specified file puts to the resulting file "as is",
-+# without any transformation
++
++# 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
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.h eggdrop1.6.19/src/mod/logs2html.mod/logs2html.h
---- ./src/mod/logs2html.mod/logs2html.h 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/logs2html.h 2009-03-28 01:46:28.000000000 +0000
-@@ -0,0 +1,76 @@
++
++
++# 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 <shurikvz@mail.ru>
+ *
-+ * 2004-2005 year
++ * 2004-2009 year
+ */
+/*
+ * This program is free software; you can redistribute it and/or
@@ -2068,120 +2660,214 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.h eggdrop1.6.19/sr
+ * 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 "/"
+
-+#undef false
-+#undef true
-+typedef enum {false = 0, true} bool;
-+
-+#ifdef MIN
-+# undef MIN
++#ifndef MAX
++#define MAX(a,b) \
++ ({ typeof (a) _a = (a); \
++ typeof (b) _b = (b); \
++ _a > _b ? _a : _b; })
+#endif
-+#define MIN(p,q) ((p < q) ? p : q)
+
-+#ifndef isleap
-+ /* Nonzero if YEAR is a leap year (every 4 years,
-+ except every 100th isn't, and every 400th is). */
-+#define isleap(year) \
-+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
++#ifndef MIN
++#define MIN(a,b) \
++ ({ typeof (a) _a = (a); \
++ typeof (b) _b = (b); \
++ _a < _b ? _a : _b; })
+#endif
+
-+#define T_LT "&lt;"
-+#define T_GT "&gt;"
-+#define T_BOLDO "<B>"
-+#define T_BOLDC "</B>"
-+#define T_UNDERLINEO "<U>"
-+#define T_UNDERLINEC "</U>"
-+#define T_SPANC "</SPAN>"
-+#define T_LINKC "</A>"
-+
-+typedef struct logs2html_data {
-+ struct logs2html_data *next;
-+ char channame[81]; /* Имя канала для которого конвертировать логи */
-+ char logfilename[128]; /* Имя (префикс) данного канала (вычисляется из выражения logfile в конфиге бота) */
-+ char outputpath[128]; /* Куда выводить конвертированные логи */
-+ char mainpagename[61]; /* Имя главной страницы */
-+ char mainpagetitle[256]; /* Заголовок на главной странице */
-+ char logspagename[61]; /* Имя (префикс) страницы переконвертированного логфайла */
-+ char logspagetitle[256]; /* Заголовок страницы логфайла */
-+} logs2htmlchan;
-+
-+typedef enum {ITS_NOTHING, ITS_EMAIL, ITS_LINK, ITS_TRUNKLINK} patternkind;
++
++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 makemainpage(logs2htmlchan *ch);
-+static void convertfile(struct tm *t, logs2htmlchan *ch);
+static void writefromexfile(FILE *dst_file, char *exfilename);
-+static int addchannels(void);
-+static patternkind whatisit(char *pattern);
++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)
+
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/logs2html.mod.desc eggdrop1.6.19/src/mod/logs2html.mod/logs2html.mod.desc
---- ./src/mod/logs2html.mod/logs2html.mod.desc 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/logs2html.mod.desc 2009-03-28 01:46:37.000000000 +0000
++../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 @@
-+This module convert all existing log files (and those, that will be created after module installation) of your eggdrop for givving channel to their html representation to be show in the web. and also the calendar page with links to that converted files.
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/modinfo eggdrop1.6.19/src/mod/logs2html.mod/modinfo
---- ./src/mod/logs2html.mod/modinfo 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/modinfo 2009-03-28 01:32:21.000000000 +0000
-@@ -0,0 +1,4 @@
-+DESC:This module convert all existing log files (and those, that will be
-+DESC:created after module installation) of your eggdrop for givving channel
-+DESC:to their html representation to be show in the web. and also the
-+DESC:calendar page with links to that converted files.
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/readme.txt eggdrop1.6.19/src/mod/logs2html.mod/readme.txt
---- ./src/mod/logs2html.mod/readme.txt 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/readme.txt 2009-03-28 01:44:20.000000000 +0000
-@@ -0,0 +1,85 @@
-+logs2html.mod v.2.3.4 by Alexander Fedotov aka Gray_Angel aka Shmupsik #ircnet.ru
++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 convert all existing log files (and those, that will be created after module installation) of your eggdrop for giving channels to their html representation to be show in the web. and also the calendar page with links to that converted files.
++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:
-+ - copy the contents of "language" directory to your eggdrops "language" directory
-+ - copy the contents of "help" directory to your eggdrops "help" directory
-+ - copy *.dll (for windows) or *.so (for unix/linux) module to your eggdrops "modules" directory (only if you have download an arhive file with precompiled modules)
-+ - copy logs2html.conf, chan.list files to your eggdrop directory
-+ - if you decide to use your own style for pages copy user.css file to your eggdrop directory
-+ - (Of course don't forget to edit logs2html.conf, chan.list and user.css files)
-+ - put "source logs2html.conf" into your eggdrop config file and restart your bot
-+
-+Module has 2 commands, which you can use from dcc chat:
-+ - convertalllogs - reconverts ALL your logs for current year (you'll need it for example if you decided to change style of your output logs even those which was created before your decision)
-+ - makemainpage - redraws mainpages
++ - 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 see the example of output on http://www.osetia.org/logs
-+You can try to find latest version on http://sourceforge.net/projects/logs2html or http://shmupsik.osetia.org
++You can try to find latest version on http://sourceforge.net/projects/logs2html or http://www.halftone.ru/projects
+*******************************************************************************
+
+
+
+*******************************************************************************
-+So, if you want to make a donation (for some strange reason I probably will never understand...) to me,
-+you can do it using WebMoney (http://www.webmoney.ru).
-+And here (http://webmoney.ru/wminouttrans1.shtml) a list of sites where you can exchange your money if you are not using WebMoney system.. :)
-+
-+My cash number: WMID:215902813411
-+ U838552550724
-+ E023251651728
-+ R735356625383
-+*******************************************************************************
++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
++
+
-+*******************************************************************************
-+Version history:
+15.10.05 - version 2.3.4
+ - added setting in config file, which allow to change value of meta tag <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=..."> in generated HTML files.
+
@@ -2221,184 +2907,511 @@ diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/readme.txt eggdrop1.6.19/src
+
+
+
++*******************************************************************************
++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 <Todd.Miller@courtesan.com>
++ *
++ * 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 <sys/types.h>
++#include <string.h>
++
++/*
++ * 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 <shurikvz@mail.ru>
++ *
++ * 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
++ }
+
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/top100.tpl eggdrop1.6.19/src/mod/logs2html.mod/top100.tpl
---- ./src/mod/logs2html.mod/top100.tpl 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/top100.tpl 2009-03-28 01:43:24.000000000 +0000
-@@ -0,0 +1,50 @@
-+
-+<p align="center">
-+<!--Rating@Mail.ru COUNTER--><script language="JavaScript"><!--
-+d=document;a='';a+=';r='+escape(d.referrer)
-+js=10//--></script><script language="JavaScript1.1"><!--
-+a+=';j='+navigator.javaEnabled()
-+js=11//--></script><script language="JavaScript1.2"><!--
-+s=screen;a+=';s='+s.width+'*'+s.height
-+a+=';d='+(s.colorDepth?s.colorDepth:s.pixelDepth)
-+js=12//--></script><script language="JavaScript1.3"><!--
-+js=13//--></script><script language="JavaScript"><!--
-+d.write('<img src="http://top.list.ru/counter'+'?id=606627;js='+js+a+';rand='+Math.random()+'" height=1 width=1>')
-+if(js>11)d.write('<'+'!-- ')//--></script><noscript><img
-+src="http://top.list.ru/counter?js=na;id=606627"
-+height=1 width=1 alt=""></noscript><script language="JavaScript"><!--
-+if(js>11)d.write('--'+'>')//--></script><!--/COUNTER-->
-+<!-- SpyLOG f:0210 -->
-+<script language="javascript"><!--
-+Mu="u5131.64.spylog.com";Md=document;Mnv=navigator;Mp=1;
-+Mn=(Mnv.appName.substring(0,2)=="Mi")?0:1;Mrn=Math.random();
-+Mt=(new Date()).getTimezoneOffset();
-+Mz="p="+Mp+"&rn="+Mrn+"&tl=0&ls=0&ln=0&t="+Mt;
-+My="";
-+My+="<img src='http://"+Mu+"/cnt?cid=513164&"+Mz+"&r="+escape(Md.referrer)+"&pg="+escape(window.location.href)+"'border=0 width=1 height=1 alt='SpyLOG'>";
-+Md.write(My);//--></script><noscript>
-+<img src="http://u5131.64.spylog.com/cnt?cid=513164&p=1" alt='SpyLOG' border='0' width=1
-+height=1 >
-+</noscript>
-+<!-- SpyLOG -->
-+<!--begin of Top100 logo-->
-+<a href="http://top100.rambler.ru/top100/">
-+<img src="http://top100-images.rambler.ru/top100/banner-88x31-rambler-blue.gif" alt="Rambler's Top100" width=88 height=31 border=0></a>
-+<!--end of Top100 logo -->
-+<script language="javascript"><!--
-+Mrn=Math.random();Mz="";
-+My="<a href='http://u5131.64.spylog.com/cnt?cid=513164&f=3&rn="+Mrn+"' target='_blank'><img src='http://u5131.64.spylog.com/cnt?cid=513164&";
-+My+="p=1&f=4&rn="+Mrn+Mz+"' border=0 width=88 height=31 alt='SpyLOG'></a>";Md.write(My);
-+//--></script><noscript>
-+<a href="http://u5131.64.spylog.com/cnt?cid=513164&f=3&p=1" target="_blank">
-+<img src="http://u5131.64.spylog.com/cnt?cid=513164&p=1&f=4" alt='SpyLOG' border='0' width=88 height=31 ></a>
-+</noscript>
-+<!--Rating@Mail.ru LOGO--><a target=_top
-+href="http://top.mail.ru/jump?from=606627"><img src="http://top.list.ru/counter?id=606627;t=231;l=1"
-+border=0 height=31 width=88
-+alt="Рейтинг@Mail.ru"></a><!--/LOGO-->
-+<!--begin of Rambler's Top100 code -->
-+<a href="http://top100.rambler.ru/top100/">
-+<img src="http://counter.rambler.ru/top100.cnt?503447" alt="" width=1 height=1 border=0></a>
-+<!--end of Top100 code-->
-+</p>
-diff -urpN eggdrop1.6.19-orig/src/mod/logs2html.mod/user.css eggdrop1.6.19/src/mod/logs2html.mod/user.css
---- ./src/mod/logs2html.mod/user.css 1970-01-01 00:00:00.000000000 +0000
-+++ ./src/mod/logs2html.mod/user.css 2009-03-28 01:32:53.000000000 +0000
-@@ -0,0 +1,121 @@
-+BODY {
-+font-family: serif;
-+font-style: normal
-+font-variant: normal;
-+font-weight: normal;
-+font-stretch: normal;
-+font-size: 12pt;
++ 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 */
++
++<!--
++body {
++font-family:"Times New Roman", Times, serif;
++background: #666666;
++margin: 0;
++padding: 0;
++text-align: center;
++color: #000000;
++}
++
++/* mainpage styles */
++.l2hMainPage #container {
++width: 99%;
++background:#FFFF99;
++margin: 0 auto;
++border: 1px solid #000000;
+text-align: left;
-+color: rgb(0,0,0);
-+background-color: transparent;
+}
-+BODY.mainpage {
-+background-color: whitesmoke;
++.l2hMainPage #container #monthtable tr {
++background: Orange;
++}
++.l2hMainPage #container .monthblock .monthname {
++font-family:"Comic Sans MS", "Brush Script Std", Verdana, Arial, Helvetica, sans-serif;
++font-size: 1.3em;
++height: 1.8em;
++background:#FF6600;
++text-align: center;
++color: white;
++}
++.l2hMainPage #container #monthtable .monthblock .dayname {
++font-weight:bold;
++height: 1.8em;
++background: Silver;
++text-align: left;
++padding: 0 5px;
++color:#333333;
++}
++.l2hMainPage #container #monthtable .monthblock .weekend {
++font-weight:bold;
++height: 1.8em;
++background: #FF6633;
++text-align: left;
++padding: 0 5px;
++color:#333333;
++}
++.l2hMainPage #container #monthtable .monthblock .emptycell {
++height: 1.8em;
++background:#DDDDDD;
++text-align: center;
++}
++.l2hMainPage #container #monthtable .monthblock .day {
++font-family:"Courier New", Courier, monospace;
++font-weight:bold;
++height: 1.8em;
++background:#FFCC00;
++text-align: center;
++color:#FF0000;
++}
++.l2hMainPage #header {
++background: #DDDDDD;
++padding: 0 10px;
++}
++.l2hMainPage #header h2 {
++font-style:italic;
++margin: 0;
++padding: 10px 0;
++}
++.l2hMainPage #mp_top {
++background: #DDDDDD;
++padding: 0 10px;
++text-align: center;
++}
++.l2hMainPage #mp_bottom {
++background: #DDDDDD;
++padding: 0 10px;
++text-align: center;
++}
++
++/* leftsidebar styles */
++.l2hMainPage #leftsidebar {
++float: left;
++width: 7em;
++background: #EBEBEB;
++padding: 10px 0;
++}
++.l2hMainPage #leftsidebar div.indexlink {
++background-color: #EBEBEB;
++margin-left: 5px;
++margin-right: 5px;
++text-align:center;
++border-bottom-width: thin;
++border-bottom-style: dotted;
++border-bottom-color: #CCCCCC;
++}
++.l2hMainPage #leftsidebar div.indexlink a {
++display:block;
++letter-spacing:.1em;
++line-height:1.5em;
++text-decoration: none;
++vertical-align:baseline;
++color:#333333;
++}
++.l2hMainPage #leftsidebar div.indexlink a:hover {
++background:#FF6600;
++letter-spacing:.3em;
++line-height:1.5em;
++color:#FFFFFF;
++font-weight:bold;
+}
-+BODY.logspage {
-+background-color: lightyellow;
++.l2hMainPage #mainblock {
++margin: 0 20px 0 8em;
+}
-+TD {
-+width: 4%;
-+background-color: lavender;
++.l2hMainPage #footer {
++padding: 0 10px;
++background:#DDDDDD;
+}
-+TD.space {
-+width: auto;
-+background-color: whitesmoke;
++.l2hMainPage #footer p {
++margin: 0;
++padding: 10px 0;
++font-size: 0.9em;
++font-weight:bold;
++color: #333333;
++}
++.l2hLogPage #lp_top {
++background: #DDDDDD;
++padding: 0 10px;
++text-align: center;
++}
++.l2hLogPage #lp_bottom {
++background: #DDDDDD;
++padding: 0 10px;
++text-align: center;
+}
-+TD.dayname {
-+width: auto;
-+font-weight: bold;
-+text-align: right;
-+background-color: lightskyblue;
++
++/* Log Page styles */
++.l2hLogPage #header {
++background: #DDDDDD;
++padding: 0 10px;
++}
++.l2hLogPage #container {
++width: 99%;
++background: #FFFF99;
++margin: 0 auto;
++border: 1px solid #000000;
++text-align: left;
++}
++.l2hLogPage #container #navtop {
++text-align: center;
++border-bottom: 1px solid Orange;
++margin-bottom: 10px;
++padding: 10px 0;
++}
++.l2hLogPage #container #navtop a {
++color:#FF0000;
++font-weight:bold;
++}
++.l2hLogPage #container #totoplink {
++color:#FF0000;
++text-align: center;
++border-top: 1px solid Orange;
++margin-top: 10px;
++padding: 10px 0;
+}
-+TD.weekend {
-+color: red;
-+width: auto;
-+font-weight: bold;
-+text-align: right;
-+width: auto;
-+background-color: lightskyblue;
++.l2hLogPage #container #totoplink a {
++color:#FF0000;
++font-weight:bold;
+}
-+TH {
-+font-weight: bold;
++.l2hLogPage #container #navbottom {
++color:#FF0000;
+text-align: center;
-+background-color: lavender;
++padding: 10px;
+}
-+SPAN.time {
-+color: silver;
++.l2hLogPage #container #navbottom span {
++padding-left:5px;
++padding-right:5px;
+}
-+SPAN.nick {
-+color: mediumblue;
++.l2hLogPage #container #navbottom #navbottom_currentpg {
++font-size:1.1em;
+}
-+SPAN.else {
-+color: green;
-+font-style: italic;
++.l2hLogPage #footer {
++padding: 0 10px;
++background:#DDDDDD;
+}
-+SPAN.action {
-+color: violet;
++.l2hLogPage #footer p {
++margin: 0;
++padding: 10px 0;
++font-size: 0.9em;
++font-weight:bold;
++color: #333333;
+}
-+SPAN.c0000, SPAN.c0100, SPAN.c0200, SPAN.c0300, SPAN.c0400, SPAN.c0500, SPAN.c0600, SPAN.c0700, SPAN.c0800, SPAN.c0900, SPAN.c1000, SPAN.c1100, SPAN.c1200, SPAN.c1300, SPAN.c1400, SPAN.c1500 {background-color: white;}
-+SPAN.c0001, SPAN.c0101, SPAN.c0201, SPAN.c0301, SPAN.c0401, SPAN.c0501, SPAN.c0601, SPAN.c0701, SPAN.c0801, SPAN.c0901, SPAN.c1001, SPAN.c1101, SPAN.c1201, SPAN.c1301, SPAN.c1401, SPAN.c1501 {background-color: black;}
-+SPAN.c0002, SPAN.c0102, SPAN.c0202, SPAN.c0302, SPAN.c0402, SPAN.c0502, SPAN.c0602, SPAN.c0702, SPAN.c0802, SPAN.c0902, SPAN.c1002, SPAN.c1102, SPAN.c1202, SPAN.c1302, SPAN.c1402, SPAN.c1502 {background-color: navy;}
-+SPAN.c0003, SPAN.c0103, SPAN.c0203, SPAN.c0303, SPAN.c0403, SPAN.c0503, SPAN.c0603, SPAN.c0703, SPAN.c0803, SPAN.c0903, SPAN.c1003, SPAN.c1103, SPAN.c1203, SPAN.c1303, SPAN.c1403, SPAN.c1503 {background-color: green;}
-+SPAN.c0004, SPAN.c0104, SPAN.c0204, SPAN.c0304, SPAN.c0404, SPAN.c0504, SPAN.c0604, SPAN.c0704, SPAN.c0804, SPAN.c0904, SPAN.c1004, SPAN.c1104, SPAN.c1204, SPAN.c1304, SPAN.c1404, SPAN.c1504 {background-color: red;}
-+SPAN.c0005, SPAN.c0105, SPAN.c0205, SPAN.c0305, SPAN.c0405, SPAN.c0505, SPAN.c0605, SPAN.c0705, SPAN.c0805, SPAN.c0905, SPAN.c1005, SPAN.c1105, SPAN.c1205, SPAN.c1305, SPAN.c1405, SPAN.c1505 {background-color: maroon;}
-+SPAN.c0006, SPAN.c0106, SPAN.c0206, SPAN.c0306, SPAN.c0406, SPAN.c0506, SPAN.c0606, SPAN.c0706, SPAN.c0806, SPAN.c0906, SPAN.c1006, SPAN.c1106, SPAN.c1206, SPAN.c1306, SPAN.c1406, SPAN.c1506 {background-color: purple;}
-+SPAN.c0007, SPAN.c0107, SPAN.c0207, SPAN.c0307, SPAN.c0407, SPAN.c0507, SPAN.c0607, SPAN.c0707, SPAN.c0807, SPAN.c0907, SPAN.c1007, SPAN.c1107, SPAN.c1207, SPAN.c1307, SPAN.c1407, SPAN.c1507 {background-color: orange;}
-+SPAN.c0008, SPAN.c0108, SPAN.c0208, SPAN.c0308, SPAN.c0408, SPAN.c0508, SPAN.c0608, SPAN.c0708, SPAN.c0808, SPAN.c0908, SPAN.c1008, SPAN.c1108, SPAN.c1208, SPAN.c1308, SPAN.c1408, SPAN.c1508 {background-color: yellow;}
-+SPAN.c0009, SPAN.c0109, SPAN.c0209, SPAN.c0309, SPAN.c0409, SPAN.c0509, SPAN.c0609, SPAN.c0709, SPAN.c0809, SPAN.c0909, SPAN.c1009, SPAN.c1109, SPAN.c1209, SPAN.c1309, SPAN.c1409, SPAN.c1509 {background-color: lime;}
-+SPAN.c0010, SPAN.c0110, SPAN.c0210, SPAN.c0310, SPAN.c0410, SPAN.c0510, SPAN.c0610, SPAN.c0710, SPAN.c0810, SPAN.c0910, SPAN.c1010, SPAN.c1110, SPAN.c1210, SPAN.c1310, SPAN.c1410, SPAN.c1510 {background-color: teal;}
-+SPAN.c0011, SPAN.c0111, SPAN.c0211, SPAN.c0311, SPAN.c0411, SPAN.c0511, SPAN.c0611, SPAN.c0711, SPAN.c0811, SPAN.c0911, SPAN.c1011, SPAN.c1111, SPAN.c1211, SPAN.c1311, SPAN.c1411, SPAN.c1511 {background-color: cyan;}
-+SPAN.c0012, SPAN.c0112, SPAN.c0212, SPAN.c0312, SPAN.c0412, SPAN.c0512, SPAN.c0612, SPAN.c0712, SPAN.c0812, SPAN.c0912, SPAN.c1012, SPAN.c1112, SPAN.c1212, SPAN.c1312, SPAN.c1412, SPAN.c1512 {background-color: blue;}
-+SPAN.c0013, SPAN.c0113, SPAN.c0213, SPAN.c0313, SPAN.c0413, SPAN.c0513, SPAN.c0613, SPAN.c0713, SPAN.c0813, SPAN.c0913, SPAN.c1013, SPAN.c1113, SPAN.c1213, SPAN.c1313, SPAN.c1413, SPAN.c1513 {background-color: magenta;}
-+SPAN.c0014, SPAN.c0114, SPAN.c0214, SPAN.c0314, SPAN.c0414, SPAN.c0514, SPAN.c0614, SPAN.c0714, SPAN.c0814, SPAN.c0914, SPAN.c1014, SPAN.c1114, SPAN.c1214, SPAN.c1314, SPAN.c1414, SPAN.c1514 {background-color: silver;}
-+SPAN.c0015, SPAN.c0115, SPAN.c0215, SPAN.c0315, SPAN.c0415, SPAN.c0515, SPAN.c0615, SPAN.c0715, SPAN.c0815, SPAN.c0915, SPAN.c1015, SPAN.c1114, SPAN.c1215, SPAN.c1315, SPAN.c1415, SPAN.c1515 {background-color: gray;}
-+SPAN.c0000, SPAN.c0001, SPAN.c0002, SPAN.c0003, SPAN.c0004, SPAN.c0005, SPAN.c0006, SPAN.c0007, SPAN.c0008, SPAN.c0009, SPAN.c0010, SPAN.c0011, SPAN.c0012, SPAN.c0013, SPAN.c0014, SPAN.c0015 {color: white;}
-+SPAN.c0100, SPAN.c0101, SPAN.c0102, SPAN.c0103, SPAN.c0104, SPAN.c0105, SPAN.c0106, SPAN.c0107, SPAN.c0108, SPAN.c0109, SPAN.c0110, SPAN.c0111, SPAN.c0112, SPAN.c0113, SPAN.c0114, SPAN.c0115 {color: black;}
-+SPAN.c0200, SPAN.c0201, SPAN.c0202, SPAN.c0203, SPAN.c0204, SPAN.c0205, SPAN.c0206, SPAN.c0207, SPAN.c0208, SPAN.c0209, SPAN.c0210, SPAN.c0211, SPAN.c0212, SPAN.c0213, SPAN.c0214, SPAN.c0215 {color: navy;}
-+SPAN.c0300, SPAN.c0301, SPAN.c0302, SPAN.c0303, SPAN.c0304, SPAN.c0305, SPAN.c0306, SPAN.c0307, SPAN.c0308, SPAN.c0309, SPAN.c0310, SPAN.c0311, SPAN.c0312, SPAN.c0313, SPAN.c0314, SPAN.c0315 {color: green;}
-+SPAN.c0400, SPAN.c0401, SPAN.c0402, SPAN.c0403, SPAN.c0404, SPAN.c0405, SPAN.c0406, SPAN.c0407, SPAN.c0408, SPAN.c0409, SPAN.c0410, SPAN.c0411, SPAN.c0412, SPAN.c0413, SPAN.c0414, SPAN.c0415 {color: red;}
-+SPAN.c0500, SPAN.c0501, SPAN.c0502, SPAN.c0503, SPAN.c0504, SPAN.c0505, SPAN.c0506, SPAN.c0507, SPAN.c0508, SPAN.c0509, SPAN.c0510, SPAN.c0511, SPAN.c0512, SPAN.c0513, SPAN.c0514, SPAN.c0515 {color: maroon;}
-+SPAN.c0600, SPAN.c0601, SPAN.c0602, SPAN.c0603, SPAN.c0604, SPAN.c0605, SPAN.c0606, SPAN.c0607, SPAN.c0608, SPAN.c0609, SPAN.c0610, SPAN.c0611, SPAN.c0612, SPAN.c0613, SPAN.c0614, SPAN.c0615 {color: purple;}
-+SPAN.c0700, SPAN.c0701, SPAN.c0702, SPAN.c0703, SPAN.c0704, SPAN.c0705, SPAN.c0706, SPAN.c0707, SPAN.c0708, SPAN.c0709, SPAN.c0710, SPAN.c0711, SPAN.c0712, SPAN.c0713, SPAN.c0714, SPAN.c0715 {color: orange;}
-+SPAN.c0800, SPAN.c0801, SPAN.c0802, SPAN.c0803, SPAN.c0804, SPAN.c0805, SPAN.c0806, SPAN.c0807, SPAN.c0808, SPAN.c0809, SPAN.c0810, SPAN.c0811, SPAN.c0812, SPAN.c0813, SPAN.c0814, SPAN.c0815 {color: yellow;}
-+SPAN.c0900, SPAN.c0901, SPAN.c0902, SPAN.c0903, SPAN.c0904, SPAN.c0905, SPAN.c0906, SPAN.c0907, SPAN.c0908, SPAN.c0909, SPAN.c0910, SPAN.c0911, SPAN.c0912, SPAN.c0913, SPAN.c0914, SPAN.c0915 {color: lime;}
-+SPAN.c1000, SPAN.c1001, SPAN.c1002, SPAN.c1003, SPAN.c1004, SPAN.c1005, SPAN.c1006, SPAN.c1007, SPAN.c1008, SPAN.c1009, SPAN.c1010, SPAN.c1011, SPAN.c1012, SPAN.c1013, SPAN.c1014, SPAN.c1015 {color: teal;}
-+SPAN.c1100, SPAN.c1101, SPAN.c1102, SPAN.c1103, SPAN.c1104, SPAN.c1105, SPAN.c1106, SPAN.c1107, SPAN.c1108, SPAN.c1109, SPAN.c1110, SPAN.c1111, SPAN.c1112, SPAN.c1113, SPAN.c1114, SPAN.c1115 {color: cyan;}
-+SPAN.c1200, SPAN.c1201, SPAN.c1202, SPAN.c1203, SPAN.c1204, SPAN.c1205, SPAN.c1206, SPAN.c1207, SPAN.c1208, SPAN.c1209, SPAN.c1210, SPAN.c1211, SPAN.c1212, SPAN.c1213, SPAN.c1214, SPAN.c1215 {color: blue;}
-+SPAN.c1300, SPAN.c1301, SPAN.c1302, SPAN.c1303, SPAN.c1304, SPAN.c1305, SPAN.c1306, SPAN.c1307, SPAN.c1308, SPAN.c1309, SPAN.c1310, SPAN.c1311, SPAN.c1312, SPAN.c1313, SPAN.c1314, SPAN.c1315 {color: magenta;}
-+SPAN.c1400, SPAN.c1401, SPAN.c1402, SPAN.c1403, SPAN.c1404, SPAN.c1405, SPAN.c1406, SPAN.c1407, SPAN.c1408, SPAN.c1409, SPAN.c1410, SPAN.c1411, SPAN.c1412, SPAN.c1413, SPAN.c1414, SPAN.c1415 {color: silver;}
-+SPAN.c1500, SPAN.c1501, SPAN.c1502, SPAN.c1503, SPAN.c1504, SPAN.c1505, SPAN.c1506, SPAN.c1507, SPAN.c1508, SPAN.c1509, SPAN.c1510, SPAN.c1511, SPAN.c1512, SPAN.c1513, SPAN.c1514, SPAN.c1515 {color: gray;}
-+SPAN.f00 {color: white;}
-+SPAN.f01 {color: black;}
-+SPAN.f02 {color: navy;}
-+SPAN.f03 {color: green;}
-+SPAN.f04 {color: red;}
-+SPAN.f05 {color: maroon;}
-+SPAN.f06 {color: purple;}
-+SPAN.f07 {color: orange;}
-+SPAN.f08 {color: yellow;}
-+SPAN.f09 {color: lime;}
-+SPAN.f10 {color: teal;}
-+SPAN.f11 {color: cyan;}
-+SPAN.f12 {color: blue;}
-+SPAN.f13 {color: magenta;}
-+SPAN.f14 {color: silver;}
-+SPAN.f15 {color: gray;}
-+SPAN.b00 {background-color: white;}
-+SPAN.b01 {background-color: black;}
-+SPAN.b02 {background-color: navy;}
-+SPAN.b03 {background-color: green;}
-+SPAN.b04 {background-color: red;}
-+SPAN.b05 {background-color: maroon;}
-+SPAN.b06 {background-color: purple;}
-+SPAN.b07 {background-color: orange;}
-+SPAN.b08 {background-color: yellow;}
-+SPAN.b09 {background-color: lime;}
-+SPAN.b10 {background-color: teal;}
-+SPAN.b11 {background-color: cyan;}
-+SPAN.b12 {background-color: blue;}
-+SPAN.b13 {background-color: magenta;}
-+SPAN.b14 {background-color: silver;}
-+SPAN.b15 {background-color: gray;}
++.l2hLogPage #mainblock div {
++white-space: pre-wrap; /* css-3 */
++white-space: pre-line; /* css-3, css-2.1 */
++white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
++white-space: -hp-pre-wrap; /* HP printers */
++white-space: -pre-wrap; /* Opera 4-6 */
++white-space: -o-pre-wrap; /* Opera 7 */
++word-wrap: break-word; /* Internet Explorer 5.5+ */
++overflow:hidden;
++}
++.l2hLogPage #mainblock span.time {
++color: #D0D0D0;
++}
++.l2hLogPage #mainblock span.nick {
++color: #0040C0;
++}
++.l2hLogPage #mainblock span.text {
++color: #111111;
++}
++.l2hLogPage #mainblock span.else_j {
++color: #99CC00;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else_li {
++color: #99CC00;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else_l {
++color: #99CC00;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else_n {
++color: #FF6666;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else_m {
++color: #00CCFF;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else_k {
++color: #FF0066;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.else {
++color: #40C000;
++font-size: 0.8em;
++}
++.l2hLogPage #mainblock span.action {
++color: #FF99FF;
++}
++
++/* mirc colors */
++.l2hLogPage span.c0000, .l2hLogPage span.c0100, .l2hLogPage span.c0200, .l2hLogPage span.c0300, .l2hLogPage span.c0400, .l2hLogPage span.c0500, .l2hLogPage span.c0600, .l2hLogPage span.c0700, .l2hLogPage span.c0800, .l2hLogPage span.c0900, .l2hLogPage span.c1000, .l2hLogPage span.c1100, .l2hLogPage span.c1200, .l2hLogPage span.c1300, .l2hLogPage span.c1400, .l2hLogPage span.c1500 {background-color: white;}
++.l2hLogPage span.c0001, .l2hLogPage span.c0101, .l2hLogPage span.c0201, .l2hLogPage span.c0301, .l2hLogPage span.c0401, .l2hLogPage span.c0501, .l2hLogPage span.c0601, .l2hLogPage span.c0701, .l2hLogPage span.c0801, .l2hLogPage span.c0901, .l2hLogPage span.c1001, .l2hLogPage span.c1101, .l2hLogPage span.c1201, .l2hLogPage span.c1301, .l2hLogPage span.c1401, .l2hLogPage span.c1501 {background-color: black;}
++.l2hLogPage span.c0002, .l2hLogPage span.c0102, .l2hLogPage span.c0202, .l2hLogPage span.c0302, .l2hLogPage span.c0402, .l2hLogPage span.c0502, .l2hLogPage span.c0602, .l2hLogPage span.c0702, .l2hLogPage span.c0802, .l2hLogPage span.c0902, .l2hLogPage span.c1002, .l2hLogPage span.c1102, .l2hLogPage span.c1202, .l2hLogPage span.c1302, .l2hLogPage span.c1402, .l2hLogPage span.c1502 {background-color: navy;}
++.l2hLogPage span.c0003, .l2hLogPage span.c0103, .l2hLogPage span.c0203, .l2hLogPage span.c0303, .l2hLogPage span.c0403, .l2hLogPage span.c0503, .l2hLogPage span.c0603, .l2hLogPage span.c0703, .l2hLogPage span.c0803, .l2hLogPage span.c0903, .l2hLogPage span.c1003, .l2hLogPage span.c1103, .l2hLogPage span.c1203, .l2hLogPage span.c1303, .l2hLogPage span.c1403, .l2hLogPage span.c1503 {background-color: green;}
++.l2hLogPage span.c0004, .l2hLogPage span.c0104, .l2hLogPage span.c0204, .l2hLogPage span.c0304, .l2hLogPage span.c0404, .l2hLogPage span.c0504, .l2hLogPage span.c0604, .l2hLogPage span.c0704, .l2hLogPage span.c0804, .l2hLogPage span.c0904, .l2hLogPage span.c1004, .l2hLogPage span.c1104, .l2hLogPage span.c1204, .l2hLogPage span.c1304, .l2hLogPage span.c1404, .l2hLogPage span.c1504 {background-color: red;}
++.l2hLogPage span.c0005, .l2hLogPage span.c0105, .l2hLogPage span.c0205, .l2hLogPage span.c0305, .l2hLogPage span.c0405, .l2hLogPage span.c0505, .l2hLogPage span.c0605, .l2hLogPage span.c0705, .l2hLogPage span.c0805, .l2hLogPage span.c0905, .l2hLogPage span.c1005, .l2hLogPage span.c1105, .l2hLogPage span.c1205, .l2hLogPage span.c1305, .l2hLogPage span.c1405, .l2hLogPage span.c1505 {background-color: maroon;}
++.l2hLogPage span.c0006, .l2hLogPage span.c0106, .l2hLogPage span.c0206, .l2hLogPage span.c0306, .l2hLogPage span.c0406, .l2hLogPage span.c0506, .l2hLogPage span.c0606, .l2hLogPage span.c0706, .l2hLogPage span.c0806, .l2hLogPage span.c0906, .l2hLogPage span.c1006, .l2hLogPage span.c1106, .l2hLogPage span.c1206, .l2hLogPage span.c1306, .l2hLogPage span.c1406, .l2hLogPage span.c1506 {background-color: purple;}
++.l2hLogPage span.c0007, .l2hLogPage span.c0107, .l2hLogPage span.c0207, .l2hLogPage span.c0307, .l2hLogPage span.c0407, .l2hLogPage span.c0507, .l2hLogPage span.c0607, .l2hLogPage span.c0707, .l2hLogPage span.c0807, .l2hLogPage span.c0907, .l2hLogPage span.c1007, .l2hLogPage span.c1107, .l2hLogPage span.c1207, .l2hLogPage span.c1307, .l2hLogPage span.c1407, .l2hLogPage span.c1507 {background-color: orange;}
++.l2hLogPage span.c0008, .l2hLogPage span.c0108, .l2hLogPage span.c0208, .l2hLogPage span.c0308, .l2hLogPage span.c0408, .l2hLogPage span.c0508, .l2hLogPage span.c0608, .l2hLogPage span.c0708, .l2hLogPage span.c0808, .l2hLogPage span.c0908, .l2hLogPage span.c1008, .l2hLogPage span.c1108, .l2hLogPage span.c1208, .l2hLogPage span.c1308, .l2hLogPage span.c1408, .l2hLogPage span.c1508 {background-color: yellow;}
++.l2hLogPage span.c0009, .l2hLogPage span.c0109, .l2hLogPage span.c0209, .l2hLogPage span.c0309, .l2hLogPage span.c0409, .l2hLogPage span.c0509, .l2hLogPage span.c0609, .l2hLogPage span.c0709, .l2hLogPage span.c0809, .l2hLogPage span.c0909, .l2hLogPage span.c1009, .l2hLogPage span.c1109, .l2hLogPage span.c1209, .l2hLogPage span.c1309, .l2hLogPage span.c1409, .l2hLogPage span.c1509 {background-color: lime;}
++.l2hLogPage span.c0010, .l2hLogPage span.c0110, .l2hLogPage span.c0210, .l2hLogPage span.c0310, .l2hLogPage span.c0410, .l2hLogPage span.c0510, .l2hLogPage span.c0610, .l2hLogPage span.c0710, .l2hLogPage span.c0810, .l2hLogPage span.c0910, .l2hLogPage span.c1010, .l2hLogPage span.c1110, .l2hLogPage span.c1210, .l2hLogPage span.c1310, .l2hLogPage span.c1410, .l2hLogPage span.c1510 {background-color: teal;}
++.l2hLogPage span.c0011, .l2hLogPage span.c0111, .l2hLogPage span.c0211, .l2hLogPage span.c0311, .l2hLogPage span.c0411, .l2hLogPage span.c0511, .l2hLogPage span.c0611, .l2hLogPage span.c0711, .l2hLogPage span.c0811, .l2hLogPage span.c0911, .l2hLogPage span.c1011, .l2hLogPage span.c1111, .l2hLogPage span.c1211, .l2hLogPage span.c1311, .l2hLogPage span.c1411, .l2hLogPage span.c1511 {background-color: aqua;}
++.l2hLogPage span.c0012, .l2hLogPage span.c0112, .l2hLogPage span.c0212, .l2hLogPage span.c0312, .l2hLogPage span.c0412, .l2hLogPage span.c0512, .l2hLogPage span.c0612, .l2hLogPage span.c0712, .l2hLogPage span.c0812, .l2hLogPage span.c0912, .l2hLogPage span.c1012, .l2hLogPage span.c1112, .l2hLogPage span.c1212, .l2hLogPage span.c1312, .l2hLogPage span.c1412, .l2hLogPage span.c1512 {background-color: blue;}
++.l2hLogPage span.c0013, .l2hLogPage span.c0113, .l2hLogPage span.c0213, .l2hLogPage span.c0313, .l2hLogPage span.c0413, .l2hLogPage span.c0513, .l2hLogPage span.c0613, .l2hLogPage span.c0713, .l2hLogPage span.c0813, .l2hLogPage span.c0913, .l2hLogPage span.c1013, .l2hLogPage span.c1113, .l2hLogPage span.c1213, .l2hLogPage span.c1313, .l2hLogPage span.c1413, .l2hLogPage span.c1513 {background-color: fuchsia;}
++.l2hLogPage span.c0014, .l2hLogPage span.c0114, .l2hLogPage span.c0214, .l2hLogPage span.c0314, .l2hLogPage span.c0414, .l2hLogPage span.c0514, .l2hLogPage span.c0614, .l2hLogPage span.c0714, .l2hLogPage span.c0814, .l2hLogPage span.c0914, .l2hLogPage span.c1014, .l2hLogPage span.c1114, .l2hLogPage span.c1214, .l2hLogPage span.c1314, .l2hLogPage span.c1414, .l2hLogPage span.c1514 {background-color: silver;}
++.l2hLogPage span.c0015, .l2hLogPage span.c0115, .l2hLogPage span.c0215, .l2hLogPage span.c0315, .l2hLogPage span.c0415, .l2hLogPage span.c0515, .l2hLogPage span.c0615, .l2hLogPage span.c0715, .l2hLogPage span.c0815, .l2hLogPage span.c0915, .l2hLogPage span.c1015, .l2hLogPage span.c1114, .l2hLogPage span.c1215, .l2hLogPage span.c1315, .l2hLogPage span.c1415, .l2hLogPage span.c1515 {background-color: gray;}
++.l2hLogPage span.c0000, .l2hLogPage span.c0001, .l2hLogPage span.c0002, .l2hLogPage span.c0003, .l2hLogPage span.c0004, .l2hLogPage span.c0005, .l2hLogPage span.c0006, .l2hLogPage span.c0007, .l2hLogPage span.c0008, .l2hLogPage span.c0009, .l2hLogPage span.c0010, .l2hLogPage span.c0011, .l2hLogPage span.c0012, .l2hLogPage span.c0013, .l2hLogPage span.c0014, .l2hLogPage span.c0015 {color: white;}
++.l2hLogPage span.c0100, .l2hLogPage span.c0101, .l2hLogPage span.c0102, .l2hLogPage span.c0103, .l2hLogPage span.c0104, .l2hLogPage span.c0105, .l2hLogPage span.c0106, .l2hLogPage span.c0107, .l2hLogPage span.c0108, .l2hLogPage span.c0109, .l2hLogPage span.c0110, .l2hLogPage span.c0111, .l2hLogPage span.c0112, .l2hLogPage span.c0113, .l2hLogPage span.c0114, .l2hLogPage span.c0115 {color: black;}
++.l2hLogPage span.c0200, .l2hLogPage span.c0201, .l2hLogPage span.c0202, .l2hLogPage span.c0203, .l2hLogPage span.c0204, .l2hLogPage span.c0205, .l2hLogPage span.c0206, .l2hLogPage span.c0207, .l2hLogPage span.c0208, .l2hLogPage span.c0209, .l2hLogPage span.c0210, .l2hLogPage span.c0211, .l2hLogPage span.c0212, .l2hLogPage span.c0213, .l2hLogPage span.c0214, .l2hLogPage span.c0215 {color: navy;}
++.l2hLogPage span.c0300, .l2hLogPage span.c0301, .l2hLogPage span.c0302, .l2hLogPage span.c0303, .l2hLogPage span.c0304, .l2hLogPage span.c0305, .l2hLogPage span.c0306, .l2hLogPage span.c0307, .l2hLogPage span.c0308, .l2hLogPage span.c0309, .l2hLogPage span.c0310, .l2hLogPage span.c0311, .l2hLogPage span.c0312, .l2hLogPage span.c0313, .l2hLogPage span.c0314, .l2hLogPage span.c0315 {color: green;}
++.l2hLogPage span.c0400, .l2hLogPage span.c0401, .l2hLogPage span.c0402, .l2hLogPage span.c0403, .l2hLogPage span.c0404, .l2hLogPage span.c0405, .l2hLogPage span.c0406, .l2hLogPage span.c0407, .l2hLogPage span.c0408, .l2hLogPage span.c0409, .l2hLogPage span.c0410, .l2hLogPage span.c0411, .l2hLogPage span.c0412, .l2hLogPage span.c0413, .l2hLogPage span.c0414, .l2hLogPage span.c0415 {color: red;}
++.l2hLogPage span.c0500, .l2hLogPage span.c0501, .l2hLogPage span.c0502, .l2hLogPage span.c0503, .l2hLogPage span.c0504, .l2hLogPage span.c0505, .l2hLogPage span.c0506, .l2hLogPage span.c0507, .l2hLogPage span.c0508, .l2hLogPage span.c0509, .l2hLogPage span.c0510, .l2hLogPage span.c0511, .l2hLogPage span.c0512, .l2hLogPage span.c0513, .l2hLogPage span.c0514, .l2hLogPage span.c0515 {color: maroon;}
++.l2hLogPage span.c0600, .l2hLogPage span.c0601, .l2hLogPage span.c0602, .l2hLogPage span.c0603, .l2hLogPage span.c0604, .l2hLogPage span.c0605, .l2hLogPage span.c0606, .l2hLogPage span.c0607, .l2hLogPage span.c0608, .l2hLogPage span.c0609, .l2hLogPage span.c0610, .l2hLogPage span.c0611, .l2hLogPage span.c0612, .l2hLogPage span.c0613, .l2hLogPage span.c0614, .l2hLogPage span.c0615 {color: purple;}
++.l2hLogPage span.c0700, .l2hLogPage span.c0701, .l2hLogPage span.c0702, .l2hLogPage span.c0703, .l2hLogPage span.c0704, .l2hLogPage span.c0705, .l2hLogPage span.c0706, .l2hLogPage span.c0707, .l2hLogPage span.c0708, .l2hLogPage span.c0709, .l2hLogPage span.c0710, .l2hLogPage span.c0711, .l2hLogPage span.c0712, .l2hLogPage span.c0713, .l2hLogPage span.c0714, .l2hLogPage span.c0715 {color: orange;}
++.l2hLogPage span.c0800, .l2hLogPage span.c0801, .l2hLogPage span.c0802, .l2hLogPage span.c0803, .l2hLogPage span.c0804, .l2hLogPage span.c0805, .l2hLogPage span.c0806, .l2hLogPage span.c0807, .l2hLogPage span.c0808, .l2hLogPage span.c0809, .l2hLogPage span.c0810, .l2hLogPage span.c0811, .l2hLogPage span.c0812, .l2hLogPage span.c0813, .l2hLogPage span.c0814, .l2hLogPage span.c0815 {color: yellow;}
++.l2hLogPage span.c0900, .l2hLogPage span.c0901, .l2hLogPage span.c0902, .l2hLogPage span.c0903, .l2hLogPage span.c0904, .l2hLogPage span.c0905, .l2hLogPage span.c0906, .l2hLogPage span.c0907, .l2hLogPage span.c0908, .l2hLogPage span.c0909, .l2hLogPage span.c0910, .l2hLogPage span.c0911, .l2hLogPage span.c0912, .l2hLogPage span.c0913, .l2hLogPage span.c0914, .l2hLogPage span.c0915 {color: lime;}
++.l2hLogPage span.c1000, .l2hLogPage span.c1001, .l2hLogPage span.c1002, .l2hLogPage span.c1003, .l2hLogPage span.c1004, .l2hLogPage span.c1005, .l2hLogPage span.c1006, .l2hLogPage span.c1007, .l2hLogPage span.c1008, .l2hLogPage span.c1009, .l2hLogPage span.c1010, .l2hLogPage span.c1011, .l2hLogPage span.c1012, .l2hLogPage span.c1013, .l2hLogPage span.c1014, .l2hLogPage span.c1015 {color: teal;}
++.l2hLogPage span.c1100, .l2hLogPage span.c1101, .l2hLogPage span.c1102, .l2hLogPage span.c1103, .l2hLogPage span.c1104, .l2hLogPage span.c1105, .l2hLogPage span.c1106, .l2hLogPage span.c1107, .l2hLogPage span.c1108, .l2hLogPage span.c1109, .l2hLogPage span.c1110, .l2hLogPage span.c1111, .l2hLogPage span.c1112, .l2hLogPage span.c1113, .l2hLogPage span.c1114, .l2hLogPage span.c1115 {color: aqua;}
++.l2hLogPage span.c1200, .l2hLogPage span.c1201, .l2hLogPage span.c1202, .l2hLogPage span.c1203, .l2hLogPage span.c1204, .l2hLogPage span.c1205, .l2hLogPage span.c1206, .l2hLogPage span.c1207, .l2hLogPage span.c1208, .l2hLogPage span.c1209, .l2hLogPage span.c1210, .l2hLogPage span.c1211, .l2hLogPage span.c1212, .l2hLogPage span.c1213, .l2hLogPage span.c1214, .l2hLogPage span.c1215 {color: blue;}
++.l2hLogPage span.c1300, .l2hLogPage span.c1301, .l2hLogPage span.c1302, .l2hLogPage span.c1303, .l2hLogPage span.c1304, .l2hLogPage span.c1305, .l2hLogPage span.c1306, .l2hLogPage span.c1307, .l2hLogPage span.c1308, .l2hLogPage span.c1309, .l2hLogPage span.c1310, .l2hLogPage span.c1311, .l2hLogPage span.c1312, .l2hLogPage span.c1313, .l2hLogPage span.c1314, .l2hLogPage span.c1315 {color: fuchsia;}
++.l2hLogPage span.c1400, .l2hLogPage span.c1401, .l2hLogPage span.c1402, .l2hLogPage span.c1403, .l2hLogPage span.c1404, .l2hLogPage span.c1405, .l2hLogPage span.c1406, .l2hLogPage span.c1407, .l2hLogPage span.c1408, .l2hLogPage span.c1409, .l2hLogPage span.c1410, .l2hLogPage span.c1411, .l2hLogPage span.c1412, .l2hLogPage span.c1413, .l2hLogPage span.c1414, .l2hLogPage span.c1415 {color: silver;}
++.l2hLogPage span.c1500, .l2hLogPage span.c1501, .l2hLogPage span.c1502, .l2hLogPage span.c1503, .l2hLogPage span.c1504, .l2hLogPage span.c1505, .l2hLogPage span.c1506, .l2hLogPage span.c1507, .l2hLogPage span.c1508, .l2hLogPage span.c1509, .l2hLogPage span.c1510, .l2hLogPage span.c1511, .l2hLogPage span.c1512, .l2hLogPage span.c1513, .l2hLogPage span.c1514, .l2hLogPage span.c1515 {color: gray;}
++.l2hLogPage span.f00 {color: white;}
++.l2hLogPage span.f01 {color: black;}
++.l2hLogPage span.f02 {color: navy;}
++.l2hLogPage span.f03 {color: green;}
++.l2hLogPage span.f04 {color: red;}
++.l2hLogPage span.f05 {color: maroon;}
++.l2hLogPage span.f06 {color: purple;}
++.l2hLogPage span.f07 {color: orange;}
++.l2hLogPage span.f08 {color: yellow;}
++.l2hLogPage span.f09 {color: lime;}
++.l2hLogPage span.f10 {color: teal;}
++.l2hLogPage span.f11 {color: aqua;}
++.l2hLogPage span.f12 {color: blue;}
++.l2hLogPage span.f13 {color: fuchsia;}
++.l2hLogPage span.f14 {color: silver;}
++.l2hLogPage span.f15 {color: gray;}
++
++/* Miscellaneous classes for reuse */
++.clearfloat {
++/* this class should be placed on a div or break element and should be the final element before
++the close of a container that should fully contain a float */
++clear:both;
++height:0;
++font-size: 1px;
++line-height: 0px;
++}
++
++-->
++
diff --git a/main/eggdrop/utf8.patch b/main/eggdrop/utf8.patch
new file mode 100644
index 0000000000..385357cd95
--- /dev/null
+++ b/main/eggdrop/utf8.patch
@@ -0,0 +1,12 @@
+diff -Nura e2/src/tcl.c e1/src/tcl.c
+--- e2/src/tcl.c 2011-09-10 01:37:53.000000000 +0400
++++ e1/src/tcl.c 2016-10-08 01:25:00.830082096 +0300
+@@ -863,7 +863,7 @@
+ }
+
+ if (encoding == NULL) {
+- encoding = "iso8859-1";
++ encoding = "utf-8";
+ }
+
+ Tcl_SetSystemEncoding(NULL, encoding);