Page MenuHomeDevCentral

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..26d6bc8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,8 @@
+Copyright (C) 1996 Darkbot Project.
+
+This program is free software, you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2. 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 COPYING file for the full
+license.
diff --git a/README b/README
index a77b00a..c7418ac 100644
--- a/README
+++ b/README
@@ -1,54 +1,55 @@
-Darkbot, Talking Robot - Copyright (c) 1996 Darkbot Project
+Darkbot, Talking Robot
+
+Copyright (C) 1996 Darkbot Project.
+
+This program is free software, you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2. 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 COPYING file for the full
+license.
+
- To build your Darkbot on Unixes (or cygwin),
run the ./build.sh script.
- For full documentation and step by step configuration help,
please check Darkbot's help page at http://darkbot.sourceforge.net
- Read docs/WHATSNEW for added/latest features and changes.
- Read docs/README_UTILS for info on shell utilities and all files in
scripts dir.
- If you are running a Darkbot with version release prior to 7.0
use convertdb to convert your userlist.db to an encrypted password
format. Users will need to set their passwords on IRC which initial
value would be 0(zero). convertdb script and all integrated Darkbot
utility scripts are on scripts directory.
- If your bot is stupid, and you want it to know some general
stuff, download pre-made databases from the Darkbot site. You should be
aware of database mechanics before installing and running any database.
Darkbot should compile and run on a lot of operating systems (OS).
Please note that the darkbot team is small, most of the time there's
only one developer actively working on it, in their spare time. So we
can't support every version of every OS under the sun, we just don't
have the time for them all. Some OS's are free to install, some cost
money, some cost a lot of money. So, we have to draw the line
somewhere. The general principle is that we support the oldest stable
release that is still supported by the OS maker from BSD (FreeBSD,
OpenBSD, and Mac OS X), Linux (Debian and Ubuntu), and Windows. The
assumption is that later versions should be backwards compatible enough.
Also, it should be easy to get these running on a VM, preferably qemu.
More Linux varieties might be added, especially RPM based ones.
-This program is provided free for non-commercial use only. Any
-commercial use of this source code or binaries compiled thereof
-requires the prior written consent of the project administrator.
-Distribution of modified source code or binaries compiled from
-modified source code for any platform is expressly forbidden!
-All code patches to be applied to the program are donations to
-the project and must remain under this terms and conditions.
-No code with copyright statements other than the ones ruled by this
-project is accepted unless agreed by all parties in writing.
All Darkbot program and information is provided as is without
warranty of any kind. In any event shall Darkbot project or any
of it's collaborators be liable for any damages whatsoever.
If you do not agree with the above user disclaimer, please do not
use the program and delete all Darkbot files.
Darkbot is a creation of Jason Hamilton [ Jason@superlink.net ]
and has been coded by several contributors who donates their
-code patches to the project. Please read file contributors in
+code patches to the project. Please read file AUTHORS in
docs directory with a list of who makes this program possible.
diff --git a/autogen.sh b/autogen.sh
index 9ad77bc..5473950 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,7 +1,16 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
sh bootstrap.sh
if test -z "$NOCONFIGURE"; then
cd build && sh configure -C --prefix=$HOME/darkbot "$@" && cd ..
fi
diff --git a/bootstrap.sh b/bootstrap.sh
index 54def88..3826499 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -1,16 +1,25 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
sh clean.sh
mkdir build && \
cp source/configure.ac source/Makefile.am build && \
mkdir build/compat && \
mkdir build/dat && \
cp dat/*.ini dat/*.db build/dat && \
mkdir build/dat/rdb && \
cp dat/rdb/*.rdb build/dat/rdb && \
mkdir build/dat/timers && \
autoreconf -fiv -Wall build
rm -rf build/autom4te.cache
rm -f build/*.c
rm -f build/*.h
diff --git a/build.sh b/build.sh
index 252ed7d..754ff1b 100755
--- a/build.sh
+++ b/build.sh
@@ -1,8 +1,17 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
make='make'
if which gmake; then make='gmake'; fi
test ! -r build/configure && sh bootstrap.sh
cd build && sh configure -C --prefix=$HOME/darkbot "$@" && $make && $make install && cd ..
diff --git a/build_small.sh b/build_small.sh
index abb6a11..fbc5954 100755
--- a/build_small.sh
+++ b/build_small.sh
@@ -1,10 +1,19 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
make='make'
if which gmake; then make='gmake'; fi
test ! -r build/configure && sh bootstrap.sh
cd build && sh configure -C --prefix=$HOME/darkbot \
--disable-CTCP --disable-channel --disable-math --disable-google --disable-weather --disable-METAR --disable-TAF --disable-randq --disable-stoned --disable-verbose --disable-random "$@" && \
$make && $make install && cd ..
diff --git a/clean.sh b/clean.sh
index bc13792..f2c084f 100755
--- a/clean.sh
+++ b/clean.sh
@@ -1,5 +1,14 @@
#! /bin/sh
-
# Clean up after previous compile.
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
rm -rf $HOME/darkbot
rm -rf build
diff --git a/distribute.sh b/distribute.sh
index 7282430..69087c7 100755
--- a/distribute.sh
+++ b/distribute.sh
@@ -1,13 +1,22 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
sh bootstrap.sh
DESTDIR="darkbot-`cat VERSION`-CVS-SNAPSHOT"
rm -rf $DESTDIR
rm -f $DESTDIR.tar.gz
mkdir $DESTDIR
cp -p * $DESTDIR 2>/dev/null
cp -p .* $DESTDIR 2>/dev/null
cp -a build dat docs m4 scripts source $DESTDIR
tar cfz build/$DESTDIR.tar.gz $DESTDIR
rm -rf $DESTDIR
diff --git a/docs/INSTALL b/docs/INSTALL
index 6d26c8c..7d0c685 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -1,506 +1,504 @@
##################################################################################
- Darkbot, Talking Robot - Copyright (c) 1996 Darkbot Project
-
Welcome to the Darkbot install file. This will be a step by step guide to
installing your Darkbot, so read it all, before you do anything.
If you have not read this file and come into the help channel on the Darkbot
Network, we will know, and it might mean you will be helped last.
With that out of the way, if you have done every thing in this file and still
can not get your Darkbot running, feel free to join #Darkbot on the Darkbot
Network, and we will do our best to help you. Keep in mind that we are not
there to set up and run your bot for you. One or two questions about commands
are okay, but if you have to ask about every command, then maybe you shouldn't
be running a bot.
Note: There are many builds of Linux out in the world today. The coders try and
build Darkbot to be run on as many as possible but some times it doesn't work
out that way. If there is a problem with compiling Darkbot on your Linux build,
please let us know. The same goes for other Operating Systems, Windows, Mac OS
X, BSD, etc. In particular, if make complains that it can't find source files,
try gmake.
Help can be found for Darkbot either by irc, or from our web page.
Irc: Server chat.freenode.net
Channel: #darkbot
Web site: http://darkbot.sourceforge.net
We do not support any Darkbot code that has been downloaded from any site other
then the official one. Any code that has been modified by anyone other than an
official Darkbot coder, will also not be supported. (If you have a good idea
for a modification, please share it with us. If it makes the final code, you
will be given credit.)
###############################################################
Follow the order of events described here, and you'll have your Darkbot up and
running!
There are two ways to install Darkbot, from a git checkout, or from a source
tarball. If you are using git, make sure you have the usual autotools installed,
and GNU make (which might be called gmake for your operating system).
INSTALL FROM A SOURCE TARBALL -
Download to your shell compressed archive from -
https://sourceforge.net/projects/darkbot/files/
De-compress the downloaded archive (tar -zxvf *.tar.gz) -
tar -zxvf darkbot-8rc4.tar.gz
INSTALL FROM GIT -
Clone the git source repository from -
git clone git://git.code.sf.net/p/darkbot/darkbot darkbot-darkbot
FOR BOTH -
Change to the newly created directory.
BASIC CONFIGURATION -
For a basic configuration you can just run the build.sh script -
./build.sh
Which will start the build process, and install the result to $HOME/darkbot.
In that directory you will need to edit two files at least -
darkbot/var/servers.ini, change it to have the name of the IRC server/s you wish
your Darkbot to join.
darkbot/var/setup.ini, at the very least you should change BOT_NICK so that all
the Darkbots don't have the same IRC nick name. DEFAULT_CHANNEL should also be
changed to what ever IRC channel you want your bot to be in. None of the other
stuff really needs to be changed.
ADVANCED CONFIGURATION -
If you are using git, then run the autogen.sh script, otherwise don't. Change to
the build directory, then run -
./configure --help
We are not going into detail and repeating the instructions shown when you run
./configure, because they are self-explanatory. It's just the usual thing you
expect when using autotools configure scripts. Run the configure script again
with your chosen options, then "make" and "make install" as usual.
OFFLINE CONFIGURATION SETTINGS
(follow the samples in the files and don't leave any empty lines)
How to do it.
[userlist.db]
Adding users to Darkbot's user list.
Open darkbot\dat\userlist.db and check this sample line: '#*
*user@*.yourhostmask.com 3 0 mypass I need to use SETINFO' with your
information.
#* = (with asterisk) adds user to all channels; #channel1 adds user to channel1
*user@*.yourhostmask.com = is the mask of the user to add
3 = user level -- You should always be Darkbot's administrator (level 3) on your
darkbot\dat\userlist.db [Level 3 is the highest, allows you to control all
Darkbot functions; level 2 gives access to channel operation commands plus level
1 commands; level 1 only permits to manage Darkbot's database - it's the so
called helper level; all other commands are public, meaning everyone can perform
them].
0 = number of times Darkbot saw that user on the default channel
mypass = If you want to define a password for you can do it replacing 'mypass'
with user's one.
'I need to use SETINFO' = is a message Darkbot sends to newly registered users
in order to remind them to define or not it's greeting message. Leave it as is
or write, for example, "Hi Boss ;)". You can also replace 'setinfo' message with
a 0 (zero) to disable it.
(You can add more users from online with the !adduser command or delete with the
!deluser command)
[setup.ini]
Open darkbot\dat\setup.ini. See the SETUP file for more details.
This is the file you need to edit to setup your Darkbot's nickname, username,
realname, default channel to join, virtual host, command character prefix and
seen users switch. Change the contents of the file as you need overwriting
existing parameters. Do not remove anything before '='. Do not leave extra
spaces or lines. Do not use carriage returns. Save and exit.
Obs.:
'VHOST= ' to set your virtual host (must be a registered domain pointed to the
same computer as Darkbot and configured for IRC)
'CHAN=#ChannelHere' sets Darkbot's default channel. If you want to add
more channels use perform.ini.
'CMDCHAR= ' to set Darkbot's command prefix to trigger most of it's commands.
'NICK='This is the nick your bot will have when it joins irc, default is Darkbot
'USERID='This will be the name before the @ in the bots user host
'REALNAME=' This will be the info after your bots user host
'AUTOTOPIC='Automatically cycles channel's topic every 30 minutes. To turn
autotopic off, use "0" (zero) in place of the topic.
'SEEN='Turns seen on or off. 1= on, 0= off
[perform.ini]
Having Darkbot performing IRC commands automatically.
You can make Darkbot perform a list of raw IRC commands when it connects to the
server (as mIRC's perform function). You can make your Darkbot join other
channels, perform mode changes, login to channel services with it. Depending on
each network, your IRC knowledge and your imagination depends the commands you can
add.
Open and edit darkbot\dat\perform.ini. Write one command per line.
Examples:
- to join an additional channel besides default one
JOIN #Channel_here
- to set modes
MODE #Channel +nt
- to set a topic as soon as enters a channel
TOPIC #Channel_here :this is a test topic
- to send a message to you as soon as it connects
PRIVMSG YourNick :hey... I'm here
- to send a notice to you
NOTICE YourNick :be ready to feed me :p
- to authenticate on Freenode's Services
PRIVMSG NickServ :IDENTIFY username password
- to authenticate on Undernet's CService
PRIVMSG x@channels.undernet.org :login username password
- to have bot X giving op to your Darkbot on Undernet
PRIVMSG X :op #channel_here username
- to login and get Ops on a eggdrop
PRIVMSG Eggdrop_nick :op password #channel
General rule to send raw IRC messages is preceding the message with ':'. However
there are situations where you might be able to perform commands without it.
- to identity your Darkbot on some servers
NICKSERV IDENTIFY darkbot_password
- for some channel services
CHANSERV OP #channel_here Darkbot
[deop.ini]
Changing Darkbot's behavior when is not Op.
You can have your Darkbot perform commands when it loses channel Op like messaging
you, automatically asking Op to the channel service or another bot or Ops. Open
and edit darkbot\dat\deop.ini. Check the examples below. Leave this file blank
if you want it to do nothing. (see also examples used on perform.ini)
PRIVMSG #channel_here :Hmm, wish I had ops...
NOTICE Your_nick : I lost Ops :(
PRIVMSG NickServ :IDENTIFY username password
PRIVMSG x@channels.undernet.org :login username password
PRIVMSG Network_Channel_Service_Here :op username
chanserv op #channel_here Darkbot
PRIVMSG Eggdrop_nick :op password #channel
[servers.ini]
Changing or adding servers to Darkbot.
By default Darkbot connects to one of Freenode servers
chat.freenode.net 6667
irc.freenode.net 6667
Open and edit darkbot\dat\servers.ini. You can list as many servers as you want,
so if it's disconnected, it'll switch to others. Do not leave empty lines. Do
not mix servers, like freenode.net and dal.net. Save and exit.
GOING ONLINE
Write on your shell './darkbot' in order to have it connect to the Internet.
Wait a little bit and if you didn't change servers.ini in order to use another
network, Darkbot will join channel #Darkbot at Freenode.net. (To join this
network type in your IRC client /server chat.freenode.net and /join #darkbot)
If you did change the servers.ini and the CHAN= in the setup.ini then Darkbot
will join that server and channel that you set there.
If another nick Darkbot is already there, your Darkbot will take nick Darkbot0,
Darkbot1 etc. (You can see which one is yours by doing /whois and looking at the
output info. It will have the same hostmask as yours or the machine where it is
running).
You can have Darkbot jump to another server by performing !JUMP command.
Setting or changing the password to access Darkbot (25 characters maximum). If
you didn't change 'mypass' on userlist.db write
/msg Darkbot pass mypass my_new_pass.
After changing it you'll receive a notice like this:
-- Password for youruserid@yourhostmask.com has been updated.
Login to Darkbot:
Now you have to authenticate yourself to Darkbot to perform some commands. To do
so type
/msg Darkbot LOGIN YourPass
You'll receive a notice like this from Darkbot:
-- Verified: #darkbot[3]
Notes: have in mind - for security reasons - if you or Darkbot leaves the channel
you have to login again when returning.
ONLINE ADDITIONAL CONFIGURATION SETTINGS
Set greeting message
If you want Darkbot to greet you when you join the channel and you didn't
already edit it in the userlist.db 'I need to use SETINFO' type, for example,
!SETINFO I think I know you ;P
(!setinfo 0 disables the function; typing !setinfo without any parameters gives
you some help about the command)
Next time you join the channel Darkbot will greet you with that mesage.
Set Darkbot's nick name
In order to have Darkbot with a nick you like, you only need to type,
!SETNICK MyDarkbot
Set userid
If you want to change Darkbot's user id type,
!SETUSER newuserid
Set default channel
To instruct Darkbot what channel must be the default one, type,
!SETCHAN #YourChannel
Set Command Character
If you want to change the default command prefix [ ! ] issued to Darkbot to
execute some commands and, for instance, you want to use command character '>'
type,
!SETCHAR >
Set auto topic
Auto-topic function makes Darkbot repeat channel's topic you specify every 30
seconds (default). To do so type, for example,
!AUTOTOPIC Visit http://darkbot.sourceforge.net for complete Darkbot
information.
Set virtual host
If you want to set a virtual host to Darkbot type (must be a registered domain
pointed to the same computer as Darkbot and configured for IRC)
!VHOST your.vhost.com
--**--
The remaining files within the \dat folder can also been edited offline. info2.db
(stores topics and corresponding replies), randomstuff.ini (stores random
replies), seen.db (stores the list of users seen by Darkbot) and perbans.db
(stores permanent bans)
START ADDING TOPICS
As all commands in this document YOU MUST LOGIN (/msg BotNick LOGIN yourpass)
before you can execute any Darkbot's command)! Also, you need to read the complete
command list document where you find a more detailed explanation about each one.
This is only a superficial help file to get you to add, modify and delete basic
topic replies.
Login to your Darkbot
Type:
YourBotNick ADD hello hello N~
(now type 'hello' and Darkbot will reply 'Hello YourNick')
Type:
YourBotNick MODIFY hello Hi N~, thanks for coming to C~
(now type 'hello' and the Darkbot's reply was modified to 'Hello YourNick,
thanks for coming to #YourChannel')
Type:
YourBotNick DELETE hello
(Darkbot deletes the topic 'hello'. If you type hello he don't answer)
YOU MUST READ
Darkbots Commands List and all help documents. This is only a short
file to get your Darkbot up and running.
------------------ " -------------------
OTHER FILES
info2.db - This is the information your darkbot learns and replys to when asked
questions. It's the main database.
A topic can be more than one word, but will be separated with +'s instead of
spaces. If a data starts with a +, the reply will be in the form of an action.
If the data starts with a -, the output can be stacked using PIPES and you can
use raw data, to do things such as NOTICE, PRIVMSG and even KICK. The symbol "^"
is the $nickname variable. The ^R (reverse control char) is the $chan variable.
While this may seem a bit confusing... don't worry about it, It's very simple,
just hard to explain in words without SHOWING you the bot in action.
randomstuff.ini - List of random things to say. You can add more online by
saying: BotNick RANDOMSTUFF information to add.
permbans.db - This is a text file, just a .db (database) file name extension.
Use the !PERMBAN and !DELBAN commands from on-line to add\delete.
seen.db - This is a list of people your bot has seen. You can access it with
!SEEN , seen's over one week old are deleted.
SOMETHING WRONG
All suggestions here are proved to work on several linux flavors and several
machines. Although we believe there are no side effects to your computer or to
yourself in doing it, follow them at your own risk. Do not blame your Darkbot in
case he decides not answering you.
(A) - Before proceed:
- Turn off your Darkbot by issuing command 'kill' (do ps x to see Darkbot's
process id and kill -9 pidNumber or killall darkbot)
(B) - Always make a backup of the file you want to work with before any change
or make a copy of Darkbot's folder using command 'cp'. Leave the file or 'Copy
of darkbot' as a safe backup in case you need to restore a file, you already have
it.
(C) - Use linux text editors if you can to edit Darkbot files. If you can't use
another text editor; the one you are using might be adding hidden codes or
changing the format of the original files. Check if file extension is the same.
For instance, if you are using Windows Notepad and file userlist.db extension
after editing and saving is userlist.db.txt rename it to userlist.db.
(D) - Do not leave empty lines on the middle of others or on the end of the
text.
============================
A Few F.A.Q's
I can't read and edit some files that have kind of strange black squares. Is
that Code Black virus?
-Darkbot is done in a way that is very safe in all aspects not only on IRC but
also on it's invulnerability to virus or trojans. So no, it's not any virus or
nothing like that. Those are codes left by your editor when tabs and carriage
returns are used. Looks like you are editing those files in Windows so use
Wordpad. You can also use Notepad but in some files you need to reconstruct the
lines in a way of having each command line on a separated line. Never leave
empty lines.
My Darkbot don't connect at all.
- Run Darkbot with minimal configuration (no hand editing at all) to see if
connects to chat.freenode.net and goes to channel #darkbot. If you go there, Darkbot
should react with a short answer if you write it's nick.
- if not, install Darkbot again from the original compressed file. If problem
persists your original compressed Darkbot file or some of it's contents might be
corrupted so download it again from Darkbot's official site.
My Darkbot don't recognizes me when I /msg Darkbot login mypassword.
- After following procedures on (A) add yourself to darkbot\dat\userlist.db -
Save and exit - Connect Darkbot again and try to /msg Darkbot login
yourpassword.
- if Darkbot notices you as accepting your login, write on the public window
'Darkbot add test 123'. Darkbot should answer 'Okay'. Write 'test'. Darkbot
should answer '123'.
- if not, follow procedures on A, B, C and D.
- if Darkbot is still not accepting your login
- Open your darkbot\dat\userlist.db
On the sample line '*user@*.yourhostmask.com 3 0 mypass I need to use SETINFO'
You only need to overwrite *user@*.yourhostmask.com and 'mypass' in order to get
your Darkbot online and access to it.
The mask *user@*.yourhostmask.com should match the one you have when you connect
to the same network where your Darkbot is (do /whois to_ yournick to compare
it). You must use a wildcard * on all portions of the mask that change in every
time you connect. General concept is you should substitute all changing items on
your mask with an asterisk (*).
- While connected do /whois YourNickHere and check the first line of the output.
On the userid/ident side (the one on the left of @) you must use one * right
before of it on your userlist.db entry. If that ident has a leading ~ don't use
it. ~myident@blah.blah.blah or myident@blah.blah.blah should go to userlist as
*myident@blah.blah.blah. If your ident changes at times (some characters are
missing like this ~myid@blah.blah.blah) on the right side, right before @, use
the wildcard on both ends, i.e., *myid*@blah.blah.blah.
On the IP address side, right of @, compare what you have with the examples
bellow.
Static IPs (never changes):
- if your IP looks like this: myident@myhost123.mydomain.com
you shoud add as *myident@myhost123.mydomain.com
- if your IP looks like this: myident@11.222.12.123
you should add as *myident@11.222.12.123
Dynamic IPs (changes with each connection):
- if your IP looks like this: myident@myhost123.mydomain.com and the portion
that changes for every connection is '123'
you'll add *myident@myhost*.mydomain.com
- if your IP looks like this: myident@11.222.12.123 if the portion that changes
for every connection is 12.123 you'll add *myident@11.222.*
My Darkbot don't connect to the servers I want.
Write on darkbot/scripts directory ./AddServer and follow instructions
or
- follow procedures on A, B, C and D.
- open servers.ini and remove the servers in there adding those you would like
Darkbot to connect to. Syntax must be .irc.server.here 6667' and NOT
irc.server.here:6667' . Save and connect.
My Darkbot is not giving me the greeting message (setinfo).
Darkbot ignores whoever rejoins a channel for a period of time. The default
length of time to not recount someone when rejoins the channel is set to 60
seconds.
My Darkbot is not accepting commands if I repeat them in a short period of time.
Darkbot ignores for a certain period of time repeated commands to avoid
flooding. Use one command alias or wait a couple minutes.
My Darkbot is not answering when someone asks the same question.
Darkbot will not reply to a topic already asked (with same syntax) during a
certain period. By default that length of time is set to 5 seconds.
I'm stuck... I don't know how to turn off my Darkbot
You can use command !die online or on your shell kill -9 pidNumber after doing
'ps x' do check it's pid, or killall darkbot.
// ================ SYSTEM REQUIREMENTS ================
/*
* Change the Ansi C signal handling below if it's not in the standard place,
* usually on include/. Leave it as is if you don't know what that is. Type
* 'man signal' on your unix box for more info.
* (default = <signal.h>)
*/
#include <signal.h>
/*
* If you are getting errors during compilation about clock_t
* and clocks_per_sec not being available, turn this option ON.
* This includes <time.h> in addition to <sys/time.h>.
* (default = OFF)
*/
#define NEED_CLOCK_T ON
/*
* If your compiler does not support snprintf() turn this
* option ON. (default = OFF)
*/
#define SNPRINTF_SUPPORT ON
/*
diff --git a/m4/db_enable_command.m4 b/m4/db_enable_command.m4
index 0f7d6b4..7abe74a 100644
--- a/m4/db_enable_command.m4
+++ b/m4/db_enable_command.m4
@@ -1,65 +1,73 @@
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
AC_DEFUN([DB_ENABLE_COMMAND],
[
AC_MSG_CHECKING([whether to enable $1 command])
AC_ARG_ENABLE([$1],
AS_HELP_STRING([--enable-$1],[enable $1 command @<:@$2@:>@]),
[db_cv_enable_command_$1=$enableval],
AC_CACHE_VAL([db_cv_enable_command_$1], [db_cv_enable_command_$1=$2]))
if test "[${db_cv_enable_command_$1}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $1 command])
fi
if test "[${db_cv_enable_testing}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $1 command (testing mode)])
db_cv_enable_command_$1=yes
fi
AC_MSG_RESULT([$db_cv_enable_command_$1])
])
AC_DEFUN([DB_ENABLE_COMMANDS],
[
AC_MSG_CHECKING([whether to enable $1 commands])
AC_ARG_ENABLE([$1],
AS_HELP_STRING([--enable-$1],[enable $1 commands @<:@$2@:>@]),
[db_cv_enable_command_$1=$enableval],
AC_CACHE_VAL([db_cv_enable_command_$1], [db_cv_enable_command_$1=$2]))
if test "[${db_cv_enable_command_$1}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $1 commands])
fi
if test "[${db_cv_enable_testing}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $1 commands (testing mode)])
db_cv_enable_command_$1=yes
fi
AC_MSG_RESULT([$db_cv_enable_command_$1])
])
AC_DEFUN([DB_ENABLE_GENERIC],
[
AC_MSG_CHECKING([whether to enable $4])
AC_ARG_ENABLE([$1],
AS_HELP_STRING([--enable-$1],[enable $4 @<:@$2@:>@]),
[db_cv_enable_$1=$enableval],
AC_CACHE_VAL([db_cv_enable_$1], [db_cv_enable_$1=$2]))
if test "[${db_cv_enable_$1}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $4])
fi
if test "[${db_cv_enable_testing}]" = yes; then
AC_DEFINE_UNQUOTED([ENABLE_$3],[1],[whether to enable $4 (testing mode)])
db_cv_enable_$1=yes
fi
AC_MSG_RESULT([$db_cv_enable_$1])
])
# FIXME: AC_ARG_WITH() is not the best choice, AC_ARG_VAR() may be better.
AC_DEFUN([DB_ENABLE_VALUE],
[
AC_MSG_CHECKING([value of $4])
AC_ARG_WITH([$1],
AS_HELP_STRING([--with-$1],[set $4 @<:@$2@:>@]),
[db_cv_with_$1=$withval],
AC_CACHE_VAL([db_cv_with_$1], [db_cv_with_$1=$2]))
AC_DEFINE_UNQUOTED([$3],[$db_cv_with_$1],[value of $4])
AC_MSG_RESULT([$db_cv_with_$1])
])
diff --git a/rebuild_all.sh b/rebuild_all.sh
index 5a9f159..b130baa 100755
--- a/rebuild_all.sh
+++ b/rebuild_all.sh
@@ -1,8 +1,17 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
make='make'
if which gmake; then make='gmake'; fi
sh autogen.sh
cd build && $make && $make install && cd ..
diff --git a/scripts/AddServer b/scripts/AddServer
index ca9440a..dcff337 100755
--- a/scripts/AddServer
+++ b/scripts/AddServer
@@ -1,477 +1,487 @@
#!/bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PID=0624233000
PNAS="
* Darkbot Servers Utility *
<***********_~_***********>
"
# changes: dependencies - option of using lynx or wget (041402)
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $0 ...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
cd scripts 2>/dev/null
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNAS\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNAS\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
#DB_SCRIPTS_PATH
BASE_WORKDIR=.scriptutils
TMP=$BASE_WORKDIR/._tmp/as$$
mkdir -p $BASE_WORKDIR/._tmp/
trap 'rm -fr $BASE_WORKDIR/._tmp* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
FILESERV="../dat/servers.ini"
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $PNAS...\n\n\n"; sleep 1; exit 0
}
SERVERS_HELP () {
echo -e "$PNAS
Basically what this script does is managing your servers.ini file by adding
removing and changing servers and ports.
You have the option of manipulating only your local servers file or downloading
an updated server list from the International Federation of IRC and work with
those servers.
On all lists the servers are preceded by a number (which is not in fact part of
the files) to help you better choose or manage each entry.
On the remote servers list the ports displayed on the right are only for your
reference and corresponds to all available ports. It's recommendable to select
option 2 on the menu to load the external servers before changing local ports
so you'll have updated information to deal with.
If you decide to move all remote list to your local file, port 6667 will be
used for all servers. You can later change that port for each server on the
main menu, option 8.
On all lists PgUp/Down or arrow keys scrolls the text; Q quits from the list.
CTRL+C aborts at all times.
To launch the utility write $0. For a quick server entry write:
$0 server port (ex: $0 irc.server.here 6667 )\n
Comments, suggestions?
Support: http://darkbot.sourceforge.net\n"
if [ -n "$insider" ]; then echo "[ Hit ENTER to continue ]"; read PTR; fi
}
# test environment
TESTDEPEND () {
NonFatalError () {
echo "NON FATAL ERROR at $0 (`date`): $FiLe not detected on this system. \
Going to simple operation mode, which means only simple SERVER addition will \
be performed..." >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNAS\nNON FATAL ERROR: $FiLe not detected on this system.
Going to simple operation mode, which means only simple SERVER addition will
be performed...\n"
}
if ! (type "$1" 1>/dev/null 2>&1); then
FiLe="$1"
NonFatalError $1
sleep 1; unset $FiLe
fi
}
TESTDEPEND "grep"; TESTDEPEND "sed"; TESTDEPEND "cut"; TESTDEPEND "cat"
# test dependencies which can have optional programs and set vars for those.
TESTDEPEND_SUBST () {
# test lynx/wget
if (type "lynx" 1>/dev/null 2>&1); then
dld_prg="lynx"
else
if (type "wget" 1>/dev/null 2>&1); then
dld_prg="wget"
fi
fi
if [ -z "$dld_prg" ]; then
echo -e "FATAL ERROR at $0 (`date`): lynx and wget not detected \
on this system. One it's necessary for this utility to work \
properly" >> $BASE_WORKDIR/error_messages
echo -e "$PNAS\nFATAL ERROR at $0 (`date`)\n\n
Either lynx or wget are essential for $0 to work properly.
None of those programs were found on this system"
ABORT
fi
}
TESTDEPEND_SUBST
# dat/servers.ini
DISPLAY_LOCAL () {
if [ ! -e "$FILESERV" ] || [ ! -s "$FILESERV" ]; then
# echo -e "$PNAS\nThere are no servers present."; sleep 2
echo " #### There are no servers present - servers.ini is empty ####"; sleep 2
LASTACTION="Unaccomplished action - no servers present on ../dat/servers.ini."
else
clear
echo -e "$PNAS* Local Server List ** "$FILESERV" ** \n
[ PgUp/Down or arrow keys scrolls; Q quits from the list ]\n
`cat -b "$FILESERV"`\n
" | less -deXF
echo " Press ENTER to continue"; read PTR
LASTACTION="Displayed Darkbot servers list."
fi
}
QUICK_ADD () {
clear
echo ""$ADDserv" "$ADDport"" >> "$FILESERV"
echo -e "$PNAS\nAdded to your "$FILESERV" exactly this entry:
"$ADDserv" "$ADDport"\n\n"
}
ADDSERVER () {
unset SERV; unset PORT
while [ -z "$SERV" ]
do
clear
echo -n "$PNAS
Enter a server name: "
read SERV
if [ -z "$SERV" ]; then
echo -e "You MUST specify a server!\n"
sleep 1
fi
done
while [ -z "$PORT" ]
do
echo -n "
What port to connect to on $SERV? [6667] "
read PORT
if [ -z "$PORT" ]; then
echo -e "\n Defaulting port to 6667...\n"
PORT=6667
sleep 1
fi
done
echo "$SERV $PORT" >> $FILESERV
LASTACTION="Added: SERVER: "$SERV" PORT: "$PORT""
if [ -e "$TMP.TESTDEPEND" ]; then
clear
echo -e "$PNAS\nAdded to your "$FILESERV"\n Server: "$SERV" - Port: "$PORT"\n\n"
fi
}
DELSERVER () {
if [ -s "$FILESERV" ]; then
unset DEL_SERV
echo -n "Please enter the number corresponding to the server to be removed: "
read DEL_SERV
svr_num_lines="$(cat "$FILESERV" | wc -l | tr -cd '[:alnum:]')"
if [ ! -z "$DEL_SERV" ]; then
# if [ "$DEL_SERV" -le "$srv_num_lines" ]; then
REMOVED=$(sed -n $DEL_SERV"p" $FILESERV)
if [ ! -z "$REMOVED" ]; then
sed $DEL_SERV"d" $FILESERV > $TMP.FILESERV
LASTACTION="Removed: $REMOVED."
cat $TMP.FILESERV > $FILESERV
LASTACTION="Removed from your Darkbot IRC servers list: $REMOVED."
else
LASTACTION="Unaccomplished server entry removal - invalid input."
fi
else
LASTACTION="Unaccomplished server removal - no servers present on $FILESERV."
fi
fi
}
CHANGEPORT () {
if [ -s "$FILESERV" ]; then
unset READ_SERV_NUM; unset NEW_PORT
cat -b $FILESERV > $TMP.FILESERV
while [ -z "$READ_SERV_NUM" ]; do
echo -n "Enter the number corresponding to the server to change the port: "
read READ_SERV_NUM
SERV_TMP=$(sed -n $READ_SERV_NUM"p" $FILESERV | cut -d' ' -f1)
OLD_PORT=$(sed -n $READ_SERV_NUM"p" $FILESERV | cut -d' ' -f2)
done
## Possible port choices/ confront with remote server then put var on echo
if [ "$RemoteStatus" != "off" ]; then
PossPortChoices=$(sed -n /$SERV_TMP/p $TMP.NETW_NAME | cut -d: -f2)
fi
clear
while [ -z "$NEW_PORT" ]; do
echo -n "$PNAS
Current port on $SERV_TMP: $OLD_PORT.
`if [ ! -z $PossPortChoices ]; then echo Available ports: $PossPortChoices; fi`
Enter the new port or press ENTER for default [6667]: "
read NEW_PORT
if [ -z $NEW_PORT ]; then NEW_PORT=6667; fi
sed -e '/'$SERV_TMP'/s/'$OLD_PORT'/'$NEW_PORT'/' $FILESERV > $TMP.2.FILESERV
cat $TMP.2.FILESERV > $FILESERV
done
LASTACTION="Changed port $OLD_PORT to $NEW_PORT on $SERV_TMP"
else
LASTACTION="Unaccomplished port change - no servers present on $FILESERV."
fi
}
# remote servers
GET_REMOTE () {
if [ ! -s $TMP.rem.servers ]; then
DLD_PRG_COMMLINE () {
if [ "$dld_prg" = "lynx" ]; then
lynx -source -nostatus http://ifirc.com/servers.ini 2>/dev/null > $TMP.rem.servers
else
wget -qO $TMP.rem.servers http://ifirc.com/servers.ini
fi
}
trymax="3"; trycount="0"
while [ "$trycount" != "$trymax" ] && [ ! -s $TMP.rem.servers ]; do
trycount=`expr $trycount + 1`
echo -e "$PNAS\n An updated server list is being downloaded from the
International Federation of IRC - http://ifirc.com.\n
Please wait...\n"
DLD_PRG_COMMLINE
#cp servers.ini $TMP.rem.servers # debug only
# cp $TMP.rem.servers servers.ini # debug only
done
unset testRemote
testRemote=$(grep freenode $TMP.rem.servers)
if [ -z "$testRemote" ]; then
echo -e "$PNAS\n I can't obtain the remote servers list at this time"
LASTACTION="Remote (external) server list unreachable."
RemoteStatus="off"
fi
fi
}
SELECT_REMOTE () {
if [ ! -z "$testRemote" ]; then
while [ ! -s "$TMP.NETW_NAME" ]; do
clear
echo -n "$PNAS
* External Server List *
Write the name of the IRC network (ex: Freenode): "
read NETW_NAME
if [ ! -z "$NETW_NAME" ]; then
grep -i "$NETW_NAME": $TMP.rem.servers | cut -d: -f3-4 | sed s/GROUP// > $TMP.NETW_NAME
grep -i "$NETW_NAME": $TMP.rem.servers | cut -d: -f3 | sed 's/$/ 6667/' > $TMP.EXTERNAL_ALL6667
grep -i "$NETW_NAME": $TMP.rem.servers | cut -d: -f3 | sed 's/$//' > $TMP.EXTERNAL_NOPORTS
if [ ! -s $TMP.NETW_NAME ]; then
echo -e "\nERROR: I don't have network '$NETW_NAME' on my list.\n"
sleep 1
fi
fi
done
fi # testRemote != null
}
DISPLAY_REMOTE () {
if [ ! -z "$testRemote" ]; then
if [ ! -s $TMP.NETW_NAME ]; then
SELECT_REMOTE
clear
fi
echo -e "$PNAS* External Server List ** $NETW_NAME ** \n
[ PgUp/Down or arrow keys scrolls; Q quits from the list ]\n
`cat -b $TMP.NETW_NAME`\n
" | less -deXF
echo " Press ENTER to continue"; read PTR
LASTACTION="Displayed remote servers list."
# cat -b $TMP.NETW_NAME > NETW_NAME # debug only
# cat $TMP.NETW_NAME > NETW_NAME # debug only
fi # testRemote != null
}
ADDSERVER_REMOTE () {
unset READ_REM_SERV_NUM
if [ ! -s $TMP.NETW_NAME ]; then SELECT_REMOTE; fi
if [ ! -z "$testRemote" ]; then
ADD_1_REMOTE () {
cat -b $TMP.NETW_NAME | less -deXF
while [ -z "$READ_REM_SERV_NUM" ]; do
echo -n "
Enter the number corresponding to the server to be added: "
read READ_REM_SERV_NUM
REM_SERV_TMP=$(sed -n $READ_REM_SERV_NUM"p" $TMP.EXTERNAL_NOPORTS)
REM_SERV_PORTS=$(sed -n $READ_REM_SERV_NUM"p" $TMP.NETW_NAME | cut -d: -f2)
done
clear
echo -n "$PNAS
Available ports for "$REM_SERV_TMP": "$REM_SERV_PORTS"
Write the port number for "$REM_SERV_TMP"
or press ENTER for default [6667]: "
read READ_REM_SERV_PORT
if [ -z $READ_REM_SERV_PORT ]; then READ_REM_SERV_PORT=6667; fi
echo "$REM_SERV_TMP" "$READ_REM_SERV_PORT" >> $FILESERV
LASTACTION="Added SERVER "$REM_SERV_TMP", PORT "$READ_REM_SERV_PORT"."
}
APPEND_ALL_REMOTE () {
cat $TMP.EXTERNAL_ALL6667 >> "$FILESERV"
LASTACTION="Appended all servers from "$NETW_NAME" to your Darkbot IRC servers!"
}
OVERWRITE_ALL_REMOTE () {
cat $TMP.EXTERNAL_ALL6667 > "$FILESERV"
LASTACTION="Overwrited your Darkbot servers file with all servers from "$NETW_NAME"!"
}
fi # testRemote != null
}
SERVERS_MENU () {
while [ "$CHOICE" != "0" ]; do
unset servini_status_; unset servini_status
if [ ! -e "$FILESERV" ] || [ ! -s "$FILESERV" ]; then
servini_status_="*"
servini_status=" Not available - empty file"
fi
if [ "$RemoteStatus" = "off" ]; then
RemoteStatus1="*" # for menu
fi
clear
if [ -f "$FILESERV" ]; then TOTAL_LOCAL_SERV="$(cat "$FILESERV" | wc -l | tr -cd '[:alnum:]')"; fi
if [ "$TOTAL_LOCAL_SERV" = "1" ]; then server_s="server" ; else server_s="servers" ; fi
if [ "$TOTAL_LOCAL_SERV" = "" ]; then TOTAL_LOCAL_SERV="0" ;fi
echo -e "$PNAS
`if [ ! -z "$LASTACTION" ]; then
echo -e " | Last action/status:\n |" $servini_status_""$RemoteStatus1" "$LASTACTION" "; else echo "MAIN MENU"; fi`
| Number of servers currently in servers.ini file: "$TOTAL_LOCAL_SERV"
[1] Display my `if [ "$TOTAL_LOCAL_SERV" != "0" ]; then echo "$TOTAL_LOCAL_SERV"; fi` "$server_s". "$servini_status_"
[2] Display the external server list. "$RemoteStatus1"
[3] Add a server to my local server file. (manually)
[4] Add a server from the external list. (pick one) "$RemoteStatus1"
[5] Add all servers from the external server list. (append to local) "$RemoteStatus1"
[6] Add all servers from the external server list. (overwrite local) "$RemoteStatus1"
[7] Change the port on a server. "$servini_status_"
[8] Remove a server from my servers file. "$servini_status_"
[9] Remove all servers from my servers.ini file. "$servini_status_"
(C) Check my servers.ini file for errors (fast mode). "$servini_status_"
(H) HELP
(X) EXIT Darkbot Servers Utility.
"$servini_status_" $servini_status \n"
echo -n "Enter your choice: "
read CHOICE
case $CHOICE in
1)
#clear; DISPLAY_LOCAL;;
DISPLAY_LOCAL;;
2)
clear; GET_REMOTE; DISPLAY_REMOTE;;
3)
clear; ADDSERVER;;
4)
clear; GET_REMOTE; ADDSERVER_REMOTE; ADD_1_REMOTE;;
5)
clear; GET_REMOTE; ADDSERVER_REMOTE; APPEND_ALL_REMOTE;;
6)
clear; GET_REMOTE; ADDSERVER_REMOTE; OVERWRITE_ALL_REMOTE;;
7)
#clear; DISPLAY_LOCAL; CHANGEPORT;;
DISPLAY_LOCAL; CHANGEPORT;;
8)
#clear; DISPLAY_LOCAL; DELSERVER;;
DISPLAY_LOCAL; DELSERVER;;
9)
if [ "$servini_status_" != "*" ]; then
cat servers.ini > "$FILESERV" 2>/dev/null
echo "REMOVING all servers from servers.ini...";
LASTACTION="Removed all servers from servers.ini file."
else
echo " #### No servers to remove. File servers.ini is empty ####"
LASTACTION="Unaccomplished servers removal - empty file."
fi
sleep 2;;
C)
if [ "$servini_status_" != "*" ]; then
if [ ! -s check-integrity ]; then
LASTACTION="Unaccomplished file check - utility not installed."
else
./check-integrity servers -quick
LASTACTION="Checked servers.ini for errors."
fi
else
LASTACTION="Unaccomplished file check - empty file."
fi;;
c)
if [ "$servini_status_" != "*" ]; then
if [ ! -s check-integrity ]; then
LASTACTION="Unaccomplished file check - utility not installed."
else
./check-integrity servers -quick
LASTACTION="Checked servers.ini for errors."
fi
else
LASTACTION="Unaccomplished file check - empty file."
fi;;
h)
clear; insider=y; SERVERS_HELP;;
H)
clear; insider=y; SERVERS_HELP;;
x)
exit 0;;
X)
exit 0;;
*)
if [ -z $CHOICE ]; then
echo -e "\nERROR: Playing with the ENTER key..?"; sleep 2; clear
else
echo -e "\nERROR: '$CHOICE' is not a valid choice"; sleep 2; clear
fi
esac
done
}
# start engines
if [ "$1" = "-h" ] || [ "$1" = "-H" ] || [ "$1" = "--h" ]; then
clear; SERVERS_HELP
elif [ ! -z "$1" ] && [ ! -z "$2" ]; then
ADDserv="$1"; ADDport="$2"; QUICK_ADD
elif [ ! -e "$TMP.TESTDEPEND" ]; then SERVERS_MENU
else
ADDSERVER
fi
diff --git a/scripts/AddUser b/scripts/AddUser
index c1347f5..f6e8fad 100755
--- a/scripts/AddUser
+++ b/scripts/AddUser
@@ -1,289 +1,299 @@
#!/bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PID=0624233000
PNAU="
* Darkbot Users Utility *
<**********_~_**********>
"
# to do: check errors on user input
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $0 ...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNAU\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNAU\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
#DB_SCRIPTS_PATH
BASE_WORKDIR=.scriptutils
TMP=$BASE_WORKDIR/._tmp/au$$
mkdir -p $BASE_WORKDIR/._tmp/
trap 'rm -fr $BASE_WORKDIR/._tmp* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
FILEUSER="../dat/userlist.db"
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $PNAU...\n\n\n"; sleep 1; exit 0
}
USERS_HELP () {
echo -e "$PNAU
This utility displays, adds and removes user entries on your userlist.db file.\n
While displaying file contents all entries are preceded by a number (which is
not in fact part of the files) to help you better choose or manage each user.\n
If the entries goes over screen size use arrow keys or PgUp/Down to scroll and
type Q to quit or scroll the list to it's very end so it will automatically
exit and proceed to the next function. CTRL + C aborts at all times.\n
To launch the utility write $0. For a quick user entry write:
$0 userid@host level Ex: $0 *whateverid@*host.domain.net 2
(It will add an user with access level 2 to all channels).\n
Comments, suggestions?
Support: http://darkbot.sourceforge.net\n"
if [ -n "$insider" ]; then echo "[ Hit ENTER to continue ]"; read PTR; fi
}
# test environment
TESTDEPEND () {
NonFatalError () {
echo "NON FATAL ERROR at $0 (`date`): $FiLe not detected on this system. \
Going to simple operation mode, which means only simple USER addition will \
be performed..." >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNAU\nNON FATAL ERROR: $FiLe not detected on this system.
Going to simple operation mode, which means only simple USER addition will
be performed...\n"
}
if ! (type "$1" 1>/dev/null 2>&1); then
FiLe="$1"
NonFatalError $1
sleep 1; unset $FiLe
fi
}
TESTDEPEND "grep"; TESTDEPEND "sed"; TESTDEPEND "cut"; TESTDEPEND "cat"
# dat/userlist.db
DISPLAY_USERDB () {
if [ ! -e "$FILEUSER" ] || [ ! -s "$FILEUSER" ]; then
echo -e "$PNAU\nThere are no user entries present."
LASTACTION="Unaccomplished action: no users entries to display."
else
echo -e "$PNAU* Local User List ** "$FILEUSER" ** \n
| ---- If entries goes over screen's vertical size ---- |
| ---- PgUp/Down or arrow keys scrolls; Q quits from the list ---- |\n
`cat -b "$FILEUSER"`\n
" | less -deXF
echo " Press ENTER to continue"; read PTR
LASTACTION="Displayed Darkbot users list."
fi
}
CHECK_SYNTAX () {
echo $null
}
QUICK_ADD () {
clear
echo "#* "$ADDuser" "$ADDlevel" 0 0" >> "$FILEUSER"
echo "$PNAU
Added to your "$FILEUSER" exactly this entry:
#* "$ADDuser" "$ADDlevel" 0 0\n\n"
}
ADDUSER () {
echo -e "\n$PNAU\n
The format of the user@host must be *userid@*.host.isp
Exs: *jason@*.superlink.net <-- dyanmic ip
*mtr@darkmind.eclipse.net <-- static host
*darkmind@204.127.145.* <-- unresolved host\n"
unset NICK; unset LEVEL
while [ -z "$NICK" ]
do
echo -n "Enter the *user@host of the user you'd like to add: "
read NICK
if [ -z "$NICK" ]; then
echo -e "You MUST specify an user@host!\n"
sleep 1
fi
done
while [ -z "$LEVEL" ]
do
echo "
What level should $NICK be added at?
1) Helper access. Database management commands.
2) Channel operation commands + database management.
3) Bot administrator. All commands.
"
echo -n "Select the level: "
read LEVEL
case $LEVEL in
1)
LEVEL=1;;
2)
LEVEL=2;;
3)
LEVEL=3;;
*)
echo "\"$LEVEL\" is not a valid selection."
sleep 1;;
esac
done
clear
echo -e "\n$PNAU\n
Adding user: $NICK at level $LEVEL..."
echo "#* $NICK $LEVEL 0 0 I need to use SETINFO" >> "$FILEUSER"
echo -e "
Use ADDUSER and DELUSER commands to add or delete users on-line\n
***************************************************************\n
Darkbot now encrypt the password in the userlist!
Be aware if you are logging private messages the encryption
will not cover them, making it possible to see passwords
on the logs. So turn logs off on defines.h if you don't want
that to happen.
All users added with this script will have a password of 0
and should set their new password on IRC by issuing the command
/msg Darkbot pass 0 new_password.\n
***************************************************************\n"
echo -e "Press ENTER to continue."
read PTR
}
DELUSER () {
if [ -s "$FILEUSER" ]; then
echo -n "Please enter the number corresponding to the user entry to \
be removed: "
read DEL_USER
usr_num_lines="$(cat "$FILEUSER" | wc -l | tr -cd '[:alnum:]')"
if [ ! -z "$DEL_USER" ] && [ "$DEL_USER" -le "$usr_num_lines" ]; then
REMOVED=$(sed -n $DEL_USER"p" $FILEUSER)
sed $DEL_USER"d" $FILEUSER > $TMP.FILEUSER
LASTACTION="Removed: $REMOVED."
cat $TMP.FILEUSER > $FILEUSER
LASTACTION="Removed from your Darkbot IRC users list entry:\n "$REMOVED""
else
LASTACTION="Unaccomplished user entry removal - invalid input."
fi
else
LASTACTION="Unaccomplished user entry removal - no users present on $FILEUSER."
fi
}
USERS_MENU () {
while [ "$CHOICE" != "0" ]; do
unset userdb_status_; unset userdb_status
if [ ! -e "$FILEUSER" ] || [ ! -s "$FILEUSER" ]; then
userdb_status_="*"
userdb_status=" Not available - empty file"
fi
#if [ "$RemoteStatus" = "off" ]; then
#RemoteStatus1="*" # for menu
#fi
clear
echo -e "$PNAU
`if [ ! -z "$LASTACTION" ]; then
echo -e " | Last action/status:\n |"$userdb_status_" "$LASTACTION" "; \
else echo "Main Menu"; fi`
[1] Display my userlist.db entries. "$userdb_status_"
[2] Add an user to my userlist.db
[3] Remove an entry from my users file. "$userdb_status_"
[4] Check my userlist.db file for errors (fast mode). "$userdb_status_"
[H] HELP
[X] Exit Darkbot Users Utility.
"$userdb_status_" $userdb_status \n"
echo -n "Enter your choice: "
read CHOICE
case $CHOICE in
1)
clear; DISPLAY_USERDB;;
2)
clear; ADDUSER;;
3)
clear; DISPLAY_USERDB; DELUSER;;
4)
if [ "$userdb_status_" != "*" ]; then
if [ ! -s check-integrity ]; then
LASTACTION="Unaccomplished file check - utility not installed."
else
./check-integrity userlist -quick
fi
else
LASTACTION="Unaccomplished file check - empty file."
fi;;
h)
clear; insider=y; USERS_HELP;;
H)
clear; USERS_HELP;;
x)
exit 0;;
X)
exit 0;;
*)
if [ -z $CHOICE ]; then
echo -e "\nERROR: Playing with the ENTER key..?
Write the number or letter corresponding to the action to take."
sleep 2; clear
else
echo -e "\nERROR: '$CHOICE' is not a valid choice.
Write the number or letter corresponding to the action to take"
sleep 2; clear
fi
esac
done
}
# start engines
if [ "$1" = "-h" ] || [ "$1" = "-H" ] || [ "$1" = "--h" ]; then
clear; USERS_HELP
elif [ ! -z "$1" ] && [ ! -z "$2" ]; then
ADDuser="$1"; ADDlevel="$2"; QUICK_ADD
elif [ ! -e "$TMP.TESTDEPEND" ]; then USERS_MENU
else
ADDUSER
fi
diff --git a/scripts/Setup b/scripts/Setup
index 8a83d00..8c7f4d1 100755
--- a/scripts/Setup
+++ b/scripts/Setup
@@ -1,805 +1,815 @@
#!/bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PNCFG="
Darkbot Configuration Utility
<************_~_************>
"
PID=0624022000
lparen='('
rparen=')'
# Configures Darkbot
# to do: correcting user entry errors on the fly
ENVIRONMENT () {
BASE_WORKDIR="scripts/.scriptutils"
TMP=$BASE_WORKDIR/._tmp/cfg$$
mkdir -p $BASE_WORKDIR/._tmp/
cfg_vars=$BASE_WORKDIR/.cfg_vars
trap 'rm -fr $BASE_WORKDIR/._tmp* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
# load vars
# utility vars
if [ -e "$cfg_vars" ]; then
. "$cfg_vars"; fi
# setup.ini
if [ -s dat/setup.ini ]; then
cat dat/setup.ini | sed -e s/=/=\"/ -e s/$/\"/ > $TMP-setup.ini
. $TMP-setup.ini
fi
if [ -z "$NICK" ]; then NICK="Darkbot"; fi
if [ -z "$USERID" ]; then USERID="darkbot"; fi
if [ -z "$CHAN" ]; then CHAN="#Darkbot"; fi
if [ -z "$REALNAME" ]; then REALNAME="Get info about me at \
http://darkbot.sourceforge.net "; fi
if [ -z "$CMDCHAR" ]; then CMDCHAR="!"; fi
if [ -z "$VHOST" ]; then VHOST="0"; fi
if [ -z "$AUTOTOPIC" ]; then AUTOTOPIC="0"; fi
if [ -z "$SEEN" ]; then SEEN="0"; fi
}
CFG_INTRO () {
clear
echo -e "\n$PNCFG
--------------------------------------------------------------------------"
if [ ! -s "$cfg_vars" ]; then
echo -e "
Welcome to "$cfg_dbrev" configuration, `whoami`.\n
This will lead you through the setup of your Darkbot wich requires your
input during a few minutes.\n
During this process you could change the directives on defines.h file and
edit 3 essential files: setup.ini, servers.ini and userlist.db.
Additionally, perform.ini and deop.ini could also be edited from here.\n
If for any reason after configuring your Darkbot you would like to use
this utility again, previously configured items will be shown as session
defaults."
else
echo -e "
Welcome back to "$cfg_dbrev" configuration, `whoami`.\n"
if [ "$CFG_DEFINES" = "defined" ] && [ "$cfg_dbrev" != "$CFG_LAST_REV" ]; then
echo " Since this is a new Darkbot revision you might want to take a look on \
your
defines.h file again."; fi
echo -e "\n All previously entered information will be used now as session \
defaults.
You can bypass the items you don't want to change by hitting ENTER key.
That data on your \""$NICK"\" will not be modified."
fi
echo -e "\n Where shown, [defaults] can be used by hitting ENTER.
-------------------------------------------------------------------------- \n
[ Hit ENTER to start the configuration, `whoami` ]"
read PTR
}
CFG_VARS () {
# configuration vars
if [ ! -s "$cfg_vars" ]; then
touch $cfg_vars
fi
# CFG_EDITOR
if [ "$1" = "CFG_EDITOR" ]; then
if [ "`grep 'CFG_EDITOR' $cfg_vars`" ]; then
grep -v 'CFG_EDITOR' "$cfg_vars" > $TMP
cat $TMP > $cfg_vars
fi
echo "CFG_EDITOR=\"$CFG_EDITOR\"" >> $cfg_vars
fi
# CFG_DEFINES
if [ "$1" = "CFG_DEFINES" ]; then
if [ "`grep 'CFG_DEFINES' $cfg_vars`" ]; then
grep -v 'CFG_DEFINES' "$cfg_vars" > $TMP
cat $TMP > $cfg_vars
fi
echo "CFG_DEFINES=\"defined\"" >> $cfg_vars
fi
# CFG_LAST_REV
if [ "$1" = "CFG_LAST_REV" ]; then
if [ "`grep 'CFG_LAST_REV' $cfg_vars`" ]; then
grep -v 'CFG_LAST_REV' "$cfg_vars" > $TMP
cat $TMP > $cfg_vars
fi
echo "CFG_LAST_REV=\""$cfg_dbrev"\"" >> $cfg_vars
fi
# CFG_SETUP_INI
if [ "$1" = "CFG_SETUP_INI" ]; then
if [ "`grep 'CFG_SETUP_INI' $cfg_vars`" ]; then
grep -v 'CFG_SETUP_INI' "$cfg_vars" > $TMP
cat $TMP > $cfg_vars
fi
echo "CFG_SETUP_INI=\"set\"" >> $cfg_vars
fi
}
# PROGRAM SETTINGS #
CFG_EDITOR () {
if [ -x "`type -p pico`" ]; then CFG_EDITOR="pico"
else
if [ -x "`type -p emacs`" ]; then CFG_EDITOR="emacs"
else
if [ -x "`type -p vi`" ]; then CFG_EDITOR="vi"
else
if [ -x "`type -p vim`" ]; then CFG_EDITOR="vim"
fi
fi
fi
fi
clear
echo -e "\n$PNCFG\n* choosing text editor *\n
In order to adjust Darkbot to your needs some files might need to
to be chamged so it's necessary to know which text editor to use.\n"
if [ -n "$CFG_EDITOR" ]; then
sleep 2
echo -e " Detected '"$CFG_EDITOR"' installed on your system, but you can \
use other
editor of your choice, providing it is installed and working."
else
# no popular editor detected so have pico as (symbolic) default leaving up to
# the user to decide what to do
sleep 1
echo -e "\n Default one is 'pico' but you can use other editor of your choice,
providing it is present on this system."
CFG_EDITOR="pico"
fi
echo
while [ -z "$EEDITOR" ]
do
sleep 1
echo -n "- Write the name of the text editor you would like to \
use ["$CFG_EDITOR"]: "
read EEDITOR
if [ -z "$EEDITOR" ]; then
echo -e " No editor specified, defaulting to "$CFG_EDITOR". \n"
EEDITOR="$CFG_EDITOR"
fi
done
# put it in var
CFG_EDITOR="$EEDITOR"
CFG_VARS CFG_EDITOR
}
CFG_DEFINES () {
EEDITOR="$CFG_EDITOR"
echo -e "\n Okay, now you will update the directives in defines.h file, changing
the options you want or your system requires by enabling or disabling
it's defines. It is an important file where instructions are given to
create the final executable program.\n
[ Hit ENTER to start editing. ]"
read tmp
# put the file in a TMP for modification comparison
cp -p source/defines.h $TMP.defines.h
$EEDITOR source/defines.h
# if 1 is newer than 2
if [ source/defines.h -nt $TMP.defines.h ]; then
CFG_VARS CFG_DEFINES
CFG_VARS CFG_LAST_REV
# var to instruct new compilation
CFG_DEFINES_CHANGED=y
echo " Changes on defines.h saved!"
else
echo " No changes made on defines.h!"
fi
sleep 3
}
CFG_CMDCHAR () {
while [ -z "$CFG_CMDCHAR" ]
do
clear
echo -e "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the command character (CMDCHAR) your Darkbot should respond to
or press ENTER to use pre-defined ["$CMDCHAR"]: "
read CFG_CMDCHAR
if [ -z "$CFG_CMDCHAR" ]; then
CFG_CMDCHAR="$CMDCHAR"
fi
echo -e "
Setting command prefix to '"$CFG_CMDCHAR"'...
To change it online use command "$CFG_CMDCHAR"SETCHAR
"
done
sleep 3
}
CFG_NICK () {
while [ -z "$CFG_NICK" ]
do
clear
echo "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the nickname (NICK) you would like to use on your Darkbot
or press ENTER to use pre-defined ["$NICK"]: "
read CFG_NICK
if [ -z "$CFG_NICK" ]; then
CFG_NICK="$NICK"
fi
echo -e "\n Setting nick to '"$CFG_NICK"'...\n
To set it online use the command "$CFG_CMDCHAR"SETNICK \n"
done
sleep 3
}
CFG_USID () {
while [ -z "$CFG_USERID" ]
do
clear
echo "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the user id (USERID) you would like to use on "$CFG_NICK"
or press ENTER to use pre-defined ["$USERID"]: "
read CFG_USERID
if [ -z "$CFG_USERID" ]; then
CFG_USERID="$USERID"
fi
echo -e "\n Setting user id to "$CFG_USERID"...\n
To set it online use the command "$CFG_CMDCHAR"SETUSER \n"
done
sleep 3
}
CFG_CHAN () {
while [ -z "$CFG_CHAN" ]
do
clear
echo "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the default channel (CHAN) "$CFG_NICK" should use
or press ENTER to use pre-defined ["$CHAN"]: "
read CFG_CHAN
if [ -z "$CFG_CHAN" ]; then
CFG_CHAN="$CHAN"
fi
echo -e "\n Setting default channel to "$CFG_CHAN"...\n
To set it online use the command "$CFG_CMDCHAR"SETCHAN \n"
done
sleep 3
}
CFG_RNAME () {
while [ -z "$CFG_REALNAME" ]
do
clear
echo "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the 'real name' (REALNAME) info for "$CFG_NICK"
or press ENTER to use pre-defined one: "
read CFG_REALNAME
if [ -z "$CFG_REALNAME" ]; then
CFG_REALNAME="$REALNAME"
fi
echo -e "\n Setting 'realname' to '"$CFG_REALNAME"'...\n"
done
sleep 3
}
CFG_VHOST () {
while [ -z "$CFG_VHOST" ]
do
clear
echo "
$PNCFG
* editing SETUP.ini *
"
echo -n "- Write the virtual host (VHOST) you want "$CFG_NICK" to use. (0 = no VHOST)
Hit ENTER to use pre-defined one ["$VHOST"]:"
read CFG_VHOST
if [ -z "$CFG_VHOST" ]; then
CFG_VHOST="$VHOST"
fi
echo -e "\n Setting VHOST to "$CFG_VHOST"...\n
To change it online use command "$CFG_CMDCHAR"VHOST \n"
done
sleep 3
}
CFG_WRITE_SETUP_INI () {
clear
echo -e "\n$PNCFG\n* editing SETUP.ini *\n
Writing data settings to setup.ini \n Please wait...\n"
echo "NICK=$CFG_NICK" > dat/setup.ini
echo "USERID=$CFG_USERID" >> dat/setup.ini
echo "CHAN=$CFG_CHAN" >> dat/setup.ini
echo "REALNAME=$CFG_REALNAME" >> dat/setup.ini
echo "CMDCHAR=$CFG_CMDCHAR" >> dat/setup.ini
echo "VHOST=$CFG_VHOST" >> dat/setup.ini
echo "AUTOTOPIC="$AUTOTOPIC"" >> dat/setup.ini
echo "SEEN="$SEEN"" >> dat/setup.ini
sleep 3
CFG_VARS CFG_SETUP_INI
}
CFG_ADDSERVER () {
_CFG_COUNT_SRV () {
srv_num_entries="$(cat dat/servers.ini 2>/dev/null | wc -l \
| tr -cd '[:alnum:]')"
if [ "$srv_num_entries" = "0" ] || [ -z "$srv_num_entries" ]; then
srv_entry_s="You have currently NO server entries in your servers.ini file."
entry_s="entry"
fi
ONLY_1_NET="ATTENTION: Make sure you have servers for ONLY 1 network."
if [ "$srv_num_entries" = "1" ]; then
srv_entry_s="You have currently "$srv_num_entries" server entry \
in your servers.ini. file.\n\n
"$ONLY_1_NET""
entry_s="entry"
fi
if [ "$srv_num_entries" -gt "1" ]; then
srv_entry_s="You have currently "$srv_num_entries" servers entries \
in your servers.ini file.\n\n
"$ONLY_1_NET""
entry_s="entries"
fi
}
_CFG_COUNT_SRV
_CFG_SRV_MENU () {
clear
echo -e "
$PNCFG
* SERVERS.ini *
"$NICK" needs servers addresses to connect to IRC (as many as you want).
"$srv_entry_s"
Select one of the following 4 options:
1) - Write only one server or use the default [chat.freenode.net] `if [ ! -z \
"$srv_num_entries" ] && [ "$srv_num_entries" != "0" ]; then \
echo -e "\n ${lparen}This option will overwrite \
the existent "$entry_s" on your servers file${rparen}"; fi`
2) - Use AddServer utility which gives you many options to manage \
your servers
3) - Import a servers.ini file from another location
4) - or hit ENTER to proceed with no changes."
echo -n "
[ Type 1, 2, 3 or press ENTER to proceed ] "
read CHOICE
}
_ADD_1_SERVER () {
while [ -z "$SERVER" ]
do
clear
echo -e "\n$PNCFG\n* SERVERS *\n
- Enter the server your Darkbot should connect to [chat.freenode.net]: "
read SERVER
if [ -z "$SERVER" ]; then
echo -e " No server specified. defaulting to chat.freenode.net
You can add servers by running scripts/AddServer
or by editing dat/servers.ini\n"
sleep 2
SERVER=chat.freenode.net
PORT=6667
fi
done
while [ -z "$PORT" ]
do
echo -n "- Enter the port to connect to on $SERVER [6667]: "
read PORT
if [ -z "$PORT" ]; then
echo -e " No port specified, defaulting to 6667\n"
sleep 2
PORT=6667
fi
done
if [ ! -z "$SERVER" ] || [ ! -z "$PORT" ]; then
echo -e "\nWriting data settings to servers.ini ....."
sleep 2
echo "$SERVER $PORT (Added: `date`)" > dat/servers.ini
fi
}
# START SRV GROUP FUNCTION
while [ -z "$srv_done" ] || [ "$srv_num_entries" = "0" ] || [ -z "$srv_num_entries" ]; do
_CFG_SRV_MENU
if [ "$CHOICE" = "1" ]; then
unset srv_done
_ADD_1_SERVER
srv_done="y"
_CFG_COUNT_SRV
fi
if [ "$CHOICE" = "2" ]; then
unset srv_done
if [ -s "scripts/AddServer" ]; then
cd scripts
./AddServer
cd ..
else echo "#### ERROR #### UTILITY NOT INSTALLED"; sleep 2
fi
srv_done="y"
_CFG_COUNT_SRV
fi
if [ "$CHOICE" = "3" ]; then
unset srv_done
echo -n "
Write the complete path of servers.ini file to import.
EX: `pwd`/dat/servers.ini : "
read CFG_IMPORT_SRVINI
if [ ! -z "$CFG_IMPORT_SRVINI" ]; then
if [ "`echo "$CFG_IMPORT_SRVINI" | grep 'servers.ini$'`" ]; then
cp -f "$CFG_IMPORT_SRVINI" "`pwd`/dat/servers.ini"
else
echo "#### ERROR #### Invalid servers.ini file!"
fi
sleep 2
else
echo "#### INVALID ENTRY ####"
sleep 2
fi
srv_done="y"
_CFG_COUNT_SRV
fi # end of CHOICE 3
if [ "$CHOICE" = "4" ] || [ "$CHOICE" = "" ]; then
unset srv_done
if [ "$srv_num_entries" != "0" ] && [ ! -z "$srv_num_entries" ]; then
echo -n "
Bypassing servers configuration..."; sleep 1
fi
srv_done="y"
fi
_CFG_COUNT_SRV
if [ "$srv_num_entries" = "0" ] || [ -z "$srv_num_entries" ]; then
echo -n "
## WARNING #########################################################
## You need to have at least one server in your servers.ini file! ##
######################################################################"
sleep 3
fi
done # END OF SRV GROUP FUNCTION
}
CFG_ADDUSER () {
while [ "$usr_num_entries" = "0" ] || [ -z "$usr_num_entries" ]; do
_CFG_COUNT_USR () {
usr_num_entries="$(cat dat/userlist.db 2>/dev/null | wc -l \
| tr -cd '[:alnum:]')"
if [ "$usr_num_entries" != "0" ] || [ -z "$usr_num_entries" ]; then
usr_entry_s="You have currently NO user entries in your userlist.db file."
entry_s="entry"
fi
if [ "$usr_num_entries" = "1" ]; then
usr_entry_s="You have currently "$usr_num_entries" user entry in \
your userlist.db file."
entry_s="entry"
fi
if [ "$usr_num_entries" -gt "1" ]; then
usr_entry_s="You have currently "$usr_num_entries" users entries in \
your userlist.db file."
entry_s="entries"
fi
}
_CFG_COUNT_USR
clear
echo -e "
$PNCFG
* USERLIST.db *
"$NICK" needs at least one user as Darkbot administrator.
"$usr_entry_s"
Select one of the following 4 options:
1) - Add yourself or someone else as administrator `if [ ! -z \
"$usr_num_entries" ] && [ "$usr_num_entries" != "0" ]; then \
echo "\n ${lparen}This option will overwrite \
the existent "$entry_s" on your user list file${rparen}"; fi`
2) - Use AddUser utility with several options to manage "$NICK"'s users
3) - Import a userlist.db file from another location
4) - or hit ENTER to proceed with no changes."
echo -n "
[ Type 1, 2, 3 or press ENTER to proceed ] "
read CHOICE
_ADD_1_USER () {
while [ -z "$ADDUSER" ]
do
clear
echo -e "\n$PNCFG\n* USERS *\n
The format of the user@host is *userid@*.host.isp
Examples:
*jason@*.superlink.net <-- dyanmic ip
*mtr@darkmind.eclipse.net <-- static host
*darkmind@204.127.145.* <-- unresolved host\n
- Enter the *user@host of the administrator you'd like to add: "
read ADDUSER
if [ -z "$ADDUSER" ]; then
echo -e " No *user@host specified. Changing to AddUser utility.\n"
ADDUSER=none
else
echo -e " Writing data to userlist.db ..."
sleep 1
echo "#* $ADDUSER 3 0 0 I need to use SETINFO" > dat/userlist.db
echo -e "
Added to "$NICK"'s userlist.db file as administrator \
(level 3) hostmask:
\"$ADDUSER\". Default password is 0 (zero).
To set your new encrypted password online write:
/msg "$NICK" pass 0 New_Password (then /msg "$NICK" login New_Password)
"
echo -n "[ Hit ENTER to continue ]"
read PTR
fi
done
}
if [ "$CHOICE" = "1" ]; then _ADD_1_USER; _CFG_COUNT_USR; fi
if [ "$CHOICE" = "2" ]; then
if [ -s "scripts/AddUser" ]; then
cd scripts
./AddUser
cd ..
else echo "#### ERROR #### UTILITY NOT INSTALLED;"; sleep 2
fi
_CFG_COUNT_USR
fi
if [ "$CHOICE" = "3" ]; then
echo -n "
Write the complete path of userlist.db file to import.
EX: `pwd`/dat/userlist.db : "
read CFG_IMPORT_USRLST
if [ ! -z "$CFG_IMPORT_USRLST" ]; then
if [ "`echo "$CFG_IMPORT_USRLST" | grep 'userlist.db$'`" ]; then
cp -f "$CFG_IMPORT_USRLST" "`pwd`/dat/userlist.db"
else
echo "#### ERROR #### Invalid userlist.db file!"
fi
sleep 2
else
echo "#### INVALID ENTRY ####"
sleep 2
fi
fi # end of CHOICE 3
if [ "$CHOICE" = "4" ] || [ "$CHOICE" = "" ]; then
_CFG_COUNT_USR
if [ "$usr_num_entries" != "0" ] && [ ! -z "$usr_num_entries" ]; then
echo "
Bypassing user list configuration..."; sleep 1
fi
fi
if [ "$usr_num_entries" = "0" ] || [ -z "$usr_num_entries" ]; then
echo "
## WARNING ###############################################################
## You need to add at least one administrator in your userlist.db file! ##
############################################################################"
sleep 3
fi
done
}
CFG_MENU () {
clear
while [ -z $QUITIT ]
do
echo -e "\n$PNCFG\n* Darkbot configuration menu *\n
1) Setup deop.ini and perform.ini files
2) Read the README files
3) Quit configuration"
echo -n "
Select one: "
read CHOICE
case $CHOICE in
1)
clear
echo -e "
* Darkbot configuration menu *
The .ini's are all in RAW format... so when you
want the bot to MSG your channel \"hello!\", you'd
have to enter something like:
PRIVMSG $CHAN :hello!
(Note the :colon after $CHAN, it is required)
Check http://darkbot.sourceforge.net for examples
The first .ini you will need to setup, is the perform.ini.
Perform list is a set of commands you'd like your Darkbot
to do when it connects online. This can range from /msging
the channel service login commands (so your Darkbot can
auto get ops), to /joining other channels....
You can later modify this list by editing the perform.ini
[ Hit ENTER to begin editing your perform.ini ]"
read x
$CFG_EDITOR dat/perform.ini
clear
echo -e "\n* Darkbot configuration menu * \n\n
Okay, next is the deop.ini, the format is the same as
perform.ini. What deop.ini is, is a list of commands
you would like your darkbot to do, when it finds itself
deoped in $CHAN. This can range from /msging $CHAN OP ME!
to using other bots/channel services to regain ops.
\n[ Hit ENTER to begin editing your deop.ini ]"
read x
$CFG_EDITOR dat/deop.ini
clear
;;
2)
clear
echo -e "\n$PNCFG\n* reading documents *\n\n
First take a look at the README file...
(use arrow keys to scroll and press Q when you are done)
\n[ Hit ENTER to continue ]"
read PTR
cat README.txt | less -deXF
clear
echo -e "\n$PNCFG\n* reading documents *\n\n
You should take a look also on README_UTILS file...
(use arrow keys to scroll and press Q when you are done)
\n[ Hit ENTER to continue ]"
read PTR
cat docs/README_UTILS | less -deXF
clear
echo -e "\n$PNCFG\n* reading documents *\n\n
Check out what is new in Darkbot!
(use arrow keys to scroll and press Q when you are done)
\n[ Hit ENTER to continue ]"
read PTR
cat docs/WHATSNEW | less -deXF
clear
echo -e "\n$PNCFG\n* reading documents *\n\n
Finally, be aware of who makes this program possible.
(use arrow keys to scroll and press Q when you are done)
\n[ Hit ENTER to continue ]"
read PTR
cat docs/contributors.txt | less -deXF
;;
3)
clear
echo -e "\n$PNCFG * end of configuration *"
if [ ! -e "darkbot" ]; then
echo -e "\nThere is no darkbot binary present.
You'll need to compile the code for Darkbot to run."
else
# if defines.h were changed
if [ -n "$CFG_DEFINES_CHANGED" ]; then
echo -e "\nYour changes made on defines.h file will only take
effect after compiling the code!"
fi
sleep 1
fi
echo "
Darkbot is ready to compile.
If you get any error during compilation process recheck
the changes you made on defines.h reading the comments
next to each directive, starting at 'SYSTEM REQUIREMENTS'.
In case you run into problems, type 'make clean' then 'make
debug' following it's instructions and if Darkbot crashes
type 'backtrace' to find out exactly why it happened.
If you need further assistance use the support area of
http://darkbot.sourceforge.net for detailed information.
Linux/BSD/Unix/Win users type: make
"
sleep 1
QUITIT=yes
;;
*)
echo
if [ "$CHOICE" != 1-3 ]; then echo "That's not a valid selection. \
Select 1 or 2. 3 to quit."; fi
sleep 1
echo
clear
;;
esac
done
}
DB_REV () {
unset cfg_dbrev
cfg_dbrev="$(grep -r obkra sou*/*va*c|rev|tac|cut -d \" -f2|head -n1)"
if [ -z "$cfg_dbrev" ]; then cfg_dbrev=Darkbot; fi
}
START_CFG () {
# if there are no vars means didn't run before so do it all
ENVIRONMENT
DB_REV 2>/dev/null
CFG_INTRO
if [ -z "$CFG_EDITOR" ]; then
CFG_EDITOR
else
clear
echo "
$PNCFG
* Text Editor *
Looks like you have already chosen your default text editor.
Do you want to choose another one instead of '"$CFG_EDITOR"'?
"
echo -n "[ Type Y if you want to select another one or hit ENTER to proceed ] "
read EditorChoice
if [ "$EditorChoice" = "y" ] || [ "$EditorChoice" = "Y" ]; then
CFG_EDITOR
else
echo "
Bypassing editor choice..."; sleep 1
fi
fi
if [ -z "$CFG_DEFINES" ]; then
CFG_DEFINES
else
clear
echo "
$PNCFG
* DEFINES.h *
Do you want to edit your directives on defines.h again?
"
echo -n " [ Type Y if you want to edit defines.h or hit ENTER to proceed ] "
read DefinesChoice
if [ "$DefinesChoice" = "y" ] || [ "$DefinesChoice" = "Y" ]; then
CFG_DEFINES
else
echo "
Bypassing defines.h editing..."; sleep 1
fi
fi
# SETUP.INI -------------------
CFG_SETINI () {
CFG_CMDCHAR; CFG_NICK; CFG_USID; CFG_CHAN; CFG_RNAME; CFG_VHOST
CFG_WRITE_SETUP_INI
}
if [ -z "$CFG_SETUP_INI" ]; then
CFG_SETINI
else
clear
echo "
$PNCFG
* SETUP.ini *
This utility records show you have edited already your setup.ini file.
Do you want to change some settings?
"
echo -n "[ Type Y if you want to edit setup.ini again or hit ENTER to proceed ] "
read SetupChoice
if [ "$SetupChoice" = "y" ] || [ "$SetupChoice" = "Y" ]; then
CFG_SETINI
else
echo "
Bypassing setup.ini configuration..."; sleep 1
fi
fi
CFG_ADDSERVER
CFG_ADDUSER
CFG_MENU
}
START_CFG
exit 0
diff --git a/scripts/check-integrity b/scripts/check-integrity
index 899c928..2dde783 100755
--- a/scripts/check-integrity
+++ b/scripts/check-integrity
@@ -1,2209 +1,2219 @@
#! /bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PNCI="\nDarkbot Database File Integrity\n<*************_~_*************>\n"
PID=0624233000
SLEEP () { SLEEP=$(sleep $1); }
#cd scripts 2>/dev/null
# to do: function to remove comments from shell utils and c files
# removal of pre-made databases (in conjunction w/download-databases)
# set -x # debug only
USAGE () {
clear
echo -e >&2 "\n$PNCI Checks Darkbot data files for errors.\n
Usage: `basename $0` <file|s|all> [-option|s]
(file triggers are: all; info2; servers; setup; perform; userlist; random)
Options:
-h Shows this brief usage help (read README_UTILS for detailed info)
-quick Speeds up the process bypassing pauses (sleep instances)
-nointro Bypasses introductory information (a)
-report Shows report file contents
-topicsize sets info2.db's topic length (default 50) (a)(b)
-replysize sets info2.db's reply length (default 400) (a)(b)
-default Returns program to it's default values removing all options
(a) The values of these options will be retained unless you use -default
(b) Only necessary if you have a different length then the one on defines.h
WARNING: Darkbot must be offline for most of saved information be effective!
exs:
$0 all Starts utility in full mode
$0 info2 Checks info2.db in normal operation
$0 userlist -quick Checks userlist.db bypassing pauses\n
Support: http://darkbot.sourceforge.net\n"
exit 1
}
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $0 ...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
ENVIRONMENT () {
cd scripts 2>/dev/null
BASE_WORKDIR=.scriptutils
COMMON_TMP=$BASE_WORKDIR/tmp
mkdir -p $BASE_WORKDIR/tmp
TMP=$BASE_WORKDIR/._tmp/ci$$
mkdir -p $BASE_WORKDIR/._tmp/
ci_vars=$BASE_WORKDIR/.ci_vars
if [ -e "$ci_vars" ]; then
. "$ci_vars"; fi
ci_report=$BASE_WORKDIR/integrity-report
trap 'rm -fr $COMMON_TMP >/dev/null; rm -fr $BASE_WORKDIR/._tmp* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
# SLEEP () { SLEEP=$(sleep $1); }
}
# test environment
TESTDEPEND () {
NonFatalError () {
echo "FATAL ERROR at $0 (`date`): $FiLe not detected \
on this system." >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNCI\nFATAL ERROR at $0 (`date`)\n\n
$FiLe not detected on this system.
It is essential for $0 to work properly."
ABORT
}
if ! (type "$1" 1>/dev/null 2>&1); then
FiLe="$1"
NonFatalError $1
sleep 1; unset $FiLe
fi
}
TESTDEPEND_GO () {
TESTDEPEND "grep"; TESTDEPEND "sed"; TESTDEPEND "cut"; TESTDEPEND "tee"
TESTDEPEND "wc"; TESTDEPEND "tr"; TESTDEPEND "cat"; TESTDEPEND "expr"
}
CI_INTRO () {
count=30; counter=1
while [ $count != "$counter" ]; do
count=`expr "$count" - 1`
clear
echo -e "$PNCI
This information will vanish in ["$count"] seconds...\n
This utility executes a considerable amount of operations during
file integrity verification. It depends on the size of the files
to be checked and errors to correct the time it takes to perform
all it's functions with accuracy.
All process is done without user intervention, so be patient and
wait until it is done or leave it working and check afterwards
it's final results on the integrity-report file or by typing
$0 -report.
If you are in a rush type $0 -quick (fast mode).\n
If you get wrong results on final counts due to unpredictable
characters or symbols you might have on your files please help
us correct the problem by participating it on the web page.\n
For detailed information about this utility read README_UTILS.\n
To bypass this introduction write $0 -nointro
To abort all operations at any time press CTRL + C"
SLEEP 1
done
}
LINE_FEED () {
# just for diagnose since DELEMPTY_LINES will fix any eventual problem
clear
echo -e "$PNCI* Line Feed *\n
Checking for missing line feed at the end of file contents...\n"
unset line_feed
if [ "$(tail -n1 $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')" = \
"0" ]; then
echo "- Detected missing Line Feed at the end of $ORIG_FILE!" \
| tee -a $TMP-LINE_FEED.$ORIG_FILE.rep.head
line_feed=y
else
echo "- No missing line feed detected at the end of $ORIG_FILE!" \
| tee -a $TMP-LINE_FEED.$ORIG_FILE.rep.head
fi
SLEEP 4
}
EMPTY_LINES () {
clear
echo -e "$PNCI* Empty Lines *\n
Checking for empty lines on $ORIG_FILE...\n"
SLEEP 1
# check numb lines if not done b4
if [ -z "$numLinesORI" ]; then
numLinesORI=$(cat $ORIG_PATH | wc -l | tr -cd '[:alnum:]')
fi
# added this in case info2.db is empty and the working file is an imported db
if [ ! -z "$numLinesORI" ] || [ "$numLinesORI" != "0" ]; then
numLinesORI=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
fi
# if detected no line feed actual lines will be + 1
if [ "$line_feed" = "y" ]; then
numLinesORI="`expr $numLinesORI + 1`"
CHANGED=""$CHANGED" "$ORIG_FILE""
fi
# clean empty
grep '.' $TMP-DB.WORK.FILE > $TMP-DB.WORK.FILE_TMP
mv -f $TMP-DB.WORK.FILE_TMP $TMP-DB.WORK.FILE
#check numb lines after
numLinesNOW=$(cat "$TMP-DB.WORK.FILE" | wc -l | tr -cd '[:alnum:]')
# REPORT
# a quick report
echo "EMPTY LINES on "$ORIG_FILE"" > $TMP-EMPTY_LINES.$ORIG_FILE.rep.head
if [ "$numLinesORI" != "$numLinesNOW" ]; then
CHANGED=""$CHANGED" "$ORIG_FILE""
numLinesORI_NOW=$(expr $numLinesORI - $numLinesNOW 2>/dev/null)
echo "- Total found - ["$numLinesORI_NOW"] Lines before = "$numLinesORI"\
Lines after = "$numLinesNOW"" | tee -a $TMP-EMPTY_LINES.$ORIG_FILE.rep.head
line_s=$(if [ "$numLinesORI_NOW" -gt "1" ]; then echo lines
else echo line; fi)
echo -e "\nRemoved "$numLinesORI_NOW" empty "$line_s"!"
else
echo "- No empty lines found!" | tee -a $TMP-EMPTY_LINES.$ORIG_FILE.rep.head
fi
SLEEP 4
}
INCOMPL_ENTRIES () {
# checks for lines with only 1 word followed by carriage return
clear
echo -e "$PNCI* Incomplete Entries *\n
Checking for topics with no replies on $ORIG_FILE...\n"
SLEEP 1
grep -ne '^ *[^ ]\+$' $TMP-DB.WORK.FILE > $TMP-noreply
noreply_lines=$(cat $TMP-noreply | wc -l | tr -cd '[:alnum:]')
if [ "$noreply_lines" != "0" ]; then
echo -e " Total found - [$noreply_lines]\n"
# removing it
echo -e "sed '" > $TMP-noreply.to.be.deleted
sed s/:/d' '/ $TMP-noreply | cut -d' ' -f1 >> $TMP-noreply.to.be.deleted
echo -e "' $TMP-DB.WORK.FILE > $TMP-noreply.deleted" >> \
$TMP-noreply.to.be.deleted
echo -e "Removing it...\n"
. $TMP-noreply.to.be.deleted
mv -f $TMP-noreply.deleted $TMP-DB.WORK.FILE
entry_pl=$(if [ "$noreply_lines" -gt "1" ]; then echo entries
else echo entry; fi)
echo -e "Removed "$noreply_lines" incomplete "$entry_pl" from \
$ORIG_FILE!\n"
fi
# REPORT
echo -e "INCOMPLETE ENTRIES (no topic or reply)" > \
$TMP-INCOMPL_ENTRIES.rep.head
if [ -s $TMP-noreply ]; then
echo -e "- Incomplete entries found: "$noreply_lines"" >> \
$TMP-INCOMPL_ENTRIES.rep.head
echo "(Check section \"Removed INCOMPLETE ENTRIES from $ORIG_FILE\" \
on this file)" >> $TMP-INCOMPL_ENTRIES.rep.head
echo -e "===== Removed INCOMPLETE ENTRIES from $ORIG_FILE
`cut -d: -f2- $TMP-noreply`
_______________________ end of incomplete entries \
_______________________" > $TMP-INCOMPL_ENTRIES.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "- No incomplete entries found!" | tee -a \
$TMP-INCOMPL_ENTRIES.rep.head
fi
SLEEP 4
}
DUP_ENTRIES () {
clear
echo -e "$PNCI* Duplicate Entries *\n
Checking for duplicate entries on $ORIG_FILE ..."
SLEEP 1
# get duplicate lines - 1 item per dups on a vertical list ( for infos)
sort $TMP-DB.WORK.FILE | uniq -di > $TMP.dup.entries
# count number of lines that have repeated replies
dupentries_lines=$(cat $TMP.dup.entries | wc -l | tr -cd '[:alnum:]')
# if there are dup entries proceed with deletion and report
if [ -s $TMP.dup.entries ]; then
# just a condition for entry/entries
if [ "$dupentries_lines" -gt "1" ]; then ENTRY_pl=entries
else ENTRY_pl=entry
fi
echo -e "\n Total found - ["$dupentries_lines"]\n"
# get total num of lines on the main file before entry deletion; used on infos
dupentries_lin_bef=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
#DELETE
# execute uniq - produce final file without repeats
echo -e "Removing it..."
#duplicate "$dupentries_lines" $ENTRY_pl from $ORIG_FILE..."
sort $TMP-DB.WORK.FILE | uniq -i > $TMP-DB.WORK.FILE-TMP
mv -f $TMP-DB.WORK.FILE-TMP $TMP-DB.WORK.FILE
# COUNTS
# count main after
dupentries_lin_aft=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
# result - count amount of repetitions ( lines extracted )
dupentries_lin_rem=$(expr "$dupentries_lin_bef" - "$dupentries_lin_aft")
if [ "$dupentries_lin_rem" -gt "1" ]; then
echo -e "\nRemoved all "$dupentries_lin_rem" repetitions of \
"$dupentries_lines" $ENTRY_pl from $ORIG_FILE!"
else
echo -e "\nRemoved "$dupentries_lin_rem" repetition of \
"$dupentries_lines" $ENTRY_pl from $ORIG_FILE!"
fi
fi
# REPORT
if [ -s $TMP.dup.entries ]; then
echo "DUPLICATE ENTRIES
- Number of entries with repetitions: "$dupentries_lines"
- Number of repetitions found: "$dupentries_lin_rem"
- Number of lines removed: "$dupentries_lin_rem"
(Check section \"Removed DUPLICATE ENTRIES from $ORIG_FILE\" on this file)" \
> $TMP-DUP_ENTRIES.$ORIG_FILE.rep.head
echo -e "===== Removed DUPLICATE ENTRIES from "$ORIG_FILE"" > \
$TMP-DUP_ENTRIES.$ORIG_FILE.rep.body
cat $TMP.dup.entries >> $TMP-DUP_ENTRIES.$ORIG_FILE.rep.body
echo "_______________________ end of duplicate entries \
________________________" >> $TMP-DUP_ENTRIES.$ORIG_FILE.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo
echo "- No repeated entries found!" \
| tee -a $TMP-DUP_ENTRIES.$ORIG_FILE.rep.head
fi
SLEEP 4
}
DUP_TOPICS () {
clear
echo -e "$PNCI* Duplicate Topics *\n
Checking for duplicate topics on $ORIG_FILE ...\n"
SLEEP 1
# get a list of all dups (including repetitions) and line numbers
grep -n . $TMP-DB.WORK.FILE | cut -d' ' -f1 | sed s/:/' '/ | sort +1 | \
uniq -iD -f1 > $TMP.dup.topics
# count number of lines with repeated topics
duptopics_lines=$(cat $TMP.dup.topics | wc -l | tr -cd '[:alnum:]')
# if there are dup topics proceed with deletion and report
if [ -s $TMP.dup.topics ]; then
# get total num of lines on the main file before entry deletion; used on infos
duptopics_lin_bef=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
# get only 1 line of repeats (2nd column on this 1) then sort it/numerical order# this file will have lines not to be removed from main file
# i.e., 1 of the dups needs to be kept on the main file
uniq -id -f1 $TMP.dup.topics | cut -d' ' -f1 | sort -g > $TMP-duptopics.uniques
duptopics_uniques=$(cat $TMP-duptopics.uniques | wc -l | tr -cd '[:alnum:]')
duptopics_repetitions=$(expr "$duptopics_lines" - "$duptopics_uniques")
# condition for topic/topics repetition/s etc
topic_s="$(if [ "$duptopics_uniques" -gt "1" ]; then echo topics; \
dbs_plural=y; else echo topic; dbs_plural=n; fi)"
repetition_s="$(if [ "$duptopics_repetitions" -gt "1" ]; then echo repetitions; \
else echo repetition; fi)"
echo -e " Detected a total of "$duptopics_repetitions" $repetition_s on \
$duptopics_uniques $topic_s!"
if [ "$duptopics_repetitions" -gt 250 ]; then
echo -e "That's a huge amount of repetitions.
This process envolves several operations and can take some time to complete."
fi
echo -e "\n Please wait...\n"
# sort file $TMP.dup.topics so next step will not be a mess
cut -d' ' -f1 $TMP.dup.topics | sort -g > $TMP-duptopics.sorted
entry_ies="$(if [ "$repetition_s" = "repetitions" ]; then echo "entries"; \
else echo "entry"; fi)"
echo -e " Marking "$entry_ies" to be removed...\n"
# compare with diff then extract only lines to be removed from main file
diff -y $TMP-duptopics.sorted $TMP-duptopics.uniques | grep "<" | \
sed s/[[:blank:]]*[\<$]// > $TMP-duptopics.2b.del
# DELETE from main file
# prepare sed operations
echo "sed '" > $TMP-duptopics.2.del
sed 's/$/d/' $TMP-duptopics.2b.del >> $TMP-duptopics.2.del
echo "' $TMP-DB.WORK.FILE > $TMP-topic.lines.deleted" >> $TMP-duptopics.2.del
duplicate_s="$(if [ "$repetition_s" = "repetitions" ]; then echo \
"all "$duptopics_repetitions" duplications"; else echo \
""$duptopics_repetitions" duplication"; fi)"
echo -e " Trying to remove "$duplicate_s" from $ORIG_FILE..."
# execute the file
. $TMP-duptopics.2.del
## move file w/deletes to working file
mv -f $TMP-topic.lines.deleted $TMP-DB.WORK.FILE
# COUNTS
# count main after
duptopics_lin_aft=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
# result - count amount of repetitions ( lines extracted )
duptopics_lin_rem=$(expr "$duptopics_lin_bef" - "$duptopics_lin_aft")
# compare lines on file from total antecipated lines 2 be removed
if [ "$duptopics_lin_rem" = "$duptopics_repetitions" ]; then
if [ "$duptopics_lin_rem" -gt "1" ]; then
echo -e "\nRemoved all "$duptopics_lin_rem" repetitions of \
"$duptopics_uniques" "$topic_s" from $ORIG_FILE!"
else
echo -e "\nRemoved "$duptopics_lin_rem" repetition of \
"$duptopics_uniques" $topic_s from $ORIG_FILE!"
fi
else
echo -e "There is a discrepancy between what was antecipated to be removed
("$duptopics_repetitions $repetition_s") and what whas actually removed \
("$duptopics_lin_rem").
That can be caused by some symbols or characters on your $ORIG_FILE
which are creating a conflict with this utility.
Check $ci_report and compare the results
with what you have in your file."
fi
fi
# REPORT
if [ -s $TMP.dup.topics ]; then
echo -e "\nPlease wait while a copy of all removed entries is being made
and a report generated..."
SLEEP 2
echo "DUPLICATE TOPICS
- Number of topics with repetitions: "$duptopics_uniques"
- Number of repetitions found: "$duptopics_repetitions"
- Number of lines removed: "$duptopics_lin_rem"" > \
$TMP-DUP_TOPICS.rep.head
echo "(You'll find on DUPLICATE TOPICS section of this file all removed entries
in case you would like to modify it and then reinsert it on it's previous
location. One entry with the same topic was left on your $ORIG_FILE file)" \
>> $TMP-DUP_TOPICS.rep.head
if [ "$duptopics_repetitions" != "$duptopics_lin_rem" ]; then
echo -e "##### WARNING #####\nWrong result: Removed \
"$duptopics_lin_rem" of "$duptopics_repetitions" repetitions on \
"$duptopics_uniques" topics.
Check the corresponding section of this file and compare the results with
your $ORIG_FILE file. Data with unpredictable characters might be causing
the difference. If you discover the cause please contact us at the official site
and if possible attach the file."
fi >> $TMP-DUP_TOPICS.rep.head
echo -e "===== Removed DUPLICATE TOPICS from "$ORIG_FILE"" > \
$TMP-DUP_TOPICS.rep.body
# prepare sed operations
echo "sed -n '" > $TMP.report_duptopics_0
sed 's/$/p/' $TMP-duptopics.2b.del >> $TMP.report_duptopics_0
echo "' $TMP-DB.WORK.FILE >> $TMP-DUP_TOPICS.rep.body" >> \
$TMP.report_duptopics_0
# execute sed
. $TMP.report_duptopics_0
echo "________________________ end of duplicate topics \
________________________" >> $TMP-DUP_TOPICS.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "- No duplicate topics found." | tee -a $TMP-DUP_TOPICS.rep.head
fi
SLEEP 5
}
TOPIC_SIZE () {
# checks max length your database topics
# topics + than 400 chars or whatever is set on defines.h's
# define TOPIC_SIZE
clear
echo -e "$PNCI* Maximum Topic Size/Length *\n
Checking maximum character length of the topics entries on $ORIG_FILE...\n"
# if no var with size go for defines.h. if no defimes.h assume 400
if [ ! -n "$TOPIC_SIZE" ]; then
# get defines.h setting if existent
TOPIC_SIZE="$(sed -n '/MAX_TOPIC_SIZE/s/#define[[:blank:]]MAX_TOPIC_SIZE//p' \
../source/defines.h 2>/dev/null | tr -cd '[:alnum:]')"
if [ ! -n "$TOPIC_SIZE" ]; then
echo -e "Unable to obtain configured maximum topic lenght allowed.
Assuming default value of 400 characters...\n
If this is not the setting you actually have please press CTRL + C to abort
and write $0 -topic_size to set the default for this utility.\n"
TOPIC_SIZE=50
SLEEP 2
else
echo -e "Your defined maximum topic length is "$TOPIC_SIZE" characters."
fi
fi
# get max topic length on file
ACTUAL_TOPIC_SIZE=$(cat $TMP-DB.WORK.FILE | cut -d' ' -f1 | wc -L \
| tr -cd '[:alnum:]')
# size+1 - ( if TOPIC_SIZE this will put it as 401
# because what we need is remove all exceeding max length, i.e, 401&+)
TOPIC_SIZE_PLUS_1=`expr $TOPIC_SIZE + 1`
# if length in file is greater than max size... work on it
if [ "$ACTUAL_TOPIC_SIZE" -gt "$TOPIC_SIZE" ]; then
echo -e "- Currently your longest topic (length) is: \
"$ACTUAL_TOPIC_SIZE" characters \n"
SLEEP 1
echo -e "Please wait while the total number of topics exceeding maximum
character lenght allowed is being obtained..."
SLEEP 1
# get all over length
cat $TMP-DB.WORK.FILE | grep -nE '^.[^ ]{'$TOPIC_SIZE',}' \
> $TMP-topic.size.all
if [ -s $TMP-topic.size.all ]; then # we have entries in fault
# get only line numbers ( will be needed to report file )
cut -d: -f1 $TMP-topic.size.all > $TMP-topic.size.all.numb
# get number of lines on working file (later will be used to check if
# operations went right
NUM_LINES_B4=$(cat "$TMP-DB.WORK.FILE" | wc -l | tr -cd '[:alnum:]')
# count total before deletion
NUM_TOPICS_EXCEEDING_SIZE=$(cat "$TMP-topic.size.all.numb" | wc -l \
| tr -cd '[:alnum:]')
echo -e "- Total entries with topic length exceeding size found: \
"$NUM_TOPICS_EXCEEDING_SIZE"\n"
SLEEP 2
echo "Preparing for deletion process..."
SLEEP 1
echo "sed '
`cat $TMP-topic.size.all | sed s/:/d' '/ | cut -d' ' -f1`
' $TMP-DB.WORK.FILE > $TMP-topic.size.deleted" >> $TMP-topic.size.lines.to.del
echo -e "Removing it ..."
SLEEP 1
# execute
. $TMP-topic.size.lines.to.del
# move it to working file
mv -f $TMP-topic.size.deleted $TMP-DB.WORK.FILE
entry_pl=$(if [ "$NUM_TOPICS_EXCEEDING_SIZE" -gt "1" ]; \
then echo entries; else echo entry; fi)
echo -e "Removed "$NUM_TOPICS_EXCEEDING_SIZE" "$entry_pl" from \
"$ORIG_FILE"!\n"
fi # end of -s $TMP-topic.size.all
else # "$ACTUAL_TOPIC_SIZE" is not greater than "$TOPIC_SIZE"
echo -e "\nYour topic's length is within your current configuration
value, which is "$TOPIC_SIZE" characters maximum.\n\n"
SLEEP 3
fi
# REPORT
if [ -s $TMP-topic.size.all ]; then
# first check from the working file
NUM_LINES_AFTER=$(cat "$TMP-DB.WORK.FILE" | wc -l | tr -cd '[:alnum:]')
NUM_LINES_NOW="$(expr "$NUM_LINES_B4" - "$NUM_LINES_AFTER")"
NUM_LINES_DIFF="$(expr "$NUM_TOPICS_EXCEEDING_SIZE" - "$NUM_LINES_NOW")"
# report head top
echo "TOPICS LENGTH" > $TMP-TOPIC_SIZE.rep.head
if [ "$NUM_LINES_NOW" != "0" ]; then # means at least some were removed
# check if are the same as the ones that were supposed too
if [ "$NUM_LINES_NOW" = "$NUM_TOPICS_EXCEEDING_SIZE" ]; then # looks ok
# report header
echo "- Allowed length = "$TOPIC_SIZE" \
Maximum lenght detected = "$ACTUAL_TOPIC_SIZE"
- Entries exceeding configured value = "$NUM_TOPICS_EXCEEDING_SIZE"
- Total entries removed = "$NUM_LINES_NOW""
# report body
echo -e "\n===== Removed TOPICS LENGTH exceeding allowed value on \
"$ORIG_FILE"
`cat $TMP-topic.size.all | cut -d: -f2-`
________________ end of topics with maximum length exceeded \
__________________" > $TMP-TOPIC_SIZE.rep.body
else # something wrong, diff of lines on working file don't match total 2b del
echo "$NUM_LINES_DIFF entries were not removed! Please check report file."
fi
else # final lines count on working file is = 0 so no lines were removed
echo "Something went wrong... not possible to remove entries.
Check report file."
fi
CHANGED=""$CHANGED" "$ORIG_FILE""
else # (-s $TMP-topic.size.all) no entries in fault
echo -e "No topics exceeding maximum length allowd found!"
fi >> $TMP-TOPIC_SIZE.rep.head
SLEEP 5
}
DATA_SIZE () {
# checks max length your database replies
# replies + than 400 chars or whatever is set on defines.h's
# define DATA_SIZE
clear
echo -e "$PNCI* Maximum Reply Size/Length *\n
Checking maximum character length of the replies entries on $ORIG_FILE...\n"
# if no var with size go for defines.h. if no defimes.h assume 400
if [ ! -n "$DATA_SIZE" ]; then
# get defines.h setting
DATA_SIZE="$(sed -n '/MAX_DATA_SIZE/s/#define[[:blank:]]MAX_DATA_SIZE//p' \
../source/defines.h 2>/dev/null | tr -cd '[:alnum:]')"
if [ ! -n "$DATA_SIZE" ]; then
echo -e "Unable to obtain configured maximum reply lenght allowed.
Assuming default value of 400 characters...\n
If this is not the setting you actually have please press CTRL + C to abort
and write $0 -data_size to set the default for this utility.\n"
DATA_SIZE=400
SLEEP 2
else
echo -e "Your defined maximum reply length is "$DATA_SIZE" characters."
fi
fi
# get max reply length on file
ACTUAL_DATA_SIZE=$(cat $TMP-DB.WORK.FILE | cut -d' ' -f2- | wc -L \
| tr -cd '[:alnum:]')
# size+1 - ( if DATA_SIZE this will put it as 401
# because what we need is remove all exceeding max length, i.e, 401&+)
DATA_SIZE_PLUS_1=`expr $DATA_SIZE + 1`
# if length in file is greater than max size... work on it
if [ "$ACTUAL_DATA_SIZE" -gt "$DATA_SIZE" ]; then
echo -e "---- Currently your longest reply (length) is: \
"$ACTUAL_DATA_SIZE" characters ----\n"
SLEEP 1
echo -e "Please wait while the total number of topics exceeding maximum
character lenght allowed is being obtained..."
SLEEP 1
# get length after 1st whitespace//assuming there's no whitspace in front
# cat $TMP-DB.WORK.FILE | grep -En '^[^ ]* +(.{400,})$'
cat $TMP-DB.WORK.FILE | grep -En '^ *[^ ]* +.{'$DATA_SIZE_PLUS_1',}$' \
> $TMP-data.size.all
if [ -s $TMP-data.size.all ]; then # we have entries in fault
# get only line numbers ( will be needed to report file )
cut -d: -f1 $TMP-data.size.all > $TMP-data.size.all.numb
# get number of lines on working file (later will be used to check if
# operations went right
NUM_LINES_B4=$(cat "$TMP-DB.WORK.FILE" | wc -l | tr -cd '[:alnum:]')
# count total before deletion
NUM_REPLIES_EXCEEDING_SIZE=$(cat "$TMP-data.size.all.numb" | wc -l \
| tr -cd '[:alnum:]')
echo -e "- Total entries with reply length exceeding size found: \
"$NUM_REPLIES_EXCEEDING_SIZE"\n"
SLEEP 2
echo "Preparing for deletion process..."
SLEEP 1
echo "sed '
`cat $TMP-data.size.all | sed s/:/d' '/ | cut -d' ' -f1`
' $TMP-DB.WORK.FILE > $TMP-data.size.deleted" >> $TMP-data.size.lines.to.del
echo -e "Removing it ..."
SLEEP 1
# execute
. $TMP-data.size.lines.to.del
# move it to working file
mv -f $TMP-data.size.deleted $TMP-DB.WORK.FILE
entry_pl=$(if [ "$NUM_REPLIES_EXCEEDING_SIZE" -gt "1" ]; \
then echo entries; else echo entry; fi)
echo -e "Removed "$NUM_REPLIES_EXCEEDING_SIZE" "$entry_pl" from \
"$ORIG_FILE"!\n"
fi # end of -s $TMP-data.size.all
else # "$ACTUAL_DATA_SIZE" is not greater than "$DATA_SIZE"
echo -e "\nYour replies length is within your current configuration
value, which is "$DATA_SIZE" characters maximum.\n\n"
SLEEP 3
fi
# REPORT
if [ -s $TMP-data.size.all ]; then
# first check from the working file
NUM_LINES_AFTER=$(cat "$TMP-DB.WORK.FILE" | wc -l | tr -cd '[:alnum:]')
NUM_LINES_NOW="$(expr "$NUM_LINES_B4" - "$NUM_LINES_AFTER")"
NUM_LINES_DIFF="$(expr "$NUM_REPLIES_EXCEEDING_SIZE" - "$NUM_LINES_NOW")"
# report head top
echo "REPLIES LENGTH" > $TMP-DATA_SIZE.rep.head
if [ "$NUM_LINES_NOW" != "0" ]; then # means at least some were removed
# check if are the same as the ones that were supposed too
if [ "$NUM_LINES_NOW" = "$NUM_REPLIES_EXCEEDING_SIZE" ]; then # looks ok
# report header
echo "- Allowed length = "$DATA_SIZE" \
Maximum lenght detected = "$ACTUAL_DATA_SIZE"
- Entries exceeding configured value = "$NUM_REPLIES_EXCEEDING_SIZE"
- Total entries removed = "$NUM_LINES_NOW""
# report body
echo -e "\n===== Removed REPLIES LENGTH exceeding allowed value on \
"$ORIG_FILE"
`cat $TMP-data.size.all | cut -d: -f2-`
________________ end of replies with maximum length exceeded \
__________________" > $TMP-DATA_SIZE.rep.body
else # something wrong, diff of lines on working file don't match total 2b del
echo "$NUM_LINES_DIFF entries were not removed! Please check report file."
fi
else # final lines count on working file is = 0 so no lines were removed
echo "Something went wrong... not possible to remove entries.
Check report file."
fi
CHANGED=""$CHANGED" "$ORIG_FILE""
else # (-s $TMP-data.size.all) no entries in fault
echo -e "No replies exceeding maximum length allowd found!"
fi >> $TMP-DATA_SIZE.rep.head
SLEEP 5
}
# check for entries without related rdb files
CHECK_RDBS () {
clear
echo -e "$PNCI* RDB links and files *\n
Checking for RDB entries on $ORIG_FILE ...\n"
SLEEP 1
# extract possible rdbs links
sed -n /[[:space:]]~[[:alnum:]]/p "$TMP-DB.WORK.FILE" > $TMP-rdb.lines.all
if [ -s $TMP-rdb.lines.all ]; then
# count total
rdb_lines_all=$(cat $TMP-rdb.lines.all | wc -l | tr -cd '[:alnum:]')
# examine which ones are really rdb links and extract uniques
count="0"
while [ $count != "$rdb_lines_all" ]; do
count=`expr $count + 1`
# just a progress ind.
clear; echo -e "$PNCI* RDB links and files *\n
Examining existent RDB links on your $ORIG_FILE...\n"
if [ $count != "$rdb_lines_all" ]; then
echo -e " [`expr $count \* 100 / $rdb_lines_all`%] done\n"
fi
# extract line by line (all lines even ones that are not rdbs)
rdb_line="$(sed -n "$count"p $TMP-rdb.lines.all)"
# if = 2 words -> is a rdb
if [ "`echo "$rdb_line" | wc -w | tr -cd '[:alnum:]'`" = "2" ]; then
# put it on a list
echo "$rdb_line" >> $TMP-rdb.lines.with.repeats
fi
done
SLEEP 3
fi # end of if there are entries with leading ~
# if there are indeed rdb links (count uniques, repeats and extract only links)
if [ -s $TMP-rdb.lines.with.repeats ]; then
# count total (with) repeats
rdb_lines_with_repeats=$(cat $TMP-rdb.lines.with.repeats | wc -l \
| tr -cd '[:alnum:]')
entry_s=$(if [ "$rdb_lines_with_repeats" -gt "1" ]; then echo entries
else echo entry; fi)
echo -e " So far detected "$rdb_lines_with_repeats" "$entry_s" \
with RDB links..."
SLEEP 1
# extract only links; sort; uniq
cat $TMP-rdb.lines.with.repeats | cut -d ' ' -f2 | sort | uniq > \
$TMP-rdb.lines.uniques
# count total uniques
rdb_lines_uniques=$(cat $TMP-rdb.lines.uniques | wc -l | tr -cd '[:alnum:]')
link_s=$(if [ "$rdb_lines_uniques" -gt "1" ]; then echo links
else echo link; fi)
echo -e " Detected "$rdb_lines_with_repeats" "$entry_s" with \
"$rdb_lines_uniques" unique RDB "$link_s"!"
SLEEP 1
fi
# check which rdb files exist on ../dat/
ls ../dat/*.rdb > $TMP-rdb.files.all
# remove whut and dunno, not needed for first operation
grep -vw whut.rdb $TMP-rdb.files.all > $TMP-rdb.files.tmp
grep -vw dunno.rdb $TMP-rdb.files.tmp > $TMP-rdb.files
# count total rdb files for info (before matching)
if [ -s $TMP-rdb.files ]; then
rdb_files_b4=$(cat $TMP-rdb.files | wc -l | tr -cd '[:alnum:]')
file_s=$(if [ "$rdb_files_b4" -gt "1" ]; then echo files; else echo file; fi)
echo -e " Found "$rdb_files_b4" RDB "$file_s" on ..dat/ directory!"
SLEEP 3
# check which links don't have a file
if [ ! -z "$rdb_lines_uniques" ]; then
count="0"
while [ $count != "$rdb_lines_uniques" ]; do
count=`expr $count + 1`
# extract line by line
rdb_line="$(sed -n "$count"p $TMP-rdb.lines.uniques)"
# just a progress ind.
clear; echo -e "$PNCI* RDB links and files *\n
Comparing RDB links from your $ORIG_FILE with \
existent RDB files.\n"
echo " Processing RDB link: $rdb_line ..."
if [ $count != "$rdb_lines_uniques" ]; then
echo -e " [`expr $count \* 100 / $rdb_lines_uniques`%] done\n"
else
echo -e " Done!\n"; fi
# extract rdb link with no leading ~
rdb_link="`echo "$rdb_line" | cut -d' ' -f2 | cut -d~ -f2`"
# compare with the rdb files
# # # test this one better # # #
if [ `grep -w $rdb_link $TMP-rdb.files` ]; then
# means there is a corresponding file
# remove that file from files list so the ones left need to be
# checked because might not have any entry on info2
grep -wv $rdb_link $TMP-rdb.files > $TMP-rdb.files.tmp
mv -f $TMP-rdb.files.tmp $TMP-rdb.files
else
# there is no match; put the line on a file for deletion and report
# first all corresponding link lines with respective number
grep -nw "[[:space:]]*$rdb_line" "$TMP-DB.WORK.FILE" 2>/dev/null >> \
$TMP-rdb.nomatch.all
# then only that link
echo "$rdb_line" >> $TMP-rdb.nomatch.unique
fi
done
SLEEP 3
fi # if [ ! -z "$rdb_lines_uniques" ]; then
fi # if [ -s $TMP-rdb.files ]; then
# count total files without match (the ones left out)
if [ -s "$TMP-rdb.files" ]; then
rdb_files=$(cat $TMP-rdb.files | wc -l | tr -cd '[:alnum:]')
echo -e " Found "$rdb_files" RDB files without any match.\n"
SLEEP 2
fi
if [ -s $TMP-rdb.nomatch.unique ]; then
# count total unique link lines (without repeats) without match
rdb_nomatch_unique=$(cat $TMP-rdb.nomatch.unique | wc -l | tr -cd '[:alnum:]')
echo " Found "$rdb_nomatch_unique" unmatched unique RDB links."
SLEEP 1
# count total links lines (with repeats) without match
rdb_nomatch_all=$(cat $TMP-rdb.nomatch.all | wc -l | tr -cd '[:alnum:]')
echo " (A total of "$rdb_nomatch_all" related entries on $ORIG_FILE)"
SLEEP 1
# prepare a file for deletion and report process
cut -d: -f1 $TMP-rdb.nomatch.all > $TMP-rdb.nomatch.all.linenumb
# extract line/s to be deleted to a tmp file for report
# sed operations
echo "sed -n '" > $TMP-rdb.nomatch.all.2.report
sed 's/$/p/' $TMP-rdb.nomatch.all.linenumb >> $TMP-rdb.nomatch.all.2.report
echo "' "$TMP-DB.WORK.FILE" >> $TMP-CHECK_RDBS.rep.body.0" >> $TMP-rdb.nomatch.all.2.report
# execute sed
. $TMP-rdb.nomatch.all.2.report
# DELETE
echo -e "\nRemoving broken RDB links...\n"
SLEEP 3
# make file with line numbers for deletion
echo "sed '" > $TMP-rdb.nomatch.all.2.del
sed 's/$/d/' $TMP-rdb.nomatch.all.linenumb >> $TMP-rdb.nomatch.all.2.del
echo "' "$TMP-DB.WORK.FILE" > $TMP-rdb.nomatch.all.deleted" \
>> $TMP-rdb.nomatch.all.2.del
# execute it
. $TMP-rdb.nomatch.all.2.del
# move file w/deletes to working file
mv -f $TMP-rdb.nomatch.all.deleted $TMP-DB.WORK.FILE
link_s=$(if [ "$rdb_nomatch_unique" -gt "1" ]; then echo links
else echo link; fi)
echo -e "Removed "$rdb_nomatch_unique" unmatched RDB "$link_s" from \
$ORIG_FILE!"
SLEEP 3
fi # if there were no non matching rdbs
# end of main engine
# REPORT
clear
echo -e "$PNCI* RDB links and files *\n"
SLEEP 1
# report header links
RDBS_rep_head () {
echo "RDB LINKS AND FILES" | tee -a $TMP-CHECK_RDBS.rep.head
if [ ! -z "$rdb_lines_uniques" ]; then
echo "- Existent RDB unique links = $rdb_lines_uniques"
echo "- Existent RDB entries = $rdb_lines_with_repeats"
if [ ! -z "$rdb_nomatch_unique" ]; then
echo "- Total broken unique RDB links = $rdb_nomatch_unique"
echo "- Total entries with broken RDB links = $rdb_nomatch_all"
# make report body for broken links
echo -e "===== Removed BROKEN RDB LINKS from "$ORIG_FILE"" > \
$TMP-CHECK_RDBS.rep.body
cat $TMP-CHECK_RDBS.rep.body.0 >> $TMP-CHECK_RDBS.rep.body
echo "________________________ end of broken rdb links \
________________________" >> $TMP-CHECK_RDBS.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "- No broken RDB links found!"
fi
else
echo "- Existent RDB links = none found"
fi
# report header files
if [ ! -z "$rdb_files_b4" ]; then
echo "- Existent RDB files = $rdb_files_b4"
if [ ! -z "$rdb_files" ]; then
echo "- RDB files without any RDB lynk = $rdb_files (not removed)"
# make report body for files without rdb links
echo -e "\n===== RDB FILES WITHOUT MATCHING LINKS on $ORIG_FILE
----< NOT REMOVED from ../dat/ directory - do it yourself >----" >> \
$TMP-CHECK_RDBS.rep.body
cat $TMP-rdb.files >> $TMP-CHECK_RDBS.rep.body
echo "________________ end of rdb files without matching links \
__________________" >> $TMP-CHECK_RDBS.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
fi
else
echo "- Existent RDB files = none found"
fi
}
RDBS_rep_head | tee $TMP-CHECK_RDBS.rep.head
if [ ! -z "$rdb_nomatch_unique" ]; then
echo "(Check section \"Removed BROKEN RDB LINKS from "$ORIG_FILE"\" \
on this file)" >> $TMP-CHECK_RDBS.rep.head
fi
SLEEP 5
}
RANDOM_FILES () {
clear
echo -e "$PNCI* Random Phrases Files *\n\n
Preparing files for checking.\n
Please wait..."
_RM_RD_TOP_LINE () {
# function to make a var when Darkbot version is affected on the new format
# of random files where top line number is not needed anymore.
# Using backup_randomstuff as a search pattern since it was created on the
# same revision, RC4, instead of more complicate version extraction.
if [ "`grep 'BACKUP_RANDOMSTUFF' ../docs/WHATSNEW 2>/dev/null`" ] \
|| [ "`grep 'BACKUP_RANDOMSTUFF' ../source/defines.h 2>/dev/null`" ]; then
rm_rd_top_line="y"
fi
}
# this condition is here in case i'll decide to trigger this all process from
# (also) another utility, like live-update or configure, so revision will
# be analyzed there
if [ -z "$rm_rd_top_line" ]; then
_RM_RD_TOP_LINE
fi
# make a list of rdb files on dat directory
ls ../dat/*.rdb > $TMP-rd.files.all
# put random.ini and randomstuff.ini on the list of files to check
echo "../dat/random.ini" >> $TMP-rd.files.all
echo "../dat/randomstuff.ini" >> $TMP-rd.files.all
# count total number of lines on the list file
rd_files_all=$(cat $TMP-rd.files.all | wc -l | tr -cd '[:alnum:]')
SLEEP 2
# start checking
count="0"
while [ $count != "$rd_files_all" ]; do
count=`expr $count + 1`
# extract line by line
rd_file="$(sed -n "$count"p $TMP-rd.files.all)"
rd_file_name="$(echo "$rd_file" | cut -d/ -f3)"
# just a progress ind.
clear
echo -e "$PNCI* Random Phrases Files *\n
`expr "$rd_files_all" - "$count"` of "$rd_files_all" files to check. $(if \
[ $count != "$rd_files_all" ]; \
then echo " [`expr $count \* 100 / $rd_files_all`%] done."; \
else echo " Done!"; fi)"
echo -e "Processing "$rd_file_name"\n"
echo -e "Checking for missing line feed at the end of file contents ..."
SLEEP 1
# remove tmp errors file for a new cycle
rm -f $TMP-random.errors.rep.head
# prepare random.ini
if [ "$rd_file_name" = "random.ini" ]; then
grep -wv "^\/\*" ../dat/random.ini > $TMP-random.ini
grep -w "^\/\*" ../dat/random.ini > $TMP-random.ini.comments
rd_file="$TMP-random.ini"
fi
# check numb lines before
rd_numLinesORI=$(cat $rd_file | wc -l | tr -cd '[:alnum:]')
echo " Initial number of lines = "$rd_numLinesORI""
unset line_feed
if [ "$(tail -n1 $rd_file | wc -l | tr -cd '[:alnum:]')" = \
"0" ]; then
echo "- Detected missing Line Feed on the last line!" \
| tee -a $TMP-random.errors.rep.head
line_feed="y"
else
echo "- No missing line feed detected on the last line!"
fi
SLEEP 2
# if detected no line feed actual lines will be + 1
if [ "$line_feed" = "y" ]; then
rd_numLinesORI="`expr $rd_numLinesORI + 1`"
fi
# clean empty lines
echo -e "\nChecking for empty lines ..."
SLEEP 1
grep '.' $rd_file > $TMP-rd_file
# check numb lines after
rd_numLinesNOW=$(cat $TMP-rd_file | wc -l | tr -cd '[:alnum:]')
echo " Number of lines after checking = "$rd_numLinesNOW""
line_s=`if [ "$rd_numLinesNOW" -gt "1" ]; then echo lines; else echo line; fi`
# a quick report
if [ "$rd_numLinesORI" != "$rd_numLinesNOW" ]; then
rd_numLinesORI_NOW=$(expr "$rd_numLinesORI" - "$rd_numLinesNOW" 2>/dev/null)
echo " ### ERROR ###"
echo " Total lines before = "$rd_numLinesORI""
echo " Total lines after = "$rd_numLinesNOW""
echo "- Removed "$rd_numLinesORI_NOW" empty "$line_s"." \
| tee -a $TMP-random.errors.rep.head
echo
else
echo -e "- No empty lines found!\n"
fi
if [ "$line_feed" = "y" ]; then echo " (there is now an additional line \
due to the missing line feed)"; fi #| tee -a $TMP-random.errors.rep.head
SLEEP 1
echo "Checking top line number and random entries..."
SLEEP 1
# check number on top
top_rd_line= total_rd_lines=
top_rd_line=$(head -n1 "$TMP-rd_file" | grep ^[0-9])
total_rd_lines=$(cat "$TMP-rd_file" | wc -l | tr -cd '[:alnum:]')
if [ -n "$top_rd_line" ]; then # there is a number
# if the file being checked is not the only one not in need to remove the line
# on top with the number, which is random.ini, and Darkbot version being checked
# is not prior to the one where top line number is not needed anymore...
if [ "$rd_file_name" = "random.ini" ] || [ $rm_rd_top_line != "y" ]; then
# proceed, it's not included on the files to remove top line
# count lines - subtract 1 from total so top line is not counted
echo " Existent top line number = "$top_rd_line""
rd_lines=$(expr "$total_rd_lines" - 1 2>/dev/null)
echo " Total number of random entries = "$rd_lines""
if [ "$top_rd_line" != "$rd_lines" ]; then # is not the same so it's wrong
echo -e " ### ERROR ### Total line number is not correct!\n Fixing it..."
echo "$rd_lines" > $TMP-fixed.rd.lines
sed 1d "$TMP-rd_file" >> $TMP-fixed.rd.lines
mv -f $TMP-fixed.rd.lines "$TMP-rd_file"
echo "- Replaced top number of random entries from "$top_rd_line" \
to "$rd_lines"" | tee -a $TMP-random.errors.rep.head
else
echo -e "- Random number correct!\n"
fi
else # if $rd_file_name isnot "random.ini" & $rm_rd_top_line is y
# remove top line, it's not needed it on RC4 & +
sed 1d "$TMP-rd_file" >> $TMP-fixed.rd.lines
mv -f $TMP-fixed.rd.lines "$TMP-rd_file"
echo "- Removed top line with number of random entries, not \
needed anymore." | tee -a $TMP-random.errors.rep.head
fi
else # there is no line number on top so make a new file fixed
if [ "$rd_file_name" = "random.ini" ] || [ $rm_rd_top_line != "y" ]; then
# proceed, it's not included on the files to remove top line
echo " Total number of random entries = "$total_rd_lines""
echo -e " ### ERROR ### There is no total lines number on top!
Fixing it..."
echo "$total_rd_lines" > $TMP-fixed.rd.lines
cat "$TMP-rd_file" >> $TMP-fixed.rd.lines
mv -f $TMP-fixed.rd.lines "$TMP-rd_file"
echo "- Added missing total number of random entries of "$total_rd_lines"" \
| tee -a $TMP-random.errors.rep.head
else echo "- Nothing wrong with it. It's not present and it's not needed anymore."
fi
fi
# prep file for report with random file name and errors
if [ -s $TMP-random.errors.rep.head ]; then
echo " Random file "$rd_file_name"" >> $TMP-random.errors.rep.head0
cat $TMP-random.errors.rep.head >> $TMP-random.errors.rep.head0
# prep a file for backup and save
# replace random.ini comments
if [ "$rd_file_name" = "random.ini" ]; then
cat $TMP-rd_file >> $TMP-random.ini.comments
mv -f $TMP-random.ini.comments $TMP-$rd_file_name
else
mv -f $TMP-rd_file $TMP-$rd_file_name
fi
# backup file
echo "echo -e \"\nBacking up "$rd_file_name" before applying the changes...\"
cp -f $rd_file $rd_file.bak
echo \"Moving "$rd_file_name"'s working file to it's original location...\"
mv -f $TMP-$rd_file_name ../dat/$rd_file_name
SLEEP 1" >> $TMP-RANDOM_FILES
fi
echo -e "\nDone with "$rd_file_name"."
SLEEP 3
done
file_s="`if [ "$rd_files_all" -gt "1" ]; then echo files; else echo file; fi`"
# REPORT
# report header
echo "RANDOM PHRASES FILES CHECK
- line feed, empty lines and total entries number -
(only files with errors will be mentioned here)
Total files checked: $rd_files_all" > $TMP-RANDOM_FILES.rep.head
if [ -s $TMP-random.errors.rep.head0 ]; then
cat $TMP-random.errors.rep.head0 >> $TMP-RANDOM_FILES.rep.head
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo " No errors found on "$rd_files_all" "$file_s" checked!" \
| tee -a $TMP-RANDOM_FILES.rep.head
fi
SLEEP 4
}
SETUP_INI () {
clear
echo -e "$PNCI* setup.ini file *\n"
echo -e "\n - setup.ini file as is before been checked -"
cat $TMP-DB.WORK.FILE
SLEEP 3
echo -e "\nChecking contents of setup.ini file...\n"
SLEEP 1
# count words
numLinesSETUP=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
# count words
numWordsSETUP=$(cat $TMP-DB.WORK.FILE | wc -w | tr -cd '[:alnum:]')
# start checking values
if [ ! "`grep 'NICK=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "NICK=Darkbot"
Missing_Parm="$Missing_Parm""NICK "
else
grep 'NICK' $TMP-DB.WORK.FILE | tr -d ' '
fi > $TMP-DB.WORK.FILE.tmp
if [ ! "`grep 'USERID=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "USERID=darkbot"
Missing_Parm="$Missing_Parm""USERID "
else
grep 'USERID' $TMP-DB.WORK.FILE | tr -d ' '
fi >> $TMP-DB.WORK.FILE.tmp
if [ ! "`grep 'CHAN=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "CHAN=#darkbot"
Missing_Parm="$Missing_Parm""CHAN "
else
grep 'CHAN' $TMP-DB.WORK.FILE | tr -d ' ' > $TMP-DB.WORK.FILE.chan
# check if there isn't a # before channel name
if [ ! `grep 'CHAN=#' $TMP-DB.WORK.FILE.chan` ]; then
sed 's/CHAN=/CHAN=#/' $TMP-DB.WORK.FILE.chan > $TMP-DB.WORK.FILE.chan2
mv -f $TMP-DB.WORK.FILE.chan2 $TMP-DB.WORK.FILE.chan
fi
# check if there isn't a # before channel name after a ,
if [ `grep ',' $TMP-DB.WORK.FILE.chan` ]; then
sed -e 's/,/,#/g' -e 's/##/#/g' $TMP-DB.WORK.FILE.chan > $TMP-DB.WORK.FILE.chan2
mv -f $TMP-DB.WORK.FILE.chan2 $TMP-DB.WORK.FILE.chan
fi
cat $TMP-DB.WORK.FILE.chan >> $TMP-DB.WORK.FILE.tmp
fi >> $TMP-DB.WORK.FILE.tmp
if [ ! "`grep 'REALNAME=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "REALNAME=Download me from http://darkbot.sourceforge.net"
Missing_Parm="$Missing_Parm""REALNAME "
else
grep 'REALNAME' $TMP-DB.WORK.FILE
fi >> $TMP-DB.WORK.FILE.tmp
if [ ! "`grep 'VHOST=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "VHOST=0"
Missing_Parm="$Missing_Parm""VHOST "
else
grep 'VHOST' $TMP-DB.WORK.FILE | tr -d ' '
fi >> $TMP-DB.WORK.FILE.tmp
if [ ! "`grep 'CMDCHAR=' $TMP-DB.WORK.FILE | cut -d= -f2`" ]; then
echo "CMDCHAR=!"
Missing_Parm="$Missing_Parm""CMDCHAR "
else
grep 'CMDCHAR' $TMP-DB.WORK.FILE | tr -d ' '
fi >> $TMP-DB.WORK.FILE.tmp
if [ "`grep 'SEEN' $TMP-DB.WORK.FILE`" ]; then
SEEN=$(grep 'SEEN' $TMP-DB.WORK.FILE | tr -d ' '| cut -d= -f2)
# check if is 0 or 1
if [ "$SEEN" -lt "2" 2>/dev/null ]; then
echo "SEEN="$SEEN""
else
# is not 0 or 1 so check if is off or on
if [ `echo "$SEEN" | grep -i "on" 2>/dev/null` ]; then
echo "SEEN=1"
else
echo "SEEN=0"
fi
fi
fi >> $TMP-DB.WORK.FILE.tmp
mv -f $TMP-DB.WORK.FILE.tmp $TMP-DB.WORK.FILE
clear
echo -e "$PNCI* setup.ini file *\n"
echo -e "\n - setup.ini file as is after being checked -"
cat $TMP-DB.WORK.FILE
echo -e "\n"
echo " - Summary -"
echo "setup.ini file contents" > $TMP-SETUP_INI.rep.head
numLinesSETUP_now=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
if [ "$numLinesSETUP_now" -lt "$numLinesSETUP" ]; then
numLinesSETUP_diff="$(expr "$numLinesSETUP" - "$numLinesSETUP_now")"
fi
numWordsSETUP_now=$(cat $TMP-DB.WORK.FILE | wc -w | tr -cd '[:alnum:]')
if [ "$numWordsSETUP_now" -lt "$numWordsSETUP" ]; then
numWordsSETUP_diff="$(expr "$numWordsSETUP" - "$numWordsSETUP_now")"
space_s=$(if [ "$numWordsSETUP_diff" -gt "1" ]; then echo spaces;
else echo space; fi)
echo "- Found "$numWordsSETUP_diff" misplaced empty "$space_s"!"
else echo "- No misplaced spaces found!"
fi | tee -a $TMP-SETUP_INI.rep.head
if [ -n "$Missing_Parm" ]; then
echo "- Missing values on `echo "$Missing_Parm" | \
sed s/[[:space:]]/,' '/` (defaults were used)"
else
echo "- Parameters and values looks ok."
fi | tee -a $TMP-SETUP_INI.rep.head
echo
if [ -n "$numLinesSETUP_diff" ] || [ -n "$numWordsSETUP_diff" ] || \
[ -n "$Missing_Parm" ]; then
echo "setup.ini contents and syntax appears to be correct now." \
| tee -a $TMP-SETUP_INI.rep.head
echo -e "\n===== setup.ini file contents before changes
`cat $ORIG_PATH`
________________ end of setup.ini file before changes made \
__________________" > $TMP-SETUP_INI.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "setup.ini contents and syntax appears to be correct." \
| tee -a $TMP-SETUP_INI.rep.head
fi
echo
SLEEP 5
}
SERVERS_INI () {
clear
echo -e "$PNCI* servers.ini file *\n"
echo -e " - servers.ini file as is before been checked -"
cat $TMP-DB.WORK.FILE
SLEEP 1
# count lines
numLinesSERVERS=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
# count words
numWordsSERVERS=$(cat $TMP-DB.WORK.FILE | wc -w | tr -cd '[:alnum:]')
count="0"
numMissPORTS=0
while [ $count != "$numLinesSERVERS" ]; do
count=`expr $count + 1`
servers_tmp="$(sed -n "$count"p $TMP-DB.WORK.FILE)"
if [ `echo "$servers_tmp" | grep -E :` ]; then
server="$(echo $servers_tmp | cut -d: -f1)"
port="$(echo $servers_tmp | cut -d: -f2 | grep [0-9])"
else
server="$(echo $servers_tmp | cut -d' ' -f1)"
port="$(echo $servers_tmp | cut -d' ' -f2 | grep [0-9])"
fi
clear
echo -e "$PNCI* servers.ini file *\n
Checking entries syntax...\n
SERVER - "$server"
PORT - "$port""
if [ ! -n "$port" ]; then
echo -e "#### ERROR #####\nNo port detected.\nDefaulting to 6667..."; SLEEP 1
Missing_PORTS=`expr $numMissPORTS + 1`
echo "$server" "6667" >> $TMP-DB.WORK.FILE.tmp
else
echo "$servers_tmp" >> $TMP-DB.WORK.FILE.tmp
fi
SLEEP 1
done
SLEEP 1
clear
echo -e "$PNCI* servers.ini file *\n\n"
if [ -s $TMP-DB.WORK.FILE.tmp ]; then
mv -f $TMP-DB.WORK.FILE.tmp $TMP-DB.WORK.FILE
fi
echo "servers.ini file contents" > $TMP-SERVERS_INI.rep.head
numLinesSERVERS_now=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
if [ "$numLinesSERVERS_now" -lt "$numLinesSERVERS" ]; then
numLinesSERVERS_diff="$(expr "$numLinesSERVERS" - "$numLinesSERVERS_now")"
fi
numWordsSERVERS_now=$(cat $TMP-DB.WORK.FILE | wc -w | tr -cd '[:alnum:]')
if [ "$numWordsSERVERS_now" -lt "$numWordsSERVERS" ]; then
numWordsSERVERS_diff="$(expr "$numWordsSERVERS" - "$numWordsSERVERS_now")"
space_s=$(if [ "$numWordsSERVERS_diff" -gt "1" ]; then echo spaces;
else echo space; fi)
echo "- Found "$numWordsSERVERS_diff" misplaced empty "$space_s"!"
else echo "- No misplaced spaces found!"
fi | tee -a $TMP-SERVERS_INI.rep.head
port_s="$(if [ -n "$Missing_PORTS" ] && [ "$Missing_PORTS" -gt "1" ]; then echo "s"; else echo ""; fi)"
if [ -n "$Missing_PORTS" ]; then
echo "- Missing value$port_s on "$Missing_PORTS" port$port_s! \
(default 6667 were used)"
else
echo "- Apparently there are no errors on entries syntax and PORTS placement."
fi | tee -a $TMP-SERVERS_INI.rep.head
echo
if [ -n "$numLinesSERVERS_diff" ] || [ -n "$numWordsSERVERS_diff" ] || \
[ -n "$Missing_PORTS" ]; then
echo "servers.ini contents and syntax appears to be correct now."
echo -e "\n===== servers.ini file contents before changes
`cat $ORIG_PATH`
________________ end of servers.ini file before changes made \
__________________" > $TMP-SERVERS_INI.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "servers.ini contents and syntax appears to be correct." \
| tee -a $TMP-SERVERS_INI.rep.head
fi
echo
SLEEP 5
}
USERLIST_DB () {
# just a basic check at this stage
# to do: check repeated IPs at the end of the process besides repeated
# entries at start; optimize all integers check
clear
echo -e "$PNCI* userlist.db file *\n"
# count lines
numLinesUSERLIST=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
usrlst_removed="0"; usrlst_errors="0"; usrlst_errors_b4="0"
count=0
while [ "$count" != "$numLinesUSERLIST" ]; do
count=`expr "$count" + 1`
# get complete line
usrlst_entry="$(sed -n "$count"p $TMP-DB.WORK.FILE)"
clear
echo -e "$PNCI* userlist.db file *\n"
echo -e "[`expr "$numLinesUSERLIST" - "$count"`] entries to be checked.\n"
echo -e "Verifying syntax on entry:\n$usrlst_entry\n"
# get complete line
#usrlst_entry="$(sed -n "$count"p $TMP-DB.WORK.FILE)"
# if no @ bypass to later remove entry
if [ "`echo "$usrlst_entry" | cut -d' ' -f2 | grep '@'`" ]; then
# check if 1st field or after a , starts with # ( #channel or #*)
usrlst_chan="$(echo "$usrlst_entry" | cut -d' ' -f1)"
usrlst_chan0="$(echo "$usrlst_chan" | sed -e s/,/,'#'/g -e s/'##'/'#'/g)"
if [ ! "`echo "$usrlst_chan0" | grep -E '^\#'`" ]; then
usrlst_chan0="#"$usrlst_chan0""
fi
if [ "$usrlst_chan" != "$usrlst_chan0" ]; then
echo -e "#### ERROR ####\n Channel field incorrect! \
Missing channel prefix '#'. Adding it...\n"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
usrlst_chan="$usrlst_chan0"
fi
# get user mask
usrlst_mask="$(echo "$usrlst_entry" | cut -d' ' -f2)"
if [ "`echo "$usrlst_mask" | grep '\.$'`" ]; then
echo -e "#### ERROR ####\n Unexpected end of user IP! Adding '*'...\n"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
usrlst_mask="$(echo ""$usrlst_mask"*")"
fi
if [ "`echo "$usrlst_mask" | grep -E '\.\.'`" ]; then
echo -e "#### ERROR ####\n Incorrect syntax on user IP '..'. Fixing it...\n"
usrlst_mask="$(echo "$usrlst_mask" | sed 's/\.\./\./')"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
usrlst_ip="@$(echo "$usrlst_mask" | cut -d@ -f2)"
#check if 2nd string starts with * (*userid) not ~ | not *!
usrlst_userid="$(echo "$usrlst_entry" | cut -d' ' -f2 | cut -d@ -f1)"
if [ "`echo "$usrlst_userid" | grep '~'`" ]; then
echo -e "#### ERROR ####\n USER ID field incorrect! Unnecessary leading ~\n"
usrlst_userid="$(echo "$usrlst_userid" | sed 's/~//')"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
if [ "`echo "$usrlst_userid" | grep -E '^\*!'`" ]; then
echo -e "#### ERROR ####\n USER ID field incorrect! Disallowed leading characters *!\n"
usrlst_userid="$(echo "$usrlst_userid" | sed 's/\*\!//')"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
if [ ! "`echo "$usrlst_userid" | grep '^\*'`" ]; then
echo -e "#### ERROR ####\n USER ID field incorrect! Missing leading *\n"
usrlst_userid="$(echo "*"$usrlst_userid"")"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
# check if 3rd colum is 1 2 or 3 (levels)
usrlst_level="$(echo "$usrlst_entry" | cut -d' ' -f3)"
if [ ! "`echo "$usrlst_level" | grep '^[0-3]$'`" ]; then
echo -e "#### ERROR ####\n USER Access level field incorrect! Using 1...\n"
usrlst_level="1"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
# check if 4th column is an integer (times bot saw user)
usrlst_seen="$(echo "$usrlst_entry" | cut -d' ' -f4)"
unset testinteger
testinteger="$(expr "$usrlst_seen" - "0" 2>/dev/null)"
if [ -z "$testinteger" ]; then
echo -e "#### ERROR ####\n Number of times seen field is not an integer! \
Fixing it...\n"
usrlst_seen="0"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
# check if 5th column is password
usrlst_pass="$(echo "$usrlst_entry" | cut -d' ' -f5)"
if [ -z "$usrlst_pass" ]; then
echo -e "#### ERROR ####\n Missing password field! Using password 0...\n"
usrlst_pass="0"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
# check if 6th column is 0 or setinfo
usrlst_setinfo="$(echo "$usrlst_entry" | cut -d' ' -f6-)"
if [ -z "$usrlst_setinfo" ]; then
echo -e "#### ERROR ####\n Missing SETINFO field! Using 0...\n"
usrlst_setinfo="0"
usrlst_errors="$(expr "$usrlst_errors" + 1)"
fi
usrlst_new=""$usrlst_chan" "$usrlst_userid""$usrlst_ip" "$usrlst_level" \
"$usrlst_seen" "$usrlst_pass" "$usrlst_setinfo""
echo "$usrlst_new" >> $TMP-USERLIST.DB
if [ "$usrlst_errors" -gt "$usrlst_errors_b4" ]; then
echo -e "Corrected entry:"
echo "----" >> $TMP-USERLIST_DB.rep.body0
echo "$usrlst_entry" >> $TMP-USERLIST_DB.rep.body0
echo "$usrlst_new" | tee -a $TMP-USERLIST_DB.rep.body0
SLEEP 4
fi
else # no @ on IP
echo -e "#### ERROR ####\n Unable to obtain IP. Entry is being removed...\n"
echo "$usrlst_entry" >> $TMP-USERLIST_DB.rep.body1
usrlst_removed="$(expr "$usrlst_removed" + 1)"
SLEEP 4
fi
usrlst_errors_b4="$usrlst_errors"
done
usrlst_uniq_errors="$(expr "`cat $TMP-USERLIST_DB.rep.body0 2>/dev/null | wc -l | tr -cd '[:alnum:]'`" / 3)"
# if no $TMP-USERLIST.DB means all entries were irrecoverable/wrong / missing @
if [ ! -s $TMP-USERLIST.DB ]; then
touch $TMP-USERLIST.DB
no_entries=y # since file is 0 just a var to avoid 2nd round of dup check
fi
mv -f $TMP-USERLIST.DB $TMP-DB.WORK.FILE
# REPORT
# start gathering results
# get/accumulate results from 1st passage of DUP_ENTRIES
if [ -s $TMP.dup.entries ]; then
dupentries_lines_1="$dupentries_lines"
dupentries_lin_rem_1="$dupentries_lin_rem"
cat $TMP.dup.entries >> $TMP.dup.entries_1
fi
# checking dup entries again if/after changes
if [ -z "$no_entries" ]; then
if [ "$usrlst_uniq_errors" -gt "0" ] || [ "$usrlst_removed" -gt "0" ]; then
clear
echo -e "$PNCI* userlist.db file *\n
Doing a quick check for duplicate entries again on "$ORIG_FILE" after
syntax changes made"
SLEEP 2
DUP_ENTRIES
fi
fi
# get total entries after changes
numLinesUSERLIST_after=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
error_s="$(if [ "$usrlst_errors" -gt "1" ]; then echo errors; else echo error; fi)"
entry_s="$(if [ "$usrlst_uniq_errors" -gt "1" ]; then echo entries; else echo entry; fi)"
clear
echo -e "$PNCI* userlist.db file *\n"
echo "userlist.db file contents" > $TMP-USERLIST_DB.rep.head
echo "- Total entries before checking: "$numLinesUSERLIST_ORI" \
After: "$numLinesUSERLIST_after""| tee -a $TMP-USERLIST_DB.rep.head
if [ "$usrlst_uniq_errors" -gt "0" ] || [ "$usrlst_removed" -gt "0" ]; then
if [ "$usrlst_uniq_errors" -gt "0" ]; then
echo "- Corrected a total of "$usrlst_errors" "$error_s" on \
"$usrlst_uniq_errors" "$entry_s"."
fi
if [ -s $TMP-USERLIST_DB.rep.body0 ]; then
echo -e "===== Fixed userlist.db errors
(first entry on each section corresponds to the one with errors)
`cat $TMP-USERLIST_DB.rep.body0`
_______________________ end of fixed userlist.db entries \
_______________________" > $TMP-USERLIST_DB.rep.body
fi
if [ "$usrlst_removed" -gt "0" ]; then
echo "- Removed entries due to missing or irrecoverable IP: "$usrlst_removed""
echo -e "-=-=- Removed entries from userlist.db due to irrecoverable IP
`cat $TMP-USERLIST_DB.rep.body1`
_______________________ end of removed userlist.db entries \
_______________________" >> $TMP-USERLIST_DB.rep.body
fi
else
echo "- No syntax errors found."
fi | tee -a $TMP-USERLIST_DB.rep.head
# dup_entries
if [ -s $TMP.dup.entries ]; then
dupentries_lines="$(expr "$dupentries_lines" + "$dupentries_lines_1")"
dupentries_lin_rem="$(expr "$dupentries_lin_rem" + "$dupentries_lin_rem_1")"
dupentries_lin_rem="$(expr "$dupentries_lin_rem" + "$dupentries_lin_rem_1")"
cat $TMP.dup.entries >> $TMP.dup.entries_1
echo "DUPLICATE ENTRIES on "$ORIG_FILE"
- Number of entries with repetitions: "$dupentries_lines"
- Number of repetitions found: "$dupentries_lin_rem"
- Number of lines removed: "$dupentries_lin_rem"
(Check section \"Removed DUPLICATE ENTRIES from $ORIG_FILE\" on this file)"
echo -e "-=-=- Removed DUPLICATE ENTRIES from "$ORIG_FILE"" >> \
$TMP-USERLIST_DB.rep.body
cat $TMP.dup.entries_1 >> $TMP-USERLIST_DB.rep.body
echo "_______________________ end of duplicate entries on "$ORIG_FILE"\
________________________" >> $TMP-USERLIST_DB.rep.body
CHANGED=""$CHANGED" "$ORIG_FILE""
else
echo "- No repeated entries found!"
fi | tee -a $TMP-USERLIST_DB.rep.head
rm -f $TMP.dup.entries
rm -f $TMP-DUP_ENTRIES.$ORIG_FILE.rep.head
rm -f $TMP-DUP_ENTRIES.$ORIG_FILE.rep.body
SLEEP 3
# end of dup_entries report
if [ "$usrlst_uniq_errors" -gt "0" ] || [ "$usrlst_removed" -gt "0" ]; then
CHANGED=""$CHANGED" "$ORIG_FILE""
fi
SLEEP 4
}
# NOT IMPLEMENTED YET
REMOVE_PREMADE_DBS () {
echo $null
}
## END OF MAIN FUNCTIONS ##
###########################
###########
## FILES ##
################ PREP AND START
FILES_PREP () {
clear
echo -e "$PNCI\n-- Preparing $ORIG_FILE file --\n\nUsing $ORIG_FILE in a safe
temporary working file..."
SLEEP 1
if [ ! -s $ORIG_PATH ]; then
touch $ORIG_PATH
if [ "$ORIG_PATH" = "../dat/userlist.db" ]; then
echo "#channel *user_ident@*user.ip.net 1 0 password_here \
You need to !setinfo" >> "$ORIG_PATH"
fi
fi
# copy orig file to working file
cp -f $ORIG_PATH $TMP-DB.WORK.FILE
if [ "$external_db" = "DB_MASTER" ]; then
numLinesDB_MASTER=$(cat $COMMON_TMP/TMP-DB_MASTER | wc -l | tr -cd '[:alnum:]')
echo -e "\nMoving downloaded database to the info2.db working file..."
cat $COMMON_TMP/TMP-DB_MASTER >> $TMP-DB.WORK.FILE
info2db_lines="$(if [ "$numLines_info2_ORI" = "0" ]; then
echo "info2.db empty file."; else
echo "initial "$numLines_info2_ORI" info2.db lines,\nmaking a total of \
`expr "$numLinesDB_MASTER" + "$numLines_info2_ORI"` entries to be checked."; fi)"
echo -e "\n"$numLinesDB_MASTER" new entries added to your "$info2db_lines""
CHANGED=""$CHANGED" "$ORIG_FILE""
SLEEP 4
fi
numLinesORI=$(cat $TMP-DB.WORK.FILE | wc -l | tr -cd '[:alnum:]')
SLEEP 3
}
# files start
START_INFO2 () {
ORIG_FILE="info2.db"
ORIG_PATH="../dat/info2.db"
numLines_info2_ORI=$(cat $ORIG_PATH 2>/dev/null | wc -l | tr -cd '[:alnum:]')
sleep 2
# if file is not empty ...
if [ "$numLines_info2_ORI" != "0" ] || [ -n "$external_db" ]; then
FILES_PREP
LINE_FEED; EMPTY_LINES; INCOMPL_ENTRIES; DUP_ENTRIES; DUP_TOPICS
TOPIC_SIZE; DATA_SIZE; CHECK_RDBS
if echo "$CHANGED" | grep -q info2.db 1>/dev/null; then
mv -f $TMP-DB.WORK.FILE $TMP-INFO2.DB
fi
else # if is empty
clear
echo -e "$PNCI\ninfo2.db file is empty. There is no need to check it!
Add topics and replies to it so your Darkbot could "talk".\n"
SLEEP 3
fi
}
START_SERVERS () {
ORIG_FILE="servers.ini"
ORIG_PATH="../dat/servers.ini"
numLinesORI=$(cat $ORIG_PATH 2>/dev/null | wc -l | tr -cd '[:alnum:]')
# if file is not empty ...
if [ "$numLinesORI" != "0" ]; then
FILES_PREP
LINE_FEED; EMPTY_LINES;
SERVERS_INI
if echo "$CHANGED" | grep -q servers.ini 1>/dev/null; then
mv -f $TMP-DB.WORK.FILE $TMP-SERVERS.INI
fi
else # if is empty
clear
echo -e "$PNCI\nservers.ini file is empty. There is no need to check it!
You'll need to add servers so your Darkbot can connect to IRC.\n"
SLEEP 3
fi
}
START_SETUP () {
ORIG_FILE="setup.ini"
ORIG_PATH="../dat/setup.ini"
numLinesORI=$(cat $ORIG_PATH 2>/dev/null | wc -l | tr -cd '[:alnum:]')
FILES_PREP
LINE_FEED; EMPTY_LINES;
SETUP_INI
if echo "$CHANGED" | grep -q setup.ini 1>/dev/null; then
mv -f $TMP-DB.WORK.FILE $TMP-SETUP.INI
fi
}
START_PERFORM () {
ORIG_FILE="perform.ini"
ORIG_PATH="../dat/perform.ini"
numLinesORI=$(cat $ORIG_PATH 2>/dev/null | wc -l | tr -cd '[:alnum:]')
# if file is not empty ...
if [ "$numLinesORI" != "0" ]; then
FILES_PREP
LINE_FEED; EMPTY_LINES
if echo "$CHANGED" | grep -q perform.ini 1>/dev/null; then
mv -f $TMP-DB.WORK.FILE $TMP-PERFORM.INI
fi
else # if is empty
clear
echo -e "$PNCI\nperform.ini file is empty. There is no need to check it!\n"
SLEEP 3
fi
}
START_USERLIST () {
ORIG_FILE="userlist.db"
ORIG_PATH="../dat/userlist.db"
numLinesUSERLIST_ORI="$(cat $ORIG_PATH 2>/dev/null | wc -l | tr -cd '[:alnum:]')"
numLinesORI="$numLinesUSERLIST_ORI"
# if file is not empty ...
if [ "$numLinesORI" != "0" ]; then
FILES_PREP
LINE_FEED; EMPTY_LINES; DUP_ENTRIES
USERLIST_DB
if echo "$CHANGED" | grep -q userlist.db 1>/dev/null; then
mv -f $TMP-DB.WORK.FILE $TMP-USERLIST.DB
fi
else # if is empty
clear
echo -e "$PNCI\nuserlist.db file is empty. There is no need to check it!
Use AddUser to add yourself as Darkbot administrator."
SLEEP 3
fi
}
START_RANDOM () {
RANDOM_FILES
}
## END OF FILES PREP AND START ##
#################################
####################
## UPDATE PROCESS ##
FILES_BACKUP () {
# backup file
clear
echo -e "$PNCI\n- ORIGINAL FILES UPDATE -\n"
if [ -s "$2" ]; then
echo -e "Backing up your current "$1" before updating it \
with the changes made...\n"
cp -fp "$2".bak.1 "$2".bak.2 2>/dev/null
cp -fp "$2".bak.0 "$2".bak.1 2>/dev/null
mv -f "$2" "$2".bak.0
echo "Your most current $ORIG_FILE backup is "$2".bak.0"
if [ -e "$2".bak.1 ]; then
echo "You still have a previous backup on "$2".bak.1"
fi
if [ -e "$2".bak.2 ]; then
echo "and an older one as "$2".bak.2"
fi
fi
SLEEP 3
}
FILES_UPDATE () {
if [ -n "$CHANGED" ]; then
count=10; counter=1
while [ $count != "$counter" ]; do
count=`expr "$count" - 1`
clear
echo -e "$PNCI\n- ORIGINAL FILES UPDATE -\n
The changes made will be effectively updated now.
If you do not want those changes to be saved to the original files press
CTRL + C now to abort.\n
The update process will start in ["$count"] seconds...\n"
SLEEP 1
done
no_changes () {
#if echo $ci_files | grep $1; then
if [ ! -s $TMP-no.changes ]; then
echo -e "clear\necho \"$PNCI\n- ORIGINAL FILES UPDATE -\n\"" > $TMP-no.changes
fi
if echo "$ci_files" | grep -i `echo "$1" | cut -d. -f1`; then
echo -e "echo \"No changes made on your $1 $2.\"
SLEEP 1" >> $TMP-no.changes
fi
}
if [ -s $TMP-INFO2.DB ]; then
FILES_BACKUP info2.db ../dat/info2.db
echo -e "\nMoving working file to ../dat/info2.db ...\n"
mv -f $TMP-INFO2.DB ../dat/info2.db
SLEEP 1
else
no_changes info2.db file
fi
if [ -s $TMP-SERVERS.INI ]; then
FILES_BACKUP servers.ini ../dat/servers.ini
echo -e "\nMoving working file to ../dat/servers.ini ...\n"
mv -f $TMP-SERVERS.INI ../dat/servers.ini
SLEEP 1
else
no_changes servers.ini file
fi
if [ -s $TMP-SETUP.INI ]; then
FILES_BACKUP setup.ini ../dat/setup.ini
echo -e "\nMoving working file to ../dat/setup.ini ...\n"
mv -f $TMP-SETUP.INI ../dat/setup.ini
SLEEP 2
else
no_changes setup.ini file
fi
if [ -s $TMP-PERFORM.INI ]; then
FILES_BACKUP perform.ini ../dat/perform.ini
echo -e "\nMoving working file to ../dat/perform.ini ...\n"
mv -f $TMP-PERFORM.INI ../dat/perform.ini
SLEEP 2
else
no_changes perform.ini file
fi
if [ -f $TMP-USERLIST.DB ]; then
FILES_BACKUP userlist.db ../dat/userlist.db
echo -e "\nMoving working file to ../dat/userlist.db ...\n"
mv -f $TMP-USERLIST.DB ../dat/userlist.db
SLEEP 2
else
no_changes userlist.db file
fi
if [ -s $TMP-RANDOM_FILES ]; then
# do some cosmetic work on the file for backups, only on these random files
echo -e "clear\n echo -e \"$PNCI\n- ORIGINAL FILES UPDATE -\n\"" > $TMP-RANDOM_FILES_TMP
cat $TMP-RANDOM_FILES >> $TMP-RANDOM_FILES_TMP
mv -f $TMP-RANDOM_FILES_TMP $TMP-RANDOM_FILES
echo "SLEEP 1" >> $TMP-RANDOM_FILES
# go for it
echo -e "\nMoving random files to dat directory...\n"
. $TMP-RANDOM_FILES
SLEEP 2
else
no_changes random files
fi
# execute no changes messages
if [ -s $TMP-no.changes ]; then
. $TMP-no.changes
fi
fi # end of count down to update changes
SLEEP 4
}
## END OF UPDATE PROCESS ##
###########################
############
## REPORT ##
INTEGRITY_REPORT () {
if [ -s $ci_report ]; then
cp -fp $ci_report $ci_report.old
fi
_head_separator_ () {
echo "----------------------------------\
---------------------------------------" >> $ci_report
}
_head_entry_ () {
cat $1 >> $ci_report 2>/dev/null
}
# obtain numb of lines after process done
echo -e "$PNCI* Integrity Check Report File *
Generated on `date`
=========================================================================
| SUMMARY |
================================== ==================================" \
> $ci_report
_head_separator_
info2LinesFinal=$(cat ../dat/info2.db 2>/dev/null | wc -l | tr -cd '[:alnum:]')
echo "TOTAL LINES/ENTRIES on info2.db: \
Before = "$numLines_info2_ORI" Now = "$info2LinesFinal"\
`if [ "$line_feed" = "y" ]; then echo -e "\n(There is one \
additional line due to an added line feed)"; fi`" >> $ci_report
_head_entry_ $TMP-LINE_FEED.info2.db.rep.head
_head_entry_ $TMP-EMPTY_LINES.info2.db.rep.head
_head_entry_ $TMP-INCOMPL_ENTRIES.rep.head
_head_entry_ $TMP-DUP_ENTRIES.info2.db.rep.head
_head_entry_ $TMP-DUP_TOPICS.rep.head
_head_entry_ $TMP-TOPIC_SIZE.rep.head
_head_entry_ $TMP-DATA_SIZE.rep.head
_head_entry_ $TMP-CHECK_RDBS.rep.head
_head_separator_ # end of info2.db
_head_entry_ $TMP-RANDOM_FILES.rep.head
_head_separator_ # servers.ini
_head_entry_ $TMP-SERVERS_INI.rep.head
_head_entry_ $TMP-LINE_FEED.servers.ini.rep.head
_head_entry_ $TMP-EMPTY_LINES.servers.ini.rep.head
_head_separator_ # setup.ini
_head_entry_ $TMP-SETUP_INI.rep.head
_head_entry_ $TMP-LINE_FEED.setup.ini.rep.head
_head_entry_ $TMP-EMPTY_LINES.setup.ini.rep.head
_head_separator_ # perform.ini
_head_entry_ $TMP-LINE_FEED.perform.ini.rep.head
_head_entry_ $TMP-EMPTY_LINES.perform.ini.rep.head
_head_separator_ # userlist.db
_head_entry_ $TMP-USERLIST_DB.rep.head
_head_entry_ $TMP-LINE_FEED.userlist.db.rep.head
_head_entry_ $TMP-EMPTY_LINES.userlist.db.rep.head
_head_separator_
echo "
=========================================================================
| MODIFICATIONS |
================================== ==================================
" >> $ci_report
_body_entry_ () {
cat $1 >> $ci_report 2>/dev/null
}
_body_separator_ () {
echo "" >> $ci_report
}
_body_entry_ $TMP-INCOMPL_ENTRIES.rep.body
_body_separator_
_body_entry_ $TMP-DUP_ENTRIES.info2.db.rep.body
_body_separator_
_body_entry_ $TMP-DUP_TOPICS.rep.body
_body_separator_
_body_entry_ $TMP-TOPIC_SIZE.rep.body
_body_separator_
_body_entry_ $TMP-DATA_SIZE.rep.body
_body_separator_
_body_entry_ $TMP-CHECK_RDBS.rep.body
_body_separator_
_body_entry_ $TMP-SETUP_INI.rep.body
_body_separator_
_body_entry_ $TMP-USERLIST_DB.rep.body
}
## END OF REPORT ##
###################
CI_LOG_VARS () {
if [ ! -s "$ci_vars" ]; then
touch $ci_vars
fi
if [ "$1" = "topicsize" ]; then
unset TOPIC_SIZE
while [ -z "$TOPIC_SIZE" ]; do
clear
echo -e "$PNCI\n - CHANGING TOPIC LENGTH VALUE -\n\n"
echo -n "Enter the topic length to be set for this utility
(Default value for topic length is 50 characters): "
read topic_size
unset testinteger
testinteger="$(expr "$topic_size" - "0" 2>/dev/null)"
if [ ! -z "$testinteger" ]; then
TOPIC_SIZE="$topic_size"
if [ "`grep 'TOPIC_SIZE' $ci_vars`" ]; then
grep -v 'TOPIC_SIZE' $ci_vars > $TMP
cat $TMP > $ci_vars
fi
echo "TOPIC_SIZE=\"$TOPIC_SIZE\"" >> $ci_vars
echo -e "\nAdded value of "$topic_size" for maximum topic length!\n
This value MUST be the same as the one given on defines.h
when Darkbot was configured.
[ To remove this setting type $0 -default ]\n"
else
echo -e "\n#### ERROR ####\nPlease enter an integer [0-9]"
sleep 2
fi
done
SLEEP 4
fi
if [ "$1" = "replysize" ]; then
unset DATA_SIZE
while [ -z "$DATA_SIZE" ]; do
clear
echo -e "$PNCI\n - CHANGING REPLY LENGTH VALUE -\n\n"
echo -n "Enter the reply length to be set for this utility
(Default value for reply length is 400 characters): "
read reply_size
unset testinteger
testinteger="$(expr "$reply_size" - "0" 2>/dev/null)"
if [ ! -z "$testinteger" ]; then
DATA_SIZE="$reply_size"
if [ "`grep 'DATA_SIZE' $ci_vars`" ]; then
grep -v 'DATA_SIZE' $ci_vars > $TMP
cat $TMP > $ci_vars
fi
echo "DATA_SIZE=\"$DATA_SIZE\"" >> $ci_vars
echo -e "\nAdded value of "$reply_size" for maximum reply length!\n
This value MUST be the same as the one given on defines.h
when Darkbot was configured.
[ To remove this setting type $0 -default ]\n"
else
echo -e "\n#### ERROR ####\nPlease enter an integer [0-9]"
sleep 2
fi
done
SLEEP 4
fi
if [ "$1" = "nointro" ]; then
ci_intro_OnOff=off
if [ "`grep 'ci_intro_OnOff' $ci_vars`" ]; then
grep -v 'ci_intro_OnOff' "$ci_vars" > $TMP
cat $TMP > $ci_vars
fi
echo "ci_intro_OnOff=\"$ci_intro_OnOff\"" >> $ci_vars
clear
echo -e "$PNCI\n - INTRODUCTION TEXT -\n\n
Introduction is now turned off\n
[ To remove this setting type $0 -default ]\n"
SLEEP 4
fi
}
CI_INTRO_START () {
if [ ! `echo "$ci_arg" | grep 'nointro' 2>/dev/null` ]; then # \
if [ ! `echo "$ci_intro_OnOff" | grep 'off' 2>/dev/null` ]; then
if [ ! `echo "$ci_switches" | grep 'quick' 2>/dev/null` ]; then
CI_INTRO
fi
fi
fi
}
# ------------------------ START UTILITY ------------------------ #
###########
## START ##
#DB_SCRIPTS_PATH;
ENVIRONMENT; TESTDEPEND_GO
ci_files= ci_switches=
for ci_arg
do
case "$ci_arg" in
-*) ci_switches="$ci_switches $ci_arg" ;;
*) ci_files="$ci_files $ci_arg" ;;
esac
done
# not in use but left here for future consid.
case "$ci_files" in
#"") USAGE 1>&2 ;;
"") $null 1>&2 ;;
*) for file in $ci_files
do
CI_INTRO_START
done
stat=0
;;
esac
if [ -z "$ci_files" ] && [ -z "$ci_switches" ]; then
USAGE
fi
# ----- SWITCHES -----
# help __
if echo "$ci_switches" | grep -qi 'h' 1>/dev/null; then
USAGE
fi
# default __
if echo "$ci_switches" | grep -qi 'default' 1>/dev/null; then
rm -f "$ci_vars"
fi
# SLEEP function __
if echo "$ci_switches" | grep -qi 'quick' 1>/dev/null; then
# bypasses or not 'sleep' (pause) periods -- syntax= SLEEP 3
SLEEP () { SLEEP=$($null); }
# if wants quick there is no reason for intro, so... bypass INTRO
else
SLEEP () { SLEEP=$(sleep $1); }
fi
# bypasses introduction __
if echo "$ci_switches" | grep -qi 'nointro' 1>/dev/null; then
CI_LOG_VARS nointro
#else
#if [ "$ci_intro_OnOff" != "off" ]; then CI_INTRO; fi
fi
# show report __
if echo "$ci_switches" | grep -qi 'report' 1>/dev/null; then
if [ -s $ci_report ]; then
cat $ci_report | less -deXF
else
echo -e "$PNCI\n\nThere is no report file registered\n"
fi
fi
# topic length __
if echo "$ci_switches" | grep -qi 'topicsize' 1>/dev/null; then
CI_LOG_VARS topicsize
fi
# reply length __
if echo "$ci_switches" | grep -qi 'replysize' 1>/dev/null; then
CI_LOG_VARS replysize
fi
# ----- FILES -----
# do all
if echo "$ci_files" | grep -qi "all" 1>/dev/null; then
START_INFO2
START_SERVERS
START_SETUP
START_PERFORM
START_USERLIST
START_RANDOM
fi
# info2.db
if echo "$ci_files" | grep -qi 'info2' 1>/dev/null; then
START_INFO2
fi
# servers.ini
if echo "$ci_files" | grep -qi 'servers' 1>/dev/null; then
START_SERVERS
fi
# setup.ini
if echo "$ci_files" | grep -qi 'setup' 1>/dev/null; then
START_SETUP
fi
# perform.ini
if echo "$ci_files" | grep -qi 'perform' 1>/dev/null; then
START_PERFORM
fi
# userlist.db
if echo "$ci_files" | grep -qi 'userlist' 1>/dev/null; then
START_USERLIST
fi
# random.ini
if echo "$ci_files" | grep -qi 'random' 1>/dev/null; then
START_RANDOM
fi
# external databases
if echo "$ci_files" | grep -qi 'DB_MASTER' 1>/dev/null; then
external_db="DB_MASTER"
START_INFO2
fi
# remove dbs ###### NOT IMPLEMENTED YET ######
if echo "$ci_files" | grep -qi 'remove dbs' 1>/dev/null; then
# go to dd and use remove function
./download-databases
# do a pre check on info2
START_INFO2
REMOVE_PREMADE_DBS # add selected dbs to the end of info2 with a mark; run a
# dup entries function for this only where uniques and dups
# are removed; check at the end entries left after the mark
# meaning they didn't have any match ( just for info); do
# counts at the end | add actions to report
fi
# ____________________ FINAL ____________________
if [ -n "$CHANGED" ]; then
FILES_UPDATE
INTEGRITY_REPORT
echo -e "\nA file `pwd`/$ci_report was created
with the result of all actions taken during this process.
You can see it by typing $0 -report"
# rm empty lines
# clean empty
grep '.' $ci_report > $TMP-ci_report
mv -f $TMP-ci_report $ci_report
else # no changes made to any file
clear
echo -e "$PNCI\n"
if [ ! -z "$ci_files" ]; then
echo -e "\nNo changes were made to your files!\n"
fi
fi
if [ ! -z "$ci_files" ]; then
if echo "$ci_files" | grep -qi 'DB_MASTER' 1>/dev/null; then
ci_files_0="info2.db with downloaded and installed pre-made database"
else
file_s="$( if [ "`echo "$ci_files" | wc -w | tr -cd '[:alnum:]'`" -gt "1" ] \
|| `echo "$ci_files" | grep -qi 'random'`; then \
echo files; else echo file; fi)"
ci_files_0="$(echo "$ci_files" | sed -e s/[[:space:]]/''-''/g)"
fi
echo -e "\n Data integrity check process on
"[$ci_files_0-]" "$file_s" complete.\n"
fi
SLEEP 3
exit 0
diff --git a/scripts/dbcron b/scripts/dbcron
index 17db35c..a360427 100755
--- a/scripts/dbcron
+++ b/scripts/dbcron
@@ -1,142 +1,152 @@
#! /bin/sh
-PID=0624233000
# Darkbot utility to auto generate crontab.
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
# Just run this script and a new one with the same name will be created
# with the actual path of your Darkbot installation. At the same time
# a crontab job will be created with 10 mins interval.
# to do: user defined timers on command line utility launch
+PID=0624233000
MAKE_DBCRON () {
cat > dbcron << EOF[DBCRON]
#! /bin/sh
# Darkbot's crontab utility
DBPATH="$DBPATH" # your darkbot directory
DBBIN="$DBBIN" # Darkbot's binary (executable) file
DBPIDFILE="$DBBIN.pid" # process ID file (same as binary + .pid)
# This file was automatically generated the first time you've run dbcron.
# If for any reason you've changed your Darkbot directory or it's binary
# you'll need to modify the variables DBPATH DBBIN and DBPIDFILE on top of
# this file accordingly to the actual values.
# Defaulty crontab job is of 10 mins interval. If you wish to change it
# edit '0,10,20,30,40,50 * * * *'. If you don't understand it type 'man crontab'
# -----------------------------------------------------------------------------
# What this script does:
# Changes to darkbot root dir; if pid file exists extracts pid number;
# tests it by issuing an inoffensive kill; if pid is active exits, doing
# nothing; if not means the file with pid is there but there is no active
# process, so removes it. finally cheks if program bin exists then starts it.
# ____________ Do not change anything bellow this line! ____________#
cd \$DBPATH
if test -r \$DBPATH/\$DBPIDFILE; then
DBPID=\$(cat \$DBPATH/\$DBPIDFILE)
if \$(kill -CHLD \$DBPID >/dev/null 2>&1)
then
exit 0
fi
echo -e "\nstale pid file (erasing it)"
rm -f \$DBPATH/\$DBPIDFILE
fi
echo -e "\nDarkbot is dead! Restarting . . . . . . . .\n"
if test -x \$DBBIN ;then
\$DBPATH/\$DBBIN
exit 0
fi
echo "could not reload"
EOF[DBCRON]
}
# PREP SCRIPT
# check if it is on the right place
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $0...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
#DB_SCRIPTS_PATH
# check if crontab is present if not there is no reason to run this script
if ! type crontab >/dev/null 2>&1 ; then
echo -e "\nThis script needs 'crontab' command to run, which appears it's \
not installed on this system.
Leaving..."
exit 0
fi
#check if crond is active
if [ ! "$(ps ax | grep -v grep | grep crond 2>/dev/null)" ]; then
echo -e "\nThis script needs 'crond' running, which appears it's \
not on this system.
Leaving..."
fi
# dbcron engine creation. make vars for darkbot path, dir and pid file
DBPATH=$(cd ..; pwd)
if [ -x "$DBPATH/darkbot" ]; then
DBBIN="darkbot"
DBPIDFILE=$DBBIN.pid
# vars are done so let's tell crontab how we want it setup
# check every 10 minutes; send messages to null
# echo '0,10,20,30,40,50 * * * *' "$DBPATH/scripts/dbcron" > crontable.$$ #debug only
echo '0,10,20,30,40,50 * * * *' "$DBPATH/scripts/dbcron >/dev/null 2>&1" >> crontable.$$
crontab crontable.$$; rm -f crontable.$$
# transfer crontab engine file with new vars on top to a new file with same
# name as this one. THIS FILE CONTENTS WILL BE GONE!
MAKE_DBCRON
clear
echo -e "\n\nDarkbot crontab utility\n\nCrontab job created successfully!
To check if everything is okay, kill your bot if it is connected to IRC.
It should automatically restart in 10 minutes.\n
Suggestions, improvements?
Support: http://darkbot.sourceforge.net\n\n"
else
echo -e "\nDarkbot's Crontab Utility.
WARNING!!!!\nDarkbot's binary not found.
Please run ./configure if you haven't do so or restore \
file names to it's default values.\n
Leaving $0..."
exit 0
fi
diff --git a/scripts/download-databases b/scripts/download-databases
index ce87a6e..c8c665c 100755
--- a/scripts/download-databases
+++ b/scripts/download-databases
@@ -1,384 +1,394 @@
#!/bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PNDD="Darkbot's pre-made Databases Utility\n<****************_~_****************>\n"
PID=0624233000
# todo -- download tars as of live-update instead of *.db
# removal of pre-made databases (in conjunction w/check-integrity)
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $PN...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
#DB_SCRIPTS_PATH
ENVIRONMENT () {
BASE_WORKDIR=.scriptutils
COMMON_TMP=$BASE_WORKDIR/tmp
mkdir -p $BASE_WORKDIR/tmp
DDDIR=$BASE_WORKDIR/dldatabases
TMP=$BASE_WORKDIR/._tmp/ddat$$
mkdir -p $BASE_WORKDIR/._tmp/
DD_LOGFILE=$BASE_WORKDIR/.dbs_status
cp -f $DD_LOGFILE $TMP-DBS_STATUS 2>/dev/null
trap 'rm -f $TMP* >/dev/null; rm -fr $BASE_WORKDIR/._* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
}
# test dependencies
TESTDEPEND () {
NonFatalError () {
echo "FATAL ERROR at $0 (`date`): $FiLe not detected \
on this system." >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNDD\nFATAL ERROR at $0 (`date`)\n\n
$FiLe not detected on this system.
It is essential for $0 to work properly."
ABORT
}
if ! (type "$1" 1>/dev/null 2>&1); then
FiLe="$1"
NonFatalError $1
sleep 1; unset $FiLe
fi
}
TESTDEPEND_GO () {
TESTDEPEND "grep"; TESTDEPEND "sed"; TESTDEPEND "cut"
TESTDEPEND "wc"; TESTDEPEND "cat"; TESTDEPEND "expr"
}
# test dependencies which can have optional programs and set vars for those.
TESTDEPEND_SUBST () {
# test lynx/wget
if (type "lynx" 1>/dev/null 2>&1); then
dld_prg="lynx"
else
if (type "wget" 1>/dev/null 2>&1); then
dld_prg="wget"
fi
fi
if [ -z "$dld_prg" ]; then
echo -e "FATAL ERROR at $0 (`date`): lynx and wget not detected \
on this system. One it's necessary for this utility to work \
properly" >> $BASE_WORKDIR/error_messages
clear
echo -e "$PN\nFATAL ERROR at $0 (`date`)\n\n
Either lynx or wget are essential for $0 to work properly.
None of those programs were found on this system"
ABORT
fi
}
# download command line to parse redirection url
GET_SERVER_URLS () {
if [ "$dld_prg" = "lynx" ]; then
lynx -source http://darkbot.sourceforge.net 2>/dev/null > $TMP
else
wget -qO $TMP http://darkbot.sourceforge.net
fi
# parse redir. main url. ex: http://darkbot.sourceforge.net
REDIRECT_URL_MAIN=$(grep "FRAME SRC" $TMP | cut -d\" -f2)
# redirection url for dbs. ex: http://darkbot.sourceforge.net/arquive/databases/
REDIRECT_URL_DBS=""$REDIRECT_URL_MAIN"archive/databases"
if [ ! -s $TMP ]; then
clear
echo -e "$PNDD\nWARNING\n
Unable to establish connection with the server."
ABORT; fi
}
# get dbs info text
# download command line to parse redirection url
GET_DBS_INFO () {
if [ "$dld_prg" = "lynx" ]; then
lynx -dump -nolist "$REDIRECT_URL_MAIN"databases.html > $TMP-db.txt
else
wget -qO $TMP-db.txt "$REDIRECT_URL_MAIN"databases.html
fi
if ! grep -qwi "Pre-made" $TMP-db.txt 2>/dev/null; then
clear
echo -e "$PNDD\nWARNING\n
Unable to obtain from the server essential information."
ABORT; fi
}
# get vars -- Database=acro2
GET_DBS_VARS () {
if [ "$dld_prg" = "lynx" ]; then
cat $TMP-db.txt | sed -ne /Elaborated/s/[[:blank:]]*/Database=/p \
| cut -d ' ' -f1 | cut -d. -f1 > $TMP.db.vars
else
sed -ne /zip[\<a*]/s/[[:blank:]]*/Database=/p $TMP-db.txt \
| cut -d. -f1 > $TMP.db.vars
fi
}
# download status; evaluate user activity; check if any new database
# register activity in local file
DBS_STATUS () {
rm -f $TMP-DISPLAY # refresh list
numLines="$(cat $TMP.db.vars | wc -l | sed s/[[:blank:]]*//)"
count="0"
while [ "$count" != "$numLines" ]; do
count=`expr $count + 1`
sed -n "$count"p $TMP.db.vars > $TMP.db.var
unset Database
. $TMP.db.var
# get complete local line if exists and put it on a file list
grep -w "$Database" $TMP-DBS_STATUS 2>/dev/null > $TMP.db.loc.var
# check the status and put the result on an organized list to display
if [ -s $TMP.db.loc.var ]; then
if grep -w "{D}" $TMP.db.loc.var 1>/dev/null; then
echo "[$count] {D} $Database -`cat $TMP.db.loc.var | cut -d- -f2`" >> $TMP-DISPLAY; fi
if grep "{I}" $TMP.db.loc.var 1>/dev/null; then
echo "[$count] {I} $Database" >> $TMP-DISPLAY; fi
if grep "{x}" $TMP.db.loc.var 1>/dev/null; then
echo "[$count] {x} $Database -`cat $TMP.db.loc.var | cut -d- -f2`" >> $TMP-DISPLAY; fi
else
echo "[$count] {A} $Database" >> $TMP-DISPLAY
fi
done
# prep file to be used on live-update
cat $TMP-DISPLAY | grep -w "{A}" | cut -d\} -f2 > $COMMON_TMP/.dbs_available
} # end of DBS_STATUS
DBS_STATUS_FINAL () {
# move all new dbs status to local status file
rm -f $DD_LOGFILE
# extract all but {A} without list number
cut -d' ' -f2- $TMP-DISPLAY | grep -v "{A}" > $TMP-DISPLAY1
# extract {I} and add to local
grep "{I}" $TMP-DISPLAY1 >> $DD_LOGFILE
# extract old {D} and add to local
grep "{D}" $TMP-DISPLAY1 >> $DD_LOGFILE
# move newly download entries to local
cat $TMP-DISPLAY2 2>/dev/null >> $DD_LOGFILE
}
# MENU and DOWNLOAD
DBS_MENU_DLD () {
while [ -z $LEAVENOW ]; do
DBS_STATUS
clear
# menu
# start by listing dbs by number and corresponding db, ex: 1 acro2.db
echo -e "$PNDD\nAvailable Databases:
( {A}=Available {D}=Downloaded {I}=Ignored {x}=Marked for Installation )
`#cut -d= -f2 $TMP.db.vars | cat -b`
`cat $TMP-DISPLAY`
------------------------------------
[I] Ignore databases
`if [ "$dld_prg" = "lynx" ]; then echo -e " [R] Read Databases information"; fi`
[Q] Quit "$Quit_txt"" | less -deXF
echo -n "
Please make your choice. To select databases write their corresponding
numbers, separated by spaces or commas, ie, 1,2,5 or 1 2 5: "
read CHOICE
# outputs 1 2 3 etc corresponding to database number or I/X
# dbs to be ignored
_DBS_IGNORE () {
clear
echo -e "$PNDD\nIgnore Databases\n
This feature is only useful when $0 is being used
during live-update process so the utility will not prompt for available
pre-made databases on non wanted files.\n"
echo -n "Enter the number corresponding to the database to be ignored
or write 'ALL' to mark all {A}vailable databases as {I}gnored: "
read CHOICE_I
# mark all ignored
if echo "$CHOICE_I" | grep -qwi all 1>/dev/null; then
sed s/{A}/{I}/g $TMP-DISPLAY > $TMP
cat $TMP | cut -d' ' -f2- > $TMP-DBS_STATUS
fi
# if choice is a number
sed -n "$CHOICE_I"p $TMP.db.vars 2>/dev/null > $TMP.db.vari
. $TMP.db.vari
#check if it is marked other way than {A}. (for {D} or {x})
if [ "$CHOICE_I" != "all" ] || [ "$CHOICE_I" != "uuu" ] ; then
grep -wi "$Database" $TMP-DISPLAY > $TMP
if grep -qwi "{D}" $TMP 2>/dev/null; then
echo -e "\nDatabase $Database is marked as {D}ownloaded!\n"; sleep 2
elif grep -qwi "{x}" $TMP; then
echo -e "\nDatabase $Database is {x} marked for installation!\n"; sleep 2
else # is marked as {A} so {I}gnore
echo "{I} $Database" >> $TMP-DBS_STATUS
fi
fi # if not all or uuu
} # end of _DBS_IGNORE (Ignore options)
if echo $CHOICE | grep -qwi i 1>/dev/null; then _DBS_IGNORE; fi
# [r]ead info about the files
if echo $CHOICE | grep -qwi r 1>/dev/null; then
clear
echo -e "$PNDD\nAvailable database files information\n
`grep Elaborated $TMP-db.txt | less -deX`
\nPress ENTER to continue"
read PTR
fi
# [q]uits databases utility and start integrity check in case there is any {x}
if echo $CHOICE | grep -qwi q 1>/dev/null; then
# check if $TMP-DISPLAY2 exists (created if there is any {x}download)
if [ ! -s $TMP-DISPLAY2 ]; then # no files to download so log other changes
DBS_STATUS_FINAL
fi
LEAVENOW=end
fi
DB_SELECT_DLD () {
# check how many lines on the remote list
numLines="$(cat $TMP.db.vars | wc -l | sed s/[[:blank:]]*//)"
# set max = total number/lines
max="$numLines"; count="0"
while [ $count != $max ]; do
count=`expr $count + 1`
# if CHOICE is between the range of num lines/items to choose
if (echo $CHOICE | grep -qw "$count" 1>/dev/null); then
# extract corresponding line from vars file
sed -n "$count"p $TMP.db.vars > $TMP.db.var
# then extracs var itself, ie Database=whatever
. $TMP.db.var
DLD_PRG_COMMLINE4 () {
clear; echo -e "\n$PNDD\n
\n* ========== > Downloading $Database pre-made database > > > >\n\nPlease wait..."
if [ "$dld_prg" = "lynx" ]; then
lynx -source "$REDIRECT_URL_DBS/$Database".db >> $TMP-DB_MASTER
else
wget -qO $TMP-DB_MASTER "$REDIRECT_URL_DBS"/"$Database".db
fi
# add database to log file
echo "{x} $Database - (marked for installation)" >> $TMP-DBS_STATUS
# prepare log entry in case the process finishes
echo "{D} $Database - `date +%D`" >> $TMP-DISPLAY2
# just a var for QUIT text
Quit_txt="and proceed with check integrity and final installation."
}
# check if it was ignored
if grep -w "$Database" $TMP-DBS_STATUS 2>/dev/null | grep -qw "{I}"; then
clear
echo -e "$PNDD\n
Removing [I]gnored status from "$Database"..."
sleep 2
grep -wv $Database $TMP-DBS_STATUS > $TMP
cat $TMP > $TMP-DBS_STATUS
fi
# check if it was downloaded already
if grep -w "$Database" $TMP-DBS_STATUS 2>/dev/null | grep -qw "{D}"; then
clear
echo -e "$PNDD\n
Looks like you have already downloaded database
`grep -w "$Database" $TMP-DBS_STATUS`.\n"
echo -n "Download it again? [(y)es or (n)o]: "
unset yesno1
read yesno1
case $yesno1 in
y* | Y*)
input1=y;;
n* | N*)
input1=n;;
esac
# if Y remove from list; download
if [ "$input1" = "y" ]; then
grep -wv $Database $TMP-DBS_STATUS > $TMP
cat $TMP > $TMP-DBS_STATUS
DLD_PRG_COMMLINE4
fi
else # means is a 1st download
DLD_PRG_COMMLINE4
fi # end of if database is in status list
fi
done
} # end DB_SELECT_DLD
DB_SELECT_DLD
done
} # DBS_MENU_DLD
DBS_FINALS () {
if [ -s $TMP-DB_MASTER ]; then
DBS_STATUS_FINAL
if [ -s check-integrity ]; then
cat $TMP-DB_MASTER > $COMMON_TMP/TMP-DB_MASTER
./check-integrity DB_MASTER
else
if [ -s ../dat/external_databases ]; then
mv -f ../dat/external_databases ../dat/external_databases.old
fi
cat $TMP-DB_MASTER > ../dat/external_databases
clear
echo -e ""$PNDD"\nDownloaded database is now at ../dat/external_databases\n
Move it to your info2.db file by writing
cat external_databases >> info2.db\n\n"
fi
fi
}
if [ "$1" = "-s" ]; then
ENVIRONMENT
TESTDEPEND_GO
TESTDEPEND_SUBST
GET_SERVER_URLS
GET_DBS_INFO
GET_DBS_VARS
DBS_STATUS
else
ENVIRONMENT
TESTDEPEND_GO
TESTDEPEND_SUBST
GET_SERVER_URLS
GET_DBS_INFO
GET_DBS_VARS
DBS_MENU_DLD
DBS_FINALS
fi
diff --git a/scripts/kill.darkbot b/scripts/kill.darkbot
index 546becc..2b1a429 100755
--- a/scripts/kill.darkbot
+++ b/scripts/kill.darkbot
@@ -1,5 +1,14 @@
#!/bin/sh
# Kills darkbot.pid process.
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
kill -9 `cat ../darkbot.pid`
diff --git a/scripts/live-update b/scripts/live-update
index c9e70a0..3889352 100755
--- a/scripts/live-update
+++ b/scripts/live-update
@@ -1,552 +1,562 @@
#!/bin/sh
+
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
PNLU="Darkbot Live-Update"
PN2="
$PNLU
<*******_~_*******>
"
PID=0624233000
USAGE () {
echo -e >&2 "\n$PNLU - Updates Darkbot program.\n
This program basically does the following: checks directory and file
integrity; contacts Darkbot site and downloads latest information;
compares recent information with the one installed; updates local
installation if necessary or display messages from the developers.\n
Usage: <program> -[option]
"$0" (with no option/flag) executes the program
"$0" -u Undo last changes
"$0" -n News - (latest news, usually related to updates)
"$0" -v (v0, v1, v2) Verbose mode. [currently - `if [ "$verbose" = "" ]; then echo "1"; else echo "$verbose"; fi`] *
"$0" -h Help information (this one)
"$0" -o "$PNLU" execution ON/OFF [currently `if [ "$livupd_OnOff" != "OFF" ]; then echo "ON"; else echo "OFF"; fi`] *\n
* - By switching this utility OFF you'll not be able to
receive live updates from Darkbot's site.
* - Settings for verbose: 0=stealth/silent; 1=minimal messages (default,
no prompts if no updates present); 2=all available messages\n
Support: http://darkbot.sourceforge.net\n"
exit 1
}
ABORT () {
echo -e "\nThis utility will stop now!\n\nLeav\
ing $PNLU...\n\n\n"; sleep 1; exit 0
}
DB_SCRIPTS_PATH () {
dirutil="scripts"
filutil="`basename $0`"
# check if dir is correct
if ! echo `pwd` | grep -q "\/"$dirutil""; then
# file is not being launched from $dirutil
if [ -d "$dirutil" ]; then # dir is there
# if file is not in the correct dir
if [ ! "`ls "$dirutil" | grep "$filutil"`" ]; then
# file is not in the correct dir so move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory.\n"
echo "Moving it now...."
sleep 2
cat > db_wrong_path << EOF[WP]
mv -f $0 "$dirutil"/
cd "$dirutil"/
echo -e "\n| Your "$filutil" is now located in your "$dirutil" directory |
| Launch it from there when necessary |\n\n"
sleep 4
$0
rm -f ../db_wrong_path
exit 0
EOF[WP]
. db_wrong_path
else # file is in dir so just cd
cd "$dirutil"/
fi
else # dir is not there so don't bother - tell user to move it
clear
echo -e "$PNCI\n\n##### WARNING #####\n\n"$filutil" must be located \
in "$dirutil" directory and launched from there or Darkbot's root.
Please move it and launch it again."
sleep 3
ABORT
fi
fi
}
#DB_SCRIPTS_PATH
ENVIRONMENT () {
# set environment dirs and vars
BASE_WORKDIR=.scriptutils
COMMON_TMP=$BASE_WORKDIR/tmp
mkdir -p $BASE_WORKDIR/tmp
LUDIR=$BASE_WORKDIR/liveupdate
TMP=$LUDIR/._tmp/lu$$
mkdir -p $LUDIR/._tmp/
if [ -e "$LUDIR/.l_vars" ]; then
. "$LUDIR/.l_vars"; fi
trap 'rm -fr $COMMON_TMP >/dev/null; rm -fr $TMP* >/dev/null; \
rm -fr $LUDIR/._* >/dev/null 2>&1' 0
m_trap="echo -e \n\n -- `basename $0` terminated by `whoami` --\n\n"
trap '$m_trap 1>&2; exit' 1 2 3 13 15
}
# test dependencies
TESTDEPEND () {
NonFatalError () {
echo "FATAL ERROR at $0 (`date`): $FiLe not detected \
on this system." >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNLU\nFATAL ERROR at $0 (`date`)\n\n
$FiLe not detected on this system.
It is essential for $0 to work properly."
ABORT
}
if ! (type "$1" 1>/dev/null 2>&1); then
FiLe="$1"
NonFatalError $1
sleep 1; unset $FiLe
fi
}
TESTDEPEND_GO () {
TESTDEPEND "grep"; TESTDEPEND "sed"; TESTDEPEND "cut"; TESTDEPEND "tar"
TESTDEPEND "wc"; TESTDEPEND "cat"; TESTDEPEND "expr"; TESTDEPEND "head"
}
TESTDEPEND_GO
# test dependencies which can have optional programs and set vars for those.
TESTDEPEND_SUBST () {
# test lynx/wget
if (type "lynx" 1>/dev/null 2>&1); then
dld_prg="lynx"
else
if (type "wget" 1>/dev/null 2>&1); then
dld_prg="wget"
fi
fi
if [ -z "$dld_prg" ]; then
echo -e "FATAL ERROR at $0 (`date`): lynx and wget not detected \
on this system. One it's necessary for this utility to work \
properly" >> $BASE_WORKDIR/error_messages
clear
echo -e "$PNLU\nFATAL ERROR at $0 (`date`)\n\n
Either lynx or wget are essential for $0 to work properly.
None of those programs were found on this system"
ABORT
fi
}
TESTDEPEND_SUBST
YESNO() {
# usage -- YESNO "question..?"
# if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then echo no; fi
# y/n function - Returns: 0 (true) = yes; 1 (false) = no
YESNO_DFLT=y # Set default: -y = yes; -n = no; otherwise no default
# options & args
for YESNO_OPT do
case "$YESNO_OPT" in
-[yY]*) YESNO_DFLT='y' ;;
-[nN]*) YESNO_DFLT='n' ;;
--) shift; break ;;
-*) ;;
*) break
esac
shift
done
YESNO_PROMPT="$*"
# get the response
while : ; do
echo -n "$YESNO_PROMPT (y/n)?${YESNO_DFLT:+ [$YESNO_DFLT]} " >&2
read YESNO_ANSWER YESNO_JUNK
: ${YESNO_ANSWER:=$YESNO_DFLT}
case "$YESNO_ANSWER" in
[yY]*)
#echo "YES ANSWER"
return 0
;;
[nN]*)
#echo "NO ANSWER"
return 1
;;
*)
clear
echo -e "$PN2\n\nERROR: invalid entry!\n
PLEASE press ENTER or type Y (Yes) to proceed or N (No) or CTRL+C to abort.
..." >&2
esac
done
return
}
###### LOGS ######
LOG_VARS () {
echo "livupd_OnOff=\"$livupd_OnOff\"" > $LUDIR/.l_vars
echo "WarnOnOff=\"$WarnOnOff\"" >> $LUDIR/.l_vars
echo "verbose=\"$verbose\"" >> $LUDIR/.l_vars
echo "l_livupdID=\"$livupdID\"" >> $LUDIR/.l_vars
echo "loc_Revision=\"$Revision\"" >> $LUDIR/.l_vars
echo "prev_Revision=\"$l_version\"" >> $LUDIR/.l_vars
echo "LastUpdate=\"`date`\"" >> $LUDIR/.l_vars
echo "l_db_dir=\"$l_db_dir\"" >> $LUDIR/.l_vars
}
LOG_NEWS () {
if [ -z "$TMP-livupd" ]; then
echo "No NEWS available from last update." > $LUDIR/.l_news
else
. $TMP-livupd -n > $LUDIR/.l_news
fi
}
INTEGRITY () {
if [ -d "../source" ]; then
if [ "`ls -l ../source 2>/dev/null | grep '[ch]$'`" != "" ]; then
l_sourceDir="../source"; dat="../dat"; docs="../docs"; scripts="../scripts"
l_db_dir=`pwd | cut -d/ -f4`
else
clear
echo -e "$PN2\n\nWARNING!!!!\n\n No source files found!\n"
ABORT
fi
else
if [ -e "../darkbot.c" ]; then
l_sourceDir=".."; dat="../dat"; docs="../docs"; scripts="../scripts"
l_db_dir=`pwd | cut -d/ -f4`
else
clear
echo -e "$PN2\n\nWARNING!!!!\n\n No source files found!\n"
ABORT
fi
fi #source exists
}
REMOTE1 () {
# download command line
DLD_PRG_COMMLINE () {
updater="http://darkbot.sourceforge.net/project_utils"
#updater="http://192.168.1.10/ongoing/.livupd"
if [ "$dld_prg" = "lynx" ]; then
lynx -source "$updater" > $TMP-livupd
else
wget -qO $TMP-livupd "$updater"
fi
}
#get remote updater
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
Contacting Darkbot site.\n\n
Please wait..."
sleep 3
else 1>&2; fi
trymax="3"; trycount="0"
while [ "$trycount" != "$trymax" ] && [ ! -s $TMP-livupd ]; do
trycount=`expr $trycount + 1`
########################################################
DLD_PRG_COMMLINE
#cp -f .livupd $TMP-livupd # debug only
done
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
Connection with Darkbot site established.
Retrieving the most recent information...\n
Please wait"
sleep 3
else 1>&2
fi
}
CHECK_PREMADE_DBS () {
# check for pre-made databases
if [ "$check_pre_made_dbs" != "complete" ]; then
./download-databases -s
if [ -s $COMMON_TMP/.dbs_available ]; then
rm -f $COMMON_TMP/.dbs_available
clear
echo -e "$PN2\n
Detected pre-made databases available for download!\n\n"
YESNO " Run pre-made databases download utility?
[ ENTER or Y (Yes); N (No) or CTRL+C to abort ]"
if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then
clear
echo -e "$PN2\nIf you want to avoid $0 detecting available databases
select 'I' on ./download-databases to ignore them.\n
Bypassing pre-made databases download utility...\n
[ Hit ENTER to continue ]\n"
read PTR
else
echo -e "\nPlease wait..."; sleep 1
./download-databases
echo -e "Pre-made databases check complete!\n\n"
sleep 3
check_pre_made_dbs=complete
fi
fi
fi
} # end of check/pre-made databases
REMOTE2 () {
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
Information with latest updates received.
Comparing local information with the current one from the site...\n
Please wait"
sleep 3
else 1>&2
fi
# change local id vars so remote ones will not colide
# check remote vars
. $TMP-livupd -cvars 2>/dev/null
if [ ! -z "$livupdID" ]; then
# remote file id not null so proceed
if [ "$l_livupdID" != "$livupdID" ]; then
# local file id != same as remote one so there's something new
if [ ! -z "$loc_Revision" ]; then
if [ "$loc_Revision" != "$Revision" ]; then
# local revision != same as remote so there is a new program release
if [ "$verbose" != "0" ]; then clear
echo -e "$PN2\n
New Release Update detected!\n
You have Darkbot $loc_Revision installed.
Most recent release is Darkbot $Revision.\n\n"
YESNO " Read information about it?
[ENTER or Y (Yes) to read it or N (No) not to. CTRL+C aborts]"
if [ "$YESNO_ANSWER" != "n" ]; then
if [ "$YESNO_ANSWER" != "N" ]; then
# display news
. $TMP-livupd -n
YESNO "
..............
Proceed?
[ ENTER or Y (Yes) to proceed; N (No) or CTRL+C to abort ]"
if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then ABORT; fi
fi
fi # yes/no answer is no
else 1>&2; fi # verbose = 0
# run remote updater
. $TMP-livupd -s
else
if [ "$loc_Revision" = "$Revision" ]; then
if [ "$verbose" != "0" ]; then clear; echo -e "$PN2\n
You are running Darkbot "$Revision", latest release."
sleep 1
else 1>&2; fi
fi
# local revision is the same as remote but still there's something new
# first display news then run optional updater; this optional script can
# also have small updates or non source ones, like new database
if [ "$verbose" != "0" ]; then #clear
echo -e "\n There are some NEWS from Darkbot's developers
regarding your Darkbot $loc_Revision!\n"
YESNO " Read it?
[ ENTER or Y (Yes) to proceed; N (No) or CTRL+C to abort ]"
if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then ABORT; fi
else 1>&2; fi # verbose = 0
. $TMP-livupd -n
. $TMP-livupd -o
LOG_VARS
LOG_NEWS
fi
else # missing local revision
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
Unable to obtain local revision ID
Most probably due to misplaced or adulterated source files.\n"
ABORT
else 1>&2; fi
fi
else # files ids are the same
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
No news or updates available!\n\n
Leaving $PNLU..."
echo -e "\n\n"
sleep 3
else 1>&2; fi
exit 0
fi
else # no remote file id present so we didn't get the file or arrived corrupted
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n
Unable to compare information at this time.
most probably due to misplaced source files or adulterated version.\n
Leaving $0...\n"
sleep 3
else 1>&2; fi
exit 0
fi
}
###### STARTING & LIVE-UPDATE SETTINGS ######
VERBOSE () {
if [ ! -z "$1" ]; then # means choice is 0, 1 or 2
if [ "$verbose" != "$1" ]; then
verbose="$1"
LOG_VARS
fi
clear
echo -e "$PN2\n\n Switch value on $PNLU for verbose mode is now [\
`if [ "$verbose" = "" ]; then echo "1"; else echo "$verbose"; fi`] \n"
if [ "$verbose" = "0" ]; then
echo -e " which means, NO $PNLU program messages will be shown.
Recommended setting is 1 (minimal display of messages).\n
NOTE: have in mind, by deactivating \""$PNLU"\" functioning
messages you'd might miss important information!\n"
fi
if [ "$verbose" = "1" ]; then
echo -e " which means, MINIMAL but essential program messages will be shown.\n"
fi
if [ "$verbose" = "2" ]; then
echo -e " which means, ALL program messages will be shown.\n"
fi
else clear # choice was v or V (var $1 null)
echo -e "$PN2\n\n $PNLU verbose mode is currently on value [\
`if [ "$verbose" = "" ]; then echo "1"; else echo "$verbose"; fi`] \n"
fi
echo -e " Possible options/values are:
$0 -v Displays verbose status.
$0 -v0 Turns all messages off. (stealth mode - Not recommendable)
$0 -v1 Runs with essential messages. ( default - Recommended)
$0 -v2 Runs with all available program messages.
-------------------------------------------------
* option 0 will not run the engine on the background and not all messages will
be hidden, specially the ones involving the actual update process, because
we want you to know what's going into your computer.\n\n"
exit 1
}
LIVUPDONOFF () {
if [ "$livupd_OnOff" = "ON" ] || [ -z "$livupd_OnOff" ]; then
livupd_OnOff=OFF
else
livupd_OnOff=ON
fi
LOG_VARS
clear
echo -e "$PN2\n\nON/OFF program switch is now turned "$livupd_OnOff".\n"
if [ "$livupd_OnOff" = "OFF" ]; then
echo -e "NOTE: have in mind, by deactivating \""$PNLU"\"
you'll not be able to receive live updates!\n\n"
fi
if [ "$livupd_OnOff" = "ON" ]; then
echo -e " To run "$PNLU" just type $0\n\n"
fi
exit 1
}
WARNONOFF () {
if [ "$WarnOnOff" = "ON" ] || [ -z "$WarnOnOff" ]; then
WarnOnOff=OFF
else
WarnOnOff=ON
fi
LOG_VARS
clear
echo -e "$PN2\n\nON/OFF switch WARNING message is now turned "$WarnOnOff"\n"
if [ "$WarnOnOff" = "OFF" ]; then
echo -e "which means you can't receive live updates from Darkbot's site.\n
**** It's recommendable reactivating it by writing $0 -o
* You can see a short program usage help by typing $0 -h
* If you don't want to see this warning again type $0 -W
**************************************************\n\n"
fi
exit 1
}
#__________________________________________________________________
### START ENGINE ###
ENVIRONMENT
# switches
if [ "$1" = "-n" ] || [ "$1" = "-N" ]; then
if [ -e "$LUDIR/.l_news" ]; then clear
cat $LUDIR/.l_news | less -de; exit 1
else clear
echo -e "$PN2\n\n Sorry, no news available.\n\n"
exit 1
fi
fi
if [ "$1" = "-u" ] || [ "$1" = "-U" ]; then
if [ -e "$LUDIR/.l_undo" ]; then
clear
echo -e "$PN2\n\n This operation will restore your Darkbot as it was \
before latest
update ($LastUpdate - Darkbot $prev_Revision -> $loc_Revision).
All $PNLU settings will return to it's defaults.\n"
YESNO " Are you sure you want to reverse your changes?
[ ENTER or Y (Yes) to proceed; N (No) or CTRL+C to abort ]"
if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then ABORT; fi
tar -zxf $LUDIR/back.tar.gz -C $LUDIR
. $LUDIR/.l_undo
clear
echo -e "$PN2\n\n Changes reversed to their previous state.\n
$PNLU returned to it's default mode.\n\n"
rm -fr $LUDIR
exit 1
else clear
echo -e "$PN2\n\n Sorry, no UNDO CHANGES available.\n\n"
if [ ! -z "$loc_Revision" ]; then
echo -e " This utility was last used on $LastUpdate
during Darkbot $prev_Revision to $loc_Revision live update.
To see information about last update type $0 -n\n\n"; fi
exit 1
fi
fi
if [ "$1" = "-v" ] || [ "$1" = "-V" ]; then VERBOSE; fi
if [ "$1" = "-v0" ]; then VERBOSE 0; fi
if [ "$1" = "-v1" ]; then VERBOSE 1; fi
if [ "$1" = "-v2" ]; then VERBOSE 2; fi
if [ "$1" = "-h" ] || [ "$1" = "--h" ]; then clear; USAGE; fi
if [ "$1" = "-o" ] || [ "$1" = "-O" ]; then LIVUPDONOFF; fi
if [ "$1" = "-w" ] || [ "$1" = "-W" ]; then WARNONOFF; fi
if [ -z "$livupd_OnOff" ] || [ "$livupd_OnOff" != "OFF" ]; then
# if no vars present this is a first time
if [ ! -e "$LUDIR/.l_vars" ]; then
clear
echo -e "$PN2\n
Welcome to $PNLU engine.
Looks like this is your first time running this utility
(or you've reversed to it's defaults any previous changes).\n
For help on $PNLU options exit and type $0 -h
or press ENTER to proceed with update process.
If there are no updates available this utility will exit with
no messages.\n"
YESNO " Proceed?
[ ENTER or Y (Yes) to proceed; N (No) or CTRL+C to exit ]"
if [ "$YESNO_ANSWER" = "n" -o "$YESNO_ANSWER" = "N" ]; then ABORT; fi
fi
INTEGRITY
if [ ! -z "$l_sourceDir" ]; then
REMOTE1
if [ -s download-databases ]; then CHECK_PREMADE_DBS; fi
fi
# check if update file came
if [ ! "`grep livupdID $TMP-livupd 2>/dev/null`" ]; then
if [ "$verbose" = "2" ]; then clear
echo -e "$PN2\n\nUnable to retrieve update information.
Leaving....\n\n"
else 1>&2
fi
exit 0
fi
if [ ! -z "$TMP-livupd" ]; then REMOTE2
fi
if [ "$remote_end" = "end" ]; then LOG_VARS; LOG_NEWS
exit 0
fi
else # program is off by user choice so.. exit with a warning
if [ -z "$WarnOnOff" ] || [ "$WarnOnOff" != "OFF" ]; then
clear
echo -e "$PN2\n\nWARNING\n
$PNLU is inactive (OFF)
which means you can't receive live updates from Darkbot's site.\n
**** It's recommendable reactivating it by writing $0 -o
* You can see a short program usage help by typing $0 -h
* If you don't want to see this warning again type $0 -W
**************************************************\n\n"
fi
fi
exit 0
diff --git a/scripts/restart.darkbot b/scripts/restart.darkbot
index e416b3b..94949c3 100755
--- a/scripts/restart.darkbot
+++ b/scripts/restart.darkbot
@@ -1,5 +1,14 @@
#!/bin/sh
# Restarts darkbot.pid process. (only for unix)
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
kill -HUP `cat ../darkbot.pid`
diff --git a/source/Makefile.am b/source/Makefile.am
index 0d72a54..5919451 100644
--- a/source/Makefile.am
+++ b/source/Makefile.am
@@ -1,59 +1,68 @@
## Process this file with automake to produce Makefile.in.
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
## Top level diectory.
topdir = @srcdir@/..
db_db = $(topdir)/dat
db_src = $(topdir)/source
cm_src = $(topdir)/source/compat
db_scripts = $(topdir)/scripts
VPATH = @srcdir@/../source @srcdir@/../source/compat
## Database location.
databasedir = $(localstatedir)/@PACKAGE@
## Setup options for other programs.
ACLOCAL_AMFLAGS = -I ../m4
AM_CPPFLAGS = -g -I $(db_src) -I $(cm_src) -DDATABASEDIR='"$(databasedir)"' -DSOURCEDIR='"@srcdir@"'
## Compatability library.
noinst_LIBRARIES = compat/libcompat.a
compat_libcompat_a_SOURCES = dummy.c
compat_libcompat_a_LIBADD = @LIBOBJS@
## Darkbot server.
bin_PROGRAMS = darkbot convertdb
darkbot_SOURCES = chan.c general.c permbans.c reserved.c sockets.c \
users.c chansrv.c helpers.c quiz.c seen.c stats.c \
vars.c comm.c main.c random.c server.c topics.c web.c \
parse.c raw.c signals.c tree.c url.c xmlame.c \
langs/*.h \
prototypes.h tree.h vars.h
darkbot_LDADD = compat/libcompat.a
## Utility programs.
convertdb_SOURCES = convertdb.c
convertdb_LDADD = compat/libcompat.a
dist_bin_SCRIPTS = $(db_scripts)/AddServer $(db_scripts)/AddUser $(db_scripts)/check-integrity $(db_scripts)/dbcron $(db_scripts)/download-databases \
$(db_scripts)/kill.darkbot $(db_scripts)/live-update $(db_scripts)/restart.darkbot $(db_scripts)/Setup
## databases.
dist_database_DATA = $(db_db)/deop.ini $(db_db)/info2.db $(db_db)/perform.ini $(db_db)/permbans.db $(db_db)/quiz.db $(db_db)/random.ini \
$(db_db)/randomstuff.ini $(db_db)/servers.ini $(db_db)/setup.ini $(db_db)/stats.db $(db_db)/userlist.db
rdbdir = $(databasedir)/rdb
dist_rdb_DATA = $(db_db)/rdb/dunno.rdb $(db_db)/rdb/whut.rdb
timersdir = $(databasedir)/timers
## Documentation.
## docdir = $(datadir)/doc/@PACKAGE@
doc_DATA = $(topdir)/COPYING $(topdir)/docs/INSTALL $(topdir)/README $(topdir)/VERSION $(topdir)/docs/AUTHORS $(topdir)/docs/HACKING \
$(topdir)/docs/README_UTILS $(topdir)/docs/TODO $(topdir)/docs/WHATSNEW
## FIXME: Move this one to a ./configure --enable-win32-console
## Uncomment this line for no-console mode on Windows.
## AM_LDFLAGS = -Wl,--subsystem,windows
## FIXME: Check that autofoo is doing its job and then remove this.
## Uncomment this line to compile on Solaris.
## AM_LIBS = -lresolv
diff --git a/source/chan.c b/source/chan.c
index 17b9c7e..4354644 100644
--- a/source/chan.c
+++ b/source/chan.c
@@ -1,599 +1,610 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#ifdef ENABLE_MATH
/* Changed input to be unsigned instead of signed. This
* suppressed warning messages when compiling on Solaris.
*/
struct chanserv_output *do_math (const char *who, char *target, char *math)
{
char number_string[STRING_SHORT] = { 0 };
char op = 0;
unsigned char input[STRING_SHORT] = { 0 };
unsigned int index = 0;
unsigned int to = 0;
unsigned int input_length = 0;
unsigned int number_length = 0;
double result = 0.0;
double number = 0.0;
strncpy (input, math, sizeof (input));
input_length = strlen (input);
for (to = 0, index = 0; index <= input_length; index++)
if (*(input + index) != ' ')
*(input + to++) = *(input + index);
input_length = strlen (input);
index = 0;
if (input[index] == '=')
index++;
else
{
number_length = 0;
if (input[index] == '+' || input[index] == '-')
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
if (*(input + index) == '.')
{
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
}
*(number_string + number_length) = '\0';
if (number_length > 0)
result = atof (number_string);
}
for (; index < input_length;)
{
op = *(input + index++);
number_length = 0;
if (input[index] == '+' || input[index] == '-')
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
if (*(input + index) == '.')
{
*(number_string + number_length++) = *(input + index++);
for (; isdigit (*(input + index)); index++)
*(number_string + number_length++) = *(input + index);
}
*(number_string + number_length) = '\0';
number = atof (number_string);
switch (op)
{
case '+':
result += number;
break;
case '-':
result -= number;
break;
case '*':
result *= number;
break;
case '/':
if (number == 0)
{
L016 (target, who);
return;
}
else
result /= number;
break;
case '%':
if ((long) number == 0)
{
L016 (target, who);
return;
}
else
result = (double) ((long) result % (long) number);
break;
default:
L017 (target, who);
return;
}
}
return chanserv_asprintf(NULL, "%f\n", result);
}
#endif
long
cf (char *host, char *nick, char *chan)
{
int f_n = 0;
if (check_access (host, chan, 0, nick) >= 3)
return 0;
f_n = f_f (host);
if (f_n == -1)
{
a_f (host);
return 0;
}
if (ood[f_n].value)
return 1;
ood[f_n].count++;
if ((time (NULL) - ood[f_n].time) > FT)
ood[f_n].count = 0;
else if ((time (NULL) - ood[f_n].time) <= FT && ood[f_n].count >= FR)
{
ood[f_n].value = true;
if (!ood[f_n].kick)
{
ood[f_n].kick = 1;
if (*chan == '#' || *chan == '&')
{
#ifdef ENABLE_CHANNEL
if (FLOOD_KICK == true)
L018 (chan, nick, FLOOD_REASON, fc, host);
else
#endif
L019 (CHAN, fc, host);
}
else
L019 (CHAN, fc, host);
}
return 1;
}
ood[f_n].time = time (NULL);
return 0;
}
/**
* Update a nick's channel greeting and user@host.
* 6/23/00 Dan:
* - All method arguments are now pointers to const data
* - Rewrote to use a for loop, and fewer variables
* - Info is only saved to disk if changes are made
*/
void
update_setinfo (const char *new_uh, const char *new_greetz, const char *nick)
{
struct helperlist *c = helperhead;
bool madeChange = false;
size_t i = 0;
for (; c != NULL; c = c->next)
{
++i;
if (!match_wild (c->uh, new_uh) == 0)
{
strncpy (c->greetz, new_greetz, sizeof (c->greetz));
strlwr (c->uh);
L020 (nick, i, c->uh, new_greetz);
madeChange = true;
}
}
if (madeChange)
{
save_changes ();
}
}
/**
* 6/23/00 Dan:
* - All variables now initialized when declared
* - Altered variable types to reflect usage
*/
void
info (const char *source, char *target)
{
FILE *fp;
clock_t starttime = 0;
char b[STRING_LONG] = { 0 };
size_t topics = 0, dup = 0;
time_t t2time = 0, c_uptime = 0;
char *ptr = NULL, *subj = NULL;
char last[STRING_LONG] = { 0 };
t2time = time (NULL);
unlink (TMP_URL);
starttime = clock ();
fp = fopen (URL2, "r");
if (NULL == fp)
{
L003 (source, URL2);
return;
}
while (fgets (b, STRING_LONG, fp))
{
topics++;
if (FIND_DUPS)
{
if(*b == '\n')
continue;
stripline (b);
subj = strtok (b, " ");
ptr = strtok (NULL, "");
strlwr (subj);
if (strcasecmp (last, subj) == 0)
{
dup++;
if (SAVE_DUPS)
db_log (BACKUP_DUP, "%s %s\n", subj, ptr);
}
else
{
db_log (TMP_URL, "%s %s\n", subj, ptr);
}
strncpy (last, subj, sizeof (last));
last[sizeof (last) - 1] = '\0';
}
}
fclose (fp);
rename (TMP_URL, URL2);
if ((FIND_DUPS) && (dup > 0))
{
L025 (target, dup);
}
c_uptime = time (NULL) - uptime;
topics -= dup;
if (c_uptime > 86400)
{
L026 (target,
dbVersion,
topics,
c_uptime / 86400,
(c_uptime / 86400 ==
1) ? "" : "s",
(c_uptime / 3600) % 24,
(c_uptime / 60) % 60, QUESTIONS,
ADDITIONS, DELETIONS,
(double) (clock () -
starttime) /
CLOCKS_PER_SEC, (((double) (clock () - starttime) / CLOCKS_PER_SEC) == 1) ? "" : "s");
}
else if (c_uptime > 3600)
{
L027 (target,
dbVersion,
topics,
c_uptime / 3600,
c_uptime / 3600 == 1 ? "" : "s",
(c_uptime / 60) % 60,
(c_uptime / 60) % 60 ==
1 ? "" : "s", QUESTIONS,
ADDITIONS, DELETIONS,
(double) (clock () -
starttime) /
CLOCKS_PER_SEC, (((double) (clock () - starttime) / CLOCKS_PER_SEC) == 1) ? "" : "s");
}
else
{
L028 (target,
dbVersion,
topics,
c_uptime / 60,
c_uptime / 60 == 1 ? "" : "s",
c_uptime % 60,
c_uptime % 60 == 1 ? "" : "s",
QUESTIONS, ADDITIONS, DELETIONS,
(double) (clock () - starttime) / CLOCKS_PER_SEC, (((double)
(clock () -
starttime) /
CLOCKS_PER_SEC) == 1) ? "" : "s");
}
//#ifdef ENABLE_STATS
// get_stats(target, NULL); */
//#endif
}
/**
* Output information about the bot's database to a target.
* 6/22 Dan:
* - Changed both method arguments to be pointers to const data,
* this is a read only method.
*/
struct chanserv_output *show_info2 (const char *target, const char *source, enum chanserv_invoke_type invoked)
{
return chanserv_asprintf(NULL, "Compiled on %s. I have processed %ld lines of text since startup...", __DATE__, NUMLINESSEEN);
}
/**
* 6/23/00 Dan:
* - All method arguments are now pointer to const
* - Return type is now time_t
* - A for loop is now used instead of a while loop
*/
time_t
return_useridle (const char *chan, const char *who, int toggle)
{ /* toggle=0 is for idle time, toggle=1 is to check if user
is in the chan */
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, c->chan))
{
if (toggle == 1)
{
/* If we only care if user is present or not.. */
return 1;
}
else
return c->idle;
} /* if */
} /* for */
return 0;
}
void
process_nick (char *nick, char *newnick)
{
struct userlist *c;
c = userhead;
newnick++;
while (c)
{
if (strcasecmp (nick, c->nick) == 0)
{
strncpy (c->nick, newnick, sizeof (c->nick));
}
c = c->next;
}
// Check if it's our own bot nick being changed.
if (strcasecmp(nick, Mynick) == 0)
{
strncpy(Mynick, newnick, sizeof (Mynick));
strncpy(s_Mynick, Mynick, sizeof (s_Mynick));
snprintf(NICK_COMMA, sizeof (NICK_COMMA), "%s,", Mynick);
snprintf(COLON_NICK, sizeof (COLON_NICK), "%s:", Mynick);
snprintf(BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", Mynick);
}
}
/**
* 6/23/00 Dan:
* - All method arguments are now pointer to const
* - A for loop is now used instead of a while loop
*/
struct chanserv_output *show_chaninfo (const char *nick, const char *chan, const char *target)
{
size_t totalUsers = 0, foundUsers = 0;
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
++totalUsers;
if (!strcasecmp (chan, c->chan))
++foundUsers;
}
return chanserv_asprintf(NULL, "I see %d users in %s (%d users total in ram)", foundUsers, chan, totalUsers);
}
/*
* This function displays a list of users that are listed in the bot's internal user
* list as being on the channel pointed to by chan, to the nick pointed to by nick.
* Each message sent to the target should be no more than about 200 characters in length.
*/
struct chanserv_output *show_chanusers (const char *nick, const char *chan)
{
struct chanserv_output *result = NULL;
struct userlist *c = userhead;
char DATA[512] = {0};
size_t foundUsers = 0, len = 0;
for (; c != NULL; c = c->next)
{
if (strcasecmp (chan, c->chan) == 0)
{
++foundUsers;
strcat(DATA, c->nick);
strcat(DATA, " ");
/* Add the length of the new nick and room for a space to the length of the current buffer. */
len += (strlen(c->nick) + 1);
if (len >= 200)
{
result = chanserv_asprintf(result, DATA);
len = 0;
DATA[0] = 0;
db_sleep (2);
}
}
}
/* If there's any leftover data in our buffer after we've reached the end of the list send that as well. */
if (len > 0)
result = chanserv_asprintf(result, "%s", DATA);
/* Even if no users were found... */
result = chanserv_asprintf(result, "End of CHANUSERS list; %d user%s found.", foundUsers, (foundUsers == 1 ? "" : "s"));
return result;
}
void
do_modes (char *source, char *data)
{
char *chan = NULL, *mode = NULL, *nick = NULL, *ptr = NULL;
long PM = 0, j = 0, i = 0;
chan = strtok (data, " ");
mode = strtok (NULL, " ");
if ((ptr = strchr (source, '!')) != NULL)
*ptr++ = '\0';
j = strlen (mode);
i = -1; /* i needs to start at 0 */
while (j > 0)
{
j--;
i++;
if (mode[i] == '+')
PM = 1;
if (mode[i] == '-')
PM = 0;
if (mode[i] == 'o')
{
nick = strtok (NULL, " ");
do_op(nick, chan, PM); /* flag this member as having been (De)OP'd/ */
continue;
}
if (mode[i] == 'v')
{ /* voice sucks, ignore it */
nick = strtok (NULL, " ");
continue;
}
if (mode[i] == 'k' || mode[i] == 'b')
{
nick = strtok (NULL, " ");
if (nick[0] == '*' && nick[1] == '!')
{
nick += 2;
}
strlwr (nick);
if (PM == 1)
scan_chan_users (chan, source, nick);
continue;
}
if (mode[i] == 'l' && PM == 1)
{ /* don't parse if -limit
* since no parms */
nick = strtok (NULL, " ");
continue;
}
}
}
/**
* do_quit
*
* Purpose:
* 1) delete all instances when a nick matches (nick)
* 2) delete all users off a given channel
* 2) delete everything (i.e., when the bot is disconnected from irc)
*
* toggle 1 = delete user.
* toggle 2 = delete chan
* toggle 3 = everything (when I'm killed).
*/
void
do_quit (const char *nick, long toggle)
{
struct userlist *pNode = userhead;
struct userlist *pPrev = NULL;
if (toggle == 1)
{
/* delete user */
while (pNode)
{
if (strcasecmp (pNode->nick, nick) == 0)
{
/* found a match, remove it */
save_seen (pNode->nick, pNode->uh, pNode->chan);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
free (pNode);
pNode = pPrev->next;
}
else
{
/* first node in the list */
userhead = pNode->next;
free (pNode);
pNode = userhead;
}
}
else
{
/* No match, continue to next node */
pPrev = pNode;
pNode = pNode->next;
}
}
}
else if (toggle == 2)
{
/* delete channel */
while (pNode)
{
if (strcasecmp (pNode->chan, nick) == 0)
{
/* found a match, remove it */
save_seen (pNode->nick, pNode->uh, pNode->chan);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
free (pNode);
pNode = pPrev->next;
}
else
{
/* first node in the list */
userhead = pNode->next;
free (pNode);
pNode = userhead;
}
}
else
{
/* No match, continue to next node */
pPrev = pNode;
pNode = pNode->next;
}
}
}
else if (toggle == 3)
{
struct userlist *tempPtr = userhead;
while (pNode)
{
tempPtr = pNode->next;
free (pNode);
pNode = tempPtr;
}
}
}
long
f_f (char *host)
{
int i = 0;
for (i = 0; i < fc; i++)
if (!strcasecmp (ood[i].host, host))
return i;
return -1;
}
void
a_f (char *host)
{
if (++fc > 100)
fc = 0;
fc--;
strncpy (ood[fc].host, host, sizeof (ood[fc].host));
ood[fc].time = time (NULL);
ood[fc].count = 0;
ood[fc].value = false;
fc++;
}
void
reset_ (void)
{
int i = 0;
for (i = 0; i < fc; i++)
{
if (ood[i].value && (time (NULL) - ood[i].time) > rt)
{
ood[i].count = 0;
ood[i].time = time (NULL);
ood[i].value = false;
ood[i].kick = 0;
}
}
}
diff --git a/source/chansrv.c b/source/chansrv.c
index f5fae7d..c7f484a 100644
--- a/source/chansrv.c
+++ b/source/chansrv.c
@@ -1,2542 +1,2553 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
// FIXME: When the command is invoked in a channel, target is the channel name, otherwise target is the bots name?
// Due to the original nature of this code, some of these routines assume the in channel case, others assume the /msg case.
// Also check the commands that can have a channel argument work the same in and out of channel.
enum chanserv_command_type
{
INFO_COMMAND = 0,
SAFE_COMMAND = 1,
NORMAL_COMMAND = 2,
DANGER_COMMAND = 3,
PASSWORD_COMMAND = 4
};
struct chanserv_command
{
enum chanserv_command_type type;
int access;
int arg_count;
int too_many; /* Check for too many args */
struct chanserv_output *(*func) (char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost);
char *command[5];
char *syntax;
char *summary;
};
static void show_output(char *source, char *target, struct chanserv_output *result, enum chanserv_invoke_type input_type, int question);
struct chanserv_output *chanserv_show_help(char *cmd, int user_level);
struct chanserv_output *chanserv_asprintf(struct chanserv_output *output, const char *format, ...)
{
struct chanserv_output *result = NULL;
static char temp[BUFSIZ]; /* a temp buffer (8KB) */
va_list list;
int r;
va_start(list, format);
r = vsprintf(temp, format, list);
va_end(list);
if (r >= 0)
{
char *ptr;
ptr = malloc(r + 1);
if (ptr)
{
result = malloc(sizeof(struct chanserv_output));
if (result)
{
strncpy(ptr, temp, r); /* copy at most n */
ptr[r] = '\0'; /* ensure \0 at end */
result->output = ptr;
result->next = NULL;
if (output)
{
struct chanserv_output *next = output;
while (next->next)
next = next->next;
next->next = result;
result = output;
}
}
else
free(ptr);
}
}
if (result == NULL)
{
;// FIXME: Should bitch about lack of ram.
}
return result;
}
void chanserv_output_free(struct chanserv_output *output)
{
while (output)
{
struct chanserv_output *next = output->next;
free(output->output);
free(output);
output = next;
}
}
struct chanserv_output *chanserv_add(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = { 0 }, topic [STRING_LONG] = {0};
if (!args || !args[0])
return chanserv_asprintf(NULL, "Add what?");
/* Save topic since we're chopping args[0] off later. */
strncpy (topic, args[0], sizeof (topic));
/* Check to make sure the topic doesn't exist first. */
if (check_existing_url(source, topic, target) == 1)
{
return chanserv_asprintf(result, "%s \37%s\37\n",
EXISTING_ENTRY, topic);
}
/* Cut off the first argument (the topic) */
args++;
if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf(result, "What info is to be added for %s?", topic);
// Fix for some segmentation fault problems
// concerning topics consisting entirely of
// wildcard characters.
if (strspn(topic, "*?") == strlen(topic))
return chanserv_asprintf(NULL, "Sorry, but support for that topic has been removed.");
/* FIXME: If both things happen, result is overwritten with
* the second event, and the first truncation isn't displayed
*/
if (strlen(topic) > MAX_TOPIC_SIZE)
{
topic[MAX_TOPIC_SIZE] = '\0';
result = chanserv_asprintf(NULL, "Topic is over the limit, and has had characters truncated.");
}
if (strlen(str) > MAX_DATA_SIZE)
{
str[MAX_DATA_SIZE] = '\0';
result = chanserv_asprintf(NULL, "Data is over the limit, and has had characters truncated.");
}
strlwr(topic);
/* Don't allow the topic to be an rdb file name. */
if (*topic == '~')
return chanserv_asprintf(result, "Rdb files can only be called from the data of a topic, they cannot be used in the topic itself.");
if (LOG_ADD_DELETES)
db_log(ADD_DELETES, "[%s] %s!%s ADD %s %s\n", date(), source,
userhost, topic, str);
ADDITIONS++;
if ((strspn (topic, "ilc")) == 3 ||
(strspn (topic, "iln")) == 3)
{
db_log(URL2, "%s ([%s] %s!%s): %s\n", topic, date(),
source, userhost, str);
}
else
{
db_log(URL2, "%s %s\n", topic, str);
}
return chanserv_asprintf(result, "Okay.");
}
struct chanserv_output *chanserv_add_user(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char temp[1024] = { 0 };
long sn = 0;
if (!args || !args[0] || !args[1] || !args[2] || !args[3])
return result;
sn = atoi(args[2]);
if (sn > 10 || sn <= 0)
return result;
if (strlen(args[1]) < 7)
return result;
snprintf(temp, sizeof (temp), "I haven't used \2%cSETINFO\2 yet!", *CMDCHAR);
add_helper(args[0], mask_from_nick(args[1], target), sn, 0, temp, args[3], 0);
save_changes();
return chanserv_asprintf(NULL, "Added user: %s - level %d.", mask_from_nick(args[1], target), sn);
}
struct chanserv_output *chanserv_alarm(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char temp[1024] = { 0 };
time_t sn = 0, unixtime = 0;
long i = 0;
if (!args || !args[0] || !args[1] || (strlen(args[0]) < 2))
return chanserv_asprintf(NULL, "Syntax: <time type: \2d/h/m/s\2><time> <text to say>");
if (tolower(*args[0]) == 'd')
{
/* Days. */
sn = 86400;
args[0]++;
}
else if (tolower(*args[0]) == 'h')
{
/* Hours */
sn = 3600;
args[0]++;
}
else if (tolower(*args[0]) == 'm')
{
/* Minutes */
sn = 60;
args[0]++;
}
else if (tolower(*args[0]) == 's')
{
/* Seconds */
sn = 1;
args[0]++;
}
else
{
return chanserv_asprintf(NULL, "Syntax: <time type: \2d/h/m/s\2><time> <text to say>");
}
snprintf(temp, sizeof (temp), "%s/%ld",
DBTIMERS_PATH,
(atoi (args[0]) * sn) + time (NULL));
db_log(temp, "PRIVMSG %s :\2ALARMCLOCK\2 by %s!%s: %s", source, source, userhost, args[1]);
unixtime = atoi (args[0]) * sn;
if (unixtime > 86400)
result = chanserv_asprintf(NULL, "alarmclock set to go off in %d day%s, %02d:%02d.",
unixtime / 86400,
plural((unixtime / 86400)),
(unixtime / 3600) % 24,
(unixtime / 60) % 60);
else if (unixtime > 3600)
result = chanserv_asprintf(NULL, "alarmclock set to go off in %d hour%s, %d min%s.",
unixtime / 3600,
plural ((unixtime / 3600)),
(unixtime / 60) % 60,
plural (((unixtime / 60) % 60)));
else
result = chanserv_asprintf(NULL, "alarm clock set to go off in %d minute%s, %d sec%s.",
unixtime / 60,
unixtime / 60 == 1 ? "" : "s",
unixtime % 60,
unixtime % 60 == 1 ? "" : "s");
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_autotopic(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char topic [STRING_LONG] = {0};
if (!args || !args[0])
return result;
if (db_argstostr(topic, args, 0, ' ') < 1)
return result;
set_autotopic (source, target, topic);
return result;
}
#endif
//#ifndef WIN32
struct chanserv_output *chanserv_backup(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
char temp[1024] = { 0 };
int ret;
snprintf(temp, sizeof (temp), "/bin/cp -f %s %s_`date +%%F_%%R.bak`\n", URL2, URL2);
ret = system(temp);
return chanserv_asprintf(NULL, "Backed up database.");
}
//#endif
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_ban_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return show_banlist(source);
}
#endif
#ifdef ENABLE_MATH
struct chanserv_output *chanserv_calc(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
if (strlen(args[0]) > 200)
args[0][200] = '\0';
return do_math(source, target, args[0]);
}
#endif
struct chanserv_output *chanserv_chan_info(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
else
/* If args[0] is not a valid channel name, just use the current channel */
result = show_chaninfo (source, ((*args[0] == '#' || *args[0] == '&' || *args[0] == '+') ? args[0] : target), target);
return result;
}
struct chanserv_output *chanserv_chan_users(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
result = show_chanusers (source, target);
else
/* If args[0] is not a valid channel name, just use the current channel. */
result = show_chanusers (source, ((*args[0] == '#' || *args[0] == '&' || *args[0] == '+') ? args[0] : target));
return result;
}
struct chanserv_output *chanserv_char(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
return chanserv_asprintf(NULL, "%c -> %d.", args[0][0], args[0][0]);
}
struct chanserv_output *chanserv_char_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "My command char is: %c.", *CMDCHAR);
}
struct chanserv_output *chanserv_cpu_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
getrusage(RUSAGE_SELF, &r_usage);
return chanserv_asprintf(NULL, "CPU usage: %ld.%06ld, System = %ld.%06ld.", r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec, r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);
}
struct chanserv_output *chanserv_cycle(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
int i = 0;
/* Check for channel list parameter being specified. */
if (!args | !args[0])
{
S ("PART %s\n", target);
S ("JOIN %s\n", target);
}
else
{
result = chanserv_asprintf(NULL, "Cycling %s.", args[0]);
S("PART %s\n", args[0]);
S("JOIN %s\n", args[0]);
}
return result;
}
struct chanserv_output *chanserv_data_search(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "What should I be %sing for?", cmd);
printf ("args[0] = %s\n", args[0]);
datasearch (source, args[0], target);
return result;
}
struct chanserv_output *chanserv_date(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "%s.", date());
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_delban(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Enter the user@host to purge!");
if (del_permban(source, args[0]) == 1)
S("MODE %s -b %s\n", target, args[0]);
else
result = chanserv_asprintf(NULL, "No such ban.");
return result;
}
#endif
struct chanserv_output *chanserv_delete(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "%s what?", cmd);
if (strlen (args[0]) > MAX_TOPIC_SIZE)
args[0][MAX_TOPIC_SIZE] = '\0';
if (LOG_ADD_DELETES)
db_log (ADD_DELETES, "[%s] %s!%s DEL %s\n", date (), source, userhost, args[0]);
if (*args[0] == '~')
{ /* need level 2 to delete .rdb files */
if (invoked == MSG_INVOKE)
{
if (check_access (userhost, "#*", 0, source) >= 2)
delete_url (source, args[0], source);
}
else
{
if (check_access (userhost, target, 0, source) >= 2)
delete_url (source, args[0], target);
}
return result;
}
if (invoked == MSG_INVOKE)
delete_url (source, args[0], source);
else
delete_url (source, args[0], target);
return result;
}
struct chanserv_output *chanserv_deluser(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Enter the user@host to delete!");
delete_user_ram (source, args[0]);
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_deop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0}, chan[STRING_LONG] = {0};
/* Make sure first arg, which should be target chan, is there. */
if (!args || !args[0])
return result;
strncpy (chan, args[0], sizeof (chan));
/* Chop of first arg, since we have a copy as chan. */
args++;
db_argstostr (str, args, 0, ' ');
if ((invoked == MSG_INVOKE) || (*chan == '#'))
{
if (check_access (userhost, chan, 0, source) >= 3)
{
if (str[0] == '\0')
return result;
S ("MODE %s -oooooo %s\n", chan, str);
}
}
else
{
if (str[0] == '\0')
S ("MODE %s -oooooo %s\n", target, chan);
else
S ("MODE %s -oooooo %s %s\n", target, chan, str);
}
return result;
}
struct chanserv_output *chanserv_devoice(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char chan [STRING_LONG] = {0}, str [STRING_LONG] = {0};
if (!args || !args[0])
return result;
strncpy (chan, args[0], sizeof (chan));
args++;
db_argstostr (str, args, 0, ' ');
if ((invoked == MSG_INVOKE) || (*chan == '#'))
{
if (check_access (userhost, chan, 0, source) >= 3)
{
if (str[0] == '\0')
return result;
S ("MODE %s -vvvvvv %s\n", chan, str);
}
}
else
{
if (str[0] == '\0')
S ("MODE %s -vvvvvvv %s\n", target, chan);
else
S ("MODE %s -vvvvvvv %s %s\n", target, chan, str);
}
return result;
}
#endif
struct chanserv_output *chanserv_die(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
long unixtime = 0;
if (!args || !args[0])
Snow("QUIT :K\2\2illed (%s (cause I say so!))\n", source);
else
{
if ((db_argstostr (str, args, 0, ' ')) < 1)
return result;
Snow("QUIT :K\2\2illed (%s (%s))\n", source, str);
}
db_sleep (1);
printf ("\n\nGood-bye! %s (c) Jason Hamilton\n\n", dbVersion);
uptime = time (NULL) - uptime;
printf("Time elapsed: %ld hour%s, %ld min%s\n\n",
uptime / 3600,
uptime / 3600 == 1 ? "" : "s",
(uptime / 60) % 60, (uptime / 60) % 60 == 1 ? "" : "s");
db_sleep (5);
exit (0);
return result;
}
struct chanserv_output *chanserv_display(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
result = display_url(target, source, args[0]);
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_down(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
S ("MODE %s -o %s\n", target, source);
return result;
}
#endif
struct chanserv_output *chanserv_darkbot(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (Sleep_Toggle == 1)
return result;
if (cf (userhost, source, target))
return result;
return chanserv_asprintf(NULL, "%s reporting! My cmdchar is %c.", dbVersion, *CMDCHAR);
}
struct chanserv_output *chanserv_help(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args || !args[0])
{
result = chanserv_asprintf(result, "I can be triggered by various forms of speech, all which must be addressed to me, in one of the following formats: %s %s %s or even %s . In my database, you can find a topic by saying my nick, <topic> . eg; \37%s nuke\37 . To do a search on a word, or partial text, just type: search <text> or dsearch <text> , eg; \37search nuke\37.",
NICK_COMMA, COLON_NICK, BCOLON_NICK, Mynick, NICK_COMMA);
if (cf (userhost, source, target))
return result;
result = chanserv_asprintf(result, "I can also be triggered with even more human formats: \37%s who is bill gates?\37 . You can also phrase it as a question: \37%s where is msie?\37 . For a list of commands use \37help commands\37 . For a list of setup parameters use \37help parameters\37 . For more info about me, visit http://darkbot.sourceforge.net .",
NICK_COMMA, NICK_COMMA, NICK_COMMA);
return (result);
}
if ((db_argstostr (str, args, 0, ' ')) < 1)
return;
result = chanserv_show_help(str, check_access(userhost, (invoked == MSG_INVOKE) ? "#*" : target, 0, source));
return result;
}
struct chanserv_output *chanserv_idle(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
long unixtime = 0;
if (!args || !args[0])
return result;
if (strcasecmp (args[0], source) == 0)
return chanserv_asprintf(NULL, "Don't be lame.");
unixtime = return_useridle (target, args[0], 0);
if (unixtime == 0)
return chanserv_asprintf(NULL, "I do not see %s in %s.", args[0], target);
unixtime = time (NULL) - unixtime;
if (unixtime > 86400)
result = chanserv_asprintf(result, " %s has been idle %d day%s, %02d:%02d.",
args[0], unixtime / 86400,
(unixtime / 86400 == 1) ? "" : "s",
(unixtime / 3600) % 24, (unixtime / 60) % 60);
else if (unixtime > 3600)
result = chanserv_asprintf(result, "%s has been idle %d hour%s, %d min%s.",
args[0], unixtime / 3600,
unixtime / 3600 == 1 ? "" : "s",
(unixtime / 60) % 60, (unixtime / 60) % 60 == 1 ? "" : "s");
else
result = chanserv_asprintf(result, " %s has been idle %d minute%s, %d sec%s.",
args[0], unixtime / 60,
unixtime / 60 == 1 ? "" : "s", unixtime % 60, unixtime % 60 == 1 ? "" : "s");
return result;
}
struct chanserv_output *chanserv_ignore(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Ignore who?");
if ( add_ignore_user_ram(args[0]) > 0 )
result = chanserv_asprintf(result, "Ignoring %s.", args[0]);
else
result = chanserv_asprintf(result, "Unable to ignore %s.", args[0]);
return result;
}
struct chanserv_output *chanserv_info(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
info (source, (invoked == MSG_INVOKE) ? source : target);
return result;
}
struct chanserv_output *chanserv_info_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return show_info2((invoked == MSG_INVOKE) ? source : target, source, invoked);
}
struct chanserv_output *chanserv_info_size(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
struct stat statbuf;
if (stat (URL2, &statbuf) == 0)
result = chanserv_asprintf(NULL, "My database file is presently %ld byte%s in size.", statbuf.st_size, ((statbuf.st_size == 1) ? "" : "s"));
return result;
}
struct chanserv_output *chanserv_isop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
result = chanserv_asprintf(NULL, "%s is %san op in channel %s.", args[0], is_op(args[0], target) ? "" : "not ", target);
return result;
}
struct chanserv_output *chanserv_join(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
S ("JOIN %s\n", target);
else
{
S ("JOIN %s\n", args[0]);
result = chanserv_asprintf(NULL, "Joining %s.", args[0]);
}
return result;
}
struct chanserv_output *chanserv_joins_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "I have seen %d joins thus far.", JOINs);
}
struct chanserv_output *chanserv_jump(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char server [STRING_LONG] = {0}, str [STRING_LONG] = {0};
long sn = 0;
if (!args || !args[0])
return result;
strncpy (server, args[0], sizeof (server));
args++;
if ((db_argstostr (str, args, 0, ' ')) < 1)
sn = 6667;
else
sn = atoi(str);
S ("QUIT :Jumping to %s:%d\n", server, sn);
db_sleep (1);
strncpy (BS, server, sizeof (BS));
BP = sn;
prepare_bot ();
register_bot ();
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_kick(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char chan[STRING_LONG] = {0}, nick[STRING_LONG] = {0},
reason [STRING_LONG] = {0};
if (!args || !args[0])
return chanserv_asprintf(NULL, "Specify a nick/channel!");
if (invoked == MSG_INVOKE)
{
/* Copy channel variable and chuck it. */
strncpy (chan, args[0], sizeof (chan));
args++;
/* Make sure first parameter is a channel name. */
if ((*chan != '#') && (*chan != '&'))
return chanserv_asprintf (NULL, "You must specify a channel name first.");
if (check_access (userhost, chan, 0, source) >= 3)
{
if (!args[0])
return chanserv_asprintf(NULL, "You must specity a nickname to kick!");
strncpy (nick, args[0], sizeof (nick));
args++;
/* Remaining args are fed into reason. */
if ((db_argstostr (reason, args, 0, ' ')) < 1)
S ("KICK %s %s %s\n", chan, nick, DEFAULT_KICK);
else
S ("KICK %s %s :%s\n", chan, nick, reason);
return result;
}
}
else
{
if (*args[0] != '#' && *args[0] != '&')
{
strncpy (nick, args[0], sizeof (nick));
args++;
if (strcasecmp (nick, Mynick) == 0)
S ("KICK %s %s :hah! As *IF*\n", target, source);
if ((db_argstostr (reason, args, 0, ' ')) < 1)
S ("KICK %s %s :\2%s\2'ed: %s\n", target, nick, cmd, DEFAULT_KICK);
else
S ("KICK %s %s :\2%s\2'ed: %s\n", target, nick, cmd, reason);
}
else
{
if (!args[0] || !args[1])
return chanserv_asprintf(result, "You must specify a nickname to kick!");
strncpy (chan, args[0], sizeof chan);
args++;
strncpy (nick, args[0], sizeof nick);
args++;
if (strcasecmp (nick, Mynick) == 0)
S ("KICK %s %s :hah! As *IF*\n", target, nick);
if ((db_argstostr (reason, args, 0, ' ')) < 1)
S ("KICK %s %s :\2%s\2ed: %s\n", chan, nick, cmd, DEFAULT_KICK);
else
S ("KICK %s %s :\2%s\2ed: %s\n", chan, nick, cmd, reason);
}
}
return result;
}
#endif
struct chanserv_output *chanserv_language(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "I speak English.");
}
struct chanserv_output *chanserv_leave(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char chan [STRING_LONG] = {0},
reason [STRING_LONG] = {0};
if (!args || !args[0])
S ("PART %s\n", target);
else
{
strncpy (chan, args[0], sizeof chan);
args++;
/* Don't bother telling the channel we left about it. */
if ((strcasecmp (target, chan)) != 0)
result = chanserv_asprintf(result, "Leaving %s.", chan);
if ((db_argstostr (reason, args, 0, ' ')) < 1)
S ("PART %s :Requested!\n", chan);
else
S ("PART %s :%s\n", chan, reason);
}
return (result);
}
struct chanserv_output *chanserv_length(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args || !args[0])
return result;
if ((db_argstostr (str, args, 0, ' ')) == 0)
strcpy(str, args[0]);
return chanserv_asprintf(NULL, "It was %d characters long.", strlen (str));
}
struct chanserv_output *chanserv_level(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char *uh;
if (!args || !args[0])
return result;
uh = uh_from_nick(args[0], target);
if (uh)
result = chanserv_asprintf(result, "%s is level %d in channel %s.", args[0], check_access(uh, target, 0, args[0]), target);
return result;
}
struct chanserv_output *chanserv_location_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "There %s %d server%s in my server list. I am currently on server #%d.", (snr == 1) ? "is" : "are", snr, (snr == 1) ? "" : "s", spr);
}
struct chanserv_output *chanserv_login(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
do_login (source, args[0]);
return result;
}
struct chanserv_output *chanserv_mask(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
int i = 0;
struct chanserv_output *result = NULL;
if(!args || !args[0])
return result;
return chanserv_asprintf(NULL, " %s",
(invoked == MSG_INVOKE) ? mask_from_nick(args[0], "#*") : mask_from_nick(args[0], target));
}
//#ifndef WIN32
struct chanserv_output *chanserv_memory(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
char temp[1024] = { 0 };
snprintf(temp, sizeof (temp), "ps u -p %d\n", getpid());
const char *ptr = run_program (temp);
if (ptr == NULL)
return chanserv_asprintf(NULL, "Unable to gather data for mem output.\n");
else
return chanserv_asprintf(NULL, "ps: %s", ptr);
}
//#endif
#ifdef ENABLE_METAR
struct chanserv_output *chanserv_metar(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if(!args || !args[0])
return chanserv_asprintf(NULL, "Metar what?");
result = web_post_query (cmd, source, userhost, target, args[0], strlen(args[0]));
return result;
}
#endif
struct chanserv_output *chanserv_nick(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
// If no nick was specified...
if(!args || !args[0])
return chanserv_asprintf(NULL, "Specify a nick!");
// If the nick specified contains illegal characters...
if(strspn(args[0], LEGAL_NICK_TEXT) != strlen(args[0]))
return chanserv_asprintf(NULL, "The nickname %s contains illegal characters.", args[0]);
if (isdigit(args[0][0]))
return chanserv_asprintf(NULL, "The nickname %s should not start with a digit.", args[0]);
S("NICK %s\n", args[0]);
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_op(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0};
int ischan = 0;
if (!args[0])
return chanserv_asprintf (NULL, "You must specify a nickname/channel!.");
/* Check for channel name specified, set up args accordingly. */
if ((*args[0] == '#') || (*args[0] == '&'))
{
ischan = 1; /* channel specified */
strncpy (chan, args[0], sizeof chan);
args++;
}
if ((db_argstostr (nicks, args, 0, ' ')) < 1)
return chanserv_asprintf (NULL, "You must specify a nickname to op.");
if ((invoked == MSG_INVOKE) || (ischan == 1))
{
/* If MSG_INVOKE, make sure chan == 1. This seems weird, but
* we could have MSG_INVOKE without channel specified. */
if (ischan != 1)
return chanserv_asprintf (NULL, "You must specify a channel to deop people on.");
if (check_access (userhost, chan, 0, source) >= 3)
{
S ("MODE %s +oooooo %s\n", chan, nicks);
return result;
}
}
else
S ("MODE %s +oooooo %s\n", target, nicks);
return result;
}
#endif
struct chanserv_output *chanserv_os_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char temp[1024] = { 0 };
char *reply = NULL;
#ifdef WIN32
snprintf (temp, sizeof (temp), "cmd /c ver\n");
#else
snprintf (temp, sizeof (temp), "uname\n");
#endif
return chanserv_asprintf(NULL, "I am running %s.", run_program(temp));
}
struct chanserv_output *chanserv_password(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (args[0] == NULL || args[1] == NULL)
return result;
if (strlen(args[1]) > 25)
args[1][25] = '\0';
set_pass(source, userhost, args[0], args[1]);
return result;
}
struct chanserv_output *chanserv_performs(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
/* Set the default umodes */
S ("MODE %s %s\n", Mynick, DEFAULT_UMODE);
run_perform ();
return chanserv_asprintf(NULL, "Performs have been executed.");
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_perm_ban(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char reason [STRING_LONG] = {0}, host [STRING_LONG] = {0};
if (!args || !args[0])
return result = chanserv_asprintf(result, "Type !help permbans");
strncpy (host, args[0], sizeof host);
args++;
if ((db_argstostr (reason, args, 0, ' ')) < 1)
strncpy (reason, "Permbanned!", sizeof reason);
add_permban(host, 0, reason);
result = chanserv_asprintf(result, "Added in permban #%d, %s; reason: %s.",
PERMBAN_counter, host, reason);
save_permbans();
S("MODE %s +b %s\n", target, host);
/* FIXME: Scan for user in room and kick them with reason. */
return result;
}
struct chanserv_output *chanserv_perm_bans_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "There %s %d permban%s loaded into ram.", (PERMBAN_counter == 1) ? "is" : "are", PERMBAN_counter, (PERMBAN_counter == 1) ? "" : "s");
}
#endif
#ifdef ENABLE_CTCP
struct chanserv_output *chanserv_ping(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (cf(userhost, source, target))
return result;
if (cf(userhost, source, target))
return result;
if (args[0] != NULL)
{
if (strlen (args[0]) > 21)
args[0][21] = '\0';
S ("NOTICE %s :\1PING %s\n", source, args[0]);
}
return result;
}
#endif
struct chanserv_output *chanserv_ping2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "PONG!");
}
struct chanserv_output *chanserv_queue_show(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "There is currently %d item%s in queue.", get_sendq_count(2), (get_sendq_count(2) == 1) ? "" : "s");
}
#ifdef ENABLE_QUIZ
struct chanserv_output *chanserv_quiz(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (quiz_halt == 0)
result = run_quiz_question (target);
return result;
}
#endif
#ifdef ENABLE_RANDQ
struct chanserv_output *chanserv_quote(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return do_randq(args[0], RANDQ_RAND, target, source);
}
struct chanserv_output *chanserv_random_quote(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
if (!args || !args[0])
return chanserv_asprintf (NULL, "You must specify a search string.");
// RANDQ_NORMAL
return do_randq(args[0], RANDQ_NORMAL, target, source);
}
struct chanserv_output *chanserv_random_quote_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
if (!args || !args[0])
return chanserv_asprintf (NULL, "You must specify a search string.");
// RANDQ_CASE
return do_randq(args[0], RANDQ_CASE, target, source);
}
#endif
#ifdef ENABLE_RANDOM
struct chanserv_output *chanserv_random_stuff(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
/* Fill argument buffer, if it's empty we return a message to
* the user asking for input. */
if (!args || !args[0])
return chanserv_asprintf(NULL, "What do you want to add?");
if ((db_argstostr (str, args, 0, ' ')) < 1)
return result;
if (invoked == MSG_INVOKE)
{
if (check_access (userhost, "#*", 0, source) >= RAND_LEVEL)
{
if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf(NULL, "What do you want to add?");
add_randomstuff(source, source, str);
}
}
else
add_randomstuff(source, target, str);
return result;
}
struct chanserv_output *chanserv_random_stuff_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "%d seconds left till randstuff.", Rand_Stuff);
}
#endif
struct chanserv_output *chanserv_raw(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args || !args[0])
return result;
if ((db_argstostr (str, args, 0, ' ')) < 1)
return result;
Snow("%s\n", str);
return result;
}
//#ifndef WIN32
struct chanserv_output *chanserv_rdb(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char temp[1024] = { 0 };
char str [STRING_LONG] = {0};
/* Check for arguments */
if (!args || !args[0])
{
snprintf(temp, sizeof (temp), "ls %s/*.rdb | wc\n", RDB_DIR);
result = chanserv_asprintf(result, "RDB: %s.", run_program(temp));
}
else
{
if ((db_argstostr (str, args, 0, ' ')) < 1)
return result;
if (strspn(str, SAFE_LIST) != strlen(str))
return chanserv_asprintf(NULL, "Rdb files are made up of letters and or numbers, no other text is accepted.");
snprintf(temp, sizeof (temp), "cat %s/%s.rdb | wc -l\n", RDB_DIR, str);
result = chanserv_asprintf(result, "%s", run_program(temp));
}
return result;
}
//#endif
struct chanserv_output *chanserv_repeat(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
long sn2 = 0, sn = 0;
char str [STRING_LONG] = {0};
if (!args || !args[0] || !args[1] || !args[2])
return result;
sn = atoi (args[0]);
sn2 = atoi (args[1]);
if ((db_argstostr (str, args, 2, ' ')) < 1)
return result;
while (sn > 0)
{
S ("%s\n", str);
db_sleep (sn2);
sn--;
}
return result;
}
struct chanserv_output *chanserv_replace(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char topic [STRING_LONG] = {0}, str [STRING_LONG] = {0};
if (!args || !args[0])
return chanserv_asprintf(NULL, "Replace what?");
if (strlen(args[0]) > MAX_TOPIC_SIZE)
args[0][MAX_TOPIC_SIZE] = '\0';
/* Copy topic, and traverse args for data to be replaced. */
strncpy (topic, args[0], sizeof topic);
args++;
/* Make sure there's information to be replaced. */
if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf(NULL, "What info should replace %s?",
topic);
/* Don't let str go over MAX_DATA_SIZE characters. */
if (strlen(str) > MAX_DATA_SIZE)
str[MAX_DATA_SIZE] = '\0';
strlwr(topic);
if (check_existing_url(source, topic, target) != 1)
return chanserv_asprintf(NULL, "%s \37%s\37", NO_ENTRY, topic);
/* Replace the data. */
delete_url (source, topic, target);
if (LOG_ADD_DELETES)
db_log (ADD_DELETES, "[%s] %s!%s REPLACE %s %s\n", date (), source, userhost, topic, str);
ADDITIONS++;
db_log (URL2, "%s %s\n", topic, str);
return chanserv_asprintf(NULL, "%s has been updated.", topic);
}
struct chanserv_output *chanserv_reserved_1(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
call_reserved_1(source, target, args[0]);
return result;
}
struct chanserv_output *chanserv_reserved_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result;
call_reserved_2(source, target, args[0]);
return result;
}
struct chanserv_output *chanserv_restart(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char temp[1024] = { 0 };
int ret;
S("QUIT :Restarting %s ...\n", dbVersion);
db_sleep(2);
snprintf(temp, sizeof (temp), "%s", DARKBOT_BIN);
ret = system(temp);
db_sleep(1);
exit(0);
return result;
}
struct chanserv_output *chanserv_search(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
{
if (strcasecmp(cmd, "FIND") == 0)
result = chanserv_asprintf(NULL, "%s?", TRY_FIND);
else
result = chanserv_asprintf(NULL, "What should I be %sing for?", cmd);
return result;
}
find_url(source, args[0], target);
return result;
}
struct chanserv_output *chanserv_seen(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
{
count_seen(source, target);
return result;
}
if (return_useridle (target, args[0], 1) == 1)
return chanserv_asprintf(NULL, "%s is right here in the channel!", args[0]);
result = show_seen(args[0], source, target);
return result;
}
struct chanserv_output *chanserv_set(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
struct setup_parameter *param = NULL;
if (!args || !args[0])
return result;
param = set_parameter(args[0]);
if (param)
{
switch (param->type)
{
case ST_BOOLEAN :
{
bool *variable = param->value;
result = chanserv_asprintf(result, "Setting %s = %s", param->summary, (*variable) ? "true" : "false");
break;
}
case ST_INTEGER :
{
long *variable = param->value;
result = chanserv_asprintf(result, "Setting %s = %ld", param->summary, *variable);
break;
}
case ST_STRING :
{
char *variable = param->value;
result = chanserv_asprintf(result, "Setting %s = %s", param->summary, variable);
break;
}
}
save_setup();
}
else
result = chanserv_asprintf(result, "Unknown parameter.");
return result;
}
struct chanserv_output *chanserv_setinfo(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args)
return chanserv_asprintf (NULL, "My %s variables are: ^ nick, %% number of joins, & Channel, $ user@host. Example: !setinfo ^ has joined & %% times (also, if you make the first char of your %s a \"+\", the %s will be shown as an ACTION).", cmd, cmd, cmd);
if ((db_argstostr (str, args, 0, ' ')) < 1)
return;
update_setinfo (userhost, str, source);
return (result);
}
struct chanserv_output *chanserv_sleep(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
Sleep_Toggle = 1;
/* Copy arguments to buffer, if there is one convert to long
* and use it as the sleep time in seconds. */
if ((db_argstostr (str, args, 0, '\0')) < 1)
Sleep_Time = SLEEP_TIME;
else if ((Sleep_Time = strtol (str, (char **) NULL, 10)) < 1)
Sleep_Time = SLEEP_TIME;
strncpy (sleep_chan, target, sizeof (sleep_chan));
/* If the user has specified a custom length of time to sleep for, send
* a notice reminding the user how long the bot will be asleep, in a
* more readible format.
*/
if (Sleep_Time != SLEEP_TIME)
{
if (Sleep_Time > 86400)
result = chanserv_asprintf(result, "Sleeping for %ld day%s, %02ld:%02ld.",
Sleep_Time / 86400,
(Sleep_Time / 86400 == 1) ? "" : "s",
(Sleep_Time / 3600) % 24,
(Sleep_Time / 60) % 60);
else if (Sleep_Time > 3600)
result = chanserv_asprintf(result, "Sleeping for %ld hour%s, %ld min%s.",
Sleep_Time / 3600,
Sleep_Time / 3600 == 1 ? "" : "s",
(Sleep_Time / 60) % 60,
(Sleep_Time/ 60) % 60 == 1 ? "" : "s");
else
result = chanserv_asprintf(result, "Sleeping for %ld minute%s, %ld sec%s.",
Sleep_Time / 60,
Sleep_Time / 60 == 1 ? "" : "s",
Sleep_Time % 60,
Sleep_Time % 60 == 1 ? "" : "s");
}
else
S ("PRIVMSG %s :%s\n", target, GOSLEEP_ACTION);
return result;
}
#ifdef ENABLE_STATS
struct chanserv_output *chanserv_stats(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return result = chanserv_asprintf (NULL, "Syntax: %s <nick>", cmd);
result = get_stats(target, args[0]);
return result;
}
#endif
#ifdef ENABLE_TAF
struct chanserv_output *chanserv_taf(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if(!args || !args[0])
return chanserv_asprintf(NULL, "Taf what?");
result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
return result;
}
#endif
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_teaseop(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Specify a nick!");
if (strcasecmp (args[0], Mynick) == 0)
result = chanserv_asprintf(result, "How about I not do that?");
else
S ("MODE %s +o-o+o-o+o-o %s %s %s %s %s %s\n", target, args[0], args[0], args[0], args[0], args[0], args[0]);
return result;
}
#endif
struct chanserv_output *chanserv_tell(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args || !args[0])
return chanserv_asprintf(NULL, "Tell who?");
if (!args[1])
return chanserv_asprintf(NULL, "What do you want me to tell %s?", args[0]);
if (strcasecmp (args[1], Mynick) == 0)
return result; /* don't bother telling myself about stuff */
if (strcasecmp (args[1], "ABOUT") == 0)
{
if ((db_argstostr (str, args, 2, '+')) < 1)
return chanserv_asprintf(NULL, "Tell %s about what?", args[0]);
strlwr(str);
if (invoked == MSG_INVOKE)
result = show_url (source, get_multiword_topic (str), args[0], 1, 0, userhost, 1);
else
result = show_url (args[0], get_multiword_topic (str), target, 1, 0, userhost, 1);
}
else
{
if ((db_argstostr (str, args, 1, '+')) < 1)
return chanserv_asprintf (NULL, "Tell %s about what?", args[0]);
strlwr(str);
if (invoked == MSG_INVOKE)
result = show_url (source, get_multiword_topic (str), args[0], 1, 0, userhost, 1);
else
result = show_url (args[0], get_multiword_topic (str), target, 1, 0, userhost, 1);
}
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_topic(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf (NULL, "What do you want the topic changed to?");
else
S ("TOPIC %s :%s\n", target, str);
return result;
}
#endif
struct chanserv_output *chanserv_unignore(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Unignore who?");
if ( delete_ignore_user_ram (args[0]) > 0 )
result = chanserv_asprintf(result, "Unignoring %s.", args[0]);
else
result = chanserv_asprintf(result, "Unable to unignore %s. :(", args[0]);
return result;
}
struct chanserv_output *chanserv_unixtime(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
time_t unixtime = 0, input_t = 0, cur_t = 0;
char *things = NULL;
int errno;
/* Check if anything was given as input and only do stuff
* (in this function, anyway) if so. */
if (!args || !args[0])
return result;
/* Make sure current time is available while acquiring it. */
if ((cur_t = time (NULL)) < 0)
{
result = chanserv_asprintf (result, "Unable to produce results because current system time is unavailable.");
return (result);
}
/* Convert input value to time_t. We check if the return value is
* 0 here, but our main concern is if things is NULL, because that
* would mean the function converted a string value "0", instead
* of returning a failing code. Set errno to 0 first as for a
* precautionary measure.
*/
errno = 0;
if ((input_t = (time_t) strtol (args[0], &things, 10)) == 0)
{
if (things == NULL)
{
result = chanserv_asprintf (result, "%s (things = %s)", strerror (errno), things);
return (result);
}
/* things was not NULL, this is "0" converted to long.
* So we continue as if nothing happened. */
}
/* Check for out of range values, tell the user which range
* was exceeded, perhaps for debugging purposes. */
if (errno == ERANGE)
{
result = chanserv_asprintf (result, "Your implementation does not support numeric ranges beyond %ld for this function.",
input_t);
return (result);
}
unixtime = input_t - cur_t;
if (unixtime > 86400)
result = chanserv_asprintf(result, "%d day%s, %02d:%02d.",
unixtime / 86400,
plural (unixtime / 86400),
(unixtime / 3600) % 24,
(unixtime / 60) % 60);
else if (unixtime > 3600)
result = chanserv_asprintf(result, "%d hour%s, %d min%s.",
unixtime / 3600,
plural(unixtime / 3600),
(unixtime / 60) % 60,
plural(unixtime / 60));
else
result = chanserv_asprintf(result, "%d minute%s, %d sec%s.",
unixtime / 60,
plural(unixtime / 60),
unixtime % 60,
plural(unixtime % 60));
return result;
}
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_up(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
S ("MODE %s +o %s\n", target, source);
return result;
}
#endif
//#ifndef WIN32
struct chanserv_output *chanserv_uptime(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
char temp[1024] = { 0 };
snprintf(temp, sizeof (temp), "uptime\n");
return chanserv_asprintf(NULL, "Uptime: %s.", run_program(temp));
}
//#endif
struct chanserv_output *chanserv_user_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
int i = 0;
if (!args)
{
result = show_helper_list(result, source, 0);
}
else
{
int level = 0;
for (i = 0; args[i]; i++)
result = show_helper_list(result, source, atoi (args[i]));
}
return result;
}
#ifdef ENABLE_STATUS
struct chanserv_output *chanserv_users_list(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
S ("LUSERS\n");
return result;
}
#endif
struct chanserv_output *chanserv_variables(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
return chanserv_asprintf(NULL, "Data variables are: N~ (Nick), C~ (Chan), T~ (Time/date) B~ (Botnick), Q~ (Question asked), R~ (random nick), !~ (command char), S~ (current Server), P~ (current port) V~ (botVer), W~ (db WWW site), H~ (u@h), t~ (unixtime), BAN (sets a ban), TEMPBAN (bans for 60 sec).");
}
#ifdef ENABLE_CTCP
struct chanserv_output *chanserv_version(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (cf (userhost, source, target))
return result;
if (cf (userhost, source, target))
return result;
return chanserv_asprintf(NULL, "\1VERSION Hi, I'm a Darkbot. Download me from http://darkbot.sourceforge.net\1.");
}
#endif
#ifdef ENABLE_CHANNEL
struct chanserv_output *chanserv_voice(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0},
str [STRING_LONG] = {0};
int ischan = 0;
if (!args[0])
return result;
db_argstostr (str, args, 0, ' ');
/* Check for channel name specified, set up args accordingly. */
if ((*args[0] == '#') || (*args[0] == '&'))
{
ischan = 1; /* channel specified */
strncpy (chan, args[0], sizeof chan);
args++;
}
if ((db_argstostr (nicks, args, 0, ' ')) < 1)
return chanserv_asprintf (NULL, "You must specify a nickname to voice.");
if ((invoked == MSG_INVOKE) || (ischan == 1))
{
/* If MSG_INVOke, make sure chan ==1. This seems weird,
* but we could have MSG_INVOKE without a channel given,
* and this is an error. */
if (ischan != 1)
return chanserv_asprintf (NULL, "You must specify a channel to give voice on.");
if (check_access (userhost, chan, 0, source) >= 3)
{
S ("MODE %s +vvvvvv %s\n", chan, nicks);
return result;
}
}
else
S ("MODE %s +vvvvvv %s\n", target, nicks);
return result;
}
#endif
struct chanserv_output *chanserv_wakeup(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (Sleep_Toggle == 0)
return result;
Sleep_Toggle = 0;
AIL4 = 0;
S ("PRIVMSG %s :%s\n", target, WAKEUP_ACTION);
if (strcasecmp (sleep_chan, target) != 0)
S ("PRIVMSG %s :%s\n", sleep_chan, WAKEUP_ACTION);
return result;
}
#ifdef ENABLE_WEATHER
struct chanserv_output *chanserv_weather(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "Show weather from where?");
result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
return result;
}
#endif
#ifdef ENABLE_WEBSEARCH
struct chanserv_output *chanserv_websearch(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if(!args || !args[0])
return chanserv_asprintf(NULL, "Web search for what?");
result = web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
return result;
}
#endif
struct chanserv_output *chanserv_where(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
char *ptr3 = NULL;
if (!args || !args[0])
return chanserv_asprintf(NULL, "You were asking?");
if (args[1] == NULL)
return result;
strlwr (args[1]);
ptr3 = strchr (args[1], '?');
if (ptr3 != NULL)
memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
ptr3 = strchr (args[1], '!');
if (ptr3 != NULL)
memmove (ptr3, ptr3 + 1, strlen (ptr3 + 1) + 1);
if (strcasecmp (args[1], "A") == 0 || strcasecmp (args[1], "AN") == 0)
{
if ((db_argstostr (str, args, 2, ' ')) < 1)
return chanserv_asprintf(NULL, "%s %s %s? Mind rephrasing that? (Type %cHELP for syntax hints).", cmd, args[0], args[1], *CMDCHAR);
result = show_url (source, get_multiword_topic (str), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
}
else
result = show_url (source, get_multiword_topic (args[1]), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
return result;
}
struct chanserv_output *chanserv_whisper(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
char str [STRING_LONG] = {0};
if (!args || !args[0])
return chanserv_asprintf(NULL, "Whisper to who?");
if (args[1] == NULL)
return chanserv_asprintf(NULL, "What do you want me to whisper to %s?", args[0]);
if (strcasecmp (args[1], Mynick) == 0)
return result; /* don't bother telling myself about stuff */
if (strcasecmp (args[1], "ABOUT") == 0)
{
if ((db_argstostr (str, args, 2, ' ')) < 1)
return chanserv_asprintf(NULL, "Whisper to %s about what?", args[0]);
strlwr(str);
result = show_url(source, get_multiword_topic(str), args[0], 1, 0, userhost, 1);
}
else
{
strlwr (args[1]);
result = show_url(source, get_multiword_topic(args[1]), args[0], 1, 0, userhost, 1);
}
return result;
}
/* The help system uses the first alias for each command for the list of commands.
* So make the first alias the most meaningful, and keep the list sorted by that first alias.
*/
struct chanserv_command chanserv_commands[] =
{
{NORMAL_COMMAND, ADD_LEVEL, 1, 0, chanserv_add, {"ADD", "REMEMBER", "SAVE", "STORE", NULL}, "<topic> <text>", "Add a topic and it's text."},
{PASSWORD_COMMAND, 3, 4, 0, chanserv_add_user, {"ADDUSER", NULL, NULL, NULL, NULL}, "<#channel|#*> <user@host> <level> [password]", "Add a user to the access list."},
{SAFE_COMMAND, 2, 2, 0, chanserv_alarm, {"ALARM", "ALARMCLOCK", NULL, NULL, NULL}, "<time type: d/h/m><time> <text to say>", "Set some text to be said by the bot at a later time."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_autotopic, {"AUTOTOPIC", NULL, NULL, NULL, NULL}, "<channel topic>", "Refreshes the channel topic every thirty minutes (set to \"0\" to turn off)."},
#endif
//#ifndef WIN32
{DANGER_COMMAND, 3, 0, 0, chanserv_backup, {"BACKUP", NULL, NULL, NULL, NULL}, NULL, "Create a backup of the database."},
//#endif
#ifdef ENABLE_CHANNEL
{INFO_COMMAND, 1, 0, 0, chanserv_ban_list, {"BANLIST", NULL, NULL, NULL, NULL}, NULL, "Displays permanent bans."},
#endif
#ifdef ENABLE_MATH
{INFO_COMMAND, 0, 1, 0, chanserv_calc, {"CALC", "MATH", NULL, NULL, NULL}, "<expression>", "Very basic calculator."},
#endif
{INFO_COMMAND, 0, 1, 0, chanserv_chan_info, {"CHANINFO", NULL, NULL, NULL, NULL}, "<#channel>", "Displays number of users in channel and in ram."},
{INFO_COMMAND, 0, 1, 0, chanserv_chan_users, {"CHANUSERS", NULL, NULL, NULL, NULL}, "<#channel>", "Displays names of users in channel."},
{INFO_COMMAND, 0, 1, 0, chanserv_char, {"CHAR", NULL, NULL, NULL, NULL}, "<character>", "Show the ascii code of the character."},
{INFO_COMMAND, 0, 0, 1, chanserv_char_show, {"CMDCHAR?", NULL, NULL, NULL, NULL}, NULL, "Show command character."},
{INFO_COMMAND, 0, 0, 1, chanserv_cpu_show, {"CPU?", NULL, NULL, NULL, NULL}, NULL, "Show the cpu usage of the bot."},
{DANGER_COMMAND, 2, 0, 0, chanserv_cycle, {"CYCLE", "CYC", NULL, NULL, NULL}, "[#channel]", "Leave and rejoin the channel."},
{INFO_COMMAND, 0, 1, 0, chanserv_data_search, {"DATASEARCH", "DSEARCH", "DFIND", NULL, NULL}, "<topic>", "Search in the replies."},
{INFO_COMMAND, 0, 0, 0, chanserv_date, {"DATE", "TIME", NULL, NULL, NULL}, NULL, "Show the current date and time."},
{DANGER_COMMAND, 0, 1, 0, chanserv_reserved_2, {RESERVED2, NULL, NULL, NULL, NULL}, "<>", ""},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_delban, {"DELBAN", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the permanent ban list."},
#endif
{NORMAL_COMMAND, DEL_LEVEL, 1, 0, chanserv_delete, {"DELETE", "DEL", "REMOVE", "FORGET", NULL}, "<topic>", "Delete a topic."},
{DANGER_COMMAND, 3, 1, 0, chanserv_deluser, {"DELUSER", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the access list."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_deop, {"DEOP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Remove channel operator status from users."},
{NORMAL_COMMAND, 3, 1, 0, chanserv_devoice, {"DEVOICE", "DV", "DEV", "DVOICE", NULL}, "[#channel] <nicks>", "Remove channel voice status from users."},
#endif
{DANGER_COMMAND, 3, 0, 0, chanserv_die, {"DIE", "QUIT", NULL, NULL, NULL}, NULL, "Stop bot from running."},
{INFO_COMMAND, 0, 1, 0, chanserv_display, {"DISPLAY", NULL, NULL, NULL, NULL}, "<topic>", "Display the text for a topic."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 0, 0, chanserv_down, {"DOWN", NULL, NULL, NULL, NULL}, NULL, "Remove channel operator status from yourself."},
#endif
{INFO_COMMAND, 0, 0, 0, chanserv_darkbot, {"\2\2DARKBOT", NULL, NULL, NULL, NULL}, NULL, ""},
{DANGER_COMMAND, 0, 1, 0, chanserv_reserved_1, {RESERVED1, NULL, NULL, NULL, NULL}, "<>", ""},
{INFO_COMMAND, 0, 0, 0, chanserv_help, {"HELP", NULL, NULL, NULL, NULL}, "[command]", "Show some help text to the user."},
{INFO_COMMAND, 0, 1, 0, chanserv_idle, {"IDLE", NULL, NULL, NULL, NULL}, "<nick>", "Shows how long the user has been idle."},
{DANGER_COMMAND, 1, 1, 0, chanserv_ignore, {"IGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to ignore a user."},
{INFO_COMMAND, 0, 0, 1, chanserv_info, {"INFO", NULL, NULL, NULL, NULL}, NULL, "Shows some information about bot and it's activity."},
{INFO_COMMAND, 0, 0, 1, chanserv_info_2, {"INFO2", NULL, NULL, NULL, NULL}, NULL, "Shows when the bot was compiled, and lines processed since startup."},
{INFO_COMMAND, 2, 0, 1, chanserv_info_size, {"INFOSIZE", "DBSIZE", NULL, NULL, NULL}, NULL, "Show size of the database."},
{INFO_COMMAND, 0, 1, 0, chanserv_isop, {"ISOP", NULL, NULL, NULL, NULL}, "<nick>", "Is user a channel op?"},
{DANGER_COMMAND, 2, 1, 0, chanserv_join, {"JOIN", "J", NULL, NULL, NULL}, "<#channel>", "Get bot to join a channel."},
{INFO_COMMAND, 0, 0, 1, chanserv_joins_show, {"JOINS?", NULL, NULL, NULL, NULL}, NULL, "Shows the number of user joins bot has seen in this channel since startup."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_kick, {"KICK", "WHACK", "K", "NAIL", NULL}, "[#channel] <nick> [reason]", "Kick a user off the channel."},
#endif
{INFO_COMMAND, 0, 0, 0, chanserv_language, {"LANGUAGE", "LANG", NULL, NULL, NULL}, NULL, "Shows the language that bot is currently speaking."},
{DANGER_COMMAND, 2, 0, 0, chanserv_leave, {"LEAVE", "PART", "L", "P", NULL}, "[#channel]", "Get bot to leave the channel."},
{INFO_COMMAND, 0, 1, 0, chanserv_length, {"LENGTH", NULL, NULL, NULL, NULL}, "<text>", "Show the length of the text."},
{INFO_COMMAND, 0, 1, 0, chanserv_level, {"LEVEL", NULL, NULL, NULL, NULL}, "<nick>", "Show users level."},
{INFO_COMMAND, 0, 0, 0, chanserv_location_show, {"LOCATION?", NULL, NULL, NULL, NULL}, NULL, "Shows what servers are available and in use."},
{PASSWORD_COMMAND, 0, 1, 0, chanserv_login, {"LOGIN", NULL, NULL, NULL, NULL}, "<password>", "Gives you access to high level bot commands if you are on the access list."},
#ifdef ENABLE_STATUS
{INFO_COMMAND, 1, 0, 0, chanserv_users_list, {"LUSERS", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
{INFO_COMMAND, 0, 1, 0, chanserv_mask, {"MASK", NULL, NULL, NULL, NULL}, "<nick>", "Show the users user@host mask."},
//#ifndef WIN32
{INFO_COMMAND, 3, 0, 1, chanserv_memory, {"MEM", "RAM", NULL, NULL, NULL}, NULL, "Shows some memory usage and process statistics."},
//#endif
#ifdef ENABLE_METAR
{NORMAL_COMMAND, 0, 1, 0, chanserv_metar, {"METAR", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw METAR weather data."},
#endif
{DANGER_COMMAND, 3, 1, 0, chanserv_nick, {"NICK", "N", NULL, NULL, NULL}, "<newnick>", "Change bot's nickname, but not the default."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_op, {"OP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel operator status to users."},
#endif
{INFO_COMMAND, 0, 0, 1, chanserv_os_show, {"OS", NULL, NULL, NULL, NULL}, NULL, "Show the operating system that bot is running on."},
{PASSWORD_COMMAND, 0, 2, 0, chanserv_password, {"PASSWORD", "PASS", "PASSWD", NULL, NULL}, "<old password> <new password>", "Change your bot access list password."},
{DANGER_COMMAND, 3, 0, 0, chanserv_performs, {"PERFORMS", NULL, NULL, NULL, NULL}, NULL, "Perform the tasks in the perform.ini startup script."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, 0, chanserv_perm_ban, {"PERMBAN", "SHITLIST", NULL, NULL, NULL}, "<user@host> [reason]", "Adds a user to the permanent ban list."},
{INFO_COMMAND, 0, 0, 0, chanserv_perm_bans_list, {"PERMBANS?", NULL, NULL, NULL, NULL}, NULL, "Shows how many permanent bans there are."},
#endif
#ifdef ENABLE_CTCP
{INFO_COMMAND, 0, 1, 0, chanserv_ping, {"\1PING", NULL, NULL, NULL, NULL}, "<>", ""},
#endif
{INFO_COMMAND, 0, 0, 0, chanserv_ping2, {"PING", NULL, NULL, NULL, NULL}, NULL, "Replies with \"PONG\" to see how lagged the bot is.."},
{INFO_COMMAND, 0, 0, 0, chanserv_queue_show, {"SENDQ?", "QUE?", NULL, NULL, NULL}, NULL, "Shows how many items are ready to be displayed."},
#ifdef ENABLE_QUIZ
{SAFE_COMMAND, 0, 0, 0, chanserv_quiz, {"QUIZ", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
#ifdef ENABLE_RANDQ
{NORMAL_COMMAND, 0, 1, 0, chanserv_quote, {"QUOTE", NULL, NULL, NULL, NULL}, "[text]", "Shows a random quote."},
{NORMAL_COMMAND, 0, 1, 0, chanserv_random_quote, {"RANDQUOTE", "RANDQ", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
{NORMAL_COMMAND, 0, 1, 0, chanserv_random_quote_2, {"RANDQUOTE2", "RANDQ2", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
#endif
#ifdef ENABLE_RANDOM
{NORMAL_COMMAND, RAND_LEVEL, 1, 0, chanserv_random_stuff, {"RANDOMSTUFF", "RANDSTUFF", "RS", NULL, NULL}, "<text>", "Add random stuff to say."},
{INFO_COMMAND, 0, 0, 0, chanserv_random_stuff_list, {"RANDOMSTUFF?", "RANDSTUFF?", NULL, NULL, NULL}, NULL, "Shows time until next random thing is said."},
#endif
{DANGER_COMMAND, 3, 1, 0, chanserv_raw, {"RAW", NULL, NULL, NULL, NULL}, "<raw data>", "Get bot to send raw IRC data."},
//#ifndef WIN32
{INFO_COMMAND, 0, 0, 0, chanserv_rdb, {"RDB", NULL, NULL, NULL, NULL}, "[topic]", "Display information about the random databases."},
//#endif
{DANGER_COMMAND, 3, 3, 0, chanserv_repeat, {"REPEAT", "TIMER", NULL, NULL, NULL}, "<number> <delay> <raw data>", "Get bot to send raw IRC data a number of times."},
{NORMAL_COMMAND, 1, 1, 0, chanserv_replace, {"REPLACE", NULL, NULL, NULL, NULL}, "<topic> <text>", "Replace the text of a topic."},
{DANGER_COMMAND, 3, 0, 0, chanserv_restart, {"RESTART", "REHASH", NULL, NULL, NULL}, NULL, "Restart the bot."},
{INFO_COMMAND, 0, 1, 0, chanserv_search, {"SEARCH", "LOOK", "FIND", NULL, NULL}, "<text>", "Search in the topics."},
{INFO_COMMAND, 0, 1, 0, chanserv_seen, {"SEEN", NULL, NULL, NULL, NULL}, "<nick>", "Show the last time a user was seen."},
{DANGER_COMMAND, 3, 1, 0, chanserv_jump, {"SERVER", "JUMP", NULL, NULL, NULL}, "<server> [port]", "Switch bot to a different server."},
{DANGER_COMMAND, 3, 1, 0, chanserv_set, {"SET", NULL, NULL, NULL, NULL}, "<parameter>[=<new value>]", "Set or show the value of a setup.ini parameter. Usually requires a restart."},
{DANGER_COMMAND, 1, 1, 0, chanserv_setinfo, {"SETINFO", NULL, NULL, NULL, NULL}, "<new user greeting|0>", "Set your greeting from the bot when you join a channel."},
{SAFE_COMMAND, SLEEP_LEVEL, 1, 1, chanserv_sleep, {"SLEEP", "HUSH", NULL, NULL, NULL}, "[period]", "Deactivate bot for a period."},
#ifdef ENABLE_STATS
{INFO_COMMAND, 0, 0, 0, chanserv_stats, {"STATS", NULL, NULL, NULL, NULL}, "[nick]", "Shows statistics about questions answered."},
#endif
#ifdef ENABLE_TAF
{NORMAL_COMMAND, 0, 1, 0, chanserv_taf, {"TAF", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw TAF weather data."},
#endif
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 1, 0, chanserv_teaseop, {"TEASEOP", "TO", NULL, NULL, NULL}, "<nick>", "Tease a user with channel operator status."},
#endif
{INFO_COMMAND, 0, 2, 0, chanserv_tell, {"TELL", NULL, NULL, NULL, NULL}, "<nick> [ABOUT] <topic>", "Get bot to recall a topic to a user."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 0, 0, chanserv_topic, {"TOPIC", "T", NULL, NULL, NULL}, "<channel topic>", "Change the channels topic."},
#endif
{DANGER_COMMAND, 1, 1, 0, chanserv_unignore, {"UNIGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to stop ignoring a user."},
{INFO_COMMAND, 0, 1, 0, chanserv_unixtime, {"UNIXTIME", NULL, NULL, NULL, NULL}, "<time>", "Shows unixtime."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 0, 0, chanserv_up, {"UP", NULL, NULL, NULL, NULL}, NULL, "Add channel operator status to yourself."},
#endif
//#ifndef WIN32
{INFO_COMMAND, 0, 0, 0, chanserv_uptime, {"UPTIME", NULL, NULL, NULL, NULL}, NULL, "Shows the uptime statistics for the computer the bot is running on."},
//#endif
{INFO_COMMAND, 1, 0, 0, chanserv_user_list, {"USERLIST", "HLIST", "ACCESS", NULL, NULL}, NULL, "Show the bot's access list."},
{INFO_COMMAND, 0, 0, 0, chanserv_variables, {"VARIABLES", NULL, NULL, NULL, NULL}, NULL, "Displays variables you can use."},
#ifdef ENABLE_CTCP
{INFO_COMMAND, 0, 0, 0, chanserv_version, {"\1VERSION\1", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
#ifdef ENABLE_CHANNEL
{NORMAL_COMMAND, 3, 1, 0, chanserv_voice, {"VOICE", "V", NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel voice status to users."},
#endif
{SAFE_COMMAND, SLEEP_LEVEL, 0, 0, chanserv_wakeup, {"WAKEUP", NULL, NULL, NULL, NULL}, NULL, "Reactivates bot from sleep mode."},
#ifdef ENABLE_WEATHER
{NORMAL_COMMAND, 0, 1, 0, chanserv_weather, {"WEATHER", NULL, NULL, NULL, NULL}, "<city or code>", "Get decoded weather data."},
#endif
#ifdef ENABLE_WEBSEARCH
{NORMAL_COMMAND, 0, 1, 0, chanserv_websearch, {"WEBSEARCH", NULL, NULL, NULL, NULL}, "<text>", "Look up the text on the web using duckduckgo.com."},
#endif
{SAFE_COMMAND, 0, 2, 0, chanserv_where, {"WHAT", "WHO", "WHERE", NULL, NULL}, "<IS> [A|AN] <topic>", "Recall a topic."},
{SAFE_COMMAND, 0, 2, 0, chanserv_whisper, {"WHISPER", NULL, NULL, NULL, NULL}, "<nick> [ABOUT] <topic>", "Get bot to recall a topic to a user privately."},
{INFO_COMMAND, 4, 0, 0, NULL, {NULL, NULL, NULL, NULL, NULL}, NULL, NULL}
};
void chanserv(char *source, char *target, char *buf)
{
struct chanserv_output *result = NULL;
char *cmd = NULL, *userhost = NULL, oldbuf[BUFSIZ] = {"NULL"},
*ptr = NULL;
int i = 0, j = 0, found = -1, command = 0, wakeup = 0, exempt = 0,
more_needed = 0, too_many = 0, check_too_many = 0, arg_count = 0;
enum chanserv_invoke_type input_type = DIRECT_INVOKE;
enum chanserv_command_type command_type = NORMAL_COMMAND;
#ifdef ENABLE_RANDOM
if (strcasecmp (target, CHAN) == 0)
Rand_Idle = 0;
#endif
stripline (buf);
stripline (source);
if (buf == NULL || target == NULL || source == NULL)
return;
/* Make a copy of the original buffer in a safe location for
* later use. Strip the : if there is one.
*/
strncpy (oldbuf, buf, sizeof (oldbuf));
/* Pointer to oldbuf */
ptr = oldbuf;
if (*ptr == ':')
ptr++;
cmd = strtok (buf, " ");
if (!cmd)
return;
if (*cmd == ':')
cmd++;
if ((userhost = strchr (source, '!')) != NULL)
*userhost++ = '\0';
if (check_ignore_user_ram(source) > 0)
return;
if (*target != '#' && *target != '&' && *target != '+')
{
input_type = MSG_INVOKE;
}
else if (strcasecmp (cmd, NICK_COMMA) == 0 ||
strcasecmp (cmd, COLON_NICK) == 0 ||
strcasecmp (cmd, BCOLON_NICK) == 0 ||
strcasecmp (cmd, Mynick) == 0)
{
input_type = ADDRESS_INVOKE;
cmd = strtok (NULL, " ");
}
if (cmd)
{
if (*cmd == *CMDCHAR)
{
cmd++;
command = 1;
input_type = CHAR_INVOKE;
}
strupr (cmd);
for (i = 0; chanserv_commands[i].func != NULL; i++)
{
for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
{
if (strcmp(cmd, chanserv_commands[i].command[j]) == 0)
{
found = i;
command_type = chanserv_commands[found].type;
check_too_many = chanserv_commands[found].too_many;
if (strcmp(cmd, "WAKEUP") == 0)
wakeup = 1;
break;
}
}
if (found != -1)
break;
}
}
if (input_type != MSG_INVOKE)
{
if (((Sleep_Toggle == 1) && (wakeup != 1)) || (cf(userhost, source, target)))
return;
add_user(target, source, userhost, 0); /* Unidle */
}
if (found != -1)
{
/*
* password related commands can ONLY be done privately.
* Every command can be done by /msg bot !command.
* Every command can be done by /query bot !command.
* Every command can be done by /msg bot !command.
* Every danger command can be done by bot: !command.
* Every danger command can be done by !command.
* Every normal command can be done by /query bot command.
* Every normal command can be done by /msg bot command.
* Every safe command can be done by bot: command.
* Every information command can be done by command.
*/
switch (command_type)
{
case INFO_COMMAND :
break;
case SAFE_COMMAND :
{
if (input_type == DIRECT_INVOKE)
return;
break;
}
case NORMAL_COMMAND :
{
if (input_type == DIRECT_INVOKE)
return;
break;
}
case DANGER_COMMAND :
{
if (command != 1)
return;
break;
}
case PASSWORD_COMMAND :
{
if (input_type != MSG_INVOKE)
return;
break;
}
}
if (check_access(userhost, (input_type == MSG_INVOKE) ? "#*" : target, 0, source) >= chanserv_commands[found].access)
{
char **args = NULL;
int k = 0;
/* Use the char count of spaces in our oldbuf ptr. Since
* it has the cmd tacked on the beginning, the number of
* spaces gives us an accurate early number of arguments
* supplied by the user, because the count of spaces will
* return one more than the actual number of args supplied.
* The first word is the cmd, so we don't want this counted.
* This is sort of a lazy way of counting arguments before
* they're actually read into a buffer and dealt with.
*
* This allows us to "break out" of the command routine if
* we've entered accidentally by user input. Such instances
* may be if the user says "info things stuff", the bot
* realizes this is not a command, but normal conversation,
* and will respond if the topic is in it's database. If it's
* not found, the bot either ignores it or responds with a
* whut reply if addressed directly. This code is only
* intended for commands which have no arguments.
*/
if (*ptr == '!')
ptr++;
/* Actual number of arguments supplied. */
k = count_char (ptr, ' ');
/* Number of arguments expected. */
arg_count = chanserv_commands[found].arg_count;
if (k > 0)
{
args = calloc(k + 1, sizeof(char *));
if (args)
{
for (i = 0; i < k; i++)
{
args[i] = strtok(NULL, " ");
}
args[i++] = NULL;
/* Check for more arguments needed, but don't
* bail out, we'll take care of it later. */
if (i < arg_count)
more_needed = 1;
}
else
return;
/* Check for too many args on special cases. */
if (check_too_many == 1)
{
if ((input_type == ADDRESS_INVOKE) && (k > (arg_count+1)))
too_many = 1;
if ((k > arg_count) && (input_type == DIRECT_INVOKE))
too_many = 1;
if ((k > arg_count) && (input_type == MSG_INVOKE))
too_many = 1;
if ((k > arg_count) && (input_type == CHAR_INVOKE))
return;
}
}
else
{
args = calloc(1, sizeof(char *));
if (args)
{
args[0] = NULL;
if (0 < arg_count)
more_needed = 1;
}
else
return;
}
if (too_many == 1)
{
int i = 0;
char *ptr2 = NULL;
strlwr (ptr);
for (i = 0; i < strlen (ptr); i++)
{
if (ptr[i] == ' ')
ptr[i] = '+';
}
/* Strip the bot's nickname if ADDRESS_INVOKE */
if (input_type == ADDRESS_INVOKE)
{
ptr2 = strtok (ptr, "+");
ptr = strtok (NULL, "");
}
/* Output only if the topic exists. If the bot was
* addressed by nickname (ADDRESS_INVOKE), output
* anyway because show_url will supply a DUNNO
* response.
* If the input_type was MSG_INVOKE, we use the
* source as a target, because the target ends up
* being set to the bot's own nickname due to the
* parsing under certain conditions.
*/
if (check_existing_url(source, ptr, target) == 1)
// || (input_type == ADDRESS_INVOKE)
// || (input_type == MSG_INVOKE))
{
result = show_url(source, ptr,
((input_type == MSG_INVOKE)
? source : target), 1, 0, userhost, 0);
}
else
/* No matching database entry. */
return;
}
else if ((more_needed == 1) && chanserv_commands[found].syntax)
{
result = chanserv_show_help(cmd, check_access(userhost, (input_type == MSG_INVOKE) ? "#*" : target, 0, source));
}
else
{
/* We call this to give the command a chance to supply
* a custom error msg if there are not enough
* arguments. Because it fell through the loop
* this far, we assume it's a normal command with
* arguments to be parsed.
*/
result = chanserv_commands[found].func(source, target, cmd, args, input_type, userhost);
}
if (result)
{
i = 1;
show_output(source, target, result, input_type, 0);
result = NULL;
}
free(args);
}
}
else if (input_type != CHAR_INVOKE)
{
if ((input_type == ADDRESS_INVOKE) && (cmd == NULL))
{
if (RANDOM_WHUT == true)
do_randomtopic(WHUTR, target, WHUT_FILE, source, cmd);
else
{
if (input_type == MSG_INVOKE)
S("NOTICE %s :%s\n", source, WHUT);
else
S("PRIVMSG %s :%s: %s\n", target, source, WHUT);
}
}
else if ((GENERAL_QUESTIONS) && (cmd))
{
result = show_url(source, get_multiword_topic(cmd),
(input_type == MSG_INVOKE) ? source : target,
(! (input_type == DIRECT_INVOKE)),
(input_type == DIRECT_INVOKE),
userhost, 0);
if (result)
{
show_output(source, (input_type == MSG_INVOKE) ? source : target, result, input_type, 1);
result = NULL;
}
}
}
}
static void show_output(char *source, char *target, struct chanserv_output *result, enum chanserv_invoke_type input_type, int question)
{
struct chanserv_output *output = result;
// TODO - This is not working for actions.
while (output)
{
char *s, *s2, c;
int length, len;
/* RFC2812 says max packet length is 512, including CR-LF at end.
* Also a colon and a space at the beginning.
*/
//#define MAX_IRC_LEN 507 // This doesn't work.
#define MAX_IRC_LEN 475 // This works.
s = output->output;
length = strlen(s);
if (input_type == MSG_INVOKE)
{
len = 12 + strlen(source);
while ((len + length) > MAX_IRC_LEN)
{
c = s[MAX_IRC_LEN - len];
s[MAX_IRC_LEN - len] = '\0';
s2 = strrchr(s, ' ');
*s2 = '\0';
S("NOTICE %s :%s\n", source, s);
db_sleep(2);
*s2 = ' ';
s[MAX_IRC_LEN - len] = c;
s = s2 + 1;
length = strlen(s);
}
S("NOTICE %s :%s\n", source, s);
}
else
{
len = 16 + strlen(target) + strlen(source);
while ((len + length) > MAX_IRC_LEN)
{
c = s[MAX_IRC_LEN - len];
s[MAX_IRC_LEN - len] = '\0';
s2 = strrchr(s, ' ');
*s2 = '\0';
if ((('#' == target[0]) && (ADDRESS_INVOKE != input_type)) || (question))
S("PRIVMSG %s :%s\n", target, s);
else
S("PRIVMSG %s :%s: %s\n", target, source, s);
db_sleep(2);
*s2 = ' ';
s[MAX_IRC_LEN - len] = c;
s = s2 + 1;
length = strlen(s);
}
if ((('#' == target[0]) && (ADDRESS_INVOKE != input_type)) || (question))
S("PRIVMSG %s :%s\n", target, s);
else
S("PRIVMSG %s :%s: %s\n", target, source, s);
}
output = output->next;
}
chanserv_output_free(result);
}
struct chanserv_output *chanserv_show_help(char *cmd, int user_level)
{
struct chanserv_output *result = NULL;
char temp[10 * 1024] = { 0 }, cmdchar[2] = "\0\0";
int i, j, found = -1;
if (*cmd == *CMDCHAR)
cmd++;
strupr(cmd);
for (i = 0; chanserv_commands[i].func != NULL; i++)
{
for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
{
if (strcmp(cmd, chanserv_commands[i].command[j]) == 0)
{
found = i;
break;
}
}
if (found != -1)
break;
}
if (found != -1)
{
if (chanserv_commands[found].type == DANGER_COMMAND)
cmdchar[0] = *CMDCHAR;
else
cmdchar[0] = '\0';
for (j = 0; chanserv_commands[found].command[j] != NULL; j++)
{
if (j)
strcat(temp, " | ");
if (chanserv_commands[i].type == DANGER_COMMAND)
strcat(temp, cmdchar);
strcat(temp, chanserv_commands[found].command[j]);
}
result = chanserv_asprintf(result, "%s [level %d] - %s SYNTAX - %s%s %s", temp, chanserv_commands[found].access, chanserv_commands[found].summary, cmdchar, cmd,
(chanserv_commands[found].syntax != NULL) ? chanserv_commands[found].syntax : "");
}
else if (strcmp(cmd, "COMMANDS") == 0)
{
cmdchar[0] = *CMDCHAR;
for (i = 0; chanserv_commands[i].func != NULL; i++)
{
if (chanserv_commands[i].access <= user_level)
{
if (chanserv_commands[i].command[0][0] > 10)
{
if (i)
strcat(temp, " ");
if (chanserv_commands[i].type == DANGER_COMMAND)
strcat(temp, cmdchar);
strcat(temp, chanserv_commands[i].command[0]);
}
}
}
result = chanserv_asprintf(result, "%s", temp);
}
else if (strcmp(cmd, "PARAMETERS") == 0)
{
for (i = 0; parameters[i].parameter[0] != NULL; i++)
{
if (parameters[i].access <= user_level)
{
if (i)
strcat(temp, " ");
strcat(temp, parameters[i].parameter[0]);
}
}
result = chanserv_asprintf(result, "%s", temp);
}
else
{
for (i = 0; parameters[i].parameter[0] != NULL; i++)
{
for (j = 0; parameters[i].parameter[j] != NULL; j++)
{
if (strcmp(cmd, parameters[i].parameter[j]) == 0)
{
found = i;
break;
}
}
if (found != -1)
break;
}
if (found != -1)
{
for (j = 0; parameters[found].parameter[j] != NULL; j++)
{
if (j)
strcat(temp, " | ");
strcat(temp, parameters[found].parameter[j]);
}
switch (parameters[found].type)
{
case ST_BOOLEAN :
{
bool *variable = parameters[found].value;
result = chanserv_asprintf(result, "%s [level %d] - %s VALUE - %s = %s", temp, parameters[found].access, parameters[found].summary, cmd, (*variable) ? "true" : "false");
break;
}
case ST_INTEGER :
{
long *variable = parameters[found].value;
result = chanserv_asprintf(result, "%s [level %d] - %s VALUE - %s = %ld", temp, parameters[found].access, parameters[found].summary, cmd, *variable);
break;
}
case ST_STRING :
{
char *variable = parameters[found].value;
result = chanserv_asprintf(result, "%s [level %d] - %s VALUE - %s = %s", temp, parameters[found].access, parameters[found].summary, cmd, variable);
break;
}
}
}
}
return result;
}
int check_exempt (char *cmd)
{
int i = 0;
int j = 0;
int k = 0;
char *exempt_items[] = {
"CYCLE",
"HELP",
#ifdef ENABLE_STATS
"STATS",
#endif
NULL
};
strupr(cmd);
for (i = 0; chanserv_commands[i].func != NULL; i++)
{
for (j = 0; chanserv_commands[i].command[j] != NULL; j++)
{
if (strcmp (cmd, chanserv_commands[i].command[j]) == 0)
{
for (k = 0; exempt_items[k] != NULL; k++)
{
if (strcmp (chanserv_commands[i].command[j], exempt_items[k]) == 0)
{
strlwr(cmd);
return 1;
}
}
}
}
}
strlwr(cmd);
return 0;
}
diff --git a/source/comm.c b/source/comm.c
index 5bd4f66..ee99bde 100644
--- a/source/comm.c
+++ b/source/comm.c
@@ -1,451 +1,462 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Delete one or more elements from the sendq
* 1 = delete all pri/not's
* 0 = delete first in queue
* 6/23/00 Dan
* - Updated to use head and tail pointer queue
* - All variables now initialized when declared
* - Optimized the main while loop a bit, reduced amount of code
*/
void
del_sendq (long toggle)
{
struct sendq *pNode = sendqhead, *pPrev = 0;
if (NULL == sendqhead)
{
return;
}
if (toggle == 0)
{
/* Just delete the head */
pNode = sendqhead;
sendqhead = sendqhead->next;
free (pNode);
}
else
{
/* Iterate through the queue and delete each element which is
* a PRIVMSG or NOTICE
*/
for (; pNode != NULL; pPrev = pNode, pNode = pNode->next)
{
if (0 == strncmp (pNode->data, "PRI", 3) || 0 == strncmp (pNode->data, "NOT", 3))
{
/* Found one, let's delete it */
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
sendqhead = pNode->next;
}
free (pNode);
pNode = NULL;
break;
}
} /* for */
} /* else */
/* Update the tail pointer if needed */
if (NULL == sendqhead)
{
sendqtail = NULL;
}
}
int
get_sendq_count (long toggle)
{
struct sendq *c;
long i = 0, x = 0;
c = sendqhead;
while (c != NULL)
{
i++;
if (c->data[0] == 'P' && c->data[1] == 'R' && c->data[2] == 'I')
x++;
else if (c->data[0] == 'N' && c->data[1] == 'O' && c->data[2] == 'T')
x++;
c = c->next;
}
if (toggle == 1)
clear_sendq (i, 1);
if (toggle == 2)
return i;
if (i < OUTPUT1_COUNT)
SEND_DELAY = OUTPUT1_DELAY;
else if (i < OUTPUT2_COUNT)
SEND_DELAY = OUTPUT2_DELAY;
else
SEND_DELAY = OUTPUT3_DELAY;
if (x > OUTPUT_PURGE_COUNT)
clear_sendq (x, 0);
return i;
}
void
clear_sendq (long count, long toggle)
{
long i = 0;
i = count;
while (i > 1)
{
i--;
del_sendq (1);
}
send_tog = 1;
if (toggle != 1)
L090 (CHAN, count);
}
long
setinfo_lastcomm (char *rest)
{ /* Disallows joins to more than one channel (or the same chan)
* to artifically raise join counters */
long c_uptime = 0;
if (strcasecmp (rest, slc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, slc2) == 0)
return 1;
if (strcasecmp (rest, slc3) == 0)
return 1;
if (strcasecmp (rest, slc4) == 0)
return 1;
if (*slc1 == '0')
{ /* init lastcomms */
strncpy (slc1, rest, sizeof (slc1));
slcn1 = time (NULL);
}
if (*slc2 == '0')
{
strncpy (slc2, rest, sizeof (slc2));
slcn2 = time (NULL);
}
if (*slc3 == '0')
{
strncpy (slc3, rest, sizeof (slc3));
slcn3 = time (NULL);
}
if (*slc4 == '0')
{
strncpy (slc4, rest, sizeof (slc4));
slcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - slcn1) > SLASTCOMM_TIME)
{ /* reinit old data */
slcn1 = 0;
*slc1 = '0';
}
if ((c_uptime = time (NULL) - slcn2) > SLASTCOMM_TIME)
{
slcn2 = 0;
*slc2 = '0';
}
if ((c_uptime = time (NULL) - slcn3) > SLASTCOMM_TIME)
{
slcn3 = 0;
*slc3 = '0';
}
if ((c_uptime = time (NULL) - slcn4) > SLASTCOMM_TIME)
{
slcn4 = 0;
*slc4 = '0';
}
strncpy (slc4, slc3, sizeof (slc4)); /* no matches, move em on
down */
strncpy (slc3, slc2, sizeof (slc3));
strncpy (slc2, slc1, sizeof (slc2));
strncpy (slc1, rest, sizeof (slc1));
slcn4 = slcn3;
slcn3 = slcn2;
slcn2 = slcn1;
slcn1 = time (NULL);
return 0;
}
long
do_lastcomm (char *nick, char *target, char *rest)
{
long c_uptime = 0;
if (strcasecmp (rest, lc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, lc2) == 0)
return 1;
if (strcasecmp (rest, lc3) == 0)
return 1;
if (strcasecmp (rest, lc4) == 0)
return 1;
if (*lc1 == '0')
{ /* init lastcomms */
strncpy (lc1, rest, sizeof (lc1));
lcn1 = time (NULL);
}
if (*lc2 == '0')
{
strncpy (lc2, rest, sizeof (lc2));
lcn2 = time (NULL);
}
if (*lc3 == '0')
{
strncpy (lc3, rest, sizeof (lc3));
lcn3 = time (NULL);
}
if (*lc4 == '0')
{
strncpy (lc4, rest, sizeof (lc4));
lcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - lcn1) > LASTCOMM_TIME)
{ /* reinit old data */
lcn1 = 0;
*lc1 = '0';
}
if ((c_uptime = time (NULL) - lcn2) > LASTCOMM_TIME)
{
lcn2 = 0;
*lc2 = '0';
}
if ((c_uptime = time (NULL) - lcn3) > LASTCOMM_TIME)
{
lcn3 = 0;
*lc3 = '0';
}
if ((c_uptime = time (NULL) - lcn4) > LASTCOMM_TIME)
{
lcn4 = 0;
*lc4 = '0';
}
strncpy (lc4, lc3, sizeof (lc4)); /* no matches, move em on
down */
strncpy (lc3, lc2, sizeof (lc3));
strncpy (lc2, lc1, sizeof (lc2));
strncpy (lc1, rest, sizeof (lc1));
lcn4 = lcn3;
lcn3 = lcn2;
lcn2 = lcn1;
lcn1 = time (NULL);
return 0;
}
void
prepare_bot (void)
{
int esc = 0;
while (!esc)
{
gs26 ();
printf (".: Connecting to %s:%ld\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
socketfd = create_connection (BS, VHOST, BP);
switch (socketfd)
{
case ERR_TIMED_OUT:
printf (".: Connection to %s:%ld timed out!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_CONN_REFUSED:
printf (".: Connection to %s:%ld was refused!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_NOT_ADDR:
printf ("Address not in range!\n");
exit (1);
case ERR_NO_REACH:
printf ("Address not reachable!\n");
exit (1);
default:
esc = 1;
printf
(".: Connected to %s:%ld! [%ld]\t\n", BS, BP, (long) getpid ());
fflush (stdout);
db_sleep (5);
break;
}
}
/* set the socket to BLOCK */
if (fcntl (socketfd, F_SETFL, 0) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
}
int
create_connection (char *server, char *virtualhost, long port)
{
struct sockaddr_in name;
struct hostent *hostname;
struct timeval timeout;
fd_set set;
int sock = 0, vhost = 1, sockerr = 0,
optlen = sizeof (sockerr);
if ((!virtualhost) || (strlen (virtualhost) < 1))
vhost = 0;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
memset (&name, 0, sizeof (struct sockaddr_in));
setsockopt (sock, SOL_SOCKET, SO_LINGER, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
name.sin_family = AF_INET;
name.sin_addr.s_addr = (vhost ? inet_addr (virtualhost) : INADDR_ANY);
if ((name.sin_addr.s_addr == -1) && vhost)
{
hostname = gethostbyname (virtualhost);
if (hostname)
{
name.sin_addr = *(struct in_addr *) hostname->h_addr;
}
else
{
name.sin_addr.s_addr = INADDR_ANY;
}
}
if (bind (sock, (struct sockaddr *) &name, sizeof (struct sockaddr_in)) < 0)
{
printf ("\n");
perror ("bind");
close (sock);
exit (EXIT_FAILURE);
}
memset (&name, 0, sizeof (struct sockaddr_in));
name.sin_family = AF_INET;
name.sin_port = htons (port);
if(!(hostname = gethostbyname (server)))
{
printf ("\nCan't create the connection!\n");
// FIXME: This is obsolete, and solaris doesn't know about it.
// herror ("hostname");
exit (EXIT_FAILURE);
}
name.sin_addr = *(struct in_addr *) hostname->h_addr;
/* set the file descriptor to non blocking mode so that connect()
returns immediately.
*/
if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
if ((errno != EINPROGRESS) && (errno != ENOENT))
{
printf ("\n");
perror ("connect");
exit (EXIT_FAILURE);
}
}
alarm (0);
while (1)
{
/* set the timeout */
timeout.tv_sec = CONNECT_WAIT_TIMEOUT;
timeout.tv_usec = 0;
/* set the file descriptor to be empty */
FD_ZERO (&set);
/* add our socket to the file descriptor set */
FD_SET (sock, &set);
/* select will let us know when our socket is ready (connected) */
switch (select (FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
/* if select returns 0, our timeout was reached */
case 0:
alarm (AIL);
return ERR_TIMED_OUT;
/* -1 means we are not connected */
case -1:
break;
/* we MIGHT be connected */
default:
/* get the socket errno so we can check if we are connected */
switch (getsockopt (sock, SOL_SOCKET, SO_ERROR, &sockerr, &optlen))
{
case -1:
alarm (AIL);
return ERR_SOCK_OPT;
case 0:
switch (sockerr)
{
case ECONNREFUSED:
alarm (AIL);
return ERR_CONN_REFUSED;
case EADDRNOTAVAIL:
alarm (AIL);
return ERR_NOT_ADDR;
case ENETUNREACH:
alarm (AIL);
return ERR_NO_REACH;
case SUCCESS:
alarm (AIL);
return sock;
}
}
}
}
}
void
register_bot (void)
{
get_sendq_count (1);
Snow ("NICK %s\n", Mynick);
strlwr (UID);
Snow ("USER %s %d %d :%s \2%d\2\n", UID, time (NULL), time (NULL), REALNAME, NUM_HELPER);
if (BPASS != NULL)
Snow ("PASS :%s\n", BPASS);
}
diff --git a/source/configure.ac b/source/configure.ac
index 6b3ae4e..cef410d 100644
--- a/source/configure.ac
+++ b/source/configure.ac
@@ -1,111 +1,120 @@
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.63)
AC_INIT([Darkbot],[8rc4],[darkbot-devel@lists.sourceforge.net])
-AC_COPYRIGHT([Copyright 1996-2008 Darkbot Development Team])
+AC_COPYRIGHT([Copyright (C) 1996 Darkbot Project])
AC_REVISION($Revision$)
AC_CONFIG_AUX_DIR([auxdir])
AC_CONFIG_LIBOBJ_DIR([../source/compat])
AC_CONFIG_MACRO_DIR([../m4])
AC_CONFIG_SRCDIR([../source/parse.c])
# Preserve 8.3 file format for MS-DOS compatibility.
AC_CONFIG_HEADERS([config.h:config-h.in])
AM_INIT_AUTOMAKE([foreign 1.10 -Wall -Werror subdir-objects no-dependencies])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_USE_SYSTEM_EXTENSIONS
AM_PROG_AR
gl_USE_SYSTEM_EXTENSIONS
# Checks for libraries.
AC_CHECK_LIB(crypt, crypt)
LIB_SOCKET_NSL
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_STAT
AC_CHECK_HEADERS([ansidecl.h arpa/inet.h errno.h fcntl.h limits.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h])
gl_MINMAX
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_C_VOLATILE
gl_TIMESPEC
# Checks for library functions.
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
# FIXME: change all select()'s to cater to the detected results of AC_FUNC_SELECT_ARGTYPES.
# Probably not a lot can be done with the results actually.
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_LSTAT
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([alarm gethostbyname memmove select socket strchr strrchr])
AC_REPLACE_FUNCS([crypt memset nanosleep snprintf strcasecmp strcasestr strndup strspn strstr vfprintf vsprintf])
# User enabled stuff.
# testing mode must be done first.
DB_ENABLE_GENERIC([testing],[no],[TESTING],[testing mode - for developers only])
DB_ENABLE_COMMANDS([CTCP],[yes],[CTCP])
DB_ENABLE_COMMANDS([channel],[yes],[CHANNEL])
DB_ENABLE_COMMAND([math],[yes],[MATH])
DB_ENABLE_COMMAND([websearch],[yes],[WEBSEARCH])
DB_ENABLE_COMMAND([weather],[yes],[WEATHER])
DB_ENABLE_COMMAND([METAR],[yes],[METAR])
DB_ENABLE_COMMAND([TAF],[yes],[TAF])
DB_ENABLE_COMMAND([quiz],[no],[QUIZ])
DB_ENABLE_COMMAND([randq],[yes],[RANDQ])
DB_ENABLE_COMMAND([stats],[yes],[STATS])
DB_ENABLE_GENERIC([status],[no],[STATUS],[display of network status])
DB_ENABLE_GENERIC([stoned],[yes],[STONED_CHECK],[server stoned check])
DB_ENABLE_GENERIC([version],[no],[VERSION_CHECK],[new darkbot version check])
DB_ENABLE_GENERIC([verbose],[yes],[VERBOSE],[verbose startup])
DB_ENABLE_GENERIC([encrypt],[no],[ENCRYPT],[encryption of passwords])
DB_ENABLE_GENERIC([random],[yes],[RANDOM],[random utterences])
DB_ENABLE_VALUE([lang],[1],[LANG],[language])
DB_ENABLE_VALUE([sleep],[3],[SLEEP_LEVEL],[sleep command access level])
DB_ENABLE_VALUE([add],[1],[ADD_LEVEL],[topic adding access level])
DB_ENABLE_VALUE([del],[1],[DEL_LEVEL],[topic deleting access level])
DB_ENABLE_VALUE([random],[2],[RAND_LEVEL],[randomstuff command access level])
DB_ENABLE_VALUE([data],[400],[MAX_DATA_SIZE],[maximum data size])
DB_ENABLE_VALUE([topic],[50],[MAX_TOPIC_SIZE],[maximum topic size])
# If in testing mode, then make sure everything gets compiled.
if test "[${db_cv_enable_testing}]" = yes; then
AC_LIBOBJ([crypt])
AC_LIBOBJ([lstat])
AC_LIBOBJ([malloc])
AC_LIBOBJ([memset])
AC_LIBOBJ([nanosleep])
AC_LIBOBJ([realloc])
AC_LIBOBJ([snprintf])
AC_LIBOBJ([stat])
AC_LIBOBJ([strcasecmp])
AC_LIBOBJ([strcasestr])
AC_LIBOBJ([strndup])
AC_LIBOBJ([strspn])
AC_LIBOBJ([strstr])
AC_LIBOBJ([vfprintf])
AC_LIBOBJ([vsprintf])
fi
# Create output files.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/source/convertdb.c b/source/convertdb.c
index 60114f7..4837f22 100644
--- a/source/convertdb.c
+++ b/source/convertdb.c
@@ -1,107 +1,118 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#define STRING_SHORT 512
char DAT_DIR[STRING_SHORT] = { 0 };
// FIXME: This may not be compatible with putting all exes into $prefix/bin.
// Under cygwin the executable should be placed on Darkbot's root dir
// due to the necessity of cygwin dynamic library.
int main(int argc, char *argv[])
{
FILE *in, *out;
char *ptr = NULL;
const char *salt = "8fei3k";
char userlist[STRING_SHORT] = { 0 };
char tempfile[STRING_SHORT] = { 0 };
char temp[STRING_SHORT] = { 0 };
char channel[1024] = { 0 };
char uh[1024] = { 0 };
char level[10] = { 0 };
char joins[10] = { 0 };
char pass[1024] = { 0 };
char setinfo[1024] = { 0 };
struct stat st;
int ret;
printf("\nDarkbot USERLIST.DB < 7f0 conversion utility.\n");
printf("IMPORTANT :: READ THIS!\n\n");
printf("This UTILITY is for converting *OLD* (pre 7f0) userlist's\n");
printf("to the new encrypted format.\n\n");
printf("Use this utility ONLY if:\n");
printf(" - You have copied your pre 7f0 userlist.db in to the dat directory\n\n");
printf("DO NOT use this utility if:\n");
printf(" - You have created a brand new darkbot, and have no users\n\n");
if(argc < 2)
{
printf("Syntax: %s -convert\n\n", argv[0]);
return 0;
}
if(argc > 1)
{
if(strcmp(argv[1], "-convert") != 0)
{
printf("Syntax: %s -convert\n\n", argv[0]);
return 0;
}
}
#ifdef DATABASEDIR
strncpy (DAT_DIR, DATABASEDIR, sizeof (DAT_DIR));
#else
strncpy (DAT_DIR, "dat", sizeof (DAT_DIR));
#endif
#ifdef SOURCEDIR
/* Check if this is being run from the build directory before being installed. */
snprintf(temp, sizeof(temp), "%s/dat/setup.ini", SOURCEDIR);
if (stat(temp, &st) >= 0)
{
snprintf(temp, sizeof(temp), "%s/dat", SOURCEDIR);
strncpy(DAT_DIR, temp, sizeof (DAT_DIR));
}
#endif
snprintf(userlist, sizeof(userlist), "%s/userlist.db", DAT_DIR);
snprintf(tempfile, sizeof(tempfile), "%s/temp.db", DAT_DIR);
printf("Converting %s ...\n", userlist);
if((in = fopen(userlist, "r")) == NULL)
{
printf("\nCan't open %s for reading!\n", userlist);
return EXIT_FAILURE;
} if((out = fopen(tempfile, "wt")) == NULL)
{
printf("\nCan't open %s for writing!\n", tempfile);
return EXIT_FAILURE;
}
snprintf(temp, sizeof(temp), "cp %s %s/backup.db", userlist, DAT_DIR);
ret = system(temp);
while(!feof(in))
{
ret =fscanf(in, "%s %s %s %s %s %[^\n]s", channel, uh, level, joins, pass, setinfo);
#ifdef ENABLE_ENCRYPT
if ((ptr = crypt(pass, salt)) == NULL)
{
printf("\ncrypt() error\n");
return EXIT_FAILURE;
}
#endif
if(!feof(in))
fprintf(out, "%s %s %s %s %s %s\n", channel, uh, level, joins, ptr, setinfo);
}
fclose(in);
fclose(out);
remove(userlist);
rename(tempfile, userlist);
printf("Conversion Complete.\n");
return EXIT_SUCCESS;
}
diff --git a/source/defines.h b/source/defines.h
index 5e61802..ccca1e9 100644
--- a/source/defines.h
+++ b/source/defines.h
@@ -1,344 +1,354 @@
+/*
+ * Copyright (C) 2002 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
/* @configure_input@ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* defines.h
- *** Darkbot (c) 2002
* The Internet Relay Chat Talking Robot
*
*** Darkbot Creator : Jason Hamilton (play) Jason@superlink.net
* Project Administrator : LuizCB (lcb) LuizCB@dusers.sourceforge.net
* Lead Developer : David Seikel (onefang) onefang@users.sourceforge.net
*
* Official Site: http://darkbot.sourceforge.net
* http://darkbot.sourceforge.net
*
*** For any questions, suggestions, malfunctions, etc
* Use our support area at http://darkbot.sourceforge.net
*
* *******************************---******************************* */
/*
*** NOTES - READ before you start:
*** Lines beginning by # (hash) are peprocessor directives, they are not
* comments. You should NOT remove them.
*** #defines should only be changed to ON, OFF, #define, #undef
* or it's value defined on the very right end.
*** Areas between " " are messages Darkbot will send. Do not remove " ".
*** Double slash characters on de beginning of a line or slaches followed
* or preceded by * on the beginning and end of lines envolving some
* portion of text are comment characters combinations with help
* information for the delelopers or users. They do not have any effect
* in the behavior of the program.
*
,-----------------------------------------------------------------,
| Note that the defines bellow are the RECOMMENDED settings! |
| Modify it by changing it's values of the data. This file will |
| instruct the compiler to build the executable file. If you're |
| not sure of what to do, leave the default settings alone :) |
`-----------------------------------------------------------------' */
#define ON 1
#define OFF 0
/* ================ SYSTEM REQUIREMENTS ================ */
/*
* Change the Ansi C signal handling below if it's not in the standard place,
* usually on include/. Leave it as is if you don't know what that is. Type
* 'man signal' on your unix box for more info.
* (default = <signal.h>)
*/
//#include <signal.h>
/*
* Most BSD systems will not need this. If your bot will
* connect but don't react at all try turning this ON.
* (default = OFF)
*/
//#define NEED_LIBC5 OFF
/*
* SGI boxes (ie; IRIX system) need this
* define to run. (default = OFF)
*/
//#define SGI OFF
/*
* If you change anything on the next 5 directives be careful not to
* remove or change the position of '%s' nor anything outside quotes.
*/
#define L100(s,a,b,c,d,e,f) S("NOTICE %s :I can be triggered by various \
forms of speech, all which must be addressed to me, in one of the \
following formats: %s %s %s or even %s .... In my database, you can \
find a topic by saying my nick, <topic> . eg; \37%s nuke\37 ..... \
to do a search on a word, or partial text, just type: <mynick>, search \
<text> ... eg; \37%s search nuke\37\n",s,a,b,c,d,e,f)
#define L101(a,b,c,d) S("NOTICE %s :I can also be triggered with even more \
human formats: \37%s who is bill gates?\37 .. You can also phrase it \
in a question: \37%s where is msie?\37 ...For more info \
about me, visit http://darkbot.sourceforge.net\n",a,b,c,d)
#define L102(a,b,c,d) S("NOTICE %s :Welcome to %s, %s. Before \
asking your question, type %cHELP for a list of help topics.\n", a,b,c,d)
/* *******************************---******************************* */
/* --------------- Don't change anything else below! --------------- */
/* ***************************************************************** */
//#include <sys/cdefs.h>
//#include <sys/param.h>
//#include <pwd.h>
/* Here we sort out what to do based on some autoconf detected things. */
#if defined _WIN32 || defined __CYGWIN__ || defined __CYGWIN32__ || defined __MINGW32__
# ifndef WIN32
# define WIN32
# endif
#endif
#define _GNU_SOURCE 1
#if HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#if HAVE_ERRNO_H
# include <errno.h>
#endif
#ifndef errno
extern int errno;
#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <assert.h>
#if HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef WIN32
# include <windows.h>
#endif
#include <signal.h>
#include <sys/stat.h>
#include <stdio.h> /* The only one we can guarantee. */
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif
#if STDC_HEADERS
# include <string.h>
# include <stdarg.h>
# include <stdlib.h>
#else
# if !HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr ();
# if !HAVE_MEMMOVE
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#if HAVE_UNISTD_H
#include <sys/types.h>
#include <unistd.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
/* MacOS X is happier with this one AFTER timeval is declared. */
#include <sys/resource.h>
#include "stat-macros.h"
#include "minmax.h"
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# define EXIT_FAILURE 1
#endif
#if !LSTAT_FOLLOWS_SLASHED_SYMLINK
extern int rpl_lstat (const char *name, struct stat *buf);
# undef lstat
# define lstat rpl_lstat
#endif
#if !HAVE_MEMSET
# define memset rpl_memset
#endif
#if !HAVE_NANOSLEEP
# define nanosleep rpl_nanosleep
#endif
#if !HAVE_SNPRINTF
# define snprintf rpl_snprintf
#endif
#if !HAVE_STRCASECMP
# define strcasecmp rpl_strcasecmp
#endif
#if !HAVE_STRCASESTR
# define strcasestr rpl_strcasestr
#endif
#if !HAVE_STRNDUP
extern char *rpl_strndup (const char *dupMe, size_t maxBytes);
# undef strndup
# define strndup rpl_strndup
#endif
#if !HAVE_STRSPN
# define strspn rpl_strspn
#endif
#if !HAVE_STRSTR
# define strstr rpl_strstr
#endif
#if !HAVE_VPRINTF
# define vsprintf rpl_vsprintf
# define vfprintf rpl_vfprintf
#endif
#if !HAVE_LIBCRYPT
# if !HAVE_CRYPT
# define crypt rpl_crypt
# endif
#endif
/* -------------------------------------------------- */
#define FR 3 /* these two are the # of lines per secs */
#define FT 3
#define AIL 1
#define WSEC 10
#define USEC 0
#define RECHECK 45
#define DEFAULT_DBTIMERS_PATH "timers"
#define DEFAULT_LOG_DIR "logs/"
#define DEFAULT_RDB_DIR "rdb"
#ifdef ENABLE_STATS
#define DEFAULT_STATS_FILE "stats.db"
#endif
#define DEFAULT_SEEN_FILE "seen.db"
#define DEFAULT_URL2 "info2.db"
#define DUNNO_FILE "dunno"
#define WHUT_FILE "whut"
#define DEFAULT_BACKUP_DUP "backup_dups.db"
#define DEFAULT_ADD_DELETES "logs/add_delete.log"
#define TMP_URL ".info.tmp"
#define TMP_FILE ".file.tmp"
#define DEFAULT_AUTOTOPIC_F "autotopic.ini"
#define DEFAULT_HELPER_LIST "userlist.db"
#define DEFAULT_QUIZ_FILE "quiz.db"
#define DEFAULT_PERFORM "perform.ini"
#define DEFAULT_DEOP "deop.ini"
#define DEFAULT_RAND_SAY "random.ini"
#define DEFAULT_RAND_FILE "randomstuff.ini"
#define DEFAULT_RANDQ_TEMPFILE "randq.tmp"
#define DEFAULT_RAND_BACKUP_FILE "randomstuff.bak"
#define DEFAULT_SERVERS "servers.ini"
#define DEFAULT_PERMBAN "permbans.db"
#define DEFAULT_SETUP "setup.ini"
#define MAX_SEARCH_LENGTH 350
#define ERR_SOCK_OPT -1
#define ERR_TIMED_OUT -1
#define ERR_CANT_MALLOC -1
#define ERR_OPEN_SOCKET -2
#define ERR_CONN_REFUSED -2
#define ERR_NOT_ADDR -3
#define ERR_WRITE_SOCKET -3
#define ERR_NO_REACH -4
#define ERR_CANT_CONNECT -5
#define ERR_READ_SOCKET -5
#define ERR_SERVER_BUSY -6
#define ERR_NO_DOCUMENTS -6
#define ERR_NO_DATA -7
#define SUCCESS 0
#define LEGAL_TEXT "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
#define SAFE_LIST "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define LEGAL_NICK_TEXT "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-\\|[]{}`"
#define NUMBER_LIST "1234567890"
#define MAX_NICK_LENGTH 35
#ifndef LANG /* If not defined, default to english */
#define LANG 1
#endif
#define NORMALR 0
#define WHUTR 1
#define DUNNOR 2
#define RAND_NORMAL 0
#define RAND_ACTION 1
#define RAND_RAW 2
#define RANDQ_NORMAL 0
#define RANDQ_CASE 1
#define RANDQ_RAND 2
#define RDB_NORMAL 0
#define RDB_ACTION 1
#define RDB_RAW 2
/* ////////////////////////////////////////////////////////////////////// */
#define RESERVED1 "EXPLAIN"
#define RESERVED2 "DECLARE"
#include "langs/lang.h"
diff --git a/source/general.c b/source/general.c
index 4ccaa28..4f97abf 100644
--- a/source/general.c
+++ b/source/general.c
@@ -1,596 +1,607 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#if !HAVE_NANOSLEEP
# include "timespec.h"
#endif
/**
* Removed trailing newline and carriage returns.
* 6/22/00 Dan
* Rewrote to be more efficient, reduced from O(2n) to O(n)
*/
void
stripline (char *ptr)
{
for (; ptr && *ptr; ++ptr)
{
if ('\r' == *ptr || '\n' == *ptr)
{
*ptr = 0;
return;
}
}
}
void
db_log (const char *filename, const char *format,...)
{
va_list arglist;
FILE *fp;
fp = fopen (filename, "a");
if (NULL == fp)
{
/* I guess there's no sense in trying to log the error :) */
return;
}
va_start (arglist, format);
vfprintf (fp, format, arglist);
va_end (arglist);
fclose (fp);
}
/**
* Convert a character array to all lowercase.
* 6/23/00 Dan:
* - Rewrote to be more compact and a bit more efficient
*/
char *
strlwr (char *buf)
{
char *ptr = buf;
for (; ptr && *ptr; ++ptr)
{
*ptr = tolower (*ptr);
}
return buf;
}
/**
* Convert a character array to all uppercase.
* 6/23/00 Dan:
* - Rewrote to be more compact and a bit more efficient
*/
char *
strupr (char *buf)
{
char *ptr = buf;
for (; ptr && *ptr; ++ptr)
{
*ptr = toupper (*ptr);
}
return buf;
}
/*
* Added cast to str[i -1] to prevent warnings on Solaris.
* -ron
*/
void
trailing_blanks (char *str)
{
int i = 0;
if (str == NULL)
return;
for (i = strlen (str); i > 0; i--)
{
if (isspace ( (int) str[i - 1]))
str[i - 1] = '\0';
else
return;
}
}
void
save_changes (void)
{
long i = 0;
struct helperlist *c;
#ifdef ENABLE_STATS
struct statslist *d;
d = statshead;
#endif
c = helperhead;
remove (TMP_FILE);
while (c != NULL)
{
i++;
db_log (TMP_FILE, "%s %s %d %d %s %s\n",
c->chan, c->uh, (int) c->level, (int) c->num_join, c->pass, c->greetz);
c = c->next;
}
rename (TMP_FILE, HELPER_LIST);
#ifdef ENABLE_STATS
while (d != NULL)
{
i++;
db_log (TMP_FILE, "%s %s %ld %ld %ld\n",
d->nick, d->uh, d->total, d->added_time, d->last_time);
d = d->next;
}
rename (TMP_FILE, STATS_FILE);
#endif
}
char *
date (void)
{
time_t timer;
time (&timer);
strncpy (strbuff, ctime (&timer), sizeof (strbuff));
stripline (strbuff);
return strbuff;
}
int
match_wild (const char *pattern, const char *str)
{
char c = 0;
const char *s = NULL;
for (;;)
{
switch (c = *pattern++)
{
case 0:
if (!*str)
return 1;
return 0;
case '?':
++str;
break;
case '*':
if (!*pattern)
return 1;
s = str;
while (*s)
{
if (*s == *pattern && match_wild (pattern, s))
return 1;
++s;
}
break;
default:
if (*str++ != c)
return 0;
break;
} /* switch */
}
}
char **
tokenize (char *theString, size_t * numTokens)
{
static char *tokens[STRING_SHORT] = { 0 };
assert (numTokens != NULL && theString != NULL);
memset (tokens, 0, STRING_SHORT * sizeof (char *));
tokens[(*numTokens = 0)] = strtok (theString, " ");
if (NULL == tokens[0])
{
/* 0 tokens */
return tokens;
}
while ((tokens[++(*numTokens)] = strtok (NULL, " ")) != NULL)
{
/* NO-OP */ ;
}
tokens[*numTokens] = 0;
return tokens;
}
void
get_s (void)
{
char temp[50] = { 0 };
long i = 0;
i = strlen (rp391);
while (i > 0)
{
i--;
snprintf (temp, sizeof (temp), "%s%c", dbVersion, rp391[i]);
strncpy (dbVersion, temp, sizeof (dbVersion));
}
}
const char *
run_program (const char *input)
{
FILE *read_fp;
read_fp = popen (input, "r");
if (read_fp != NULL)
{
int length = 0;
while ( fgets(f_tmp + length, sizeof(f_tmp - length), read_fp) )
{
length = strlen(f_tmp);
while ((f_tmp[length - 1] == '\n') || (f_tmp[length - 1] == '\r'))
{
f_tmp[length - 1] = '\0';
length--;
}
}
pclose (read_fp);
if (f_tmp)
{
return f_tmp;
}
return "No match";
}
return NULL;
}
/**
* 6/22/00 Dan
* - Removed srand(), should only be done once, in main()
* - Changed while to for loop
*/
char *
get_rand_nick (const char *chan)
{
size_t x = 0;
size_t i = 0;
const struct userlist *c = userhead;
/* Iterate through the userlist */
for (; c != NULL; c = c->next)
{
/* Check if this user is on the channel */
if (strcasecmp (chan, c->chan) == 0)
{
if (strcasecmp (Mynick, c->nick) != 0)
{
strncpy (f_tmp, c->nick, sizeof (f_tmp));
i++;
}
}
}
x = 2 + get_random_integer(i);
i = 0; /* reinit! */
for (c = userhead; c != NULL; c = c->next)
{
if (strcasecmp (chan, c->chan) == 0)
{
i++;
if (i == x)
{
if (*c->nick == '0')
{
return f_tmp;
}
if (strcasecmp (Mynick, c->nick) != 0)
{
strncpy (f_tmp, c->nick, sizeof (f_tmp));
return f_tmp;
}
}
}
}
return f_tmp;
}
void
check_dbtimers (void)
{
DIR *dp;
long i = 0;
char filename[STRING_SHORT] = { 0 };
struct dirent *entry;
struct stat statbuf;
FILE *fp;
char b[STRING_LONG] = { 0 }, output[STRING_LONG] =
{
0};
if ((dp = opendir (DBTIMERS_PATH)) == NULL)
{
return;
}
while ((entry = readdir (dp)) != NULL)
{
stat (entry->d_name, &statbuf);
if (S_ISDIR (statbuf.st_mode) && *entry->d_name == '.')
{
continue; /* it's a dir, ignore it */
}
if (S_ISDIR (statbuf.st_mode) && strcasecmp(entry->d_name, "CVS") == 0)
{
/* Ignore the CVS directory */
continue;
}
i = time (NULL);
if (i >= atoi (entry->d_name))
{
snprintf (filename, sizeof (filename), "%s/%s", DBTIMERS_PATH, entry->d_name);
if ((fp = fopen (filename, "r")) == NULL)
{
return;
}
while (fgets (b, STRING_LONG, fp))
{
stripline (b);
snprintf (output, sizeof (output), "%s\n", b);
S (output);
}
fclose (fp);
remove (filename);
}
}
// FIXME: if CLOSEDIR_VOID is not defined, check the return value.
closedir (dp);
}
int
add_ignore_user_ram (char *nick)
{
struct ignorelist *n, *c;
c = ignorehead;
while (c)
{
if (strcasecmp (c->nick, nick) == 0)
{
return 1;
}
c = c->next;
}
if ( ( n = malloc (sizeof (struct ignorelist))) == NULL )
{
db_log ("error.log", "AHHH! No ram left! in add_ignore_user!\n");
return 0;
}
memset (n, 0, sizeof (struct ignorelist));
if (n != NULL)
{
strncpy (n->nick, nick, sizeof (n->nick));
n->next = ignorehead;
ignorehead = n;
}
return 1;
}
int
check_ignore_user_ram (char *nick)
{
struct ignorelist *c;
c = ignorehead;
while (c)
{
if (strcasecmp (c->nick, nick) == 0)
{
return 1;
}
c = c->next;
}
return 0;
}
int
delete_ignore_user_ram (char *nick)
{
struct ignorelist *pNode, *pPrev;
pNode = ignorehead;
pPrev = NULL;
while (pNode)
{
if (strcasecmp (pNode->nick, nick) == 0)
{
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
ignorehead = pNode->next;
free (pNode);
pNode = NULL;
return 1;
}
pPrev = pNode;
pNode = pNode->next;
}
return 0;
}
/* Count lines in a given filename. */
size_t count_lines (char *filename)
{
FILE *fp = NULL;
size_t lines = 0;
char b [STRING_LONG] = {0};
if((fp = fopen(filename, "r")) == NULL)
{
db_log("error.log", "Failed to open %s in count_lines()",
filename);
return (-1);
}
while(fgets(b, STRING_LONG, fp))
{
/* Ignore comments! */
if((*b != '/') && (*b != '\n'))
lines++;
if(*b == '\n')
continue;
}
/* Close the file. */
fclose(fp);
return(lines);
}
/* Self explanatory. */
void reverse (char *pString)
{
size_t nLength = strlen(pString);
char *endptr = pString + nLength - 1;
for(;pString < endptr; ++pString, --endptr)
{
char c = *pString;
*pString = *endptr;
*endptr = c;
}
}
/* Count how many times the character nChar exists in szStuff
* return that number.
*/
size_t count_char (const char *pStuff, const char nChar)
{
char szStuff [STRING_LONG] = {0};
int nIndex = 0;
int nCount = 0;
strcpy(szStuff, pStuff);
for(nIndex = 0; nIndex <= (size_t) strlen(szStuff); nIndex++)
{
if(szStuff[nIndex] == nChar)
nCount++;
}
return(nCount);
}
/* I wrote this for my matrix-RAD.net project, this is translated from the Java.
*
* Try to turn all sorts of string things into a boolean. Only the first character is considered.
*/
// true 1 yes ack ok one positive absolutely affirmative 'ah ha' 'shit yeah' 'why not'
static const char *IS_TRUE = "t1aopswy";
// false 0 no nack nope zero negative nah 'no way' 'get real' 'uh uh' 'fuck off' 'bugger off'
static const char *IS_FALSE = "f0bgnuz";
bool isBoolean(char *aBoolean)
{
bool result = false;
if ((aBoolean != NULL) && (aBoolean[0] != '\0'))
{
char test = aBoolean[0];
result = (strchr(IS_TRUE, tolower(test)) != NULL);
}
return result;
}
void db_sleep(unsigned long seconds)
{
struct timespec req, rem;
memset(&req, 0, sizeof(struct timespec));
req.tv_sec = seconds;
nanosleep(&req, &rem);
}
/* plural(): This function returns "s", or "" (empty string),
* depending on the plurality of the number specified by 'i'.
* Used for beautification purposes in output that involves
* showing a numeric count of objects.
*/
char *plural (size_t i)
{
/* We only need to return "" if 'i' is equal to 1 or -1. */
if (i == 1 || i == -1)
return ("");
/* Everything else is considered plural. */
return ("s");
}
/* db_argstostr(): This function takes char **args and fills the buffer
* pointed to by 'str' with a 'delim' delimited string of each element
* in the argument buffer. A pointer to 'str' is returned for value
* checking.
*/
int db_argstostr(char *str, char **args, size_t startarg, char delim)
{
int i = 0, j = 0, tc = 0;
/* Bail out if no args. */
if ((NULL == args) || (NULL == args[0]))
return (0);
/* Iterate words. */
for (i = startarg; args[i]; i++)
{
/* Go through the letters and fill str buffer. */
for (j = 0; args[i][j]; j++)
{
str[tc++] = args[i][j];
if (args[i+1] && !(args[i][j+1]))
str[tc++] = delim;
}
}
str[tc] = '\0';
return (tc);
}
diff --git a/source/helpers.c b/source/helpers.c
index 1cd5d18..c5d82a6 100644
--- a/source/helpers.c
+++ b/source/helpers.c
@@ -1,474 +1,485 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Add a channel helper.
* 6/22/00 Dan
* n now initialized where declared
* All pointer arguments now received as pointer to const data.
*/
void
add_helper (const char *chan,
const char *uh, long level, size_t num_join, const char *greetz, const char *pass, char mode)
{
struct helperlist *n = 0;
char *ptr = NULL;
#ifdef ENABLE_ENCRYPT
const char *salt = "8fei3k";
if ( mode == 0 )
{
if ((ptr = crypt (pass, salt)) == NULL) /* encrypt password */
return;
}
else
ptr = (char *)pass;
#else
ptr = (char *)pass;
#endif
n = malloc (sizeof (struct helperlist));
if (n == NULL)
{
db_log ("error.log", "AHHH! No ram left! in add_helper!\n");
return;
}
memset (n, 0, sizeof (struct helperlist));
NUM_HELPER++;
if (chan[0] == '#')
{
strncpy (n->chan, chan, sizeof (n->chan));
}
else
{
strncpy (n->chan, "#*", sizeof (n->chan));
}
strncpy (n->uh, uh, sizeof (n->uh));
strlwr (n->uh);
strncpy (n->pass, ptr, sizeof (n->pass));
n->num_join = num_join;
n->level = level;
strncpy (n->greetz, greetz, MIN(sizeof(n->greetz) - 1, strlen(greetz)));
n->next = helperhead;
helperhead = n;
}
/**
* Output the helper list to a nickname.
* 6/22, Dan:
* - Changed helperlist* c to be a pointer to const data
* - Changed initialization of DATA, and size to be a
* power of 2
* - Added initialization of c
* - Changed while loop to for loop
* - Changed types of i, x to size_t since they should be
* unsigned.
* - Added reinitialization of DATA using memset() (changed from
* strcpy(DATA,""))
*/
struct chanserv_output *show_helper_list(struct chanserv_output *output, const char *nick, long level)
{
char DATA [STRING_SHORT * 7] = { 0 };
char tmp [STRING_SHORT] = { 0 };
size_t i = 0, x = 0;
const struct helperlist *c = NULL;
for (c = helperhead; c != NULL; c = c->next)
{
// If we're displaying users at all levels...
if ((level == 0) || (level == c->level))
{
i++; x++;
snprintf (tmp, sizeof(tmp) - 1, "%s[%s:%ld:%d] ",
c->uh, c->chan, (long int) c->level, (int) c->num_join);
strncat(DATA, tmp, sizeof(DATA) - 1);
if (i > 6)
{
i = 0;
output = chanserv_asprintf(output, DATA);
DATA[0] = 0;
db_sleep(2);
}
}
} /* for() */
if (x != 0)
output = chanserv_asprintf(output, DATA);
output = chanserv_asprintf(output, "End of Helper Userlist; %d user%s found.", x, (x == 1) ? "" : "s");
return output;
}
void
load_helpers (void)
{
FILE *fp;
char b[STRING_LONG], *user_host, *greetz, *numb_join, *chan, *w_level, *pass;
long num_join = 0, i = 0, level = 0;
if ((fp = fopen (HELPER_LIST, "r")) == NULL)
{
printf ("Unable to open %s! Aborting connection.\n", HELPER_LIST);
printf ("Please run ./configure to setup your darkbot.\n");
exit (0);
}
printf ("Loading %s file ", HELPER_LIST);
while (fgets (b, STRING_LONG, fp))
{
if (b == NULL)
continue;
stripline (b);
if (*b == '/')
continue;
i++;
printf (".");
fflush (stdout);
chan = strtok (b, " ");
if (chan == NULL)
continue;
user_host = strtok (NULL, " ");
if (user_host == NULL)
continue;
w_level = strtok (NULL, " ");
if (w_level == NULL)
continue;
numb_join = strtok (NULL, " ");
if (numb_join == NULL)
continue;
pass = strtok (NULL, " ");
if (pass == NULL)
{
pass = "0"; /* duh */
}
greetz = strtok (NULL, "");
if (greetz == NULL)
greetz = "I haven't used \2SETINFO\2 yet!";
if (w_level != NULL)
level = atoi (w_level);
else
level = 1;
if (numb_join != NULL)
num_join = atoi (numb_join);
else
num_join = 0;
if (strlen (pass) > 25)
pass[25] = '\0';
if (DebuG == 1)
printf
("loading helperlist: %s %s l:%d j:%d %s\n",
chan, user_host, (int) level, (int) num_join, greetz);
add_helper (chan, user_host, level, num_join, greetz, pass, 1);
}
printf ("done(%d), ", (int) i);
fclose (fp);
save_changes ();
if (DebuG == 1)
db_sleep (2);
}
void
set_pass (char *nick, char *uh, char *pass, char *newpass)
{
struct helperlist *c;
char *ptr = NULL;
#ifdef ENABLE_ENCRYPT
char *salt = "8fei3k";
#endif
c = helperhead;
strlwr (uh);
#ifdef ENABLE_ENCRYPT
if ((ptr = crypt (pass, salt)) == NULL) /* encrypt old password */
return;
#else
ptr = (char *)pass;
#endif
while (c)
{
if (!match_wild (c->uh, uh) == 0)
{
if (strcmp (c->pass, ptr) == 0 || strcmp (c->pass, "0") == 0)
{
#ifdef ENABLE_ENCRYPT
if ((ptr = crypt (newpass, salt)) == NULL) /* encrypt new password */
return;
#else
ptr = (char *)newpass;
#endif
strncpy (c->pass, ptr, sizeof (c->pass));
L012 (nick, uh);
save_changes ();
return;
}
else
{
L013 (nick);
return;
}
}
c = c->next;
}
L014 (nick);
}
long
verify_pass (char *nick, char *chan, char *uh, char *pass)
{
struct helperlist *c;
char *ptr = NULL;
#ifdef ENABLE_ENCRYPT
char *salt = "8fei3k";
#endif
c = helperhead;
strlwr (uh);
#ifdef ENABLE_ENCRYPT
if ((ptr = crypt (pass, salt)) == NULL)
return 0;
#else
ptr = (char *)pass;
#endif
while (c)
{
if (!match_wild (c->uh, uh) == 0)
{
if (*c->pass == '0')
return 0; /* no pass set */
if (strcmp (c->pass, ptr) == 0)
{
if (c->chan[0] == '#' && c->chan[1] == '*')
return c->level;
if (*chan == '*')
return c->level;
if (strcasecmp (c->chan, chan) == 0)
return c->level;
return 0; /* don't match chan access */
}
}
c = c->next;
}
return 0;
}
long
get_pass (char *data)
{
/* returns 0 for no data */
/* returns 1 for just pass */
/* returns 2 for pass and data */
char b[STRING_SHORT] = { 0 }, b2[STRING_SHORT] =
{
0}
, *temp = NULL;
long i = 0;
strncpy (pass_data, "0", sizeof (pass_data)); /* init */
strncpy (pass_pass, "0", sizeof (pass_pass));
if (data == NULL)
return 0;
strncpy (b2, data, sizeof (b2));
temp = strtok (data, " ");
if (temp == NULL)
return -1;
strncpy (b, temp, sizeof (b));
while (temp != NULL)
{
i++;
strncpy (pass_pass, temp, sizeof (pass_pass));
temp = strtok (NULL, " ");
if (temp == NULL)
break;
snprintf (b, sizeof (b), "%s %s", b, temp);
}
strncpy (b, "", sizeof (b)); /* reinit */
temp = strtok (b2, " ");
strncpy (b, temp, sizeof (b));
while (i > 2)
{
i--;
temp = strtok (NULL, " ");
snprintf (b, sizeof (b), "%s %s", b, temp);
}
if (strcasecmp (b, pass_pass) == 0)
{
strncpy (pass_data, "0", sizeof (pass_data));
return 1;
}
strncpy (pass_data, b, sizeof (pass_data));
return 2;
}
void
do_login (char *nick, char *pass)
{
long i = 0, x = 0, D = 0;
char Data[STRING_SHORT] = { 0 }, b[STRING_SHORT] =
{
0};
struct userlist *c;
c = userhead;
while (c)
{
if (strcasecmp (nick, c->nick) == 0)
{
x = verify_pass (c->nick, c->chan, c->uh, pass);
if (x > 0)
{
i++;
if (c->level == 0 && x >= 2)
{
#ifdef ENABLE_CHANNEL
if (OP_USERS_ON_LOGIN)
{
/* only if not already authed */
S ("MODE %s +ov %s %s\n", c->chan, c->nick, c->nick);
}
#endif
D = 1;
}
c->level = x;
snprintf (b, sizeof (b), "%s[%d] %s", c->chan, (int) c->level, Data);
strncpy (Data, b, sizeof (Data));
}
}
c = c->next;
}
if (i != 0)
{
if (!D)
{
S ("NOTICE %s :Already authed on %s\n", nick, Data);
}
else
S ("NOTICE %s :Verified: %s\n", nick, Data);
}
}
int
check_access (char *uh, char *chan, int toggle, char *nick)
{
long i = 0, length = 0, A = 0, X = 0, Y = 0;
struct helperlist *c;
struct userlist *c2;
char temp[STRING_LONG] = { 0 };
c = helperhead;
c2 = userhead;
strlwr (uh);
if (toggle == 0)
{ /* get access level */
while (c2)
{
if (strcasecmp (c2->uh, uh) == 0)
{
if (((strcasecmp (c2->chan, chan) == 0) || (strcasecmp ("#*", chan) == 0))) /* privmsg */
{
if (strcasecmp (c2->nick, nick) == 0)
{
return c2->level;
}
}
}
c2 = c2->next;
}
return 0; /* no matches? */
}
else
while (c != NULL)
{
if (!match_wild (c->uh, uh) == 0)
{
if (*c->pass == '0')
{
L001 (nick, Mynick);
return 0;
}
if (c->chan[1] != '*')
if (strcasecmp (c->chan, chan) != 0)
return 0;
c->num_join++;
if (*c->greetz == '+')
A = 1;
strncpy (data, "", sizeof (data));
length = Y = strlen (c->greetz);
if (length > 1)
{
while (length > 0)
{
length--;
X++;
if (c->greetz[length] == '^')
{
i++;
snprintf (temp, sizeof (temp), "%s%s", nick, data);
}
else if (c->greetz[length] == '%')
{
i++;
snprintf (temp, sizeof (temp), "%u%s",(unsigned int) c->num_join, data);
}
else if (c->greetz[length] == '$')
{
i++;
snprintf (temp, sizeof (temp), "%s%s", uh, data);
}
else if (c->greetz[length] == '&')
{
i++;
snprintf (temp, sizeof (temp), "%s%s", chan, data);
}
else
snprintf (temp, sizeof (temp), "%c%s", c->greetz[length], data);
if (X == Y && A == 1)
continue;
strncpy (data, temp, sizeof (data));
} /* While */
if (JOIN_GREET)
{
if (i == 0)
{
if (setinfo_lastcomm (uh) == 0)
{
S ("PRIVMSG %s :%ld\2!\2\37(\37%s\37)\37\2:\2 %s\n",
chan, c->num_join, nick, c->greetz);
}
}
else if (A == 1)
{
if (setinfo_lastcomm (uh) == 0)
{
S ("PRIVMSG %s :\1ACTION %s\1\n", chan, data);
}
}
else
{
if (setinfo_lastcomm (uh) == 0)
{
S ("PRIVMSG %s :%s\n", chan, data);
}
}
}
return c->level;
}
}
c = c->next;
}
return 0;
}
diff --git a/source/langs/arabic.h b/source/langs/arabic.h
index 60a1e4c..67077b5 100644
--- a/source/langs/arabic.h
+++ b/source/langs/arabic.h
@@ -1,101 +1,112 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Arabic."
#define L001(a,b) S("PRIVMSG %s :Lam tada3 kalimate Morour, Li wad3i Kalimate Morour: \2/msg %s PASS <kalimate Morour 9adima> <kalimate Morour Jadida>\2 (Bima Anaha hya Al Marra Oula Allati takhtaro fiha kalimate Morour , Ista3mile '0' Sifr Ka kalimate Morour 9adima)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :7odifa Ban Da4im #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Ghayr 9adir 3ala fat7 %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, honaka %d SEEN's fi 9a3idat bayanati.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :3alayka an ta3rifa akthar mini 7awla hada al mawdou3, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Lam ara %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic 3ala %s hia OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s hya l4an OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s 7odetha: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, Anhayte. Honaka l2ana %d min al achya2 al 3achwa2iya.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :kalimte Morour li %s 9ad Jodithate.\n",a,b)
#define L013(a) S("NOTICE %s :kalimate Morour khat2a!\n",a)
#define L014(a) S("NOTICE %s :ghayr mawjood!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :7odifa al Mostakhdim: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: ta9ssim bi Sifr khata2!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: 3amalia ghayr 9anounia!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (idafatoka il tajahol #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :idafatoka ila tajahol #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :7oditha #%d: \37[\37%s\37]\37 Ma3loumate\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d Madda bo7itate.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Wajadto akthar min \37%d\37 min fadlek ij3al ba7thaka akthar di9a\2:\2 \%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :wajadto \37Motatabi9\37 Wa7eda, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :wajadto \37%d\37 Motatabi9, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :wajadto %ld madkhal motachabih. 9ad 7odifou.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Astakhdimo %s. Ladaya %ld mawadee3 fi 9a3idate bayanaty, moshaghal limodaate: %d yawm%, %02d:%02d, honaka %ld as2ila tori7at, %ld mawdoo3 odifa, and %ld mawdoo3 7odifa, Mondo an Wasalte. Wa9te Al 3amalia: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Astakhdimo %s. ladaya %ld mawadee3 fi 9a3idate bayanaty, moshaghal limodaate: %d sa3at%s, %d da9i9a%s, honaka %ld as2ila tori7at, %ld mawdoo3 odifa, and %ld mawdoo3 7odifa, Mondo an Wasalte. wa9t al 3amalia: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Astakhdimo %s. Ladaya %ld mawadee3 fi 9a3idate bayanaty, moshaghal limodaate: %d min%s, %d sec%s, honaka %ld as2ila tori7at, %ld mawdoo3 odifa, and %ld mawdoo3 7odifa, Mondo an Wasalte. wa9t al 3amalia: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: La9ad 7adaftou al mawdou3 #%ld, \2%s\2.\n",a,b,c,d)
#define L029n(a,b,c,d) S("NOTICE %s :%s: La9ad 7adaftou al mawdou3 #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 lam yakoun fii stita3aty woujouda al mawdou3 %s. 3amaliyat al 7adf fashilate.\n",a,b,c)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 lam yakoun fii stita3aty woujouda al mawdou3 %s. 3amaliyat al 7adf fashilate.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :A Tari9a: \2/msg %s PASS <kalimate Morour 9adima> <kalimate Morour Jadida>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (li anani 9olto kadalik!))\n",a)
#define L033(a) S("NOTICE %s :A Tari9a: UP <#chan> <kalimate Morour>\n",a)
#define L034(a) S("NOTICE %s :A Tari9a: OP <#chan> [la9ab] <kalimate Morour>\n",a)
#define L035(a) S("NOTICE %s :A Tari9a: DEOP <#chan> [la9ab] <kalimate Morour>\n",a)
#define L036(a) S("NOTICE %s :7adid la9ab!\n",a)
#define L037(a,b) S("NOTICE %s :Asta3id li /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :O7awil /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Moghadir %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Dokhoul %s\n",a,b)
#define L041(a) S("PRIVMSG %s :7adid la9ab/9anate!\n",a)
#define L042(a) S("NOTICE %s :Adkhil user@host Li takhaloss minh!\n",a)
#define L043(a) S("NOTICE %s :La youjad ayo ban.\n",a)
#define L044(a) S("NOTICE %s :Adkhil user@host Lil 7adf!\n",a)
#define L045(a) S("NOTICE %s :wa ida lam af3al kadalik??\n",a)
#define L046(a) S("PRIVMSG %s :9a3idate al bayanate 9ad do3imate.\n",a)
#define L047(a,b) S("NOTICE %s :A Tari9a: %cAUTOTOPIC <Mawdou3> (Da3 \"0\" Lil 2itfa2)\n",a,b)
#define L048(a) S("NOTICE %s :A Tari9a: SETCHAN <9anate jadida>\n",a)
#define L049(a,b) S("NOTICE %s :9anat Ra2issiya: %s\n",a,b)
#define L050(a) S("NOTICE %s :A Tari9a: SETCHAR <ARRamz al jadid>\n",a)
#define L051(a,b) S("NOTICE %s :Ramz al 9iyada al aana: %c\n",a,b)
#define L052(a) S("NOTICE %s :A Tari9a: SETUSER <howia jadida> (Yatattalab I3adat Atachghil)\n",a)
#define L053(a,b) S("NOTICE %s :al hawia al asslia l'aan: %s\n",a,b)
#define L054(a) S("NOTICE %s :A Tari9a: SETNICK <La9ab Jadid>\n",a)
#define L055(a) S("NOTICE %s :A Tari9a: ADDUSER <#9anate> <*user@*.host> <Daraja> <Kalimate Morour>. ie; ADDUSER #darkbot *bot@*.UPDATE.THIS.PLEASE 3 kalimate Morourih... Ista3mil #* Ida Aradta i3ta2aho Madkhal Fi Jamee3 al 9anawate.\n",a)
#define L056(a) sprintf(temp, "Lam astakhdim \2%cSETINFO\2 Ba3d!",a)
#define L057(a,b,c) S("NOTICE %s :Odifa Al Mostakhdem: %s - level %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :A Tari9a: %c%s <user@host> [Sabab]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Odifa fi al ban Da2im #%d, %s; Sabab: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :A Tari9a: I3adat <Kam min Marra> <Modda> <bayanate-raw>\n",a)
#define L061(a) S("NOTICE %s :Otmima.\n",a)
#define L062(a) S("QUIT :I3ada Tachghil %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, Mada Torido An Todife?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, Mada Torido An Todife?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Idafate Mada, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Ayate ma3loumate yajibe an todafa %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :7assanan, %s :)\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Assif %s, Lakena Daa3ma Li dalika al Mawdou3 9ad Ozile.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Assif %s, Lakena Daa3ma Li dalika al Mawdou3 9ad Ozile.\n",a,b);
#define L065n(a,b) S("NOTICE %s :Idafate Mada, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Ayate ma3loumate yajibe an todafa %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :7assanan, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Astabdile Mada, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Ayate ma3loumate yajibe an astabdile %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s 9ad Joddida.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Honaka %d ban Da2im%s fi Dakira.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d tania marrate 9able al achya2 al 3achwa2iya\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: Fiha %d Ramz.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Honaka 7aalian %d mawdou3%s fi 7alate intidar.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Ra2ayto %d yandam 7ata al ana.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Honaka %s %d khadim%s Fi 9a2imate khoddami. Ana 7alian Fi Al khadim #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, Ramz 9iyadaty howa: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Mada yajib An %O7arrire li, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, Ta7taj lita7did 3onwane!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Ghayre 9adir 3ala Nadar a3la %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Mada torido an Okhbir %s?\n",a,b,c)
#define L083n(a,b,c) S("NOTICE %s :%s: Mada torido an Okhbir %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Okhbir %s 7awla Mada?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Okhbir %s 7awla Mada?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Okhbir Man, %s?\n",a,b)
#define L085n(a,b) S("NOTICE %s :Okhbir Man, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 A tas2ale?\n",a,b)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 A tas2ale?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? A3id siyaghate dalika? (A tari9a %cHELP Lilmossa3ada 7awla Na7we)\n",a,b,c,d,e)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? A3id siyaghate dalika? (A tari9a %cHELP Lilmossa3ada 7awla Na7we)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s Mo7ashashe!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION Yastay9id...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Ata3arad lil'flood. Irssal 9a2imate al intidar (al ma3loumate fi intidar al irssal). %d Band 7odifa.\n",a,b)
diff --git a/source/langs/chinese.h b/source/langs/chinese.h
index ad406f1..e035103 100644
--- a/source/langs/chinese.h
+++ b/source/langs/chinese.h
@@ -1,112 +1,123 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "ÎÒ˵ÖÐÎÄ."
#define L001(a,b) S("PRIVMSG %s : Ä㻹ûÓÐÉèÖÿÚÁî. ÒªÉèÖÿÚÁî,Çë´ò: \2/msg %s PASS \
<¾É¿ÚÁî> <пÚÁî>\2 (Èç¹ûÊǵÚÒ»´ÎÉèÖÿÚÁî,¾É¿ÚÁîÓ¦ÌîΪ 0 )\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Òѳɹ¦É¾³ý½ûÓÃÓû§ #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :ÎÞ·¨´ò¿ª%s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, ÔÚÎÒµÄÊý¾Ý¿âÀïÒ»¹²ÓÐ%dÌõÀúÊ·Óû§¼Ç¼.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :ÄãÒѾ­ÖªµÀµÃ±ÈÎÒ¶àÁË, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, ÎÒûÓмû¹ý%s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :×Ô¶¯Ö÷Ìâ %s ¸Õ²ÅÊǹرյÄ\n",a,b)
#define L008(a,b) S("NOTICE %s :×Ô¶¯Ö÷Ìâ %s ÏÖÔڹرÕ\n",a,b);
#define L009(a,b,c) S("NOTICE %s :×Ô¶¯Ö÷Ìâ@ %s ´ò¿ª: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :×Ô¶¯Ö÷Ìâ@ %s ÒѸüÐÂ: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, ÒÑÍê³É. ÏÖ¹²ÓÐ %d ÌõËæ»úÄÚÈÝ.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :%sµÄ¿ÚÁîÒѸüÐÂ.\n",a,b)
#define L013(a) S("NOTICE %s :¿ÚÁî´íÎó!\n",a)
#define L014(a) S("NOTICE %s :ÎÞÆ¥Åä¼Ç¼!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Óû§ÒÑɾ³ý: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: ±»Áã³ý´íÎó!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: ·Ç·¨²Ù×÷!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Ôö¼Ó×Ô¶¯ºöÂÔÓû§#%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Ôö¼Ó×Ô¶¯ºöÂÔÓû§#%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :ÒѸüР#%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d Ìõ¼Ç¼ÒÑËÑË÷.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :ÒÑ·¢ÏÖ³¬¹ý\37%d\37 ÌõÆ¥Åä¼Ç¼, ÇëÊäÈë¸ü¶àÌõ¼þÒÔËõСËÑË÷·¶Î§\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :ÎÒÕÒµ½ \37Ò»Ìõ\37 ·ûºÏÌõ¼þµÄ¼Ç¼, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :ÎÒÕÒµ½\37%d\37 Ìõ·ûºÏÌõ¼þµÄ¼Ç¼, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :ÕÒµ½%ldÌõÖØ¸´¼Ç¼,ÒÑɾ³ý.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :ÕýÔÚÔËÐÐ %s. ÎÒµÄÊý¾Ý¿âÖÐÓÐ%ldÌõ¼Ç¼, ÒÑÔËÐÐʱ¼ä: \
%d Ìì%s, %02d:%02d, ±»ÌáÎÊ%ld´Î, Ôö¼Ó%ldÌõ¼Ç¼, ɾ³ý%ldÌõ¼Ç¼. \
´¦Àíʱ¼ä: %1.4lf Ãë%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :ÕýÔÚÔËÐÐ %s. ÎÒµÄÊý¾Ý¿âÖÐÓÐ%ldÌõ¼Ç¼, ÒÑÔËÐÐʱ¼ä: \
%d Сʱ%s, %d ·ÖÖÓ%s, ±»ÌáÎÊ%ld´Î, Ôö¼Ó%ldÌõ¼Ç¼, ɾ³ý%ldÌõ¼Ç¼. \
´¦Àíʱ¼ä: %1.4lf Ãë%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :ÕýÔÚÔËÐÐ %s. ÎÒµÄÊý¾Ý¿âÖÐÓÐ%ldÌõ¼Ç¼, ÒÑÔËÐÐʱ¼ä: \
%d ·ÖÖÓ%s, %d Ãë%s, ±»ÌáÎÊ%ld´Î, Ôö¼Ó%ldÌõ¼Ç¼, ɾ³ý%ldÌõ¼Ç¼. \
´¦Àíʱ¼ä: %1.4lf Ãë%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: ÎÒÒÑɾ³ýÁ˼Ǽ#%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 ÕÒ²»µ½¼Ç¼%s. ɾ³ýʧ°Ü.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: ÎÒÒÑɾ³ýÁ˼Ǽ#%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 ÕÒ²»µ½¼Ç¼%s. ɾ³ýʧ°Ü.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Ó÷¨: \2/msg %s PASS <¾É¿ÚÁî> <пÚÁî>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (cause I say so!))\n",a)
#define L033(a) S("NOTICE %s :Ó÷¨: UP <#ƵµÀ> <¿ÚÁî>\n",a)
#define L034(a) S("NOTICE %s :Ó÷¨: OP <#ƵµÀ> [êdzÆ] <¿ÚÁî>\n",a)
#define L035(a) S("NOTICE %s :Ó÷¨: DEOP <#ƵµÀ> [êdzÆ] <¿ÚÁî>\n",a)
#define L036(a) S("NOTICE %s :ÇëÖ¸¶¨Ò»¸öêdzÆ!\n",a)
#define L037(a,b) S("NOTICE %s :ÊÔͼ /êÇ³Æ %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Çë³¢ÊÔÔ /êÇ³Æ %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :À뿪 %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :¼ÓÈë%s\n",a,b)
#define L041(a) S("PRIVMSG %s :ÇëÖ¸¶¨Ò»¸öêdzÆ/ƵµÀ!\n",a)
#define L042(a) S("NOTICE %s :ÊäÈëҪɾ³ýµÄu@h!\n",a)
#define L043(a) S("NOTICE %s :ûÕÒµ½Äã˵µÄ½ûÓÃÓû§.\n",a)
#define L044(a) S("NOTICE %s :ÊäÈëҪɾ³ýµÄu@h!\n",a)
#define L045(a) S("NOTICE %s :²»ÄÇô×öÐв»ÐÐ?\n",a)
#define L046(a) S("PRIVMSG %s :Êý¾Ý¿âÒѾ­±¸·Ý.\n",a)
#define L047(a,b) S("NOTICE %s :Ó÷¨: %cAUTOTOPIC <Ö÷Ìâ> (ÉèÖÃΪ\"0\"±íʾÇå¿ÕÖ÷Ìâ)\n",a,b)
#define L048(a) S("NOTICE %s :Ó÷¨: SETCHAN <ÐÂÆµµÀ>\n",a)
#define L049(a,b) S("NOTICE %s :ȱʡƵµÀ: %s\n",a,b)
#define L050(a) S("NOTICE %s :Ó÷¨: SETCHAR <еÄÃüÁî·û>\n",a)
#define L051(a,b) S("NOTICE %s :ÏÖÔÚµÄÃüÁî·ûÊÇ: %c\n",a,b)
#define L052(a) S("NOTICE %s :Ó÷¨: SETUSER <еÄÓû§ID> (ÐèÒªÖØÐÂÆô¶¯»úÆ÷ÈË)\n",a)
#define L053(a,b) S("NOTICE %s :ÏÖÔÚµÄȱʡÓû§IDÊÇ: %s\n",a,b)
#define L054(a) S("NOTICE %s :Ó÷¨: SETNICK <еÄêdzÆ>\n",a)
#define L055(a) S("NOTICE %s :Ó÷¨: ADDUSER <#ƵµÀ> <*user@*.host> <¼¶±ð> <¿ÚÁî>. ÀýÈç, ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... ʹÓÃ#*½«Ê¹¸ÃÓû§µÄȨÏÞÊÊÓÃÓÚËùÓÐµÄÆµµÀ.\n",a)
#define L056(a) sprintf(temp, "Ä㻹ûÓÐÓÃ\2%cSETINFO\2 ÉèÖû¶Ó­ÐÅÏ¢!",a)
#define L057(a,b,c) S("NOTICE %s :Óû§ÒÑÌí¼Ó: %s - ¼¶±ð%d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Ó÷¨: %c%s <u@h> [ÀíÓÉ]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :¼ÓÈë½ûÓÃÓû§Áбí#%d, %s; ÀíÓÉ: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Ó÷¨: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :ÒÑÍê³É.\n",a)
#define L062(a) S("QUIT :ÖØÐÂÆô¶¯ %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, ÄãÏëÌí¼Óʲô?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, ÄãÏëÌí¼Óʲô?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Ìí¼Óʲô, %s?\n",a,b);
#define L065n(a,b) S("NOTICE %s :Ìí¼Óʲô, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: ÒªÌí¼ÓʲôÐÅÏ¢¸ø%s?\n",a,b,c)
#define L066n(a,b,c) S("NOTICE %s :%s: ÒªÌí¼ÓʲôÐÅÏ¢¸ø%s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Ok, %s :)\n",a,b)
#define L067n(a,b) S("NOTICE %s :Ok, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Ìæ»»Ê²Ã´, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: ÓÃʲôÐÅÏ¢Ìæ»»%s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s Òѱ»¸üÐÂ.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :ÓÐ %s %d ½ûÓÃÓû§¼Ç¼%s ÔØÈëÄÚ´æ.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, »¹ÓÐ%d ÃëÎÒ¾ÍÒªºúÑÔÂÒÓïÁË \n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: ³¤¶ÈΪ%d×Ö½Ú.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, ¶ÓÁÐÖÐÏÖÓÐ %d ¼Ç¼%s.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :µ½ÏÖÔÚÎÒÒѾ­¿´¼û%d¸öÓû§¼ÓÈë.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :ÎҵķþÎñÆ÷ÁбíÖÐÓÐ %s %d ¸ö·þÎñÆ÷%s. ÎÒÏÖÔÚÔÚ\
·þÎñÆ÷ #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, ÎÒµÄÃüÁî·ûÊÇ: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :%sʲô, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, ÄãµÃÖ¸¶¨Ò»¸öµØÖ·!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :ÎÞ·¨²éÕÒ%s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: ÄãÏëÈÃÎÒ¸æËß%sʲô?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, ¸æËß %s ʲô?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :¸æËßË­, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: ÄãÏëÈÃÎÒ¸æËß%sʲô?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, ¸æËß %s ʲô?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :¸æËßË­, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 ÄãÔÚÎÊÂð?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? ÇëÖØÐÂÊäÈëÃüÁî(´ò %cHELP ¿ÉÒÔ¿´µ½Ó÷¨Ìáʾ\
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 ÄãÔÚÎÊÂð?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? ÇëÖØÐÂÊäÈëÃüÁî(´ò %cHELP ¿ÉÒÔ¿´µ½Ó÷¨Ìáʾ\
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s ÒѾ­×íÁË!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION ÐÑÀ´ÁË...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :ÎÒÕýÔÚ±»¹àË®...ÎÒÍÂ.... \
ÒÑɾ³ý%d Ìõ¼Ç¼.\n",a,b)
diff --git a/source/langs/dutch.h b/source/langs/dutch.h
index 3754715..3091e30 100644
--- a/source/langs/dutch.h
+++ b/source/langs/dutch.h
@@ -1,120 +1,131 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Dutch."
#define L001(a,b) S("PRIVMSG %s :U heeft geen wachtwoord gezet, om een wachtwoord te zetten: \
\2/msg %s PASS <oudwachtwoord> <nieuwwachtwoord>\2 (Omdat dit de eerste keer is \
dat U een wachtwoord zet, gebruik dan '0' als uw oude wachtwoord)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Permban #%d verwijderd, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Niet mogelijk %s te openen:(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Er zijn %d SEEN's in mijn database.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Dat zou jij toch beter moeten weten, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Ik heb %s niet gezien%s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic op %s was UIT\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic op %s is nu UIT\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s AAN: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s AANGEPAST: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, gedaan. Er zijn nu %d randomstuffs.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Wachtwoord voor %s is veranderd.\n",a,b)
#define L013(a) S("NOTICE %s :Foutief wachtwoord!\n",a)
#define L014(a) S("NOTICE %s :Geen gelijkenis!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Gebruiker verwijderd: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Deling door nul fout!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Illegale bewerking!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (U wordt genegeerd #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Negeren toegevoegd voor #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :#%d aangepast: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d records doorzocht.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Meer dan \37%d\37 onderwerpen gevonden, verklein uw \
zoekgebied a.u.b.\2:\2 %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Ik heb \37een\37 onderwep gevonden, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Ik heb \37%d\37 onderwerp gevonden, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :%ld onderwerp duplicaten gevonden. Ze zijn verwijderd.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Actief %s. Ik heb %ld onderwerpen in mijn \
database, Uptime: %d dagen%s, %02d:%02d, Er zijn %ld vragen gesteld, %ld onderwerpen \
toegevoegd, en %ld onderwerpen verwijderd. Verwerkingstijd: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Actief %s. Ik heb %ld onderwerpen in mijn \
database, Uptime: %d uur%s, %d min%s, Er zijn %ld vragen gesteld, %ld onderwerpen \
toegevoegd, en %ld onderwerpen verwijderd. Verwerkingstijd: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Actief %s. Ik heb %ld onderwerpen in mijn \
database, Uptime: %d min%s, %d sec%s, Er zijn %ld vragen gesteld, %ld onderwerpen \
toegevoegd, en %ld onderwerpen verwijderd. Verwerkingstijd: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Ik heb onderwerp #%ld verwijderd, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Ik was niet in staat om onderwerp \37%s\37 te \
vinden. Verwijdering gefaald.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Ik heb onderwerp #%ld verwijderd, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Ik was niet in staat om onderwerp \37%s\37 te \
vinden. Verwijdering gefaald.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <oudwachtwoord> <nieuwwachtwoord>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (omdat ik het zeg!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#chan> <wachtwoord>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#chan> [nicks] <wachtwoord>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#chan> [nicks] <wachtwoord>\n",a)
#define L036(a) S("NOTICE %s :Specificeer een nick!\n",a)
#define L037(a,b) S("NOTICE %s :Probeer /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Probeer /nick %s-eikel.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Ik verlaat %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Ik kom binnen in %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Specificeer een nick/kanaal!\n",a)
#define L042(a) S("NOTICE %s :Vul de u@h om te verwijderen!\n",a)
#define L043(a) S("NOTICE %s :Geen ban van bekend.\n",a)
#define L044(a) S("NOTICE %s :Vul de u@h in om te verwijderen!\n",a)
#define L045(a) S("NOTICE %s :Wat vind je ervan als ik dat nou eens niet doe?\n",a)
#define L046(a) S("PRIVMSG %s :Database gebackupt.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <onderwerp> (zet hem op \"0\" om hem uit \
te zetten)\n",a,b)
#define L048(a) S("NOTICE %s :Syntax: SETCHAN <nieuwe kanalen>\n",a)
#define L049(a,b) S("NOTICE %s :Standaard kanaal: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntax: SETCHAR <nieuwe commando karakter>\n",a)
#define L051(a,b) S("NOTICE %s :Het nieuwe commando karakter is nu: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntax: SETUSER <nieuwe gebruikersid> (vereist een herstart)\n",a)
#define L053(a,b) S("NOTICE %s :Standaard gebruikersid is nu: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntax: SETNICK <nieuwenick>\n",a)
#define L055(a) S("NOTICE %s :Syntax: ADDUSER <#chan> <*user@*.host> <niveau> \
<wachtwoord>. ie; ADDUSER #darkbot *jason@*.superlink.net 3 zijnwachtwoord ... gebruik #* \
als je rechten in alle kanalen wilt geven.\n",a)
#define L056(a) sprintf(temp, "Ik heb \2%cSETINFO\2 nog niet gebruikt!",a)
#define L057(a,b,c) S("NOTICE %s :Gebruiker toegevoegd: %s - niveau %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntax: %c%s <u@h> [reden]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Toegevoegd aan permban #%d, %s; reden: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <nummer> <vertaling> <ruwe-data>\n",a)
#define L061(a) S("NOTICE %s :Klaar.\n",a)
#define L062(a) S("QUIT :Aan het herstarten %s ...\n",a)
#define L064(a,b) S("PRIVMSG %s :%s, wat wil je toevoegen?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, wat wil je toevoegen?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Voeg wat informatie toe, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Welke informatie moet worden%s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :OK, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Voeg wat informatie toe, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Welke informatie moet worden%s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :OK, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Vervang wat, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Welke informatie moet vervangen worden%s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s is aangepast.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Er %s %d permban%s in RAM geladen.\n",a,b,c,d)
#define L072(a,b) S("PRIVMSG %s :Ik heb momenteel %d banserv's geladen.\n",a,b)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d seconden tot de volgende randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: het was %d karakters lang.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Er zijn momenteel %d item%s in Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Ik heb %d binnenkomsten gezien tot nu toe.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Er zijn %s %d server%s in mijn server lijst. Ik zit \
momenteel op server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mijn commando karakter is: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Waarom zou ik moeten %sing, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, je moet een adres specificeren!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Was niet in staat om %s op te zoeken.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Wat wil je dat ik vertel %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Vertel %s wat?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Vertel wie, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Wat wil je dat ik vertel %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Vertel %s wat?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Vertel wie, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 je zei?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Vind je het erg om dat te herformuleren? \
(Type %cHELP voor syntax hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 je zei?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Vind je het erg om dat te herformuleren? \
(Type %cHELP voor syntax hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s is stoned!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION wordt wakker...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Ik wordt geflood. Output-rij gedumpt (data dat klaarstond om \
verzonden te worden). %d opdrachten.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Helaas %s, ondersteuning voor dat onderwerp is verwijderd.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Helaas %s, ondersteuning voor dat onderwerp is verwijderd.\n",a,b);
diff --git a/source/langs/ebonics.h b/source/langs/ebonics.h
index 6edc109..2036fc1 100644
--- a/source/langs/ebonics.h
+++ b/source/langs/ebonics.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Iz be speakin' Ebonic"
#define L001(a,b) S("PRIVMSG %s :Yo, you aint be havin no passwerd yet, to be settin one..: \2/msg %s PASS \
<oldpass> <newpass>\2 (since you aint be havin one yet, you bes' be usin '0' as yo' old pass)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Deleted permban: #%d, %s, werd to yo mutha!\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Can't be openin %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, There be %d SEEN's in mah database.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Why you be axin me about dat foo, youd be knowin mo' than anybody about %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, I dunno bout %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic on %s was OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s is now OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, werd! There be %d randomstuffs now.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Passwerd fo %s has been changed.\n",a,b)
#define L013(a) S("NOTICE %s :Dat aint da right passwerd foo!\n",a)
#define L014(a) S("NOTICE %s :Yo I aint be seein what you're lookin fo!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Dat foo: %s [%d:%d] has been tkain care of...\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Man I cant be doin no math by zero's!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Yo i can't be doin dat, itz illegal and I be on probation already!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (talk to da hand cuz da bot aint listenin' #%d: %s IGNORED)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Talk to da hand cuz da bot aint listenin' #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Updated #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37 .. %d entries i jus' be lookin thru.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Found mo than \37%d\37 matches, gimmie sumptin betta to work wit\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Yo, I found \37one\37 match, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Yo, I found \37%d\37 matches, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Dayem, I jus found %ld topic duplicates. They was removed.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Runnin %s. Iz be havin %ld topics in mah database, Uptime: \
%d day%s, %02d:%02d, youz mofo's axed me %ld questions, made me rememba %ld things, and fo'get %ld things. \
This wasted: %1.4lf sec%s of mah time\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Runnin %s. Iz be havin %ld topics in mah database, Uptime: \
%d hour%s, %d min%s, youz mofo's axed me %ld questions, made me rememba %ld things, and fo'get %ld things. \
This wasted: %1.4lf sec%s of mah time\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Runnin %s. Iz be havin %ld topics in mah database, Uptime: \
%d min%s, %d sec%s, youz mofo's axed me %ld questions, made me rememba %ld things, and fo'get %ld things. \
This wasted: %1.4lf sec%s of mah time\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Yo, i deleted topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 I aint be findin' %s, so I cant be delete'n it!\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Yo, i deleted topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 I aint be findin' %s, so I cant be delete'n it!\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Dis be how ya do it: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (DAMN COPS!))\n",a)
#define L033(a) S("NOTICE %s :Dis be how ya do it: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Dis be how ya do it: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Dis be how ya do it: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Yo, you might wanna gimmie a nick to do it to foo!\n",a)
#define L037(a,b) S("NOTICE %s :Gonna try ta /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Yo, /nick %s's-momma.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Takin off from %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Steppin up into %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Might wanna gimie a nick/channel to do dat to foo!\n",a)
#define L042(a) S("NOTICE %s :Might wanna gimmie a u@h to get rid of foo!!\n",a)
#define L043(a) S("NOTICE %s :Aint no such ban.\n",a)
#define L044(a) S("NOTICE %s :Try givin me tha u@h to delete foo!\n",a)
#define L045(a) S("NOTICE %s :Howz bout I bitch smack your punk ass instead?\n",a)
#define L046(a) S("PRIVMSG %s :Yo, I backed up database.\n",a)
#define L047(a,b) S("NOTICE %s :Dis be how ya do it: %cAUTOTOPIC <topic> (set to \"0\" to be turnin it off)\n",a,b)
#define L048(a) S("NOTICE %s :Dis be how ya do it: SETCHAN <new channels>\n",a)
#define L049(a,b) S("NOTICE %s :Default channel: %s\n",a,b)
#define L050(a) S("NOTICE %s :Dis be how ya do it: SETCHAR <new command char>\n",a)
#define L051(a,b) S("NOTICE %s :Tha new command char now iz: %c\n",a,b)
#define L052(a) S("NOTICE %s :Dis be how ya do it: SETUSER <new userid> (requires a restart)\n",a)
#define L053(a,b) S("NOTICE %s :Default userid now: %s\n",a,b)
#define L054(a) S("NOTICE %s :Dis be how ya do it: SETNICK <newnick>\n",a)
#define L055(a) S("NOTICE %s :Dis be how ya do it: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #ghetto \
*icecube@*.compton.net 3 hisPasswd ... use #* if you wants to be givin' access in all chans.\n",a)
#define L056(a) sprintf(temp, "I aint used \2%cSETINFO\2 yet!",a)
#define L057(a,b,c) S("NOTICE %s :Added user: %s - level %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Dis be how ya do it: %c%s <u@h> [reason]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Added in permban #%d, %s; reason: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Dis be how ya do it: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :Done.\n",a)
#define L062(a) S("QUIT :Restarting %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, might wanna tell me wut to add foo!\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, might wanna tell me wut to add foo!\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Add wut, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Might wanna tell me wut info to be addin fo %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Otay, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Add wut, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Might wanna tell me wut info to be addin fo %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Otay, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Replace wut, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Wut info should replace %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s be done gettin updated.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :There be %s %d permban's%s loaded into ram.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d seconds left till Iz be doin sumptin stupid fly!\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: it waz %d chars long, wut da hell does it matta to you anyway, foo.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, There be currently %d item%s in Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :I've seen you mofo's come and go %d times.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :There be %s %d server%s in mah server list, but I be chillin on \
server #%d wit all da homiez right now.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, my command char be: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Yo, wut should i be %sing fo, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, gimmie a address foo!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :I aint bein able to look up %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Yo, wut you want me to be tellin' %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Tell %s about wut?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Tell who, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Yo, wut you want me to be tellin' %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Tell %s about wut?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Tell who, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 you wuz asking?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Mind puttin dat differently? (Type %cHELP for syntax \
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 you wuz asking?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Mind puttin dat differently? (Type %cHELP for syntax \
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s is stoned more than i am!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION wakes up from a drunken haze...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Iz bein flooded. Dumpin output Que. %d items wuz deleted.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Damn nigs %s, we did done took out dat topic.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Damn nigs %s, we did done took out dat topic.\n",a,b);
diff --git a/source/langs/english.h b/source/langs/english.h
index 9aded66..27697ae 100644
--- a/source/langs/english.h
+++ b/source/langs/english.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak English."
#define L001(a,b) S("PRIVMSG %s :You have not set a password, to set a pass: \2/msg %s PASS \
<oldpass> <newpass>\2 (since this is your first time setting a pass, use '0' as your old pass)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Deleted permban #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Unable to open %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, There are %d SEEN's in my database.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :You'd know more about that than I do, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, I have not seen %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic on %s was OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s is now OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, done. There are now %d randomstuffs.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Password for %s has been updated.\n",a,b)
#define L013(a) S("NOTICE %s :Incorrect password!\n",a)
#define L014(a) S("NOTICE %s :No match!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Deleted user: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Division by zero error!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Illegal operation!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (adding ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Adding ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Updated #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d entries searched.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Found more than \37%d\37 matches, please narrow down your search\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :I found \37one\37 match, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :I found \37%d\37 matches, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Found %ld topic duplicates. They were removed.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Running %s. I have %ld topics in my database, Uptime: \
%d day%s, %02d:%02d, There have been %ld questions asked, %ld topic additions, and %ld topic deletions, since I connected. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Running %s. I have %ld topics in my database, Uptime: \
%d hour%s, %d min%s, There have been %ld questions asked, %ld topic additions, and %ld topic deletions, since I connected. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Running %s. I have %ld topics in my database, Uptime: \
%d min%s, %d sec%s, There have been %ld questions asked, %ld topic additions, and %ld topic deletions, since I connected. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: I have deleted topic #%ld, \2%s\2.\n",a,b,c,d)
#define L029n(a,b,c,d) S("NOTICE %s :%s: I have deleted topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 I was unable to find the topic %s. Delete failed.\n",a,b,c)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 I was unable to find the topic %s. Delete failed.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (cause I say so!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Specify a nick!\n",a)
#define L037(a,b) S("NOTICE %s :Attempting to /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Try /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Leaving %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Joining %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Specify a nick/chan!\n",a)
#define L042(a) S("NOTICE %s :Enter the u@h to purge!\n",a)
#define L043(a) S("NOTICE %s :No such ban.\n",a)
#define L044(a) S("NOTICE %s :Enter the u@h to delete!\n",a)
#define L045(a) S("NOTICE %s :How about I not do that?\n",a)
#define L046(a) S("PRIVMSG %s :Backed up database.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <topic> (set to \"0\" to turn off)\n",a,b)
#define L048(a) S("NOTICE %s :Syntax: SETCHAN <new channels>\n",a)
#define L049(a,b) S("NOTICE %s :Default channel: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntax: SETCHAR <new command char>\n",a)
#define L051(a,b) S("NOTICE %s :New command char now: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntax: SETUSER <new userid> (requires a restart)\n",a)
#define L053(a,b) S("NOTICE %s :Default userid now: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntax: SETNICK <newnick>\n",a)
#define L055(a) S("NOTICE %s :Syntax: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... use #* if you want to give access in all chans.\n",a)
#define L056(a) sprintf(temp, "I haven't used \2%cSETINFO\2 yet!",a)
#define L057(a,b,c) S("NOTICE %s :Added user: %s - level %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntax: %c%s <u@h> [reason]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Added in permban #%d, %s; reason: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :Done.\n",a)
#define L062(a) S("QUIT :Restarting %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, what do you want to add?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, what do you want to add?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Add what, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: What info to be added for %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okay, %s :)\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Sorry %s, but support for that topic has been removed.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Sorry %s, but support for that topic has been removed.\n",a,b);
#define L065n(a,b) S("NOTICE %s :Add what, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: What info to be added for %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okay, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Replace what, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: What info should replace %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s has been updated.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :There %s %d permban%s loaded into ram.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d seconds left till randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: it was %d chars long.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, There is currently %d item%s in queue.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :I have seen %d joins thus far.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :There %s %d server%s in my server list. I am currently on \
server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, my command char is: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :What should i be %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, you need to specify an address!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Was unable to look up %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: What do you want me to tell %s?\n",a,b,c)
#define L083n(a,b,c) S("NOTICE %s :%s: What do you want me to tell %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Tell %s about what?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Tell %s about what?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Tell who, %s?\n",a,b)
#define L085n(a,b) S("NOTICE %s :Tell who, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 you were asking?\n",a,b)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 you were asking?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Mind rephrasing that? (Type %cHELP for syntax \
hints)\n",a,b,c,d,e)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Mind rephrasing that? (Type %cHELP (in channel) for syntax \
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s is stoned!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION wakes up...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :I'm being flooded. Dumping output queue. \
%d items deleted.\n",a,b)
diff --git a/source/langs/french.h b/source/langs/french.h
index 2c9b1e0..67cc15c 100644
--- a/source/langs/french.h
+++ b/source/langs/french.h
@@ -1,119 +1,130 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak French."
#define L001(a,b) S("PRIVMSG %s :Vous n'avez pas de mot de passe, pour en choisir un: \
\2/msg %s PASS <Ancien mot de passe> <Nouveau mot de passe>\2 (Puisque c'est la première \
fois que vous choisissez un mot de passe, utilisez '0' comme ancien mot de passe)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Ban permanent éffacé: #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Incapable d'ouvrir %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Il y a %d SEEN dans ma base de données.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Vous devriez en connaitre plus a ce sujet que moi, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Je n'ai pas vu %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic sur %s étais DÉSACTIVÉ\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic sur %s est maintenant DÉSACTIVÉ\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ACTIF: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s MIS À JOUR: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, terminé. Il y a maintenant %d items aléatoires.\n",a,b,c)
#define L012(a,b) S("NOTICE %s : Le mot de passe pour %s a été mis à jour.\n",a,b)
#define L013(a) S("NOTICE %s :Mot de passe incorrect!\n",a)
#define L014(a) S("NOTICE %s :Aucune entrée similaire!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Usager supprimé: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Erreur! Division par zéro!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Opération illégale!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Ajout d'ignore: #%d:%s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Ignore ajoutée #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Mis à jour #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d entrées recherchés.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Trouvé plus que \37%d\37 correspondances, restreignez votre \
recherche...\2:\2 %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Trouvé \37une\37 correspondance, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Trouvé \37%d\37 correspondances, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Trouvé %ld entrées dupliquées. Elles ont été retirées.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utilise %s. J'ai %ld entrées dans ma base de \
données, Actif depuis: %d jours%s, %02d:%02d, Il y a eu %ld questions posées, %ld additions \
d'informations et %ld entrées retirées. Temp de travail: %1.4lf seconde%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utilise %s. J'ai %ld entrées dans ma base de \
données, Actif depuis: %d heure%s, %d minute%s, Il y a eu %ld questions posées, %ld additions \
d'informations, et %ld entrées retirées. Temp de travail: %1.4lf seconde%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utilise %s. J'ai %ld entrées dans ma base de \
données, Actif depuis: %d minute%s, %d seconde%s, Il y a eu %ld questions posées, %ld additions \
d'informations, et %ld entrées retirées. Temp de travail: %1.4lf seconde%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: J'ai effacé l'entrée #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 J'ai été incapable de trouvé le topic \37%s\37. Impossible \
d'éffacer.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: J'ai effacé l'entrée #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 J'ai été incapable de trouvé le topic \37%s\37. Impossible \
d'éffacer.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntaxe: \2/msg %s PASS <ancien mot de passe> <nouveau mot de passe>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (Parce que je l'ai décidé!))\n",a)
#define L033(a) S("NOTICE %s :Syntaxe: UP <#Canal> <Mot de passe>\n",a)
#define L034(a) S("NOTICE %s :Syntaxe: OP <#Canal> [alias] <Mot de passe>\n",a)
#define L035(a) S("NOTICE %s :Syntaxe: DEOP <#Canal> [alias] <Mot de passe>\n",a)
#define L036(a) S("NOTICE %s :Specifiez un alias!\n",a)
#define L037(a,b) S("NOTICE %s :Tentative de /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Essayez /nick %s-Épais.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Je quitte %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :J'entre %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Specifiez un alias ou un canal!\n",a)
#define L042(a) S("NOTICE %s :Entrez le user@host à purger!\n",a)
#define L043(a) S("NOTICE %s :Aucun ban de ce type.\n",a)
#define L044(a) S("NOTICE %s :Entrez le user@host à effacer!\n",a)
#define L045(a) S("NOTICE %s :Et si je ne le ferais pas?\n",a)
#define L046(a) S("PRIVMSG %s :Copie de sauvegarde de la base de donnée completé.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAXE: %cAUTOTOPIC <topic> (mettre à \"0\" pour désactiver)\n",a,b)
#define L048(a) S("NOTICE %s :Syntaxe: SETCHAN <nouveau canal>\n",a)
#define L049(a,b) S("NOTICE %s :Canal par défault: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntaxe: SETCHAR <nouveau caractère de commande>\n",a)
#define L051(a,b) S("NOTICE %s :Le caractère de commande est maintenant: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntaxe: SETUSER <Nouveau ID> (nécessite un redémarage)\n",a)
#define L053(a,b) S("NOTICE %s :ID d'usager par défaut: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntaxe: SETNICK <Nouveau nick>\n",a)
#define L055(a) S("NOTICE %s :Syntaxe: ADDUSER <#Canal> <*user@*.host> <Niveau> <Mot de passe>. \
Exemple; ADDUSER #Darkbot *jason@*.superlink.net 3 SonPass ... Utiliser #* pour donner accès à tout \
les canaux.\n",a)
#define L056(a) sprintf(temp, "Je n'ai pas encore utilisé \2%cSETINFO\2!",a)
#define L057(a,b,c) S("NOTICE %s :Usager ajouté: %s - Niveau %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntaxe: %c%s <user@host> [Raison]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Ban permanent ajouté #%d, %s; Raison:%s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntaxe: REPEAT <Nombre de fois> <Délai> <Information RAW>\n",a)
#define L061(a) S("NOTICE %s :Complété.\n",a)
#define L062(a) S("QUIT :Redémarage de %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, que voulez-vous ajouter?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, que voulez-vous ajouter?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Que devrais-je ajouter, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Quelle information devrait être ajoutée pour %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :D'accord, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Que devrais-je ajouter, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Quelle information devrait être ajoutée pour %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :D'accord, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Remplacer quoi, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Quelle information devrait remplacer %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s a été mis à jour.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Il y a %s %d ban%s permanent en mémoire.\n",a,b,c,d,d)
#define L072(a,b) S("PRIVMSG %s :J'ai présentement %d bans par serveurs en mémoire.\n",a,b)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d secondes restantes avant items aléatoires\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: Il y avait %d caractères de longs.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Il y a présentements %d objets%s en liste d'attente.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :J'ai pu observer %d arrivées jusqu'à maintenant.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Il y a %s %d serveur%s dans ma liste de serveurs. Je suis \
présentement sur le serveur #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mon caractère de commande est: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Que devrais-je %siser pour, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, vous devez spécifier une addresse!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Je ne suis pas parvenu à convertir %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Que voulez-vous que je dise à %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Informer %s de%s?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Dire à qui, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Que voulez-vous que je dise à %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Informer %s de%s?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Dire à qui, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 vous demandiez?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Pourriez-vous reformuler celà? (Tappez %cHELP pour de \
l'aide sur la syntaxe)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 vous demandiez?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Pourriez-vous reformuler celà? (Tappez %cHELP pour de \
l'aide sur la syntaxe)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s est mort!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION se réveille...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Je me fais flooder. Envoie de la liste d'attente (l'information en attente \
d'être envoyée). %d objets.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Désolé %s, mais soutien de cette matière a été enlevé.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Désolé %s, mais soutien de cette matière a été enlevé.\n",a,b);
diff --git a/source/langs/german.h b/source/langs/german.h
index e0cbfb6..6fa2e17 100644
--- a/source/langs/german.h
+++ b/source/langs/german.h
@@ -1,115 +1,126 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Ich spreche deutsch."
#define L001(a,b) S("PRIVMSG %s :Sie haben kein Passwort gesetzt. Um dies nachzuholen: \2/msg %s PASS \
<altpasswort> <neupasswort>\2 (Da dies ihr erstes Passwort sein wird, verwenden sie '0' als altpasswort)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Permanenten Bann geloescht #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Kann %s nicht oeffnen :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Es gibt %d SEEN's in meiner Datenbank.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Darueber wissen Sie mehr als ich, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Ich habe %s nicht gesehen in %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic auf %s wurde abgestellt (OFF)\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic aud %s ist nun abgestellt (OFF)\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s angestellt (ON): %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s aktualisiert (UPDATED): %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, erledigt. Es gibt nun %d Sprueche.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Passwort fuer %s wurde aktualisiert.\n",a,b)
#define L013(a) S("NOTICE %s :Falsches Passwort!\n",a)
#define L014(a) S("NOTICE %s :kein Treffer!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Nutzer geloescht: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Teilen durch 0 aus politischen Gruenden derzeit nicht moeglich!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Unzulaessige Aktion!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Fuege ignoriere #%d: %s hinzu)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Ignore ab sofort #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Aktualisiere #%d: \37[\37%s\37]\37 Info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d Eintraege durchsucht.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Habe mehr als \37%d\37 Treffer gefunden, bitte grenzen sie die Suche ein\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Ich habe \37einen\37 Treffer, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Ich habe \37%d\37 Treffer gefunden, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :%ld Themenduplikate gefunden. Sie wurden geloescht.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Lasse %s laufen. Ich habe %ld Themen in meiner Datenbank, Laufzeit: \
%d Tage%s, %02d:%02d, Es wurden %ld Fragen gestellt, %ld Themen ergaenzt und %ld Themen geloescht. \
Prozess Zeit: %1.4lf sek%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Lasse %s laufen. I habe %ld Themen in meiner Datenbank, Laufzeit: \
%d Stunden%s, %d Minuten%s, Es wurden %ld Fragen gestellt, %ld Themen ergaenzt und %ld Themen geloescht. \
Prozesszeit: %1.4lf Sekunden%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Lasse %s laufen. Ich habe %ld Themen in meiner Datenbank, Laufzeit: \
%d Minuten%s, %d Sekunden%s, Es wurden %ld Fragen gestellt, %ld Themen hinzugefuegt und %ld Themen geloescht. \
Prozesszeit: %1.4lf Sekunden%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Ich habe #%ld Themen geloescht, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Ich kann Themaeintrag %s nicht finden. Loeschen gescheitert.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Ich habe #%ld Themen geloescht, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Ich kann Themaeintrag %s nicht finden. Loeschen gescheitert.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :G\2\2etoetet (%s (weil ich es so sage!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Spezifiziere einen nick!\n",a)
#define L037(a,b) S("NOTICE %s :Versuche /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Versuche /nick %s-dummy.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Verlasse %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Betrete %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Spezifiziere einen nick/chan!\n",a)
#define L042(a) S("NOTICE %s :Geben sie u@h um zu loeschen!\n",a)
#define L043(a) S("NOTICE %s :Keine solche Verbannung vorhanden.\n",a)
#define L044(a) S("NOTICE %s :Geben sie u@h um sie zu loeschen!\n",a)
#define L045(a) S("NOTICE %s :Wie waers wenn ich dass nicht tue?\n",a)
#define L046(a) S("PRIVMSG %s :Datenbank gesichert.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <topic> (setze \"0\" um abzuschalten)\n",a,b)
#define L048(a) S("NOTICE %s :Syntax: SETCHAN <new channels>\n",a)
#define L049(a,b) S("NOTICE %s :Standard Raum: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntax: SETCHAR <new command char>\n",a)
#define L051(a,b) S("NOTICE %s :Neues Kommandozeichen nun: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntax: SETUSER <new userid> (benoetigt einen Neustart)\n",a)
#define L053(a,b) S("NOTICE %s :Standard NutzerID jetzt: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntax: SETNICK <newnick>\n",a)
#define L055(a) S("NOTICE %s :Syntax: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #darkbot \
*user@*.somewhere 3 hisPasswd ... nutzen #* um ihm die komplette Kontrolle ueber alle Raeume zu uebertragen.\n",a)
#define L056(a) sprintf(temp, "Ich habe \2%cSETINFO\2 noch nicht benutzt!",a)
#define L057(a,b,c) S("NOTICE %s :Nutzer hinzugefuegt: %s - Ebene %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntax: %c%s <u@h> [Begruendung]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Ergaenzt in Ausschlussliste #%d, %s; Begruendung: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :Erledigt.\n",a)
#define L062(a) S("QUIT :Starte wieder %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, was moechten sie hinzufuegen?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, was moechten sie hinzufuegen?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Was hinzufuegen, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Welcher Infoblock soll zu %s hinzugefuegt werden?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okay, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Was hinzufuegen, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Welcher Infoblock soll zu %s hinzugefuegt werden?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okay, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Ersetze was, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Welcher Infoblock soll durch %s ersetzt werden?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s wurde aktualisiert.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Es gibt %s %d permanente Ausschluesse%s in den Speicher geladen.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d Sekunden bis zum blafaseln\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: es war %d Zeichen lang.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Es gibt derzeit %d Artikel %s in der Warteschlange.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :%d Benutzer kamen bisher in den Raum.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Es gibt %s %d Server%s in meiner Serverliste. Ich bin derzeit auf \
Server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mein Kommandozeichen lautet: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Was soll fuer %sing verwendet werden, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, geben sie eine Addresse an!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Konnte %s nicht finden.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Was wollen sie mir erzaehlen %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Sagen sie %s ueber was?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Wer, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Was wollen sie mir erzaehlen %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Sagen sie %s ueber was?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Wer, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 fragten sie?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? In Gedanken umbauen? (Tippen sie %cHELP fuer die Syntax \
Hinweise)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 fragten sie?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? In Gedanken umbauen? (Tippen sie %cHELP fuer die Syntax \
Hinweise)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s ist total abgedreht!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION erwacht...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Ich wurde geflutet. Gebe Ausgabeschlange aus. \
%d Eintraege geloescht.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Leider %s, wurde die Unterstützung für dieses thema entfernt.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Leider %s, wurde die Unterstützung für dieses thema entfernt.\n",a,b);
diff --git a/source/langs/greek.h b/source/langs/greek.h
index ccf6ed1..4915360 100644
--- a/source/langs/greek.h
+++ b/source/langs/greek.h
@@ -1,117 +1,128 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Greek."
#define L001(a,b) S("PRIVMSG %s :Den exis vali kodiko, gian na valis grapse: \2/msg %s PASS \
<palioskodikos> <kainourioskodikos>\2 (epidi auti ine i prota sou fora pou vazi kodiko, \
xrisimopia '0' san ton palio sou kodiko)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :To monimo ban exi svisti #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Den mporesa na anixo to %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Eparxoun %d SEEN's stin lista mou.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Den tha xeris perissotera aposa xero ego, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Den ida to nick %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic gia to %s itan apenergepiimeno\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic gia to %s einai to apenergepiimeno\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s Energopieimeno: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, Egine. Iparxoun tora %d randomstuffs.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :O kodikos gia to nick %s exi exixronisti.\n",a,b)
#define L013(a) S("NOTICE %s :Lathos Kodikos!\n",a)
#define L014(a) S("NOTICE %s :Den Vrethike!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Svismeni xristes: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Upodieresi apo to miden eine lanthasmeni!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Paranomi epixirisi!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Prostheto to ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Prostheto to ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Exixronismos gia #%d: \37[\37%s\37]\37 plirofories\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d dedomena anazytithikan.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Vrika perissotore apo \37%d\37 dedomena, parakalo perioriste \
thn anazitisi sas\2:\2 %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Vrika \37one\37 dedomena, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Vrika \37%d\37 dedomena, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Vrika %ld themata. Exoun svisti.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Letourgiko %s. +Ellinika Exo %ld themata stin lista my, Eime energepioimenos gia: \
%d day%s, %02d:%02d, Exoun rotithi %ld erotisis,Exoun prosthethi %ld \
themata, kai exoun aferethi %ld themata. Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Letourgiko %s.+ Ellinika Exo % ld themata stin lista my, Eime energepioimenos gia: \
%d day % s, %02 d: %02 d, Exoun rotithi % ld erotisis, Exoun prosthethi % ld themata, kai exoun aferethi % ld themata.Process time: \
%1.4l f sec %s \n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Letourgiko %s. \
+Ellinika Exo %ld themata stin lista my, Eime energepioimenos gia: %d day%s, %02d:%02d, \
Exoun rotithi %ld erotisis,Exoun prosthethi %ld themata, kai exoun \
aferethi %ld themata. Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Exo svisi to thema #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Den moris na vro to thema \37%s\37. Delete failed.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Exo svisi to thema #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Den moris na vro to thema \37%s\37. Delete failed.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntaxi: \2/msg %s PASS <palioskodikos> <kainourios>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (epidi etsi leo!))\n",a)
#define L033(a) S("NOTICE %s :Syntaxi: UP <#Kanali> <kodikos>\n",a)
#define L034(a) S("NOTICE %s :Syntaxi: OP <#Kanali> [nicks] <kodikos>\n",a)
#define L035(a) S("NOTICE %s :Syntaxi: DEOP <#Kanali> [nicks] <kodikos>\n",a)
#define L036(a) S("NOTICE %s :Kathorise ena nick!\n",a)
#define L037(a,b) S("NOTICE %s :Dokimazo na kano /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Dokimase /nick %s-gios-ths-poutanas.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Fevgo apo to %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Mpeno sto %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Kathorise ena paratsoukli/Kanali!\n",a)
#define L042(a) S("NOTICE %s :Vale to u@h pou tha dioxo\n",a)
#define L043(a) S("NOTICE %s :Den vrika etsi ban.\n",a)
#define L044(a) S("NOTICE %s :Vale to u@h pou thes na svisti!\n",a)
#define L045(a) S("NOTICE %s :Pos sou fenete i idea na min to kano?\n",a)
#define L046(a) S("PRIVMSG %s :Exo filaxi thn lista mou.\n",a)
#define L047(a,b) S("NOTICE %s :Syntaxi: %cAUTOTOPIC <epikefalida> (vale \"0\" gia \
na to apenergopiisis)\n",a,b)
#define L048(a) S("NOTICE %s :Syntaxi: SETCHAN <Nea kanalia>\n",a)
#define L049(a,b) S("NOTICE %s :Proepilegmeno kanali: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntaxi: SETCHAR <Nea anagnorisi gia ths entoles>\n",a)
#define L051(a,b) S("NOTICE %s :I nea anagnorisi einai: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntaxi: SETUSER <Neon userid> (Prepi na xanaxekinisi to bot)\n",a)
#define L053(a,b) S("NOTICE %s :Proepilegmeno userid: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntaxi: SETNICK <neoparatsoukli>\n",a)
#define L055(a) S("NOTICE %s :Syntaxi: ADDUSER <#kanali> <*user@*.host> <dinami> <kodikos>. \
diladi; ADDUSER #darkbot *jason@*.superlink.net 3 tonkodikotou ... xrisimopia #* gia na dosi \
kapion dinami se ola ta kanalia.\n",a)
#define L056(a) sprintf(temp, "Den exo xrisimopioisi to \2%cSETINFO\2 akoma!",a)
#define L057(a,b,c) S("NOTICE %s :Prosthesa ton: %s - me dinami %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntaxi: %c%s <u@h> [dikeologia]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Proshethike sti lista ton monimon ban #%d, %s; logos: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <arithmos> <kathisterisi> <entoli-gia-ton-server>\n",a)
#define L061(a) S("NOTICE %s :Egine.\n",a)
#define L062(a) S("QUIT :Epanarxisi %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, ti thelis na prosthesis?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, ti thelis na prosthesis?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Ti na prostheso, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Ti proforia na protheso gia to %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Egine, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Ti na prostheso, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Ti proforia na protheso gia to %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Egine, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Ti na alaxo, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Ti pliroforia na alaxo %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s exis anavathimisti.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Iparxoun %s %d permban%s stin mnimi mou.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d defteropta exoun mini gia na xekiniso to randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: eixen %d xaraktires.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Epourxou %d pragmata%s sto Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Exo thi di %d na erxontai mexri tora.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Iparxoun %s %d server%s stin lista ton server. Eime ston \
server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, oi ento les arxizou apo: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :What should i be %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, prepi na pis mian diefthisi!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Den mporesa na to vro %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Ti thelis na po %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Na po ston %s giati pragma?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Se pion na po, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Ti thelis na po %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Na po ston %s giati pragma?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Se pion na po, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 ti rotises?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Se piraza na to xanapis? (Grapse %cHELP \
gia thn syntaxi tou)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 ti rotises?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Se piraza na to xanapis? (Grapse %cHELP \
gia thn syntaxi tou)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s eine stoned!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION xipna...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Exo gini flood. %d items.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Signomi %s, ala den iparhi boithia gia afto to thema pia.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Signomi %s, ala den iparhi boithia gia afto to thema pia.\n",a,b);
diff --git a/source/langs/italian.h b/source/langs/italian.h
index a773563..f7ee8c6 100644
--- a/source/langs/italian.h
+++ b/source/langs/italian.h
@@ -1,115 +1,126 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Io parlo italiano."
#define L001(a,b) S("PRIVMSG %s :Non hai ancora una password settata, per farlo: \2/msg %s PASS \
<vecchiapass> <nuovapass>\2 (siccome e' la prima volta che lo fai, usa '0' come vecchia password)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Permban #%d eliminato, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Impossibile aprire %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, ci sono %d SEEN nel mio database.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Credo che tu ne sappia sicuramente piu' di me, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, non ho visto %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic su %s era OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic su %s e' ora OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s AGGIORNATO: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, fatto. Ora ci sono %d randomstuff.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :La password di %s e' stata modificata.\n",a,b)
#define L013(a) S("NOTICE %s :Password errata! Ora chiamo la polizia per intrusioni in sistema informatico \
altrui!\n",a)
#define L014(a) S("NOTICE %s :Nessun riferimento!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Eliminato utente: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Errore di divisione per zero!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Operazione illegale!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (aggiunto l'ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Aggiungo l'ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Aggiornato #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d riferimenti inclusi nella ricerca.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Trovati piu' di \37%d\37 riferimenti, per favore riduci la ricerca\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Ho trovato \37un\37 riferimento, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Ho trovato \37%d\37 riferimenti, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Ho trovato %ld topic duplicati e li ho rimossi.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Sono un %s. Ho %ld topic nel mio database. Uptime: \
%d day%s, %02d:%02d. Ci sono state %ld cose chieste, %ld aggiunte, e %ld eliminate. \
Tempo di risposta: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Sono un %s. Ho %ld topic nel mio database. Uptime: \
%d hour%s, %d min%s. Ci sono state %ld cose chieste, %ld aggiunte, e %ld eliminate. \
Tempo di risposta: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Sono un %s. Ho %ld topic nel mio database. Uptime: \
%d min%s, %d sec%s. Ci sono state %ld cose chieste, %ld aggiunte, e %ld eliminate. \
Tempo di risposta: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Ho eliminato il topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Non esiste il topic %s. Eliminazione fallita.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Ho eliminato il topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Non esiste il topic %s. Eliminazione fallita.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Sintassi: \2/msg %s PASS <vecchiapass> <nuovapass>\2\n",a,b)
#define L032(a) Snow("QUIT :C'e' \2%s\2 che mi dice di shtutarmi e io mi shtuto ...\n",a)
#define L033(a) S("NOTICE %s :Sintassi: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Sintassi: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Sintassi: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Specifica un nick!\n",a)
#define L037(a,b) S("NOTICE %s :Provo a fare /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Prova /nick %s-lamer.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Esco da %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Entro in %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Specifica un nick/chan!\n",a)
#define L042(a) S("NOTICE %s :Inserisci la hostmask (u@h) da eliminare!\n",a)
#define L043(a) S("NOTICE %s :Ban inesistente.\n",a)
#define L044(a) S("NOTICE %s :Inserisci la hostmask (u@h) da cancellare!\n",a)
#define L045(a) S("NOTICE %s :Come mai non lo faccio?\n",a)
#define L046(a) S("PRIVMSG %s :Copia di riserva del database effettuata.\n",a)
#define L047(a,b) S("NOTICE %s :Sintassi: %cAUTOTOPIC <topic> (settalo a \"0\" per disattivare)\n",a,b)
#define L048(a) S("NOTICE %s :Sintassi: SETCHAN <nuovi canali>\n",a)
#define L049(a,b) S("NOTICE %s :Canale di default: %s\n",a,b)
#define L050(a) S("NOTICE %s :Sintassi: SETCHAR <nuovo command char>\n",a)
#define L051(a,b) S("NOTICE %s :Il nuovo command char ora e': %c\n",a,b)
#define L052(a) S("NOTICE %s :Sintassi: SETUSER <nuovo ident> (richiede un !restart)\n",a)
#define L053(a,b) S("NOTICE %s :L'ident di default ora e': %s\n",a,b)
#define L054(a) S("NOTICE %s :Sinstassi: SETNICK <nuovonick>\n",a)
#define L055(a) S("NOTICE %s :Sintassi: ADDUSER <#chan> <*user@*.host> <level> <pass>. Es: ADDUSER #darkbot \
*jason@*.superlink.net 3 suaPasswd ... usa #* se vuoi dare accesso su tutti i canali.\n",a)
#define L056(a) sprintf(temp, "Non ho ancora usato \2%cSETINFO\2!",a)
#define L057(a,b,c) S("NOTICE %s :Aggiunto l'utente %s con level %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Sintassi: %c%s <u@h> [motivo]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Aggiunto in permban #%d, %s; motivo: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Sintassi: REPEAT <numero> <intervallo> <dati raw>\n",a)
#define L061(a) S("NOTICE %s :Fatto.\n",a)
#define L062(a) S("QUIT :Coi superpoteri, il %s si shtuta e si rippiccia !!\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, cosa vuoi aggiungere?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, cosa vuoi aggiungere?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Aggiungere cosa, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: che info devo aggiungere per %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okay, %s, ho imparato una cosa nuova! :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Aggiungere cosa, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: che info devo aggiungere per %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okay, %s, ho imparato una cosa nuova! :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Sostiuire cosa, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: quale info deve andare a sostituire %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s e' stato aggiornato.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Ci \"%s\" (licenza poetica) %d permban%s caricati in ram.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, mancano %d secondi al prossimo randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: era lungo %d caratteri.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, ci sono %d item%s in coda.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Finora ho visto %d joins.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Ci \"%s\" (licenza poetica) %d server%s nella mia lista. Al momento sono \
sul server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, il mio command char e': %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Che cosa dovrei %sare, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, devi specificare un indirizzo!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Non riesco a risolvere %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: cosa vuoi che dica a %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, che devo dire a %s?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :A chi devo dirlo, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: cosa vuoi che dica a %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, che devo dire a %s?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :A chi devo dirlo, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 chiedevi?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Ti spiacerebbe richiedermelo? (Usa %cHELP per avere \
suggerimenti sulla sintassi)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 chiedevi?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Ti spiacerebbe richiedermelo? (Usa %cHELP per avere \
suggerimenti sulla sintassi)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s e' rincoglionito!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION si sveglia da un brutto sogno...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Sono sotto flood. Sputo fuori tutta la queue. \
%d oggetti eliminati.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Spiacente %s, ma sostegno quel soggetto è stato rimosso.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Spiacente %s, ma sostegno quel soggetto è stato rimosso.\n",a,b);
diff --git a/source/langs/lang.h b/source/langs/lang.h
index 4f88c4c..52c6aff 100644
--- a/source/langs/lang.h
+++ b/source/langs/lang.h
@@ -1,64 +1,75 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#if LANG == 1
#include "english.h"
#endif
#if LANG == 2
#include "french.h"
#endif
#if LANG == 3
#include "spanish.h"
#endif
#if LANG == 4
#include "dutch.h"
#endif
#if LANG == 5
#include "latin.h"
#endif
#if LANG == 6
#include "greek.h"
#endif
#if LANG == 7
#include "ebonics.h"
#endif
#if LANG == 8
#include "latin2.h"
#endif
#if LANG == 9
#include "russian.h"
#endif
#if LANG == 10
#include "russian2.h"
#endif
#if LANG == 11
#include "portuguese.h"
#endif
#if LANG == 12
#include "german.h"
#endif
#if LANG == 13
#include "italian.h"
#endif
#if LANG == 14
#include "chinese.h"
#endif
#if LANG == 15
#include "swedish.h"
#endif
#if LANG == 16
#include "norwegian.h"
#endif
#if LANG == 17
#include "romanian.h"
#endif
#if LANG == 18
#include "arabic.h"
#endif
#if LANG == 19
#include "taiwanish.h"
#endif
#ifndef L091
#define L091(a) S("NOTICE %s :Syntax: SETVHOST <new Vhost> (requires a restart)\n",a)
#endif
#ifndef L092
#define L092(a,b) S("NOTICE %s :Default Vhost now: %s\n",a,b)
#endif
diff --git a/source/langs/latin.h b/source/langs/latin.h
index 62beaca..734cab3 100644
--- a/source/langs/latin.h
+++ b/source/langs/latin.h
@@ -1,111 +1,122 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Latin"
#define L001(a,b) S("PRIVMSG %s :Non posuisti tesserae, ut ponere tesserae: \2/msg %s PASS \
<tessera senex> <tessera nova>\2 (quod hoc est tempus primum tuum ponendo tesseram, uti '0' \
quam tesserae tua senex)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Delevi permban #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Non possum aperire %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Habeo %d SEEN's in basis factorum mea.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Scis plus illius quam scio, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Non vidi %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic in %s erat OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic in %s modo est OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s MUTABAT: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, peragebam. Habeo %d randomstuffs.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Tessera pro %s mutavit.\n",a,b)
#define L013(a) S("NOTICE %s :Tessera mendosa!\n",a)
#define L014(a) S("NOTICE %s :Non habeo pari!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Cliens delevit: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Divisio pro nihil error!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Effectio illicita!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (addendo praeteriendo #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Addendo praeteriendo #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Mutabam #%d: \37[\37%s\37]\37 res\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d nomina investigabant.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Inveniebam plus quam \37%d\37 para, si placet coarcta \
investigatio tua\2:\2 %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Inveniebam \37unum\37 par, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Inveniebam \37%d\37 para, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Inveniebam %ld res duplices. Amovebantur.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utiendo %s. Habeo %ld res in basis \
factorum mea, Confui: %d dies%s, %02d:%02d, Habeo %ld quaestiones rogabant, %ld res addebant, \
et %ld res delebant. Tempus de ratio: %1.4lf momenta%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utiendo %s. Habeo %ld res in basis factorum \
mea, Confui: %d horae%s, %d temporis momenta%s, Habeo %ld quaestiones rogabant, %ld res addebant, \
et %ld res delebant. Tempus de ratio: %1.4lf momenta%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Utiendo %s. Habeo %ld res in basis factorum \
mea, Confui: %d temporis momenta%s, %d momenta%s, Habeo %ld quaestiones rogabant, %ld res addebant, \
et %ld res delebant. Tempus de ratio: %1.4lf momenta%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Delevi res #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Non possum invenire res \37%s\37. Delendo deficiebat.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Delevi res #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Non possum invenire res \37%s\37. Delendo deficiebat.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntaxis: \2/msg %s PASS <tessera senexa> <tessera nova>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (Quod dico!))\n",a)
#define L033(a) S("NOTICE %s :Syntaxis: UP <canalis> <tessera>\n",a)
#define L034(a) S("NOTICE %s :Syntaxis: OP <canalis> [agnomina] <tessera>\n",a)
#define L035(a) S("NOTICE %s :Syntaxis: DEOP <canalis> [agnomina] <tessera>\n",a)
#define L036(a) S("NOTICE %s :Subtiliter enumera agnomen!\n",a)
#define L037(a,b) S("NOTICE %s :Temptando /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Tenta /nick %s-baro.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Relinquendo %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Subtiliter enumera agnomen/canalis!\n",a)
#define L042(a) S("NOTICE %s :Intra cliens@hospes purgare!\n",a)
#define L043(a) S("NOTICE %s :Non quam interdictum.\n",a)
#define L040(a,b) S("PRIVMSG %s :Jungiendo %s\n",a,b)
#define L044(a) S("NOTICE %s :Intra cliens@hospes delere!\n",a)
#define L045(a) S("NOTICE %s :Quidni ago hoc?\n",a)
#define L046(a) S("PRIVMSG %s :Exscribebam ex base factorum.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <res> (pone ad \"0\" vertere \"off\")\n",a,b)
#define L048(a) S("NOTICE %s :Syntaxis: SETCHAN <canales novi>\n",a)
#define L049(a,b) S("NOTICE %s :Canalis delictum: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntaxis: SETCHAR <littera jussum nova>\n",a)
#define L051(a,b) S("NOTICE %s :Littera jussum nova jam: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntaxis: SETUSER <cliens novus> (poscit reinitium)\n",a)
#define L053(a,b) S("NOTICE %s :Cliens delictum jam: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntaxis: SETNICK <agnomen novum>\n",a)
#define L055(a) S("NOTICE %s :Syntaxis: ADDUSER <canalis> <*cliens@*.hospes> <planities> <tessera>. \
ie; ADDUSER #darkbot *jason@*.superlink.net 3 tessera-sui ... uti #* si vis dare penetrare ad canales \
omnes.\n",a)
#define L056(a) sprintf(temp, "Non utuvi \2%cSETINFO\2 tamen!",a)
#define L057(a,b,c) S("NOTICE %s :Addebam cliens: %s - planities %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntaxis: %c%s <cliens@hospes> [ratio]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Addebam in permban #%d, %s; ratio: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntaxis: REPEAT <numerus> <mora> <facta crudi>\n",a)
#define L061(a) S("NOTICE %s :Termino.\n",a)
#define L062(a) S("QUIT :Reinitium %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, quid vis addere?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, quid vis addere?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Addere quid, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Quid res addere pro %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Ita, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Quid reponit, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Quid res debet reponere %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s mutavit.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Habeo %s %d permban%s onerant in RAM.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d momenta usque ad randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: erat %d lettrae.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Habeo %d res%s in Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Vidui %d jungendis adhuc.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Habeo %s %d societates%s in numerus de societas mea. Sum in \
societas #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, Littera jussum mea est: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Quid debeo %sing pro, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, requiris subtiliter enumerare alloquio!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Non possum convidere %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Quid me vis dicere %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Dico %s de quid?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Dico quis, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Quid me vis dicere %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Dico %s de quid?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Dico quis, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 rogas?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Potes verbis rexprimere illud? (Exara in machinam \
scriptoriam %cHELP pro significationes syntaxium)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 rogas?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Potes verbis rexprimere illud? (Exara in machinam \
scriptoriam %cHELP pro significationes syntaxium)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s est lapidando!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION expergit...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Inundo. demittendi fructus Que (facta illa exspectabante mandare). \
%d res.\n",a,b)
diff --git a/source/langs/latin2.h b/source/langs/latin2.h
index 310b7af..701b038 100644
--- a/source/langs/latin2.h
+++ b/source/langs/latin2.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Pig Latin."
#define L001(a,b) S("PRIVMSG %s :Youway avehay otnay etsay away asswordpay, otay etsay away asspay: \2/msg %s PASS \
<oldpass> <newpass>\2 (incesay isthay isway yourway irstfay imetay ettingsay away asspay, usewau '0' asway yourway oldway asspay)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Eletedday ermbanpay #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Unableway otay openway %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Ereth areway %d EENSAY'say inway ymay atabaseday.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :You'dway owknay oremay aboutway atthay anthay Iway oday, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Iway avehay otnay eensay %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopicway onway %s asway OFFWAY\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopicway onway %s isway ownay OFFWAY\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPICWAY @ %s ONWAY: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPICWAY @ %s UPDATEDWAY: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, oneday. Erethay areway ownay %d andomstuffsray.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Asswordpay orfay %s ashay eenbay updatedway.\n",a,b)
#define L013(a) S("NOTICE %s :Incorrectway asswordpay!\n",a)
#define L014(a) S("NOTICE %s :Onay atchmay!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Eletedday userway: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Ivisionday ybay erozay errorway!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Illegalway operationway!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (addingway ignoreway #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Addingway ignoreway #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Updatedway #%d: \37[\37%s\37]\37 infoway\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d entriesway earchedsay.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Oundfay oremau anthay \37%d\37 atchesmay, easeplay arrownay ownday yourway earchsay\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Iway oundfay \37oneway\37 atchmay, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Iway oundfay \37%d\37 atchesmay, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Oundfay %ld opictay uplicatesday. Eythay ereway emovedray.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Unningray %s. Iway avehay %ld opicstay inway ymay atabaseday, Uptimeway: \
%d ayday%s, %02d:%02d, Erethay avehay eenbay %ld uestionsqay askedway, %ld opictay additionsway, andway %ld opictay eletionsday. \
Rocesspay imetay: %1.4lf ecsay%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Unningray %s. Iway avehay %ld opicstay inway ymay atabaseday, Uptimeway: \
%d ourhay%s, %d inmay%s, Erethay avehay eenbay %ld uestionsqay askedway, %ld opictay additionsway, andway %ld opictay eletionsday. \
Rocesspay imetay: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Unningray %s. Iway avehay %ld opicstay inway ymay atabaseday, Uptimeway: \
%d inmay%s, %d ecsay%s, Erethay avehay eenbay %ld uestionsqay askedway, %ld opictay additionsway, andway %ld opictay eletionsday. \
Rocesspay imetay: %1.4lf ecsay%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Iway avehay eletedday opictay #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Iway asway unableway otay indfay ethay opictay %s. Eleteday ailedfay.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Iway avehay eletedday opictay #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Iway asway unableway otay indfay ethay opictay %s. Eleteday ailedfay.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Yntaxsay: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (ausecay Iway aysay osay!))\n",a)
#define L033(a) S("NOTICE %s :Yntaxsay: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Yntaxsay: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Yntaxsay: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Ecifyspay away icknay!\n",a)
#define L037(a,b) S("NOTICE %s :Attemptingway otay /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Ytray /nick %s-orkday.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Eavinglay %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Oiningjay %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Ecifyspay away icknay/anchay!\n",a)
#define L042(a) S("NOTICE %s :Enterway ethay u@h otay urgepay!\n",a)
#define L043(a) S("NOTICE %s :Onay uchsay anbay.\n",a)
#define L044(a) S("NOTICE %s :Enterway ethay u@h otay eleteday!\n",a)
#define L045(a) S("NOTICE %s :Owhay aboutway Iway otnay oday atthay?\n",a)
#define L046(a) S("PRIVMSG %s :Ackedbay upway atabaseday.\n",a)
#define L047(a,b) S("NOTICE %s :YNTAXSAY: %cAUTOTOPIC <topic> (etsay otay \"0\" otay urntay offway)\n",a,b)
#define L048(a) S("NOTICE %s :Yntaxsay: SETCHAN <new channels>\n",a)
#define L049(a,b) S("NOTICE %s :Efaultday annelchay: %s\n",a,b)
#define L050(a) S("NOTICE %s :Yntaxsay: SETCHAR <new command char>\n",a)
#define L051(a,b) S("NOTICE %s :Ewnay ommandcay archay ownay: %c\n",a,b)
#define L052(a) S("NOTICE %s :Yntaxsay: SETUSER <new userid> (equiresray away estartray)\n",a)
#define L053(a,b) S("NOTICE %s :Efaultday useridway ownay: %s\n",a,b)
#define L054(a) S("NOTICE %s :Yntaxsay: SETNICK <newnick>\n",a)
#define L055(a) S("NOTICE %s :Yntaxsay: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... useway #* ifway youway antway otay ivegay accessway inway allway anschay.\n",a)
#define L056(a) sprintf(temp, "Iway avenhay'tay usedway \2%cSETINFO\2 yet!",a)
#define L057(a,b,c) S("NOTICE %s :Addedway userway: %s - evellay %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Yntaxsay: %c%s <u@h> [reason]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Addedway inway ermbanpay #%d, %s; easonray: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Yntaxsay: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :Oneday.\n",a)
#define L062(a) S("QUIT :Estartingray %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, atwhay oday youway antway otay addway?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, atwhay oday youway antway otay addway?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Addway atwhay, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Atwhay infoway otay ebay addedway orfay %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okayway, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Addway atwhay, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Atwhay infoway otay ebay addedway orfay %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okayway, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Eplaceray atwhay, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Atwhay infoway ouldshay eplaceray %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s ashay eenbay updatedway.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Erethay %s %d ermbanpay%s oadedlay intoway amray.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d econdssay eftlay illtay andstuffray\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: itway asway %d arschay onglay.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Erethay isway urrentlycay %d itemway%s inway Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Iway avehay eensay %d oinsjay usthay arfay.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Erethay %s %d erversay%s inway ymau erversay istlay. Iway amway urrentlycay onway \
erversay #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, ymay ommandcay archay isway: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Atwhay ouldshay Iway ebay %sing orfay, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, youway eednay otay ecifyspay anway addressway!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Asway unableway otay ooklay upway %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Atwhay oday youway antway emay otay elltay %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Elltay %s aboutway atwhay?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Elltay owhay, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Atwhay oday youway antway emay otay elltay %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Elltay %s aboutway atwhay?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Elltay owhay, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 youway ereway askingway?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Indmay ephrasingray atthay? (Ypetay %cHELP orfay yntaxsay \
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 youway ereway askingway?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Indmay ephrasingray atthay? (Ypetay %cHELP orfay yntaxsay \
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s isway onedstay!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION akesway upway...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Iway'may eingbay oodedflay. Umpingday outputway Que. \
%d itemsway eletedday.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Orrysay %s, utbay upportsay orfay atthay opictay ashay eenbay emovedray.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Orrysay %s, utbay upportsay orfay atthay opictay ashay eenbay emovedray.\n",a,b);
\ No newline at end of file
diff --git a/source/langs/norwegian.h b/source/langs/norwegian.h
index b2988f1..ee79073 100644
--- a/source/langs/norwegian.h
+++ b/source/langs/norwegian.h
@@ -1,113 +1,124 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Jeg snakker norsk."
#define L001(a,b) S("PRIVMSG %s :Du har ikke satt noe passord, for å sette passord: \2/msg %s PASS \
<gammeltpassord> <nyttpassord>\2 (siden dette er første gang du setetr passord, bruk '0' som gammeltpassord)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Slettet permanent ban #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Kan ikke åpne %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Det finnes %d SEENs i min database.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Du vet mere om det enn hva jeg gjør, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Jeg har ikke sett %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic on %s var OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s er nå OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s OPPDATERT: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, ferdig. Det finnes nå %d random-ting.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Passord for %s er oppdatert.\n",a,b)
#define L013(a) S("NOTICE %s :Feil passord!\n",a)
#define L014(a) S("NOTICE %s :Ingen som passer!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Slettet bruker: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Divisjon med null!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Ugyldig operasjon!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (du er herved ignorert #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Du er herved ignorert #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Oppdatert #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d antall linjer søkt.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Fant mer enn \37%d\37 treff, venligst vær mer spesifikk\2:\2 \%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Jeg fant \37one\37 treff, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Jeg fant \37%d\37 treff, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :jeg fant %ld duplikate temaer, som ble fjernet.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kjører %s. Jeg har %ld temaer i databasen min, Oppetid: \
%d dager%s, %02d:%02d, Det har vært %ld spørsmål, %ld topic tillegg, og %ld topic deklerasjoner. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kjører %s. Jeg har %ld temaer i databasen min, Oppetid: \
%d timer%s, %d min%s, Det har vært %ld spørsmål, %ld topic tillegg, og %ld topic deklerasjoner. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kjører %s. Jeg har %ld temaer i databasen min, Oppetid: \
%d min%s, %d sek%s, Det har vært %ld spørsmål, %ld topic tillegg, og %ld topic deklerasjoner. \
Process time: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Jeg har slettet topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 I Kunne ikke finne tema %s. Delete failed.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Jeg har slettet topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 I Kunne ikke finne tema %s. Delete failed.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <gammeltpassord> <nyttpassord>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (Fordi, derfor!))\n",a)
#define L033(a) S("NOTICE %s :Syntaks: UP <#chan> <passord>\n",a)
#define L034(a) S("NOTICE %s :Syntaks: OP <#chan> [nicks] <passord>\n",a)
#define L035(a) S("NOTICE %s :Syntaks: DEOP <#chan> [nicks] <passord>\n",a)
#define L036(a) S("NOTICE %s :Spessifiser et nick!\n",a)
#define L037(a,b) S("NOTICE %s :Forsøker å gjøre /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Prøv /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Forlater %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s : %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Spessifiser et nick/kanal!\n",a)
#define L042(a) S("NOTICE %s :Skriv inn u@h for å sjekke!\n",a)
#define L043(a) S("NOTICE %s :Finnes ikke et slikt ban.\n",a)
#define L044(a) S("NOTICE %s :Skriv inn u@h som skal slettes!\n",a)
#define L045(a) S("NOTICE %s :Hva med at jeg ikke gjør det?\n",a)
#define L046(a) S("PRIVMSG %s :Sikkerhetskopierte databasen.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <topic> (satt til \"0\" for å slå av)\n",a,b)
#define L048(a) S("NOTICE %s :Syntaks: SETCHAN <nye kanaler>\n",a)
#define L049(a,b) S("NOTICE %s :Standard kanal: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntaks: SETCHAR <ny kommando tegn>\n",a)
#define L051(a,b) S("NOTICE %s :nytt kommando tegn nå: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntaks: SETUSER <ny userid> (behøver en restart)\n",a)
#define L053(a,b) S("NOTICE %s :Standard userid nå: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntaks: SETNICK <nyttnick>\n",a)
#define L055(a) S("NOTICE %s :Syntaks: ADDUSER <#kanal> <*user@*.host> <level> <passord>. mao; ADDUSER #darkbot \
*jason@*.superlink.net 3 PassordetHans ... bruk #* hvis du vil at han skal ha tilgang på alle kanaler.\n",a)
#define L056(a) sprintf(temp, "Jeg har ikke brukt \2%cSETINFO\2 enda!",a)
#define L057(a,b,c) S("NOTICE %s :La til bruker: %s - level %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntaks: %c%s <u@h> [begrunnelse]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :La til i permanentban #%d, %s; begrunnelse: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntaks: REPEAT <nummer> <forsinkelse> <rå-data>\n",a)
#define L061(a) S("NOTICE %s :Ferdig.\n",a)
#define L062(a) S("QUIT :Restarter %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, hva vil du legge til?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, hva vil du legge til?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Legge til hva, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Hvilken info skal legges til for %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Greit, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Legge til hva, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Hvilken info skal legges til for %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Greit, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Erstatte hva, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Hvilken info skal erstattes %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s har blitt oppdatert.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Det er %s %d permanentebans%s lastet i minnet.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d sekunder igjen til randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: den var %d tegn lang.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Der finnes %d objekter%s i køen.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Jeg har ikke sett %d vært her til nå.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Det finnes %s %d servere%s i min server liste. Jeg bruker nå \
server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mitt kommando tegn er: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Hva burde jeg %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, du må spessifisere en adresse!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Kunne ikke finne %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Hva vil du jeg skal fortelle %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Fortell %s om hva?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Fortelle hvem, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Hva vil du jeg skal fortelle %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Fortell %s om hva?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Fortelle hvem, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 du spurte?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Ehh, gjenta? (skriv %cHELP for syntaks \
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 du spurte?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Ehh, gjenta? (skriv %cHELP for syntaks \
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s is stoned!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION våkner opp...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :jeg blir floodet. Dumper utgående kø. \
%d objekter slettet.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Beklager %s, men støtten for det emnet har blitt fjernet.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Beklager %s, men støtten for det emnet har blitt fjernet.\n",a,b);
\ No newline at end of file
diff --git a/source/langs/portuguese.h b/source/langs/portuguese.h
index 9e375ee..91deb54 100644
--- a/source/langs/portuguese.h
+++ b/source/langs/portuguese.h
@@ -1,116 +1,127 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Falo português e um pouco de inglês."
#define L001(a,b) S("PRIVMSG %s :Não foi ainda definida a senha, para o fazer: \2/msg %s PASS \
<senha_anterior> <senha_nova>\2 (já que esta é a primeira vez que a senha é configurada, usar '0' como senha anterior)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Removido ban permanente (permban) #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Não foi possível abrir %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Há %d SEENs na minha base de dados.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Sabes melhor que eu acerca disso, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Não vi %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Tópico automático (Autotopic) em %s estava desligado\n",a,b)
#define L008(a,b) S("NOTICE %s :Tópico automático (Autotopic) em %s foi desligado\n",a,b);
#define L009(a,b,c) S("NOTICE %s :Tópico automático (Autotopic) em %s LIGADO: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :Tópico automático (Autotopic) em %s ACTUALIZADO: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, Processado! Há agora %d frases para execução casual (randomstuffs).\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Senha de %s actualizada.\n",a,b)
#define L013(a) S("NOTICE %s :Senha incorrecta!\n",a)
#define L014(a) S("NOTICE %s :Nada encontrado!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Usuário removido: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Erro de divisão por zero!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Operação Incorrecta! (Usar entre os números +, -, *, /, para somar, subtrair, multiplicar e dividir respectivamente)!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Adicionado usuário a ser ignorado #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Adicionado usuário a ser ignorado #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Actualizado #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d itens verificados.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Encontrados mais que \37%d\37 itens, por favor tentar ser-se mais específico\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Encontrei \37um\37 item, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Encontrados \37%d\37 itens, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Encontrados %ld temas repetidos. Foram removidos.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Análise a %s. Tenho %ld temas na minha Base de Dados. Tempo desde que me liguei: \
%d dias%s, %02d:%02d, Foram feitas %ld perguntas, adicionados %ld temas e removidos %ld. \
Tempo de processamento: %1.4lf segundo%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Análise a %s. Tenho %ld temas na minha Base de Dados. Tempo desde que me liguei: \
%d horas%s, %d minuto%s, Foram feitas %ld perguntas, adicionados %ld temas e removidos %ld. \
Tempo de processamento: %1.4lf segundo%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Análise a %s. Tenho %ld temas na minha Base de Dados. Tempo desde que me liguei: \
%d minuto%s, %d segundo%s, Foram feitas %ld perguntas, adicionados %ld temas e removidos %ld. \
Tempo de processamento: %1.4lf segundo%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Removido o tópico #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Não consegui encontrar o tópico %s. Remoção abortada.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Removido o tópico #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Não consegui encontrar o tópico %s. Remoção abortada.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Sintaxe: \2/msg %s SENHA <senha_anterior> <senha_nova>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (manutenção!)\n",a)
#define L033(a) S("NOTICE %s :Sintaxe: UP <#canal> <senha>\n",a)
#define L034(a) S("NOTICE %s :Sintaxe: OP <#canal> [nicks] <senha>\n",a)
#define L035(a) S("NOTICE %s :Sintaxe: DEOP <#canal> [nicks] <senha>\n",a)
#define L036(a) S("NOTICE %s :Especificar um nick!\n",a)
#define L037(a,b) S("NOTICE %s :Mudança para /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Tentar /nick %s-idiota.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Saindo %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Entrando %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Especificar um nick/canal!\n",a)
#define L042(a) S("NOTICE %s :Especificar o u@h para remoção!\n",a)
#define L043(a) S("NOTICE %s :Ban não existente.\n",a)
#define L044(a) S("NOTICE %s :Especificar o u@h para remover!\n",a)
#define L045(a) S("NOTICE %s :Faz isso a outro nick, não a mim\n",a)
#define L046(a) S("PRIVMSG %s :Processamento de cópia da Base de Dados executada.\n",a)
#define L047(a,b) S("NOTICE %s :Sintaxe: %cAUTOTOPIC <tópico> (escrever um \"0\" (zero) para desligar a função)\n",a,b)
#define L048(a) S("NOTICE %s :Sintaxe: SETCHAN <#canal>\n",a)
#define L049(a,b) S("NOTICE %s :Canal inicial: %s\n",a,b)
#define L050(a) S("NOTICE %s :Sintaxe: SETCHAR <novo caracter de comando>\n",a)
#define L051(a,b) S("NOTICE %s :Novo caracter de comando é agora: %c\n",a,b)
#define L052(a) S("NOTICE %s :Sintaxe: SETUSER <novo userid> (necessário reiniciar)\n",a)
#define L053(a,b) S("NOTICE %s :userid é agora: %s\n",a,b)
#define L054(a) S("NOTICE %s :Sintaxe: SETNICK <novo_nick>\n",a)
#define L055(a) S("NOTICE %s :Sintaxe: ADDUSER <#canal> <*user@*.host> <nível> <senha>. ex; ADDUSER #darkbot \
*jason@*.superlink.net 3 sua_senha ... usar #* se pretende dar-se acesso a todos os canais.\n",a)
#define L056(a) sprintf(temp, "Não foi feito \2%cSETINFO\2 ainda!",a)
#define L057(a,b,c) S("NOTICE %s :Adicionado usuário: %s - nível %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Sintaxe: %c%s <u@h> [razão]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Adicionado em permban #%d, %s; razão: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Sintaxe: REPEAT <número de vezes> <intervalo> <data>\n",a)
#define L061(a) S("NOTICE %s :Feito.\n",a)
#define L062(a) S("QUIT :Reiniciando %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, o que é necessário adicionar?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, o que é necessário adicionar?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Adicionar o quê, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Que informação é para ser adicionada ao tópico %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Ok, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Adicionar o quê, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Que informação é para ser adicionada ao tópico %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Ok, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Substituir o quê, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Que informação deve ser substituída %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s substituído com sucesso.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :%s há %d Ban permanente%s em memória.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, faltam %d segundos até á próxima frase casual (randstuff)\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: tinha %d caracteres.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, há neste momento %d iten%s no ponto.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Vi %d entradas de usuários no canal até ao momento.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Há %s %d server%s na minha lista de servers. Encontro-me neste momento no \
server #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, o meu caracter de comando é: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :%s??? Procuro o quê %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, é necessário especificar um endereço!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :impossibilitado em verificar %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: O que digo a %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Digo a %s o quê?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Digo a quem, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: O que digo a %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Digo a %s o quê?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Digo a quem, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 é uma pergunta?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Por favor repetir a pergunta (escrever %cHELP para o sintaxe ta mesma \
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 é uma pergunta?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Por favor repetir a pergunta (escrever %cHELP para o sintaxe ta mesma \
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s está lento!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION acorda...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :estou a ser alvo de flood. Esvaziando itens do ponto. \
%d itens removidos.\n",a,b)
#define L091(a) S("NOTICE %s :Sintaxe: SETVHOST <Vhost novo> (requer que se reinicie)\n",a)
#define L092(a,b) S("NOTICE %s :Vhost está agora configurado para: %s\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Pesaroso %s, mas sustentação para esse tópico foi removido.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Pesaroso %s, mas sustentação para esse tópico foi removido.\n",a,b);
\ No newline at end of file
diff --git a/source/langs/romanian.h b/source/langs/romanian.h
index 69f5108..98b3948 100644
--- a/source/langs/romanian.h
+++ b/source/langs/romanian.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Vorbesc Romana."
#define L001(a,b) S("PRIVMSG %s :Inca nu ai stabilit o parola, pentru a stabili una: \2/msg %s PASS \
<parolaVeche> <parolaNoua>\2 (pentru ca este prima data cand stabilesti o parola, foloseste '0' pentru parolaVeche)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Am anulat ban-ul permanent #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Nu pot deschide %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Am %d SEEN'uri in baza de date.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Tu ar trebui sa stii mai multe decat mine, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, N-am dat cu ochii de %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic in %s era dezactivat \n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic in %s este acum dezactivat\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s Activ: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s actualizat: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, s-a facut! Acum am %d randomstuffs.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Parola pentru %s a fost actualizata.\n",a,b)
#define L013(a) S("NOTICE %s :Parola incorecta!\n",a)
#define L014(a) S("NOTICE %s :Nici o potrivire!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Am sters user-ul: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Nu se imparte prin 0!!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Operatie ilegala!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (adding ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Ignor pe #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Actualizat: #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. am cautat in %d inregistrari.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Am gasit mai mult de \37%d\37 potriviri, te rog incearca sa reduci numarul\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Am gasit \37o\37 potrivire, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Am gasit \37%d\37 potriviri, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Am gasit %ld inregistrari dedublate...si le-am sters.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Rulez %s. Am %ld inregistrari in baza de date, Uptime: \
%d zile%s, %02d:%02d, Am fost intrebat %ld intrebari, %ld inregistrari adaugate, si %ld inregistrari sterse. \
Timp de procesare: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Rulez %s. Am %ld topics in baza de date, Uptime: \
%d ore%s, %d min%s, Au fost puse %ld intrebari, %ld inregistrari noi, si %ld inregistrari sterse. \
Timp de procesare: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Rulez %s. Am %ld inregistrari in baza de date, Uptime: \
%d min%s, %d sec%s, S-au pus %ld intrebari, %ld inregistrari au fost adaugate, si %ld inregistrari au fost sterse. \
Timp de procesare: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Am sters inregistrarea #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Nu am gasit nici o inregistrare %s. Suprimare ratata.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Am sters inregistrarea #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Nu am gasit nici o inregistrare %s. Suprimare ratata.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <parolaVeche> <parolaNoua>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (pentru ca am zis eu!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#chan> <parola>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#chan> [nicks] <parola>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#chan> [nicks] <parola>\n",a)
#define L036(a) S("NOTICE %s :Specifica un nick!\n",a)
#define L037(a,b) S("NOTICE %s :Incerc /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Incearca /nick %s-fraiere.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Plec din %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Intru in %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Specifica un nick/canal!\n",a)
#define L042(a) S("NOTICE %s :Specifica u@h-ul de sters!\n",a)
#define L043(a) S("NOTICE %s :Acest ban nu exista.\n",a)
#define L044(a) S("NOTICE %s :Specifica u@h-ul de sters!\n",a)
#define L045(a) S("NOTICE %s :Ce-ar fi sa NU fac asta?\n",a)
#define L046(a) S("PRIVMSG %s :Am facut copie de siguranta pentru baza de date.\n",a)
#define L047(a,b) S("NOTICE %s :SINTAXA: %cAUTOTOPIC <topic> (seteaza-l \"0\" pentru a-l dezactiva)\n",a,b)
#define L048(a) S("NOTICE %s :Sintaxa: SETCHAN <canalNou>\n",a)
#define L049(a,b) S("NOTICE %s :Canalul implicit: %s\n",a,b)
#define L050(a) S("NOTICE %s :Sintaxa: SETCHAR <nou caracter de comanda>\n",a)
#define L051(a,b) S("NOTICE %s :Noul caracter de comanda este: %c\n",a,b)
#define L052(a) S("NOTICE %s :Sintaxa: SETUSER <nou userID> (trebuie restart)\n",a)
#define L053(a,b) S("NOTICE %s :userID-ul actual este: %s\n",a,b)
#define L054(a) S("NOTICE %s :Sintaxa: SETNICK <noulNick>\n",a)
#define L055(a) S("NOTICE %s :Sintaxa: ADDUSER <#canal> <*user@*.host> <nivel> <parola>. exemplu; ADDUSER #darkbot \
*jason@*.superlink.net 3 parolaLui ... foloseste #* daca vrei sa-i acorzi acces in toate canalele.\n",a)
#define L056(a) sprintf(temp, "nu am folosit \2%cSETINFO\2 inca!",a)
#define L057(a,b,c) S("NOTICE %s :Am adaugat userul: %s - nivel %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Sintaxa: %c%s <u@h> [motiv]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Am adugat ban-ul permanent #%d, %s; motiv: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Sintaxa: REPEAT <numar> <durataRepetitiei> <comanda irc>\n",a)
#define L061(a) S("NOTICE %s :S-a facut.\n",a)
#define L062(a) S("QUIT :Fac un restart %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, ce vrei sa adaugi?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, ce vrei sa adaugi?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Ce adaug, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Ce sa adaug pentru %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okay, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Ce adaug, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Ce sa adaug pentru %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okay, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Ce sa inlocuiesc, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Ce ar trebui sa inlocuiasca %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s a fost actualizat.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Am %s %d ban-uri permanente%s incarcate in ram.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d secunde ramase pana la randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: are %d caractere.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Sunt %d lucruri de zis%s in coada.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Am vazut %d join-uri pana acum.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Am %s %d servere%s in lista. Acum sunt pe server-ul \
#%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, caracterul meu de comanda este: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Ce ar trebui sa %s, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, trebuie sa specifici o adresa!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Nu am putut sa caut %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Ce vrei sa-i spun lu' %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Sa-i spun lu' %s CE?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :CUI sa-i spun, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Ce vrei sa-i spun lu' %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Sa-i spun lu' %s CE?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :CUI sa-i spun, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 ce intrebai?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Ce-ar fi sa reformulezi? (scrie %cHELP pentru sintaxa \
)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 ce intrebai?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Ce-ar fi sa reformulezi? (scrie %cHELP pentru sintaxa \
)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s e inaccesibil!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION se trezeste...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Ma flood-eaza. Renunt la coada de comenzi. \
%d comenzi sterse.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Ne pare rau %s, dar suportul pentru acel topic a fost anulat.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Ne pare rau %s, dar suportul pentru acel topic a fost anulat.\n",a,b);
\ No newline at end of file
diff --git a/source/langs/russian.h b/source/langs/russian.h
index 4122d3a..324f494 100644
--- a/source/langs/russian.h
+++ b/source/langs/russian.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "ñ ÇÏ×ÏÒÀ ÐÏ ÒÕÓÓËÉ."
#define L001(a,b) S("PRIVMSG %s :îÅ ÚÁÄÁÎ ÐÁÒÏÌØ, ÄÌÑ ÚÁÄÁÎÉÑ ÐÁÒÏÌÑ: \2/msg %s PASS \
<ÓÔÁÒÙÊÐÁÒÏÌØ> <ÎÏ×ÙÊÐÁÒÏÌØ>\2 (Ô.Ë ÐÁÒÏÌØ ÚÁÄÁÅÔÓÑ ×ÐÅÒ×ÙÅ, ÕËÁÖÉÔÅ '0' ×ÍÅÓÔÏ ÓÔÁÒÏÇÏ ÐÁÒÏÌÑ)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :õÄÁÌÅÎ permban #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, ñ ×ÉÖÕ %d SEEN'Ï× × ÍÏÅÊ ÂÁÚÅ.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :ôÙ ÚÎÁÅÛØ ÂÏÌØÛÅ, ÞÅÍ Ñ, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, ñ ÎÅ ×ÉÄÅÌ %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic on %s was OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s is now OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, ÇÏÔÏ×Ï. ôÅÐÅÒØ Õ ÍÅÎÑ ÅÓÔØ %d ÈÏÈÍ.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :ðÁÒÏÌØ ÄÌÑ %s ÏÂÎÏ×ÌÅÎ.\n",a,b)
#define L013(a) S("NOTICE %s :îÅ×ÅÒÎÙÊ ÐÁÒÏÌØ!\n",a)
#define L014(a) S("NOTICE %s :îÅ ÍÏÇÕ ÎÁÊÔÉ!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :õÄÁÌÅÎ ÐÏÌØÚÏ×ÁÔÅÌØ: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: äÅÌÅÎÉÅ ÎÁ ÎÏÌØ!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: îÅ×ÅÒÎÁÑ ÏÐÅÒÁÃÉÑ!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (adding ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Adding ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :ïÂÎÏ×ÌÅÎÏ #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d ÚÁÐÉÓÅÊ ÐÒÏÓÍÏÔÒÅÎÏ.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :îÁÊÄÅÎÏ ÂÏÌÅÅ, ÞÅÍ \37%d\37 ÚÁÐÉÓÅÊ, ÓÕÚØÔÅ ÕÓÌÏ×ÉÑ ÐÏÉÓËÁ\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :ñ ÎÁÛÅÌ \37ÏÄÎÕ\37 ÚÁÐÉÓØ, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :ñ ÎÁÛÅÌ \37%d\37 ÚÁÐÉÓÅÊ, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :îÁÊÄÅÎÏ %ld ÐÏ×ÔÏÒÑÀÝÉÈÓÑ ÔÅÍ. õÄÁÌÅÎÙ.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :úÁÐÕÝÅÎ ÎÁ %s. õ ÍÅÎÑ ÅÓÔØ %ld ÔÅÍ × ÂÁÚÅ ÄÁÎÎÙÈ, ÷ÒÅÍÑ ÒÁÂÏÔÙ: \
%d ÄÎÅÊ%s, %02d:%02d, âÙÌÏ ÚÁÄÁÎÏ %ld ×ÏÐÒÏÓÏ×, %ld ÔÅÍ ÄÏÂÁ×ÌÅÎÏ, É %ld ÔÅÍ ÕÄÁÌÅÎÏ. \
÷ÒÅÍÑ ÉÓÐÏÌÎÅÎÉÑ: %1.4lf ÓÅËÕÎÄ%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :úÁÐÕÝÅÎ ÎÁ %s. õ ÍÅÎÑ ÅÓÔØ %ld ÔÅÍ × ÂÁÚÅ ÄÁÎÎÙÈ, ÷ÒÅÍÑ ÒÁÂÏÔÙ: \
%d ÞÁÓÏ×%s, %d ÍÉÎÕÔ%s, âÙÌÏ ÚÁÄÁÎÏ %ld ×ÏÐÒÏÓÏ×, %ld ÔÅÍ ÄÏÂÁ×ÌÅÎÏ, É %ld ÔÅÍ ÕÄÁÌÅÎÏ. \
÷ÒÅÍÑ ÉÓÐÏÌÎÅÎÉÑ: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :úÁÐÕÝÅÎ ÎÁ %s. õ ÍÅÎÑ ÅÓÔØ %ld ÔÅÍ × ÂÁÚÅ ÄÁÎÎÙÈ, ÷ÒÅÍÑ ÒÁÂÏÔÙ: \
%d min%s, %d sec%s, âÙÌÏ ÚÁÄÁÎÏ %ld ×ÏÐÒÏÓÏ×, %ld ÔÅÍ ÄÏÂÁ×ÌÅÎÏ, É %ld ÔÅÍ ÕÄÁÌÅÎÏ. \
÷ÒÅÍÑ ÉÓÐÏÌÎÅÎÉÑ: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: õÄÁÌÅÎÁ ÔÅÍÁ #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 îÅ ÍÏÇÕ ÎÁÊÔÉ ÔÅÍÕ %s. õÄÁÌÅÎÉÅ ÎÅÕÄÁÌÏÓØ.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: õÄÁÌÅÎÁ ÔÅÍÁ #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 îÅ ÍÏÇÕ ÎÁÊÔÉ ÔÅÍÕ %s. õÄÁÌÅÎÉÅ ÎÅÕÄÁÌÏÓØ.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :óÉÎÔÁËÓÉÓ: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :õ\2\2ÂÉÔ (%s (ÐÏÔÏÍÕ ÞÔÏ Ñ ÔÁË ÓËÁÚÁÌ!))\n",a)
#define L033(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :õËÁÖÉ ÎÉË!\n",a)
#define L037(a,b) S("NOTICE %s :ðÙÔÁÀÓØ /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :ðÏÐÒÏÂÕÊ /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :ðÏËÉÄÁÀ %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :óÏÅÄÉÎÑÀÓØ Ó %s\n",a,b)
#define L041(a) S("PRIVMSG %s :õËÁÖÉ ÎÉË/ËÁÎÁÌ!\n",a)
#define L042(a) S("NOTICE %s :÷×ÅÄÉ u@h ÄÌÑ ÏÞÉÓÔËÉ!\n",a)
#define L043(a) S("NOTICE %s :îÅÔ ÔÁËÏÇÏ ÂÁÎÁ.\n",a)
#define L044(a) S("NOTICE %s :÷×ÅÄÉ u@h ÄÌÑ ÕÄÁÌÅÎÉÑ!\n",a)
#define L045(a) S("NOTICE %s :ëÁË ÎÁÞÓÅÔ ÂÏÌØÛÅ ÔÁËÏÇÏ ÎÅ ÄÅÌÁÔØ?\n",a)
#define L046(a) S("PRIVMSG %s :óÏÈÒÁÎÉÌÉ ÂÁÚÕ ÄÁÎÎÙÈ.\n",a)
#define L047(a,b) S("NOTICE %s :óÉÎÔÁËÓÉÓ: %cAUTOTOPIC <topic> (ÕÓÔÁÎÏ×É × \"0\" ÞÔÏÂÙ ×ÙËÌÀÞÉÔØ)\n",a,b)
#define L048(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: SETCHAN <ÎÏ×ÙÅ ËÁÎÁÌÙ>\n",a)
#define L049(a,b) S("NOTICE %s :ëÁÎÁÌ ÐÏ ÕÍÏÌÞÁÎÉÀ: %s\n",a,b)
#define L050(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: SETCHAR <ÎÏ×ÙÊ ËÏÍÁÎÄÎÙÊ ÓÉÍ×ÏÌ>\n",a)
#define L051(a,b) S("NOTICE %s :îÏ×ÙÊ ËÏÍÁÎÄÎÙÊ ÓÉÍ×ÏÌ ÔÅÐÅÒØ: %c\n",a,b)
#define L052(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: SETUSER <ÎÏ×ÙÊ userid> (ÔÒÅÂÕÅÔÓÑ ÒÅÓÔÁÒÔ)\n",a)
#define L053(a,b) S("NOTICE %s :userid ÐÏ ÕÍÏÌÞÁÎÉÀ ÔÅÐÅÒØ: %s\n",a,b)
#define L054(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: SETNICK <ÎÏ×ÙÊ ÎÉË>\n",a)
#define L055(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... use #* if you want to give access in all chans.\n",a)
#define L056(a) sprintf(temp, "I haven't used \2%cSETINFO\2 yet!",a)
#define L057(a,b,c) S("NOTICE %s :äÏÂÁ×ÌÅÎ ÐÏÌØÚÏ×ÁÔÅÌØ: %s - ÕÒÏ×ÅÎØ %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :óÉÎÔÁËÓÉÓ: %c%s <u@h> [ÐÒÉÞÉÎÁ]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :äÏÂÁ×ÌÅÎ Ë permban #%d, %s; ÐÒÉÞÉÎÁ: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: REPEAT <ÞÉÓÌÏ> <ÚÁÄÅÒÖËÁ> <ÄÁÎÎÙÅ>\n",a)
#define L061(a) S("NOTICE %s :çÏÔÏ×Ï.\n",a)
#define L062(a) S("QUIT :òÅÓÔÁÒÔÕÀ %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, ÞÔÏ ÔÙ ÈÏÞÅÛØ ÄÏÂÁ×ÉÔØ?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, ÞÔÏ ÔÙ ÈÏÞÅÛØ ÄÏÂÁ×ÉÔØ?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :äÏÂÁ×ÉÔØ ÞÔÏ, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: ëÁËÏÅ ÐÒÉ×ÅÔÓÔ×ÉÅ ÄÏÂÁ×ÉÔØ ÄÌÑ %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Ok, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :äÏÂÁ×ÉÔØ ÞÔÏ, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: ëÁËÏÅ ÐÒÉ×ÅÔÓÔ×ÉÅ ÄÏÂÁ×ÉÔØ ÄÌÑ %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Ok, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :úÁÍÅÎÉÔØ ÞÔÏ, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: ëÁËÁÑ ÉÎÆÏÒÍÁÃÉÑ ÄÏÌÖÎÁ ÚÁÍÅÎÉÔØ %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s ÏÂÎÏ×ÌÅÎÏ.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :%s %d permban%s ÚÁÇÒÕÖÅÎÏ × ÐÁÍÑÔØ.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d ÓÅËÕÎÄ ÏÓÔÁÌÏÓØ ÄÏ ÓÌÅÄÕÀÝÅÊ ÈÏÈÍÙ\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: ÜÔÏ ÂÙÌÏ ÄÌÉÎÎÏÊ %d ÓÉÍ×ÏÌÏ×.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, õ ÍÅÎÑ ÓÅÊÞÁÓ %d ÐÒÅÄÍÅÔÏ×%s × ÏÞÅÒÅÄÉ.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :ñ ×ÉÄÅÌ %d ÐÒÉÓÏÅÄÉÎÑÅÔÓÑ Ë ÎÁÍ, ÐÏËÁ ÞÔÏ.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :%s %d ÓÅÒ×ÅÒÏ×%s × ÍÏÅÍ ÓÐÉÓËÅ. óÅÊÞÁÓ Ñ ÎÁ \
ÓÅÒ×ÅÒÅ #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, ÍÏÊ ËÏÍÁÎÄÎÙÊ ÓÉÍ×ÏÌ: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :What should i be %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, îÅÏÂÈÏÄÉÍÏ ÕËÁÚÁÔØ ÁÄÒÅÓ!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :îÅ ÍÏÇÕ ×ÙÑÓÎÉÔØ %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: é ÞÔÏ ÍÎÅ ÓËÁÚÁÔØ %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, òÁÓÓËÁÚÁÔØ %s Ï ÞÅÍ?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :óËÁÚÁÔØ ËÏÍÕ, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: é ÞÔÏ ÍÎÅ ÓËÁÚÁÔØ %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, òÁÓÓËÁÚÁÔØ %s Ï ÞÅÍ?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :óËÁÚÁÔØ ËÏÍÕ, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 ÔÙ ÓÐÒÏÓÉÌ?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? ðÅÒÅÆÒÁÚÉÒÕÊ? (ÎÁÂÅÒÉ %cHELP ÄÌÑ ÐÏÍÏÝÉ × ÓÉÎÔÁËÓÉÓÅ)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 ÔÙ ÓÐÒÏÓÉÌ?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? ðÅÒÅÆÒÁÚÉÒÕÊ? (ÎÁÂÅÒÉ %cHELP ÄÌÑ ÐÏÍÏÝÉ × ÓÉÎÔÁËÓÉÓÅ)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s ÚÁÍÅÒÚ!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION ÐÒÏÓÎÙÐÁÅÔÓÑ...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :íÅÎÑ ÆÌÕÄÑÔ. ïÞÉÝÁÀ ×ÙÈÏÄÎÕÀ ÏÞÅÒÅÄØ. \
%d ÚÁÐÉÓÅÊ ÕÄÁÌÅÎÏ.\n",a,b)
#define L091(a) S("NOTICE %s :óÉÎÔÁËÓÉÓ: SETVHOST <ÎÏ×ÙÊ Vhost> (ÎÕÖÅÎ ÒÅÓÔÁÒÔ)\n",a)
#define L092(a,b) S("NOTICE %s :Vhost ÐÏ ÕÍÏÌÞÁÎÉÀ ÔÅÐÅÒØ: %s\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Izveni %s, nu poderjka dla etoy temi bil udalen.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Izveni %s, nu poderjka dla etoy temi bil udalen.\n",a,b);
diff --git a/source/langs/russian2.h b/source/langs/russian2.h
index 8eef3df..abe17f0 100644
--- a/source/langs/russian2.h
+++ b/source/langs/russian2.h
@@ -1,112 +1,123 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "ß ãîâîðþ ïî ðóññêè."
#define L001(a,b) S("PRIVMSG %s :Íå çàäàí ïàðîëü, äëÿ çàäàíèÿ ïàðîëÿ: \2/msg %s PASS \
<ñòàðûéïàðîëü> <íîâûéïàðîëü>\2 (ò.ê ïàðîëü çàäàåòñÿ âïåðâûå, óêàæèòå '0' âìåñòî ñòàðîãî ïàðîëÿ)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Óäàëåí permban #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Íå ìîãó îòêðûòü %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, ß âèæó %d SEEN'îâ â ìîåé áàçå.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Òû çíàåøü áîëüøå, ÷åì ÿ, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, ß íå âèäåë %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic on %s was OFF\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic on %s is now OFF\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ON: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, ãîòîâî. Òåïåðü ó ìåíÿ åñòü %d õîõì.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Ïàðîëü äëÿ %s îáíîâëåí.\n",a,b)
#define L013(a) S("NOTICE %s :Íåâåðíûé ïàðîëü!\n",a)
#define L014(a) S("NOTICE %s :Íå ìîãó íàéòè!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Óäàëåí ïîëüçîâàòåëü: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Äåëåíèå íà íîëü!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Íåâåðíàÿ îïåðàöèÿ!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (adding ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Adding ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Îáíîâëåíî #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d çàïèñåé ïðîñìîòðåíî.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Íàéäåíî áîëåå, ÷åì \37%d\37 çàïèñåé, ñóçüòå óñëîâèÿ ïîèñêà\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :ß íàøåë \37îäíó\37 çàïèñü, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :ß íàøåë \37%d\37 çàïèñåé, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Íàéäåíî %ld ïîâòîðÿþùèõñÿ òåì. Óäàëåíû.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Çàïóùåí íà %s. Ó ìåíÿ åñòü %ld òåì â áàçå äàííûõ, Âðåìÿ ðàáîòû: \
%d äíåé%s, %02d:%02d, Áûëî çàäàíî %ld âîïðîñîâ, %ld òåì äîáàâëåíî, è %ld òåì óäàëåíî. \
Âðåìÿ èñïîëíåíèÿ: %1.4lf ñåêóíä%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Çàïóùåí íà %s. Ó ìåíÿ åñòü %ld òåì â áàçå äàííûõ, Âðåìÿ ðàáîòû: \
%d ÷àñîâ%s, %d ìèíóò%s, Áûëî çàäàíî %ld âîïðîñîâ, %ld òåì äîáàâëåíî, è %ld òåì óäàëåíî. \
Âðåìÿ èñïîëíåíèÿ: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Çàïóùåí íà %s. Ó ìåíÿ åñòü %ld òåì â áàçå äàííûõ, Âðåìÿ ðàáîòû: \
%d min%s, %d sec%s, Áûëî çàäàíî %ld âîïðîñîâ, %ld òåì äîáàâëåíî, è %ld òåì óäàëåíî. \
Âðåìÿ èñïîëíåíèÿ: %1.4lf sec%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Óäàëåíà òåìà #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Íå ìîãó íàéòè òåìó %s. Óäàëåíèå íåóäàëîñü.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Óäàëåíà òåìà #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Íå ìîãó íàéòè òåìó %s. Óäàëåíèå íåóäàëîñü.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Ñèíòàêñèñ: \2/msg %s PASS <oldpass> <newpass>\2\n",a,b)
#define L032(a) Snow("QUIT :Ó\2\2áèò (%s (ïîòîìó ÷òî ÿ òàê ñêàçàë!))\n",a)
#define L033(a) S("NOTICE %s :Ñèíòàêñèñ: UP <#chan> <pass>\n",a)
#define L034(a) S("NOTICE %s :Ñèíòàêñèñ: OP <#chan> [nicks] <pass>\n",a)
#define L035(a) S("NOTICE %s :Ñèíòàêñèñ: DEOP <#chan> [nicks] <pass>\n",a)
#define L036(a) S("NOTICE %s :Óêàæè íèê!\n",a)
#define L037(a,b) S("NOTICE %s :Ïûòàþñü /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Ïîïðîáóé /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Ïîêèäàþ %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Ñîåäèíÿþñü ñ %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Óêàæè íèê/êàíàë!\n",a)
#define L042(a) S("NOTICE %s :Ââåäè u@h äëÿ î÷èñòêè!\n",a)
#define L043(a) S("NOTICE %s :Íåò òàêîãî áàíà.\n",a)
#define L044(a) S("NOTICE %s :Ââåäè u@h äëÿ óäàëåíèÿ!\n",a)
#define L045(a) S("NOTICE %s :Êàê íà÷ñåò áîëüøå òàêîãî íå äåëàòü?\n",a)
#define L046(a) S("PRIVMSG %s :Ñîõðàíèëè áàçó äàííûõ.\n",a)
#define L047(a,b) S("NOTICE %s :Ñèíòàêñèñ: %cAUTOTOPIC <topic> (óñòàíîâè â \"0\" ÷òîáû âûêëþ÷èòü)\n",a,b)
#define L048(a) S("NOTICE %s :Ñèíòàêñèñ: SETCHAN <íîâûå êàíàëû>\n",a)
#define L049(a,b) S("NOTICE %s :Êàíàë ïî óìîë÷àíèþ: %s\n",a,b)
#define L050(a) S("NOTICE %s :Ñèíòàêñèñ: SETCHAR <íîâûé êîìàíäíûé ñèìâîë>\n",a)
#define L051(a,b) S("NOTICE %s :Íîâûé êîìàíäíûé ñèìâîë òåïåðü: %c\n",a,b)
#define L052(a) S("NOTICE %s :Ñèíòàêñèñ: SETUSER <íîâûé userid> (òðåáóåòñÿ ðåñòàðò)\n",a)
#define L053(a,b) S("NOTICE %s :userid ïî óìîë÷àíèþ òåïåðü: %s\n",a,b)
#define L054(a) S("NOTICE %s :Ñèíòàêñèñ: SETNICK <íîâûé íèê>\n",a)
#define L055(a) S("NOTICE %s :Ñèíòàêñèñ: ADDUSER <#chan> <*user@*.host> <level> <pass>. ie; ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... use #* if you want to give access in all chans.\n",a)
#define L056(a) sprintf(temp, "I haven't used \2%cSETINFO\2 yet!",a)
#define L057(a,b,c) S("NOTICE %s :Äîáàâëåí ïîëüçîâàòåëü: %s - óðîâåíü %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Ñèíòàêñèñ: %c%s <u@h> [ïðè÷èíà]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Äîáàâëåí ê permban #%d, %s; ïðè÷èíà: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Ñèíòàêñèñ: REPEAT <÷èñëî> <çàäåðæêà> <äàííûå>\n",a)
#define L061(a) S("NOTICE %s :Ãîòîâî.\n",a)
#define L062(a) S("QUIT :Ðåñòàðòóþ %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, ÷òî òû õî÷åøü äîáàâèòü?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, ÷òî òû õî÷åøü äîáàâèòü?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Äîáàâèòü ÷òî, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Êàêîå ïðèâåòñòâèå äîáàâèòü äëÿ %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Ok, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Äîáàâèòü ÷òî, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Êàêîå ïðèâåòñòâèå äîáàâèòü äëÿ %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Ok, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Çàìåíèòü ÷òî, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Êàêàÿ èíôîðìàöèÿ äîëæíà çàìåíèòü %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s îáíîâëåíî.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :%s %d permban%s çàãðóæåíî â ïàìÿòü.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d ñåêóíä îñòàëîñü äî ñëåäóþùåé õîõìû\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: ýòî áûëî äëèííîé %d ñèìâîëîâ.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Ó ìåíÿ ñåé÷àñ %d ïðåäìåòîâ%s â î÷åðåäè.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :ß âèäåë %d ïðèñîåäèíÿåòñÿ ê íàì, ïîêà ÷òî.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :%s %d ñåðâåðîâ%s â ìîåì ñïèñêå. Ñåé÷àñ ÿ íà \
ñåðâåðå #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, ìîé êîìàíäíûé ñèìâîë: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :What should i be %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, Íåîáõîäèìî óêàçàòü àäðåñ!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Íå ìîãó âûÿñíèòü %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: È ÷òî ìíå ñêàçàòü %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Ðàññêàçàòü %s î ÷åì?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Ñêàçàòü êîìó, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: È ÷òî ìíå ñêàçàòü %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Ðàññêàçàòü %s î ÷åì?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Ñêàçàòü êîìó, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 òû ñïðîñèë?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Ïåðåôðàçèðóé? (íàáåðè %cHELP äëÿ ïîìîùè â ñèíòàêñèñå)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 òû ñïðîñèë?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Ïåðåôðàçèðóé? (íàáåðè %cHELP äëÿ ïîìîùè â ñèíòàêñèñå)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s çàìåðç!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION ïðîñíûïàåòñÿ...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Ìåíÿ ôëóäÿò. Î÷èùàþ âûõîäíóþ î÷åðåäü. \
%d çàïèñåé óäàëåíî.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Izveni %s, nu poderjka dla etoy temi bil udalen.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Izveni %s, nu poderjka dla etoy temi bil udalen.\n",a,b);
diff --git a/source/langs/spanish.h b/source/langs/spanish.h
index d622166..69461e0 100644
--- a/source/langs/spanish.h
+++ b/source/langs/spanish.h
@@ -1,119 +1,130 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "I speak Spanish."
#define L001(a,b) S("PRIVMSG %s :No has elegido una contraseña, para poner una \
contraseña: \2/msg %s PASS <oldpass> <newpass>\2 (Como es tu primera \
vez en poner una contraseña, debes usar '0' en la opcion de oldpass)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Permban ha sido borrado #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Error en abrir %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Se encuentan %d VISTOS dentro de mi base de datos.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Tu debes saber mas sobre eso que yo, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Yo no he visto %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic activado %s estaba APAGADO\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic activado %s ahora esta APAGADO\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s ACTIVADO: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPDATED: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, completo. Ahora se encuentan %d randomstuffs [cosas al lazar].\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Contraseña de %s ahora esta updated.\n",a,b)
#define L013(a) S("NOTICE %s :Contraseña incorecta!\n",a)
#define L014(a) S("NOTICE %s :Nada encontrado!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Usuario borrado: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Error de division entre cero!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Operacion Ilegal!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (Adicion de ignore #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :Adicion de ignore #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Updated #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d entradas revisadas.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :He encontrado mas de \37%d\37 entradas, por favor reducir tu \
busqueda\2:\2 %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :He encontrado \37one\37 combinaciones, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :He encontrado \37%d\37 combinaciones, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Encontre %ld topic duplicados. Han sido eliminados.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Ejecutando %s. Yo tengo %ld \
topics en mis base de datos, Uptime: %d dias%s, %02d:%02d, \
Han habido %ld preguntas hechas, %ld adiciones de topic, y %ld topic \
borrados. Tiempo de Proceso: %1.4lf seg%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Ejecutando %s. He encontrado \
%ld topics en mis base de datos, Uptime: %d horas%s, %d min%s, \
Han habido %ld preguntas hechas, %ld topics nuevos, y %ld topics \
borrados. Tiempo de Proceso: %1.4lf seg%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Ejecutando %s. Yo tengo %ld topics en mis \
base de datos, Uptime: %d min%s, %d seg%s, Han habido %ld preguntas hechas, %ld topics nuevos, y %ld topics \
borrados. Tiempo de Proceso: %1.4lf seg%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: He eliminado el topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 No he podido encontrar el topic \37%s\37. Error en \
eliminacion.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: He eliminado el topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 No he podido encontrar el topic \37%s\37. Error en \
eliminacion.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <Vieja-contraseña> <nueva-contraseña>\2\n",a,b)
#define L032(a) Snow("QUIT :K\2\2illed (%s (cause I say so!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#canal> <contaseña>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#canal> [nicks] <contraseña>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#canal> [nicks] <contraseña>\n",a)
#define L036(a) S("NOTICE %s :Favor especificar un nick!\n",a)
#define L037(a,b) S("NOTICE %s :Tratando de /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Favor tratar /nick %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Saliendo %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Entrando %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Favor especificar un nick/canal!\n",a)
#define L042(a) S("NOTICE %s :Entrar al u@h para hacer la eliminacion!\n",a)
#define L043(a) S("NOTICE %s :No se encuenta el ban.\n",a)
#define L044(a) S("NOTICE %s :Entrar al u@h para borrar!\n",a)
#define L045(a) S("NOTICE %s :Que tal no hago eso?\n",a)
#define L046(a) S("PRIVMSG %s :Backup de base de dato completo.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <topic> (Poner en \"0\" para apagar)\n",a,b)
#define L048(a) S("NOTICE %s :Syntax: SETCHAN <nuevos canales>\n",a)
#define L049(a,b) S("NOTICE %s :Canal por defecto: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntax: SETCHAR <nuevo caracter de comando>\n",a)
#define L051(a,b) S("NOTICE %s :Nuevo commando ya: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntax: SETUSER <nuevo userid> (Se requiere un restart)\n",a)
#define L053(a,b) S("NOTICE %s :Userid por defecto: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntax: SETNICK <nuevonick>\n",a)
#define L055(a) S("NOTICE %s :Syntax: ADDUSER <#canal> <*user@*.host> <nival> <contraseña>. ie; ADDUSER \
#darkbot *jason@*.superlink.net 3 Su contraseña ... usar #* Si deseas darle acceso en todo los canales.\n",a)
#define L056(a) sprintf(temp, "No he usado \2%cSETINFO\2 todavia!",a)
#define L057(a,b,c) S("NOTICE %s :Usurario Agregado: %s - Nivel %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntax: %c%s <u@h> [razon]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Agregado en permban #%d, %s; razon: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <numero> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :Listo.\n",a)
#define L062(a) S("QUIT :Re-iniciando %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, que deseas agregar?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, que deseas agregar?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Agregar que, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Que informacion deseas agregada para %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :OK, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Agregar que, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Que informacion deseas agregada para %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :OK, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Cambiar que, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Que informacion debe cambiar %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s ha sido updated.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Se encuentan %s %d permban%s cargados en memoria.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d segundos restante antes de randstuff\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: era de %d caracteres de largo.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, Se encuentran ahora mismo %d itemes%s en el Que.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Yo he visto %d joins hasta el momento.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Hay %s %d servidores%s en mi lista de servidores. Me encuentro en el \
servidor #%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mi caracter de comando es: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :What should i be %sing for, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, Necesitas poner una direcion!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :No logre encontrar %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Que deseas que yo diga %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Decir %s sobre que?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Decirle a quien, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Que deseas que yo diga %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Decir %s sobre que?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Decirle a quien, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 estabas preguntando?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Puedes reformular eso? (Escribir %cHELP para ayuda en \
syntax)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 estabas preguntando?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Puedes reformular eso? (Escribir %cHELP para ayuda en \
syntax)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s estoy drogado!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION se despierta...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Estoy siendo flooded. Vaciando output Que (data que esta esperando \
para ser mandado). %d itemes.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Apesadumbrado %s, pero ayuda para ese asunto se ha quitado.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Apesadumbrado %s, pero ayuda para ese asunto se ha quitado.\n",a,b);
diff --git a/source/langs/swedish.h b/source/langs/swedish.h
index 6cb1e44..f2a11a7 100644
--- a/source/langs/swedish.h
+++ b/source/langs/swedish.h
@@ -1,107 +1,118 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "Jag talar svenska."
#define L001(a,b) S("PRIVMSG %s :Du har inte satt något lösenord, för att sätta ett lösenord: \2/msg %s PASS \ <gammalt lösendord> <nytt lösenord>\2 (Eftersom det här är den första gången du sätter ett lösenord, använd '0' som ditt gamla lösenord)\n",a,b)
#define L002(a,b,c) S("NOTICE %s :Tog bort den permanenta bannlysningen #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :Kan inte öppna %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, Det finns %d SEENs i min databas.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :Du vet mer om det än jag, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, Jag har inte sett %s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :Autotopic på %s var AV\n",a,b)
#define L008(a,b) S("NOTICE %s :Autotopic på %s är nu AV\n",a,b);
#define L009(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s PÅ: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :AUTOTOPIC @ %s UPPDATERAD: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, klart. Det finns nu %d slumpsaker.\n",a,b,c)
#define L012(a,b) S("NOTICE %s :Lösenordet för användare %s är uppdaterat.\n",a,b)
#define L013(a) S("NOTICE %s :Felaktigt lösenord!\n",a)
#define L014(a) S("NOTICE %s :Ingen träff!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :Tog bort användare %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: Division by zero-fel!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: Felaktig handling.\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (ignorerar nu #%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :ignorerar nu #%d: %s!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :Uppdaterade #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. %d söktes igenom.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :Fann mer än \37%d\37 träffar, sök lite mer precist.\2:\2 \ %s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :Jag fann \37en\37 träff, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :Jag fann \37%d\37 träffar, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :Hittade %ld topic-dubbletter. De togs bort.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kör %s. Jag har %ld topics i min databas, en upptid på \ %d dagar, %02d:%02d. Det har frågats %ld frågor, lagts till %ld topics, och tagits bort %ld. \ Processtid: %1.4lf sekunder%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kör %s. Jag har %ld topics i min databas, Upptid: \ %d timmar och %d minuter%s. Det har frågats %ld frågor, lagts till %ld topics och tagits bort %ld. \ Processtid: %1.4lf sekunder%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :Kör %s. Jag har %ld topics i min databas, Upptid: \ %d minuter%s, %d sekunder%s. Det har frågats %ld frågor, lagts till %ld topics och tagits bort %ld. \ Processtid: %1.4lf sekunder%s\n",a,b,c,d,e,f,g,h,i,j,k,l)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: Jag tog bort topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 Jag hittade inte topicen %s. Radering misslyckades.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s: Jag tog bort topic #%ld, \2%s\2.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 Jag hittade inte topicen %s. Radering misslyckades.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :Syntax: \2/msg %s PASS <gammalt lösenord> <nytt lösenord>\2\n",a,b)
#define L032(a) Snow("QUIT :D\2\2ödad (%s (För att jag säger det!))\n",a)
#define L033(a) S("NOTICE %s :Syntax: UP <#kanal> <lösenord>\n",a)
#define L034(a) S("NOTICE %s :Syntax: OP <#kanal> [namn] <lösenord>\n",a)
#define L035(a) S("NOTICE %s :Syntax: DEOP <#kanal> [namn] <lösenord>\n",a)
#define L036(a) S("NOTICE %s :Ange ett namn!\n",a)
#define L037(a,b) S("NOTICE %s :Försöker med /nick %s\n",a,b)
#define L038(a,b) S("NOTICE %s :Försök med /nick %s-pucko.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :Lämnar %s\n",a,b)
#define L040(a,b) S("PRIVMSG %s :Går in i %s\n",a,b)
#define L041(a) S("PRIVMSG %s :Ange ett namn/kanal!\n",a)
#define L042(a) S("NOTICE %s :Skriv den u@h du vill rensa bort. \n",a)
#define L043(a) S("NOTICE %s :Det finns ingen sådan bannlysning.\n",a)
#define L044(a) S("NOTICE %s :Skriv vilken u@h du vill ta bort.\n",a)
#define L045(a) S("NOTICE %s :Hur vore det om jag inte gjorde så?\n",a)
#define L046(a) S("PRIVMSG %s :Sparade databasen.\n",a)
#define L047(a,b) S("NOTICE %s :SYNTAX: %cAUTOTOPIC <topic> (sätt till \"0\" för att stänga av)\n",a,b)
#define L048(a) S("NOTICE %s :Syntax: SETCHAN <nya kanaler>\n",a)
#define L049(a,b) S("NOTICE %s :Default-kanal: %s\n",a,b)
#define L050(a) S("NOTICE %s :Syntax: SETCHAR <nytt kommandotecken>\n",a)
#define L051(a,b) S("NOTICE %s :Nytt kommandotecken: %c\n",a,b)
#define L052(a) S("NOTICE %s :Syntax: SETUSER <ny användarid> (kräver en omstart)\n",a)
#define L053(a,b) S("NOTICE %s :Default-användarid är nu: %s\n",a,b)
#define L054(a) S("NOTICE %s :Syntax: SETNICK <nytt namn>\n",a)
#define L055(a) S("NOTICE %s :Syntax: ADDUSER <#kanal>
< *anv ä ndare @ *.v ä rddator.se > <niv å ><l ö senord >.t.ex;
ADDUSER
#darkbot \ *jason@*.superlink.net 3 hansLösenord ... använd #* om du vill ge tillgång till alla kanaler.\n",a)
#define L056(a) sprintf(temp, "Jag har inte använt \2%cSETINFO\2 ännu!",a)
#define L057(a,b,c) S("NOTICE %s :La till användare: %s - nivå %d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :Syntax: %c%s <u@h> [anledning]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :Lade till i den permanenta bannlysningslistan: #%d, %s; anledning: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :Syntax: REPEAT <nummer> <fördröjning> <rådata>\n",a)
#define L061(a) S("NOTICE %s :Klart.\n",a)
#define L062(a) S("QUIT :Startar om %s ...\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, vad vill du lägga till?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, vad vill du lägga till?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :Lägga till vad, %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: Vilken information ska läggas till för %s?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :Okej, %s :)\n",a,b)
#define L065n(a,b) S("NOTICE %s :Lägga till vad, %s?\n",a,b);
#define L066n(a,b,c) S("NOTICE %s :%s: Vilken information ska läggas till för %s?\n",a,b,c)
#define L067n(a,b) S("NOTICE %s :Okej, %s :)\n",a,b)
#define L068(a,b) S("PRIVMSG %s :Byta ut vad, %s?\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: Vilken information skulle jag byta ut %s?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :%s, %s är uppdaterad.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :Det finns %s %d permanenta bannlysningar%s laddade i ram-minnet.\n",a,b,c,d)
#define L073(a,b,c) S("PRIVMSG %s :%s, %d sekunder kvar till en slumpsak.\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: den var %d tecken lång.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, De finns för närvarande %d saker%s i kö.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :Jag har sett %d folk som kommit hit än så länge.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :Det finns %s %d server%s i min serverlista. Jag är för närvarande på \
server
#%d.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, mitt kommandotecken är: %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :Vad ska jag %sing för, %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, du måste ange en address!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :Kunde inte kolla upp %s.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: Vad vill du att jag ska säga %s?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, Berätta för %s om vad?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :Säga till vem, %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: Vad vill du att jag ska säga %s?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, Berätta för %s om vad?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :Säga till vem, %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 du frågade mig?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? Vill du omformulera det där? (Skriv %cHELP för syntax-tips)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 du frågade mig?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? Vill du omformulera det där? (Skriv %cHELP för syntax-tips)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s är brutalt hög!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION vaknar upp...\1\n",a)
#define L090(a,b) S("PRIVMSG %s :Jag blir floodad. Dumpar kön. \
%d saker togs bort.\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :Tyvärr %s, support för det området har tagits bort.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :Tyvärr %s, support för det området har tagits bort.\n",a,b);
\ No newline at end of file
diff --git a/source/langs/taiwanish.h b/source/langs/taiwanish.h
index 33f252a..063b809 100644
--- a/source/langs/taiwanish.h
+++ b/source/langs/taiwanish.h
@@ -1,114 +1,125 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define I_SPEAK "§Ú»¡¤¤¤å."
#define L001(a,b) S("PRIVMSG %s : §AÁÙ¨S¦³³]¸m±K½X. ­n³]¸m±K½X,½Ð¥´: \2/msg %s PASS \
<±K½X> <·s±K½X>\2 (¦pªG¬O²Ä¤@¦¸³]¸m±K½X,±K½XÀ³¶ñ¬° 0 )\n",a,b)
#define L002(a,b,c) S("NOTICE %s :¤w§¹¦¨§R°£¸T¥Î¥Î¤á #%d, %s.\n",a,b,c)
#define L003(a,b) S("NOTICE %s :µLªk¥´¶} %s :(\n",a,b)
#define L004(a,b,c) S("PRIVMSG %s :%s, ¦b§Úªº²Â¸£³U¥Ê¤¤¦@°O¿ý¤F %d ³o»ò¦hµo¥Í¹Lªº¨Æ.\n",a,b,c)
#define L005(a,b) S("PRIVMSG %s :§A¤w¸gª¾¹D±o¤ñ§Ú¦h¤F, %s.\n",a,b)
#define L006(a,b,c,d) S("PRIVMSG %s :%s, ¹ï¤£°_³á! §Ú¨S¦³¨£¹L%s %s\n",a,b,c,d)
#define L007(a,b) S("NOTICE %s :¦Û°Ê¥DÃD %s ­è¤~¬OÃö³¬ªº\n",a,b)
#define L008(a,b) S("NOTICE %s :¦Û°Ê¥DÃD %s ²{¦bÃö³¬\n",a,b);
#define L009(a,b,c) S("NOTICE %s :¦Û°Ê¥DÃD@ %s ¥´¶}: %s\n",a,b,c)
#define L010(a,b,c) S("NOTICE %s :¦Û°Ê¥DÃD@ %s ¤w§ó·s: %s\n",a,b,c)
#define L011(a,b,c) S("PRIVMSG %s :%s, ÁÂÁ§AÄ@·N±Ð§Ú. §Ú²{¦b¤w¸g¦³ %d ¥y¥i¥HÀH¾÷»¡ªº¸Ü¤F. :=]\n",a,b,c)
#define L012(a,b) S("NOTICE %s :%s ªº±K½X¤w§ó·s¤F.\n",a,b)
#define L013(a) S("NOTICE %s :³á~±K½X¿ù»~³á~ ½Ð¦A¥J²Ó·Q¤@·Q!\n",a)
#define L014(a) S("NOTICE %s :¹ï¤£°_! §Ú§ä¤£¨ì¾A¦X§Aªº¸ê®Æ!\n",a)
#define L015(a,b,c,d) S("NOTICE %s :¥Î¤á¤w§R°£: %s [%d:%d]\n",a,b,c,d)
#define L016(a,b) S("PRIVMSG %s :%s: ³Q¹s°£¿ù»~!\n",a,b)
#define L017(a,b) S("PRIVMSG %s :%s: «Dªk¾Þ§@!\n",a,b)
#define L018(a,b,c,d,e) S("KICK %s %s :%s (¼W¥[¦Û°Ê©¿²¤¥Î¤á#%d: %s)\n",a,b,c,d,e)
#define L019(a,b,c) S("PRIVMSG %s :§Ú¤w¸g§â #%d ªº %s ²¤¹L¤F!\n",a,b,c);
#define L020(a,b,c,d) S("NOTICE %s :§Ú¤w§ó·s #%d: \37[\37%s\37]\37 info\2:\2 %s\n",a,b,c,d)
#define L021(a,b,c,d) S("PRIVMSG %s :%s \37%s\37.. §Ú¦@§ä¤F %d ³o»ò¦hµ§¸ê®Æ.\n",a,b,c,d)
#define L022(a,b,c) S("PRIVMSG %s :§Ú©Òª¾¹Dªº¨Æ¦³¤U¦C³o \37%d\37 ¥ó²Å¦X§Aªº±ø¥ó, ¦p¤U\2:\2 \
%s\n",a,b,c);
#define L023(a,b,c) S("PRIVMSG %s :®¥³ß§A! ¦b§Úªº¸£³U¸Ì¥u¦³¤@¥ó²Å¦X§A±ø¥óªº¨Æ±¡³á, %s\2:\2 %s\n",a,b,c)
#define L024(a,b,c,d) S("PRIVMSG %s :§Ú¤@¦@¦³ \37%d\37 ¥ó§A·Qª¾¹Dªº¨Æ±¡, %s\2:\2 %s\n",a,b,c,d)
#define L025(a,b) S("PRIVMSG %s :¦b§Úªº°O¾Ð¤¤¦@¦³ %ld ±ø­«´_ªº¸ê®Æ,§Ú¤w¸g±N­«´_ªº°ÝÃD§R°£¤F.\n",a,b)
#define L026(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :§Ú¬O¨Ï¥Î %s ·í§Úªº¸£³U¥Ê. §Ú©Òª¾¹Dªº¨Æ¦@¦³ %ld ³o»ò¦h, §Ú¤w¸g¬°¥ÁªA°È¤F \
%d ¤Ñ, %02d:%02d ³o»ò¤[, ¬° %ld ¦ì¦bºô¸ô¤W°g¥¢¤è¦Vªº¤H«üÂI°g¬z, ¦b³o¬q®É¶¡¸Ì, §Úµo²{¤F %ld ¥ó·sÂA¨Æ, ¦P®É¤]§â %ld ¥ó¤£¾A¦X³o®É¥Nªº¨Æ§Ñ±¼. \
¥­§¡°_¨Ó§Ú´À¤@­Ó¤H¦^µª°ÝÃD¥u»Ý­n«ä¦Ò %1.4lf ¬í\n",a,b,c,d,f,g,h,i,j,k)
#define L027(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :§Ú¬O¨Ï¥Î %s ·í§Úªº¸£³U¥Ê. §Ú©Òª¾¹Dªº¨Æ¦@¦³ %ld ³o»ò¦h, §Ú¤w¸g¬°¥ÁªA°È¤F \
%d ¤p®É, %d ¤ÀÄÁ ³o»ò¤[, ¬° %ld ¦ì¦bºô¸ô¤W°g¥¢¤è¦Vªº¤H«üÂI°g¬z, ¦b³o¬q®É¶¡¸Ì, §Úµo²{¤F %ld ¥ó·sÂA¨Æ, ¦P®É¤]§â %ld ¥ó¤£¾A¦X³o®É¥Nªº¨Æ§Ñ±¼. \
¥­§¡°_¨Ó§Ú´À¤@­Ó¤H¦^µª°ÝÃD¥u»Ý­n«ä¦Ò %1.4lf ¬í\n",a,b,c,d,f,h,i,j,k)
#define L028(a,b,c,d,e,f,g,h,i,j,k,l) S("PRIVMSG %s :§Ú¬O¨Ï¥Î %s ·í§Úªº¸£³U¥Ê. §Ú©Òª¾¹Dªº¨Æ¦@¦³ %ld ³o»ò¦h, §Ú¤w¸g¬°¥ÁªA°È¤F \
%d ¤ÀÄÁ, %d ¬í ³o»ò¤[, ¬° %ld ¦ì¦bºô¸ô¤W°g¥¢¤è¦Vªº¤H«üÂI°g¬z, ¦b³o¬q®É¶¡¸Ì, §Úµo²{¤F %ld ¥ó·sÂA¨Æ, ¦P®É¤]§â% ld ¥ó¤£¾A¦X³o®É¥Nªº¨Æ§Ñ±¼. \
¥­§¡°_¨Ó§Ú´À¤@­Ó¤H¦^µª°ÝÃD¥u»Ý­n«ä¦Ò %1.4lf ¬í\n",a,b,c,d,f,h,i,j,k)
#define L029(a,b,c,d) S("PRIVMSG %s :%s: §Ú¤w¸g·Ó§Aªº¸Ü§â¦b§Ú°O¾Ð¤¤ªº²Ä #%ld µ§¥s°µ \2%s\2 ªº¸ê®Æ§R°£¤F.\n",a,b,c,d)
#define L030(a,b,c) S("PRIVMSG %s :%s\2:\2 §Ú¨Ã¤£ª¾¹D¦³ %s ³o¥ó¨Æ°Ú.\n",a,b,c)
#define L029n(a,b,c,d) S("NOTICE %s :%s:§Ú¤w¸g·Ó§Aªº¸Ü§â¦b§Ú°O¾Ð¤¤ªº²Ä#%ldµ§¥s°µ\2%s\2ªº¸ê®Æ§R°£¤F.\n",a,b,c,d)
#define L030n(a,b,c) S("NOTICE %s :%s\2:\2 §Ú¨Ã¤£ª¾¹D¦³ %s ³o¥ó¨Æ°Ú.\n",a,b,c)
#define L031(a,b) S("NOTICE %s :¥Îªk: \2/msg %s PASS <±K½X> <·s±K½X>\2\n",a,b)
#define L032(a) Snow("QUIT :°Ú!§Ú¥X°ÝÃD¤F, §Ú¥D¤H %s ¥¿¦bÀ°§Ú­×²z¤¤..\n",a)
#define L033(a) S("NOTICE %s :¥Îªk: UP <#ÀW¹D> <±K½X>\n",a)
#define L034(a) S("NOTICE %s :¥Îªk: OP <#ÀW¹D> [ÎîºÙ] <±K½X>\n",a)
#define L035(a) S("NOTICE %s :¥Îªk: DEOP <#ÀW¹D> [ÎîºÙ] <±K½X>\n",a)
#define L036(a) S("NOTICE %s :½Ð«ü©w¤@­ÓÎîºÙ!\n",a)
#define L037(a,b) S("NOTICE %s :¸Õ¹Ï /ÎîºÙ %s\n",a,b)
#define L038(a,b) S("NOTICE %s :½Ð¹Á¸Õ /ÎîºÙ %s-dork.\n",a,b)
#define L039(a,b) S("PRIVMSG %s :¶â! °¨¤WÂ÷¶} %s ³o­Ó²á¤Ñ«Ç!\n",a,b)
#define L040(a,b) S("PRIVMSG %s :³á! ¨º§Ú»°§Ö¶i¥h %s ²á¤Ñ«Ç¸Ì­±!\n",a,b)
#define L041(a) S("PRIVMSG %s :§A­n¹ï½Ö©Î¬O¨º¶¡²á¤Ñ«Ç»¡°Ú?\n",a)
#define L042(a) S("NOTICE %s :¿é¤J­n§R°£ªºu@h!\n",a)
#define L043(a) S("NOTICE %s :¨S§ä¨ì§A»¡ªº¸T¥Î¥Î¤á.\n",a)
#define L044(a) S("NOTICE %s :¿é¤J­n§R°£ªºu@h!\n",a)
#define L045(a) S("NOTICE %s :¤£¨º»ò°µ¦æ¤£¦æ?\n",a)
#define L046(a) S("PRIVMSG %s :µ¥µ¥, §Ú¥ý±N§Úª¾¹Dªº¨Æµ¹¼g¤U¨Ó.\n",a)
#define L047(a,b) S("NOTICE %s :¥Îªk: %cAUTOTOPIC <¥DÃD> (³]¸m¬°\"0\"ªí¥Ü²MªÅ¥DÃD)\n",a,b)
#define L048(a) S("NOTICE %s :¥Îªk: SETCHAN <·sÀW¹D>\n",a)
#define L049(a,b) S("NOTICE %s :·s³]©wÀW¹D: %s\n",a,b)
#define L050(a) S("NOTICE %s :¥Îªk: SETCHAR <·sªº©R¥O²Å>\n",a)
#define L051(a,b) S("NOTICE %s :²{¦bªº©R¥O²Å¬O: %c\n",a,b)
#define L052(a) S("NOTICE %s :¥Îªk: SETUSER <·sªº¥Î¤áID> (»Ý­n­«·s±Ò°Ê¾÷¾¹¤H)\n",a)
#define L053(a,b) S("NOTICE %s :²{¦bªº¯Ê¬Ù¥Î¤áID¬O: %s\n",a,b)
#define L054(a) S("NOTICE %s :¥Îªk: SETNICK <·sªºÎîºÙ>\n",a)
#define L055(a) S("NOTICE %s :¥Îªk: ADDUSER <#ÀW¹D> <*user@*.host> <¯Å§O> <±K½X>. ¨Ò¦p, ADDUSER #darkbot \
*jason@*.superlink.net 3 hisPasswd ... ¨Ï¥Î#*±N¨Ï¸Ó¥Î¤áªºÅv­­¾A¥Î¤_©Ò¦³ªºÀW¹D.\n",a)
#define L056(a) sprintf(temp, "§AÁÙ¨S¦³¥Î\2%cSETINFO\2 ³]¸mÅwªï«H®§!",a)
#define L057(a,b,c) S("NOTICE %s :¥Î¤á¤w²K¥[: %s - ¯Å§O%d\n",a,b,c)
#define L058(a,b,c) S("NOTICE %s :¥Îªk: %c%s <u@h> [²z¥Ñ]\n",a,b,c)
#define L059(a,b,c,d) S("NOTICE %s :¥[¤J¸T¥Î¥Î¤á¦Cªí#%d, %s; ²z¥Ñ: %s\n",a,b,c,d)
#define L060(a) S("NOTICE %s :¥Îªk: REPEAT <number> <delay> <raw-data>\n",a)
#define L061(a) S("NOTICE %s :¤w§¹¦¨.\n",a)
#define L062(a) S("QUIT :§Ú­«·s³s½u¤@¤U... %s\n",a);
#define L064(a,b) S("PRIVMSG %s :%s, §A·Q±Ð§Ú¬Æ»ò¨Æ±¡°Ú?\n",a,b)
#define L064n(a,b) S("NOTICE %s :%s, §A·Q±Ð§Ú¬Æ»ò¨Æ±¡°Ú?\n",a,b)
#define L065(a,b) S("PRIVMSG %s :§A·Q±Ð§Ú¬Æ»ò¤H¥Íªº¤j¹D²z¶Ü? %s?\n",a,b);
#define L065n(a,b) S("NOTICE %s :§A·Q±Ð§Ú¬Æ»ò¤H¥Íªº¤j¹D²z¶Ü? %s?\n",a,b);
#define L066(a,b,c) S("PRIVMSG %s :%s: §A·Q´À %s ³]©w¬Æ»ò¸ê®Æ°Ú?\n",a,b,c)
#define L066n(a,b,c) S("NOTICE %s :%s: §A·Q´À %s ³]©w¬Æ»ò¸ê®Æ°Ú?\n",a,b,c)
#define L067(a,b) S("PRIVMSG %s :ÁÂÁ %s ±Ð§Ú, §Ú¤S¦hÁA¸Ñ¤F¤@¥ó¨Æ¤F! :=]\n",a,b)
#define Lbadtopic(a,b) S("PRIVMSG %s :%s ¹ï¤£°_³á, §Ú¦³¤ä´©ªº¼ÐÃD¤w¸g³Q§R°£¤F.\n",a,b);
#define Lbadtopic2(a,b) S("NOTICE %s :%s ¹ï¤£°_³á, §Ú¦³¤ä´©ªº¼ÐÃD¤w¸g³Q§R°£¤F.\n",a,b);
#define L067n(a,b) S("NOTICE %s :ÁÂÁ %s ±Ð§Ú, §Ú¤S¦hÁA¸Ñ¤F¤@¥ó¨Æ¤F! :=]\n",a,b)
#define L068(a,b) S("PRIVMSG %s :§A·QªÈ¥¿¨º­Ó°ÝÃDªºµª®×©O? %s.\n",a,b)
#define L069(a,b,c) S("PRIVMSG %s :%s: §A·Q±N %s ³o­Ó°ÝÃD´«¦¨¬Æ»òµª®×?\n",a,b,c)
#define L070(a,b,c) S("PRIVMSG %s :ÁÂÁ %s ªÈ¥¿§Ú %s ³o­Óµª®×ªº¿ù»~.\n",a,b,c)
#define L071(a,b,c,d) S("PRIVMSG %s :¦b§Úªº¦L¶H¤¤¦@¦³ %d ­Ó¤H§Ú¤£·Q¸ò¥L­Ì»¡¸Ü.\n",a,c,c,c)
#define L073(a,b,c) S("PRIVMSG %s :%s, ¦A¹L %d ¬í§Ú´N­n­J¨¥¶Ã»y¤F.\n",a,b,c)
#define L074(a,b,c) S("PRIVMSG %s :%s: ³o¥y¸ÜÁ`¦@¦³ %d ­Ó¦ì¤¸²Õ.\n",a,b,c)
#define L075(a,b,c,d) S("PRIVMSG %s :%s, ²{¦b¦@¦³ %d ªº°O¿ýµ¥§Ú³B²z %s.\n",a,b,c,d)
#define L076(a,b) S("PRIVMSG %s :±q§Ú¶i¨Ó¨ì²{¦b, §ÚÁ`¦@¬Ý¨ì %d ­Ó¤H¶i¤J³o²á¤Ñ«Ç.\n",a,b)
#define L077(a,b,c,d,e) S("PRIVMSG %s :§ÚÁ`¦@¥i¥H¥h %s %d ­Ó²á¤Ñºô¯¸%s. §Ú²{¦b¥¿¦b\
²Ä #%d ­Ó²á¤Ñºô¯¸.\n",a,b,c,d,e)
#define L078(a,b,c) S("PRIVMSG %s :%s, ±±¨î§Úªº«ü¥O¬O %c\n",a,b,c)
#define L079(a,b,c) S("PRIVMSG %s :%s ¬Æ»ò°Ú? %s?\n",a,b,c)
#define L080(a,b) S("PRIVMSG %s :%s, §A±o«ü©w¤@­Ó¦a§}µ¹§Ú°Ú!\n",a,b)
#define L081(a,b) S("PRIVMSG %s :§Ú¨S¦³¿ìªk§ä¨ì %s ªº¸ê®Æ³á.\n",a,b)
#define L083(a,b,c) S("PRIVMSG %s :%s: §A­n§Ú§i¶D %s ¬Æ»ò¨Æ°Ú?\n",a,b,c)
#define L084(a,b,c) S("PRIVMSG %s :%s, §A­n§Ú§i¶D %s ¬Æ»ò¨Æ°Ú?\n",a,b,c)
#define L085(a,b) S("PRIVMSG %s :§A·Q­n§i¶D½Ö°Ú? %s?\n",a,b)
#define L083n(a,b,c) S("NOTICE %s :%s: §A·QÅý§Ú§i¶D %s ¬Æ»ò?\n",a,b,c)
#define L084n(a,b,c) S("NOTICE %s :%s, §A­nÅý§Ú§i¶D %s ¬Æ¨Æ°Ú?\n",a,b,c)
#define L085n(a,b) S("NOTICE %s :§A­nÅý§Ú§i¶D½Ö? %s?\n",a,b)
#define L086(a,b) S("PRIVMSG %s :%s\2:\2 §A¦b°Ý§Ú°ÝÃD¶Ü?\n",a,b)
#define L087(a,b,c,d,e) S("PRIVMSG %s :%s %s %s? ½Ð­«·s¿é¤J©R¥O(¥´ %cHELP Åý§Ú±Ð§A«ç»ò¨Ï¥Î\
hints)\n",a,b,c,d,e)
#define L086n(a,b) S("NOTICE %s :%s\2:\2 §A¦b°Ý¶Ü?\n",a,b)
#define L087n(a,b,c,d,e) S("NOTICE %s :%s %s %s? ½Ð­«·s¿é¤J©R¥O(¥´ %cHELP Åý§Ú±Ð§A«ç»ò¨Ï¥Î\
hints)\n",a,b,c,d,e)
#define L088(a) S("QUIT :%s §Ú¤w¸g¾K¨ì¨S¿ìªk¦AÀ°§A­Ì¸Ñµª¤F!\n",a)
#define L089(a) S("PRIVMSG %s :\1ACTION §Ú´_¬¡¤F!!!!\1\n",a)
#define L090(a,b) S("PRIVMSG %s :½Ö¦b¤@ª½±Ð§Ú¤@¨Ç¨S¥ÎªºªF¦è \
§Ú¤w¸g§â %d¥ó¨S¥Îªº¨Æ§R°£¤F.\n",a,b)
diff --git a/source/main.c b/source/main.c
index 58d730a..bdd14d7 100644
--- a/source/main.c
+++ b/source/main.c
@@ -1,214 +1,230 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* 6/23/00 Dan:
* - Moved declaration of newact into #ifdef
*/
int
main (int argc, char **argv)
{
char temp[STRING_SHORT] = { 0 };
char exe[STRING_SHORT] = { 0 };
struct timeval timeout;
int ret, i = 0;
fd_set fdvar;
struct stat st;
#ifdef SA_NOCLDSTOP
struct sigaction newact;
#endif
#ifdef DEBUG
DebuG = 1;
#endif
get_s ();
srand (time (0));
uptime = time (NULL);
strncpy (DARKBOT_BIN, argv[0], sizeof (DARKBOT_BIN));
strncpy (exe, argv[0], sizeof (exe)); /* Coz basename() may modify it's argument. */
#ifdef DATABASEDIR
strncpy (DAT_DIR, DATABASEDIR, sizeof (DAT_DIR));
#else
strncpy (DAT_DIR, "dat", sizeof (DAT_DIR));
#endif
#ifdef SOURCEDIR
/* Check if this is being run from the build directory before being installed. */
snprintf(temp, sizeof(temp), "%s/dat/setup.ini", SOURCEDIR);
if (stat(temp, &st) >= 0)
{
snprintf(temp, sizeof(temp), "%s/dat", SOURCEDIR);
strncpy(DAT_DIR, temp, sizeof (DAT_DIR));
}
#endif
/* Parse the command line arguements, if there are any. */
if (argv[1] != NULL)
{
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
if (argv[i][1] == 'S')
{
SeeN = true;
}
else if (argv[i][1] == 'D')
{
DebuG = 1;
}
else if (argv[i][1] == 'I')
{
strcpy (DAT_DIR, argv[++i]);
printf ("DAT_DIR: Using %s.\n", DAT_DIR);
}
else
{
printf ("\n\n%s HELP:\n\n", dbVersion);
printf ("%s (Launches Darkbot to IRC)\n", argv[0]);
printf ("%s -SEEN (Enables SEEN [Even if SEEN is undefined])\n", argv[0]);
printf ("%s -DEBUG (Launch in debug mode)\n", argv[0]);
exit (0);
}
}
}
}
if (SeeN)
{
printf ("\nSEEN ENABLED.\n");
}
if (DebuG == 1)
{
printf ("\nDEBUG ENABLED.\n");
}
set_paths ();
/* This is the best way to deternmine if sigaction() can be used.
* sigaction() is more portable than signal(), so use it if we can. */
#ifdef SA_NOCLDSTOP
newact.sa_handler = sig_alrm;
sigemptyset (&newact.sa_mask);
newact.sa_flags = 0;
sigaction (SIGALRM, &newact, NULL);
newact.sa_handler = sig_segv;
sigemptyset (&newact.sa_mask);
newact.sa_flags = 0;
sigaction (SIGSEGV, &newact, NULL);
newact.sa_handler = sig_hup;
sigemptyset (&newact.sa_mask);
newact.sa_flags = 0;
sigaction (SIGHUP, &newact, NULL);
#else
signal (SIGALRM, sig_alrm);
signal (SIGSEGV, sig_segv);
signal (SIGHUP, sig_hup);
#endif
#ifdef ENABLE_RANDOM
get_rand_stuff_time ();
#endif
printf ("\n\n\n");
- printf (" * * * * * * * * Darkbot (c) 1996 v8 Release Candidate 4 * * * * * * * * * \n");
+ printf (" * * * * * * * * * * Darkbot v8 Release Candidate 4 * * * * * * * * * * * \n");
printf (" * The IRC Talking Robot * \n");
- printf (" * * \n");
+ printf (" * * \n");
printf (" * Creator/Author : Jason <jason@superlink.net> * \n");
printf (" * Project Administrator: LuizCB <LuizCB@users.sourceforge.net> * \n");
printf (" * Lead Devekloper : onefang <onefang@users.sourceforge.net> * \n");
- printf (" * Please check docs/contributors for a list of collaborators * \n");
+ printf (" * Please check docs/AUTHORS for a list of collaborators * \n");
printf (" * * \n");
printf (" * Eventual malfunction, suggestions or patches use only * \n");
printf (" * Darkbot official site @ http:/darkbot.sourceforge.net * \n");
printf (" * * \n");
- printf (" * By running this installation you agree that this program is provided * \n");
- printf (" * free for non-commercial use only; - Distribution of modified source * \n");
- printf (" * code or binaries compiled from modified source code for any platform * \n");
- printf (" * or OS is expressly forbidden. - This program is only available at * \n");
+ printf (" * Copyright (C) 1996 Darkbot Project. * \n");
+ printf (" * * \n");
+ printf (" *This program is free software, you can redistribute it and/or modify it* \n");
+ printf (" *under the terms of the GNU General Public License version 2. This * \n");
+ printf (" *program is distributed in the hope that it will be useful, but without * \n");
+ printf (" *any warranty, without even the implied warranty of merchantability or * \n");
+ printf (" *fitness for a particular purpose. See the COPYING file for details. * \n");
+ printf (" * * \n");
+ printf (" * This program is only available at - * \n");
printf (" * http://darkbot.sourceforge.net * \n");
printf (" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n");
#ifndef WIN32
# ifdef ENABLE_VERSION_CHECK
snprintf (temp, sizeof (temp), "lynx -source http://darkbot.sourceforge.net/cgi/laun.cgi?%s &", dbVersion);
ret = system (temp);
# endif
db_sleep (2);
if (SORT)
{
printf ("Sorting database...\n");
snprintf (temp, sizeof (temp), "sort %s -o %s\n", URL2, URL2);
ret = system (temp);
}
#endif
load_helpers ();
#ifdef ENABLE_STATS
load_stats ();
#endif
check_files ();
raw_now ("SERVERS");
raw_now ("SETUP");
raw_now ("PERMBAN");
alarm (AIL);
prepare_bot ();
register_bot ();
while (1)
{
timeout.tv_sec = WSEC;
timeout.tv_usec = USEC;
FD_ZERO (&fdvar);
FD_SET (socketfd, &fdvar);
switch (select (NFDBITS, &fdvar, (fd_set *) NULL, (fd_set *) NULL, &timeout))
{
case 0:
break;
case -1:
if (!alarmed)
{
db_sleep (RECHECK);
}
else
alarmed = 0;
break;
default:
parse_server_msg (&fdvar);
break;
}
}
}
void set_paths (void)
{
int ret;
snprintf (DBTIMERS_PATH, sizeof (DBTIMERS_PATH), "%s/%s", DAT_DIR, DEFAULT_DBTIMERS_PATH);
ret = mkdir(DBTIMERS_PATH, S_IRWXU);
snprintf (LOG_DIR, sizeof (LOG_DIR), "%s/%s", DAT_DIR, DEFAULT_LOG_DIR);
ret = mkdir(LOG_DIR, S_IRWXU);
snprintf (RDB_DIR, sizeof (RDB_DIR), "%s/%s", DAT_DIR, DEFAULT_RDB_DIR);
ret = mkdir(RDB_DIR, S_IRWXU);
#ifdef ENABLE_STATS
snprintf (STATS_FILE, sizeof (STATS_FILE), "%s/%s", DAT_DIR, DEFAULT_STATS_FILE);
#endif
snprintf (SEEN_FILE, sizeof (SEEN_FILE), "%s/%s", DAT_DIR, DEFAULT_SEEN_FILE);
snprintf (URL2, sizeof (URL2), "%s/%s", DAT_DIR, DEFAULT_URL2);
snprintf (BACKUP_DUP, sizeof (BACKUP_DUP), "%s/%s", DAT_DIR, DEFAULT_BACKUP_DUP);
snprintf (AUTOTOPIC_F, sizeof (AUTOTOPIC_F), "%s/%s", DAT_DIR, DEFAULT_AUTOTOPIC_F);
snprintf (HELPER_LIST, sizeof (HELPER_LIST), "%s/%s", DAT_DIR, DEFAULT_HELPER_LIST);
snprintf (QUIZ_FILE, sizeof (QUIZ_FILE), "%s/%s", DAT_DIR, DEFAULT_QUIZ_FILE);
snprintf (PERFORM, sizeof (PERFORM), "%s/%s", DAT_DIR, DEFAULT_PERFORM);
snprintf (DEOP, sizeof (DEOP), "%s/%s", DAT_DIR, DEFAULT_DEOP);
snprintf (RAND_SAY, sizeof (RAND_SAY), "%s/%s", DAT_DIR, DEFAULT_RAND_SAY);
snprintf (RAND_FILE, sizeof (RAND_FILE), "%s/%s", DAT_DIR, DEFAULT_RAND_FILE);
snprintf (RANDQ_TEMPFILE, sizeof (RANDQ_TEMPFILE), "%s/%s", DAT_DIR, DEFAULT_RANDQ_TEMPFILE);
snprintf (RAND_BACKUP_FILE, sizeof (RAND_BACKUP_FILE), "%s/%s", DAT_DIR, DEFAULT_RAND_BACKUP_FILE);
snprintf (SERVERS, sizeof (SERVERS), "%s/%s", DAT_DIR, DEFAULT_SERVERS);
snprintf (PERMBAN, sizeof (PERMBAN), "%s/%s", DAT_DIR, DEFAULT_PERMBAN);
snprintf (SETUP, sizeof (SETUP), "%s/%s", DAT_DIR, DEFAULT_SETUP);
}
diff --git a/source/parse.c b/source/parse.c
index e351691..15fdc34 100644
--- a/source/parse.c
+++ b/source/parse.c
@@ -1,510 +1,521 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* TODO: No function should ever be this long...move to the Command Pattern
*/
void
parse (char *line)
{
char *s = NULL, *s1 = NULL, *s2 = NULL, *s3 = NULL, *s4 = NULL, *cmd = NULL, *ptr = NULL;
long TOG = 0, seen_value = 0;
LastInput = 0;
if (DebuG == 1)
printf ("IN: %s", line);
#ifdef DEBUG2
db_log ("darkbot_debug.log", "IN: %s", line);
#endif
stripline (line);
s = strtok (line, " ");
if (strcasecmp (s, "PING") == 0)
{
s1 = strtok (NULL, " ");
Snow ("PONG %s\n", s1);
}
else if (strcasecmp (s, "ERROR") == 0)
{
s1 = strtok (NULL, "");
if (s1 != NULL)
{
if (strstr (s1, "Excess Flood") != NULL)
{
prepare_bot ();
register_bot ();
}
else if (strstr (s1, "throttled") != NULL)
{
prepare_bot ();
register_bot ();
}
else if (strstr (s1, "oo many c") != NULL)
{
prepare_bot ();
register_bot ();
}
else if (strstr (s1, "o more c") != NULL)
{
prepare_bot ();
register_bot ();
}
else
{
S ("QUIT :Caught ERROR from %s :(\n", BS);
db_sleep (5);
prepare_bot ();
register_bot ();
}
}
}
else if (strstr (s, "!") == NULL)
{ /* From Server */
cmd = strtok (NULL, " ");
if (strcasecmp (cmd, "004") == 0)
{ /* Connected! */
save_changes ();
s2 = strtok (NULL, " "); /* Copy the current nick */
strncpy (Mynick, s2, sizeof (Mynick));
snprintf (NICK_COMMA, sizeof (NICK_COMMA), "%s,", Mynick);
snprintf (COLON_NICK, sizeof (COLON_NICK), "%s:", Mynick);
snprintf (BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", Mynick);
s2 = strtok (NULL, " "); /* Got server name */
}
else if (strcasecmp (cmd, "315") == 0)
{
if (DISPLAY_SYNC)
{
s2 = strtok (NULL, " "); /*mynick */
strncpy (Mynick, s2, sizeof (Mynick));
s2 = strtok (NULL, " "); /* chan */
S ("PRIVMSG %s :Sync with %s completed.\n", s2, s2);
}
}
else if (strcasecmp (cmd, "311") == 0)
{
s1 = strtok (NULL, " ");
s1 = strtok (NULL, " ");
s1 = strtok (NULL, " ");
s1 = strtok (NULL, " ");
strncpy (g_host, s1, sizeof (g_host));
}
else if (strcasecmp (cmd, "319") == 0)
{
s1 = strtok (NULL, " ");
s1 = strtok (NULL, " ");
s2 = strtok (NULL, "");
if (*s2 == ':')
s2++;
strlwr (s2);
if (strstr (s2, "arez") != NULL)
TOG = 1;
if (strstr (s2, "kidd") != NULL)
TOG = 1;
if (strstr (s2, "hack") != NULL)
TOG = 1;
if (strstr (s2, "sex") != NULL)
TOG = 1;
if (strstr (s2, "fuck") != NULL)
TOG = 1;
if (strstr (s2, "porn") != NULL)
TOG = 1;
if (strstr (s2, "pic") != NULL)
TOG = 1;
if (TOG == 1)
{
S ("NOTICE @%s :%s is on \2%s\2\n", g_chan, s1, s2);
return;
}
}
else if (strcasecmp (cmd, "432") == 0 || strcasecmp (cmd, "468") == 0)
{ /* Invalid nick/user */
// TODO - Should send this to the user requesting the nick change.
s2 = strtok (NULL, "");
printf ("Server reported error %s\n", s2);
}
else if ((strcasecmp (cmd, "376") == 0) || (strcasecmp(cmd, "422") == 0))
{
/* Set default umodes */
S ("MODE %s %s\n", Mynick, DEFAULT_UMODE);
run_perform (); /* Run performs */
S ("JOIN %s\n", CHAN);
}
else if (strcasecmp (cmd, "482") == 0)
{
#ifdef ENABLE_CHANNEL
if (BITCH_ABOUT_DEOP)
{
s2 = strtok (NULL, " "); /* mynick */
strncpy (Mynick, s2, sizeof (Mynick));
s2 = strtok (NULL, " "); /* chan */
/* We used to run the DEOP.INI here */
}
#endif
}
else if (strcasecmp (cmd, "352") == 0)
{
s2 = strtok (NULL, "");
parse_who (s2);
#ifdef ENABLE_STATUS
}
else if (strcasecmp (cmd, "252") == 0)
{
s2 = strtok (NULL, "");
parse_252 (s2);
}
else if (strcasecmp (cmd, "404") == 0
|| strcasecmp (cmd, "475") == 0
|| strcasecmp (cmd, "474") == 0 || strcasecmp (cmd, "473") == 0)
{ /* Can't join? */
s2 = strtok (NULL, " ");
s2 = strtok (NULL, " ");
db_sleep (5);
S ("JOIN %s\n", s2);
}
else if (strcasecmp (cmd, "251") == 0)
{
s2 = strtok (NULL, "");
parse_251 (s2);
}
else if (strcasecmp (cmd, "255") == 0)
{
s2 = strtok (NULL, "");
parse_255 (s2);
#endif
}
else if (strcasecmp (cmd, "433") == 0)
{
s2 = strtok (NULL, " ");
if (*s2 != '*')
{
// TODO - I dunno about these ones, so log them for now. Probably should go through process_nick().
#ifdef DEBUG2
db_log ("darkbot_debug.log", " 433 *: %s -> %s\n", Mynick, s2);
#endif
strncpy (Mynick, s2, sizeof (Mynick));
snprintf (NICK_COMMA, sizeof (NICK_COMMA), "%s,", Mynick);
snprintf (COLON_NICK, sizeof (COLON_NICK), "%s:", Mynick);
snprintf (BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", Mynick);
s3 = strtok (NULL, " ");
}
else
{
#ifdef DEBUG2
db_log ("darkbot_debug.log", " 433: %s\n", Mynick);
#endif
Snow ("NICK %s%d\n", Mynick, xtried);
xtried++;
if (xtried > 15)
Snow ("NICK _`^%s%d\n", Mynick, xtried);
if (xtried > 5)
Snow ("NICK _%s%d\n", Mynick, xtried);
}
}
}
else
{ /* Info from user */
if (*s == ':') /* Remove the colon prefix */
s++;
cmd = strtok (NULL, " "); /* Read in command */
if (strcasecmp (cmd, "NOTICE") == 0)
{
#ifdef ENABLE_CHANNEL
s2 = strtok (NULL, " "); /* target */
if ((KICK_ON_CHANNEL_NOTICE) && (*s2 == '#'))
{
s3 = strtok (s, "!");
if (BAN_ON_CHANNEL_NOTICE)
{
if (BAN_BY_HOST)
{
s4 = strtok (NULL, "@");
s4 = strtok (NULL, "");
S ("MODE %s +b *!*@%s\n", s2, s4);
}
else /* ban just by u@h */
S ("MODE %s +b *%s\n", s2, strtok (NULL, ""));
}
S ("KICK %s %s :Punt\n", s2, s3);
}
#endif
}
else if (strcasecmp (cmd, "PRIVMSG") == 0)
{ /* PRIVMSG */
s1 = strtok (NULL, " "); /* Target */
s2 = strtok (NULL, ""); /* Rest */
if ((LOG_PRIVMSG) && (*s1 != '#') && (*s1 != '&'))
{
db_log (privmsg_log, "[%s] %s %s %s\n", date (), s, s1, s2);
}
if (*s1 == '#' || *s1 == '&' || *s1 == '+')
if (do_lastcomm (s, s1, s2) == 1)
return;
chanserv (s, s1, s2); /* Process PRIVMSG commands */
}
else if (strcasecmp (cmd, "KILL") == 0)
{
s1 = strtok (NULL, " "); /* Kill nick */
if (strcasecmp (s1, Mynick) == 0)
{
do_quit (s1, 3); /* delete all users from ram since I'm gone */
prepare_bot ();
register_bot ();
}
}
else if (strcasecmp (cmd, "KICK") == 0)
{
s1 = strtok (NULL, " "); /* #chan */
s2 = strtok (NULL, " "); /* Who got kicked? */
if (strcasecmp (s2, Mynick) == 0)
{ /* Rejoin if I was
* kicked */
do_quit (s1, 2);
db_sleep (5);
S ("JOIN %s\n", s1);
S ("PRIVMSG %s :%s\n", s1, COMPLAIN_REASON);
}
else
delete_user (s2, s1);
}
else if (strcasecmp (cmd, "INVITE") == 0)
{
s1 = strtok (NULL, " "); /* Mynick */
s2 = strtok (NULL, " "); /* Target */
if (*s2 == ':')
s2++;
if (strcasecmp (s2, CHAN) == 0)
S ("JOIN %s\n", s2);
}
else if (strcasecmp (cmd, "PART") == 0)
{
if ((ptr = strchr (s, '!')) != NULL)
*ptr++ = '\0';
// Channel
s1 = strtok (NULL, " ");
// Make sure the first character in the target operative is not a :.
if (*s1 == ':')
s1++;
/*
* If we are parting the channel, remove all users in that channel from
* memory. If someone else is parting, only remove them from memory.
*/
if (strcasecmp (s, Mynick) != 0)
delete_user (s, s1);
else
do_quit (s1, 2);
}
else if (strcasecmp (cmd, "QUIT") == 0)
{
if ((ptr = strchr (s, '!')) != NULL)
*ptr++ = '\0';
do_quit (s, 1);
}
else if (strcasecmp (cmd, "MODE") == 0)
{
do_modes (s, strtok (NULL, ""));
}
else if (strcasecmp (cmd, "NICK") == 0)
{
if ((ptr = strchr (s, '!')) != NULL)
*ptr++ = '\0';
s1 = strtok (NULL, " ");
process_nick (s, s1);
}
else if (strcasecmp (cmd, "JOIN") == 0)
{
JOINs++;
s1 = strtok (NULL, " "); /* TARGET */
if (*s1 == ':')
s1++;
if ((ptr = strchr (s, '!')) != NULL)
*ptr++ = '\0';
strlwr (ptr);
if ((SeeN) && (*s1 == '#'))
seen_value = save_seen (s, ptr, s1);
if (strcasecmp (s, Mynick) != 0)
{
if (check_permban (ptr, s1, s) == 1)
return;
add_user (s1, s, ptr, 1);
if ((AUTOHELP_GUESTS) && (strstr(s, "Guest") != NULL))
S ("PRIVMSG %s :hello %s. need any help?\n", s);
if (DO_WHOIS)
{
strncpy (g_chan, s1, sizeof (g_chan));
S ("WHOIS %s\n", s);
}
if (check_access (ptr, s1, 0, s) >= 4)
{
S ("MODE %s +o %s\n", s1, s);
}
else if (check_access (ptr, s1, 1, s) >= 1)
{
#ifdef ENABLE_CHANNEL
if (VOICE_USERS_ON_JOIN)
S ("MODE %s +v %s\n", s1, s);
#endif
}
else if ((HELP_GREET) && (check_access(ptr, s1, 0, s) >= 1))
{
return; /* don't greet if the guy has
* access (and no setinfo) */
}
else if ((HELP_GREET) && (strcasecmp(s1, CHAN) == 0))
{
if (SeeN)
{
if (seen_value == 0) /* don't show people the
* notice every join */
if (setinfo_lastcomm (s1) == 0) /* don't do it if you just did it! */
L102 (s, s1, s, *CMDCHAR);
}
else
{
if (setinfo_lastcomm (s1) == 0)
L102 (s, s1, s, *CMDCHAR);
}
}
}
else
S ("WHO %s\n", s1); /* Check who is in the
* chan */
} /* JOIN */
}
}
void
parse_who (char *data)
{
char *chan = NULL, *nick = NULL, *ptr = NULL, *flags = NULL, b[STRING_SHORT] = { 0 };
nick = strtok (data, " "); /* botnick */
strncpy (Mynick, nick, sizeof (Mynick));
chan = strtok (NULL, " ");
ptr = strtok (NULL, " ");
snprintf (b, sizeof (b), "%s@%s", ptr, strtok (NULL, " "));
nick = strtok (NULL, " "); /* server */
nick = strtok (NULL, " ");
flags = strtok (NULL, " ");
add_user (chan, nick, b, 1);
if (strstr (flags, "@") != NULL)
do_op(nick, chan, 1);
}
#ifdef ENABLE_STATUS
void
parse_252 (char *s)
{
char *tmp = NULL;
int numb = 0;
tmp = strtok (s, " ");
tmp = strtok (NULL, " ");
sscanf (tmp, "%d", &numb);
IRCOPS = numb;
}
void
parse_251 (char *s)
{
char *tmp = NULL;
int numb = 0, r = 0, i = 0;
/*- Read and chuck useless data from line 'b' -*/
tmp = strtok (s, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
sscanf (tmp, "%d", &r);
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
sscanf (tmp, "%d", &i);
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
sscanf (tmp, "%d", &numb);
NUM_SERV = numb;
G_USERS = r + i;
}
void
parse_255 (char *s)
{
char *tmp = NULL, Stat[1] = { 0 };
int numb = 0, pre_CLIENTS = 0;
/* test321 :I have 1313 clients and 1 servers */
strlwr (s);
tmp = strtok (s, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
tmp = strtok (NULL, " ");
numb = atoi (tmp);
pre_CLIENTS = L_CLIENTS;
L_CLIENTS = numb;
if (L_CLIENTS < pre_CLIENTS)
{
strncpy (Stat, "-", sizeof (Stat));
pre_CLIENTS = pre_CLIENTS - L_CLIENTS;
}
else
{
strncpy (Stat, "+", sizeof (Stat));
pre_CLIENTS = L_CLIENTS - pre_CLIENTS;
}
snprintf (tmp, sizeof (tmp), "%3.2f", (float) (((float) L_CLIENTS / (float) G_USERS) * 100));
/* FIXME: I don't see PLAY defined anywhere, is it left over from something else? */
#if PLAY == 1
#define PBOT "ArchFiend"
if (pre_CLIENTS == 0 || pre_CLIENTS == L_CLIENTS)
{
S ("PRIVMSG %s :!SENDQ %d srvs, %d ops, %d users (%s%% of %d, %ld avg)\n", PBOT, NUM_SERV,
IRCOPS, L_CLIENTS, tmp, G_USERS, G_USERS / NUM_SERV);
}
else
S ("PRIVMSG %s :!SENDQ %d srvs, %d ops, %d users [%c%2d] (%s%% of %d, %ld avg)\37\n", PBOT,
NUM_SERV, IRCOPS, L_CLIENTS, Stat[0], pre_CLIENTS, tmp, G_USERS, G_USERS / NUM_SERV);
db_log (".ubcount", "%d\n%d\n0\n0\n", L_CLIENTS, L_CLIENTS);
rename (".ubcount", "/usr/local/apache/htdocs/usage/userbase/userbase.dat");
db_log (".glcount", "%d\n%d\n0\n0\n", G_USERS, G_USERS);
rename (".glcount", "/usr/local/apache/htdocs/usage/global/global.dat");
#else
if (pre_CLIENTS == 0 || pre_CLIENTS == L_CLIENTS)
{
S ("PRIVMSG %s :\1ACTION \37(\37%2d servers\37)\37: %2d opers + \2%4d\2 users \37(\37%s%% %5d global \2!\2 %3ld avg\37)\37\1\n", CHAN, NUM_SERV, IRCOPS, L_CLIENTS, tmp, G_USERS, NUM_SERV ? (G_USERS / NUM_SERV) : 0);
}
else
S ("PRIVMSG %s :\1ACTION \37(\37%2d servers\37)\37: %2d opers + \2%4d\2 users [\37%c%2d\37] \37(\37%s%% %5d global \2!\2 %3ld avg\37)\37\1\n", CHAN, NUM_SERV, IRCOPS, L_CLIENTS, Stat[0], pre_CLIENTS, tmp, G_USERS, NUM_SERV ? (G_USERS / NUM_SERV) : 0);
#endif
}
#endif
void
parse_server_msg (fd_set * read_fds)
{
if (FD_ISSET (socketfd, read_fds))
{
if (readln () > 0)
{
NUMLINESSEEN++;
parse (L);
}
else
{
close (socketfd);
}
}
}
diff --git a/source/permbans.c b/source/permbans.c
index 66837c1..931feda 100644
--- a/source/permbans.c
+++ b/source/permbans.c
@@ -1,192 +1,203 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Add a permban to the permban list.
* 6/23/00 Dan:
* - Both pointer variables are now received as pointer to const data
* - Changed counter to type size_t, this should be an unsigned type
* - Initialiazed n to 0 on declaration
* - Added support for dynamically allocated uh and reason fields
* in the struct permban list
* - Did some extra memory leak prevention
*/
void
add_permban (const char *uh, size_t counter, const char *reason)
{
struct permbanlist *n = 0;
n = malloc (sizeof (struct permbanlist));
if (n == NULL)
{
db_log ("error.log", "AHHH! no ram left! in add_permban!\n");
return;
}
memset (n, 0, sizeof (struct permbanlist));
n->uh = strndup (uh, STRING_SHORT);
if (NULL == n->uh)
{
db_log ("error.log", "add_permban> Memory allocation failure\n");
/* Prevent memory leaks */
free (n);
return;
}
n->reason = strndup (reason, STRING_SHORT);
if (NULL == n->reason)
{
db_log ("error.log", "add_permban> Memory allocation failure\n");
/* Prevent memory leaks */
free (n->uh);
free (n);
return;
}
strlwr (n->uh);
n->counter = counter;
PERMBAN_counter++;
n->next = permbanhead;
permbanhead = n;
}
/**
* Check if a permban exists for a given uh/channel/nick set.
* 6/23/00 Dan:
* - Changed all method arguments to be pointers to const data
* - Return type is now bool, returns true if ban is found,
* false otherwise
*/
bool
check_permban (const char *uh, const char *chan, const char *nick)
{
char tmpBuf[STRING_SHORT + 1] = { 0 };
struct permbanlist *c = permbanhead;
size_t len = 0;
len = MIN(STRING_SHORT, strlen(uh));
strncpy (tmpBuf, uh, len);
tmpBuf[len] = '\0';
strlwr (tmpBuf);
for (; c != NULL; c = c->next)
{
if (!match_wild (c->uh, tmpBuf) == 0)
{
c->counter++;
S ("MODE %s +b %s\n", chan, c->uh);
S ("KICK %s %s :\2[\2%d\2]\2: %s\n", chan, nick, c->counter, c->reason);
return true;
}
}
return false;
}
#ifdef ENABLE_CHANNEL
/**
* Remove a permban based on nickname and user@host.
* 6/23/00 Dan:
* - Both arguments are now pointers to const data
* - Added free() for both pNode->uh and pNode->reason now
* that the permbanlist has dynamically allocated fields
* - Changed type of toggle from long to bool
* - Changed name of toggle variable to (foundBan)
* - permbanlist pointers are now initialized when declared
* - Added if statement at end of method, this will only save
* the bans if a ban was removed
*/
int
del_permban (const char *nick, const char *uh)
{
bool foundBan = false;
struct permbanlist *pNode = permbanhead, *pPrev = 0;
int i = 0;
while (pNode)
{
if (strcasecmp (pNode->uh, uh) == 0)
{
L002 (nick, PERMBAN_counter, uh);
PERMBAN_counter--;
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
permbanhead = pNode->next;
}
free (pNode->uh);
free (pNode->reason);
free (pNode);
foundBan = true;
pNode = NULL;
break;
}
pPrev = pNode;
pNode = pNode->next;
}
if (foundBan)
{
/* Only need to save bans if ban list has changed */
save_permbans ();
}
return foundBan;
}
/**
* Save the permban list to file.
* 6/23/00 Dan:
* - the permbanlist pointer (c) is now pointer to const, because
* this is a read only method, and that is a read only variable
* - Initialized c when it is declared
*/
void
save_permbans (void)
{
const struct permbanlist *c = permbanhead;
remove (TMP_FILE);
printf ("*** Writing permbans: %s (%s)\n", PERMBAN, date ());
for (; c != NULL; c = c->next)
{
db_log (TMP_FILE, "%s %d %s\n", c->uh, c->counter, c->reason);
}
rename (TMP_FILE, PERMBAN);
if (PERMBAN_counter == 0)
remove (PERMBAN);
}
#endif
/**
* 6/22 Dan
* - c is now a pointer to const, this is a read only method
* - Changed type of x to size_t, this variable should be unsigned.
* - Changed while loop to for loop.
*/
struct chanserv_output *show_banlist (const char *nick)
{
struct chanserv_output *result = NULL;
size_t i = 0, x = 0;
const struct permbanlist *c = 0;
// TODO - the original used NOTICE. Don't think the current output stuff supports forcing NOTICE, but it should.
for (c = permbanhead; c != NULL; c = c->next)
{
++x;
result = chanserv_asprintf(result, "%s:%u ", c->uh, (unsigned int) c->counter);
}
result = chanserv_asprintf(result, "End of PERMBAN list, %d ban%s found.", x, (x == 1) ? "" : "s");
return result;
}
diff --git a/source/prototypes.h b/source/prototypes.h
index a58df1b..8bc07a9 100644
--- a/source/prototypes.h
+++ b/source/prototypes.h
@@ -1,178 +1,189 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
/* ------------ Below are function declarations --------------- */
#ifdef ENABLE_STATUS
void parse_252 (char *),
parse_251 (char *),
parse_255 (char *);
#endif
char **tokenize (char *, size_t *);
size_t count_lines (char *);
void count_seen (char *, char *);
struct chanserv_output *show_seen (char *, char *, char *);
struct chanserv_output *show_info2 (const char *, const char *, enum chanserv_invoke_type);
long save_seen (char *, char *, char *);
void do_randomtopic (int, char *, char *, char *, char *);
int get_random_integer (int max);
#ifdef ENABLE_RANDOM
void do_random_stuff (void),
check_idle_channels (void),
get_rand_stuff_time (void),
del_autotopic (const char *),
add_randomstuff (char *, char *, char *),
do_autotopics (void);
#endif
#ifdef ENABLE_RANDQ
struct chanserv_output *do_randq (char *, const int, const char *, const char *);
#endif
struct chanserv_output *display_url (char *, char *, char *);
void datasearch (const char *, char *, char *),
set_pass (char *, char *, char *, char *),
do_modes (char *, char *),
process_nick (char *, char *);
long verify_pass (char *, char *, char *, char *),
ifexist_autotopic (char *);
#ifdef ENABLE_CHANNEL
void save_permbans (void);
#endif
void do_quit (const char *, long);
#ifdef ENABLE_MATH
struct chanserv_output *do_math (const char *, char *, char *);
#endif
void parse_who (char *);
void set_autotopic (char *, char *, char *);
void delete_user_ram (char *, char *),
get_s (void),
delete_url (const char *, char *, char *),
update_setinfo (const char *, const char *, const char *);
#ifdef ENABLE_CHANNEL
void add_permban (const char *, size_t, const char *);
int del_permban (const char *, const char *);
#endif
int check_existing_url (const char *, char *, char *);
void *check_nick_parameter (struct setup_parameter *parameter, char *ptr);
struct chanserv_output *show_helper_list (struct chanserv_output *output, const char *, long);
void set_paths (void),
chanserv (char *, char *, char *),
raw_now (char *),
find_url (const char *, char *, char *),
save_changes (void);
struct chanserv_output *show_url (char *, char *, char *, long, long, char *, long);
struct chanserv_output *show_banlist (const char *);
char *strlwr (char *),
*rand_reply (const char *),
*date (void),
*get_multiword_topic (char *),
*revert_topic (char *),
*get_rand_nick (const char *),
*get_word (long, char *, char *);
void info (const char *, char *),
load_helpers (void),
scan_chan_users (char *, char *, char *),
do_login (char *, char *);
long do_lastcomm (char *, char *, char *),
setinfo_lastcomm (char *);
void parse (char *),
add_helper (const char *, const char *, long, size_t,
const char *, const char *, char);
int get_connection (const char *, const char *, int),
readln (void),
writeln (const char *);
bool check_permban (const char *, const char *, const char *);
long cf (char *, char *, char *),
f_f (char *),
get_passwd (char *);
time_t return_useridle (const char *, const char *, int);
void a_f (char *),
reset_ (void),
delete_user (const char *, char *),
add_user (char *, char *, char *, long);
void set_fds (void),
sig_hup (int),
sig_segv (int),
save_setup (void);
void stripline (char *),
init_bot (void),
sig_alrm (int);
void parse_server_msg (fd_set *);
void trailing_blanks (char *),
db_log (const char *, const char *,...),
gs26 (void),
add_s25 (char *, long, char *),
add_banned_server (char *, char *),
S (const char *,...),
del_sendq (long),
clear_sendq (long, long);
char L[524],
*random_word (char **),
*plural (size_t);
int socketfd,
alarmed,
check_access (char *, char *, int, char *),
match_wild (const char *, const char *),
Send (void),
get_sendq_count (long);
void check_dbtimers (void);
void register_bot (void);
void prepare_bot (void);
int create_connection (char *, char *, long);
int Snow (const char *, ...);
struct chanserv_output *show_chaninfo (const char *, const char *, const char *);
struct chanserv_output *show_chanusers (const char *, const char *);
const char *run_program (const char *);
void do_autotopics (void);
#ifdef ENABLE_STATS
void add_stats (char *, char *, long, long, long);
void load_stats (void);
struct chanserv_output *get_stats (char *, char *);
#endif
#ifdef ENABLE_QUIZ
struct chanserv_output *run_quiz_question (char *);
void run_quiz_answer (void);
#endif
void check_files (void);
void run_perform (void);
struct chanserv_output *web_post_query (char *trigger, char *source, char *uh, char *target, char *query, int size);
int add_ignore_user_ram (char *);
int delete_ignore_user_ram (char *);
int check_ignore_user_ram (char *);
int check_exempt (char *);
void call_reserved_1 (char *, char *, char *);
void call_reserved_2 (char *, char *, char *);
size_t count_char (const char *, const char);
bool isBoolean (char *aBoolean);
void db_sleep (unsigned long seconds);
void reverse (char *);
char *mask_from_nick (char *, const char *);
char *uh_from_nick (char *, const char *);
int db_argstostr (char *, char **, size_t, char);
long is_op (char *, const char *);
void do_op (char *, const char *, long);
struct setup_parameter *set_parameter (char *input);
struct chanserv_output *chanserv_asprintf(struct chanserv_output *output, const char *format, ...);
diff --git a/source/quiz.c b/source/quiz.c
index 5eb9794..606c76c 100644
--- a/source/quiz.c
+++ b/source/quiz.c
@@ -1,109 +1,120 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#ifdef ENABLE_QUIZ
struct chanserv_output *run_quiz_question (char *target)
{
struct chanserv_output *result = NULL;
FILE *fp;
int i = 0;
int j = 0;
int k = 0;
int size = 0;
static int pos = 0;
char b[STRING_LONG] = { 0 };
char *ptr = NULL;
if (quiz_timer > 0)
return; /* timer already running */
if ((fp = fopen (QUIZ_FILE, "r")) == NULL)
return;
while (fgets (b, sizeof (b), fp))
{
i++; /* count questions */
}
fseek (fp, 0L, SEEK_SET);
j = get_random_integer(i);
size = sizeof (recent_questions) / sizeof (recent_questions[0]);
if (i < size)
size = i / 2;
while (k <= size)
{
if (j == recent_questions[k])
{
j = get_random_integer(i);
k = 0;
continue;
}
k++;
}
if (pos == size)
pos = 0;
recent_questions[pos] = j;
quiz_line = j;
pos++;
i = 0;
while (fgets (b, sizeof (b), fp))
{
if (i == quiz_line)
break;
i++;
}
if ((ptr = strtok (b, "@")) == NULL)
{
fclose (fp);
return;
}
result = chanserv_asprintf(result, ptr);
strncpy (quiz_target, target, sizeof (quiz_target));
quiz_answer = 1; /* switch on timer */
fclose (fp);
}
void
run_quiz_answer (void)
{
FILE *fp;
int i = 0;
char b[STRING_LONG] = { 0 };
char *ptr = NULL;
if ((fp = fopen (QUIZ_FILE, "r")) == NULL)
return;
while (fgets (b, sizeof (b), fp))
{
if (i == quiz_line)
break;
i++;
}
if ((ptr = strtok (b, "@")) == NULL)
{
fclose (fp);
return;
}
if ((ptr = strtok (NULL, "")) == NULL)
{
fclose (fp);
return;
}
S ("PRIVMSG %s :%s\n", quiz_target, ptr);
fclose (fp);
return result;
}
#endif
diff --git a/source/random.c b/source/random.c
index 6623f9e..ab451d0 100644
--- a/source/random.c
+++ b/source/random.c
@@ -1,664 +1,675 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
int get_random_integer(int max)
{
int result;
result = ((float) max) * (rand() / (RAND_MAX + 1.0));
if (result >= max) // Paranoid check.
result = max - 1;
return result;
}
#ifdef ENABLE_RANDOM
void add_randomstuff (char *source, char *target, char *data)
{
char *ptr = NULL;
char file [STRING_LONG] = {0};
size_t nLines = 0;
int ret, toggle = 1;
//#ifndef WIN32
if (BACKUP_RANDOMSTUFF)
{
// Backup randomstuff file to a temporary file.
unlink(RAND_BACKUP_FILE);
snprintf(file, sizeof(file), "cp %s %s\n", RAND_FILE, RAND_BACKUP_FILE);
ret = system(file);
}
//#endif
if(*data == '~')
{
data++;
ptr = strtok(data, " ");
if(ptr != NULL)
strlwr(ptr);
if(strspn(ptr, LEGAL_TEXT) != strlen(ptr))
{
S("privmsg %s :%s, rdb files must be made up of letters and or numbers, no other text is accepted.\n",
target, source);
return;
}
snprintf(file, sizeof(file), "%s/%s.rdb", RDB_DIR, ptr);
data = strtok(NULL, "");
toggle = 0;
}
else
{
snprintf(file, sizeof(file), "%s", RAND_FILE);
nRandStuffs++;
}
db_log(file, "%s\n", data);
nLines = count_lines(file);
L011(target, source, nLines);
}
void get_rand_stuff_time (void)
{
Rand_Stuff = 2 + get_random_integer(RAND_STUFF_TIME);
if (Rand_Stuff < RAND_STUFF_TIME / 2)
Rand_Stuff = RAND_STUFF_TIME;
}
void do_random_stuff (void)
{
FILE *fp = 0;
size_t nLine = 0, nLength = 0, nIndex = 0;
int nIsAction = 0;
char temp [STRING_SHORT] = {0};
char szBuffer [STRING_LONG] = {0};
char *b2 = NULL;
// Count the randomstuffs.
if ((nRandStuffs = count_lines(RAND_FILE)) < 1)
return;
// Get a random line number to display.
nLine = 1 + (size_t) get_random_integer(nRandStuffs);
// If nLine is less than 1, nLine becomes equal to 1
if(nLine < 1)
nLine = 1;
// Complain if we can't open the randomstuff file.
if((fp = fopen(RAND_FILE, "r")) == NULL)
{
S("privmsg %s :Unable to open %s for reading in do_random_stuff()\n",
CHAN, RAND_FILE);
return;
}
while(fgets(szBuffer, STRING_LONG, fp))
{
// Ignore lines that start with a /, treat as comments.
if((*szBuffer != '/') && (*szBuffer != '\n'))
nIndex++;
else
continue;
stripline(szBuffer);
if(nIndex == nLine)
{
nLength = strlen(szBuffer);
nIndex = 0;
memset(data, 0, sizeof(data));
nIsAction = (*szBuffer == '+' ? 1 : 0);
while(nLength > 0)
{
nIndex++;
nLength--;
// Parse data for channel name variable. replace accordingly.
if(szBuffer[nLength] == '~')
snprintf(temp, sizeof(temp), "%s%s", CHAN, data);
else
snprintf(temp, sizeof(temp), "%c%s", szBuffer[nLength], data);
strncpy(data, temp, sizeof(data));
}
// Make sure the file is closed!
fclose (fp);
if(nIsAction == 1)
{
b2 = data;
b2++;
S("privmsg %s :\1ACTION %s\1\n", CHAN, b2);
return;
}
else
{
S("privmsg %s :%s\n", CHAN, data);
return;
}
}
}
fclose(fp);
}
#endif
void do_randomtopic (int type, char *target, char *file, char *nick, char *topic)
{
FILE *fp = 0;
char file2 [FILENAME_MAX] = {0};
char szBuffer2 [STRING_LONG] = {0};
char Data [STRING_LONG] = {0};
char temp [STRING_LONG] = {0};
char crm1 [STRING_LONG] = {0};
char crm2 [STRING_LONG] = {0};
char bFirst = 1;
char *pBuffer = NULL, *ptr = NULL, *pDefault = NULL;
size_t nLength = 0, nRandTopics = 0, nLine = 0,
nIndex = 0;
int toggle = 0, nType = 0, F = 0;
// This ends up being the response, if we're doing a dunno, or whut reply, and the file
// containing the random responses can't be opened.
pDefault = (type == DUNNOR ? DUNNO_Q : WHUT);
if(file != NULL)
snprintf(file2, sizeof(file2), "%s/%s.rdb", RDB_DIR, file);
if ((nRandTopics = count_lines(file2)) < 1)
{
S("privmsg %s :Sorry, I cannot answer that topic because "
"darkbot random text file (rdb) \"%s\" has no lines in it.\n",
target, file2);
return;
}
if ((fp = fopen(file2, "r")) == NULL)
{
// If this is a dunno, or whut response, instead we say our default reply.
if (type == NORMALR)
{
S("privmsg %s :Sorry, I cannot answer that topic because "
"darkbot random text file (rdb) \"%s\" was not found.\n",
target, file2);
}
else
{
S ("privmsg %s :%s\n", target, pDefault);
}
return;
}
/* db_sleep(1) */
// Get line number that we are searching for in the file.
nLine = 1 + (size_t) get_random_integer(nRandTopics);
while(fgets(szBuffer2, STRING_LONG, fp))
{
if((*szBuffer2 != '/') && (*szBuffer2 != '\n'))
nIndex++;
else
continue;
stripline(szBuffer2);
// This is our line!
if(nIndex == nLine)
{
nIndex = 0;
pBuffer = szBuffer2;
/* if ((*pBuffer == '+') || (*pBuffer == '-'))
{
pBuffer++;
nType = ((*pBuffer == '+') ? RDB_ACTION : RDB_RAW);
}
else
nType = RDB_NORMAL;
*/
if (*pBuffer == '+')
{
pBuffer++;
nType = RDB_ACTION;
}
else if (*pBuffer == '-')
{
pBuffer++;
nType = RDB_RAW;
}
else
{
nType = RDB_NORMAL;
}
nLength = (size_t) strlen(pBuffer);
while(nLength > 0)
{
nLength--;
if (toggle == 1)
{
toggle = 0;
// Support for tokens
if (pBuffer[nLength] == '1' || pBuffer[nLength] == '2' || pBuffer[nLength] == '3' ||
pBuffer[nLength] == '4' || pBuffer[nLength] == '5' || pBuffer[nLength] == '6' ||
pBuffer[nLength] == '7' || pBuffer[nLength] == '8' || pBuffer[nLength] == '9')
{
/* The first time around, we just store the topic in a "safe place" */
if (bFirst == 1)
{
strncpy (crm1, topic, sizeof(crm1));
bFirst = 0;
}
/* Each time around, get a new copy from the "safe place". */
strncpy (crm2, crm1, sizeof(crm2));
snprintf (temp, sizeof(temp), "%s%s", get_word (pBuffer[nLength], crm2, "+"), Data);
}
else if(pBuffer[nLength] == 'N')
{ // nick
snprintf(temp, sizeof(temp), "%s%s", nick, Data);
}
else if ((pBuffer[nLength] == 'H') && (*target == '#'))
{ /* u@h of user */
snprintf (temp, sizeof (temp), "%s%s", mask_from_nick (nick, target), Data);
}
else if ((pBuffer[nLength] == 'C') && (*target == '#'))
{ // channel or nick.
snprintf(temp, sizeof(temp), "%s%s", target, Data);
}
else if (pBuffer[nLength] == 'T')
{ // time
snprintf(temp, sizeof(temp), "%s%s", date(), Data);
}
else if (pBuffer[nLength] == 't')
{ /* unixtime */
snprintf (temp, sizeof (temp), "%ld%s", (long) time (NULL), Data);
}
else if ((pBuffer[nLength] == 'R') && (*target == '#'))
{ // Random nick (not if this is not a channel
snprintf(temp, sizeof(temp), "%s%s",
get_rand_nick(target), Data);
}
else if (pBuffer[nLength] == 'S')
{ // Server
snprintf(temp, sizeof(temp), "%s%s", BS, Data);
}
else if (pBuffer[nLength] == 'P')
{ // Port
snprintf(temp, sizeof(temp), "%d%s", (int) BP, Data);
}
else if(pBuffer[nLength] == 'Q')
{ // Question
snprintf(temp, sizeof(temp), "%s%s", revert_topic(topic), Data);
}
else if(pBuffer[nLength] == 'W')
{ // WWW page
snprintf(temp, sizeof(temp), "http://darkbot.sourceforge.net%s", Data);
}
else if(pBuffer[nLength] == '!')
{ // cmdchar
snprintf(temp, sizeof(temp), "%c%s", *CMDCHAR, Data);
}
else if(pBuffer[nLength] == 'V')
{ // Version
snprintf(temp, sizeof(temp), "%s%s", dbVersion, Data);
}
else if(pBuffer[nLength] == 'B')
{ // Mynick
snprintf(temp, sizeof(temp), "%s%s", Mynick, Data);
}
else
{
snprintf(temp, sizeof(temp), "%c~%s", pBuffer[nLength], Data);
}
}
else if(pBuffer[nLength] == '~')
{
toggle = 1;
}
else
{
snprintf(temp, sizeof(temp), "%c%s", pBuffer[nLength], Data);
}
strncpy(Data, temp, sizeof(Data));
}
switch (nType)
{
case RDB_ACTION:
S ("privmsg %s :\1ACTION %s\1\n", target, Data);
break;
case RDB_NORMAL:
S ("privmsg %s :%s\n", target, Data);
break;
case RDB_RAW:
ptr = strtok (Data, "|");
while (ptr != NULL)
{
if (ptr[0] == ' ')
ptr++;
if (ptr[0] == 'B' && ptr[1] == 'A' && ptr[2] == 'N')
{ // Ban the user, if the target is a channel.
if (*target == '#')
S ("mode %s +b *%s\n", target, mask_from_nick (nick, target));
else
S ("privmsg %s :Sorry, %s, I can't respond to that topic in private.\n",
target, nick);
}
if (ptr[0] == 'T' && ptr[1] == 'E' && ptr[2] == 'M' && ptr[3] == 'P' &&
ptr[4] == 'B' && ptr[5] == 'A' && ptr[6] == 'N')
{ // Ban user for 60 seconds, if the target is a channel.
if (*target == '#')
{
S ("mode %s +b *%s\n", target, mask_from_nick (nick, target));
snprintf (temp, sizeof (temp), "%s/%ld", DBTIMERS_PATH, (long) time (NULL) + 60);
db_log (temp, "MODE %s -b *%s\n", target, mask_from_nick (nick, target));
}
else
S ("privmsg %s :Sorry, %s, I can't respond to that topic in private.\n",
target, nick);
}
ptr[0] = tolower (ptr[0]);
ptr[1] = tolower (ptr[1]);
if (ptr[0] == 'p' && ptr[1] == 'r')
F = 1;
if (ptr[0] == 'k' && ptr[1] == 'i')
F = 1;
if (ptr[0] == 'n' && ptr[1] == 'o')
F = 1;
if (ptr[0] == 't' && ptr[1] == 'o')
F = 1;
if (F == 1)
{
S ("%s\n", ptr);
F = 0;
}
ptr = strtok (NULL, "|");
}
break;
} // End switch.
fclose (fp);
return;
}
}
fclose(fp);
}
/**
* 05/27/02 Ron
* - Recoded this function, random.ini no longer needs a number
* at the top.
* 6/22/00 Dan
* - Function argument is now pointer to const
* - Fixed a problem where the file was never closed
* - All variables are now initialized when declared
* - Removed an unused variable
* - Changed long variables to type size_t, they should be
* unsigned
* - Changed reinitialization of data
* - Moved the big if/else structure to a switch
*/
char *rand_reply (const char *nick)
{
FILE *fp = 0;
char temp [STRING_SHORT] = {0};
size_t nIndex = 0, nRandTopics = 0, nLine = 0,
nLength = 0;
// Count how many lines are in the RAND_SAY file, if can't be
// counted, just return.
if((nRandTopics = count_lines(RAND_SAY)) < 1)
return(0);
// set nLine to be a random number between 1 and nRandTopics.
nLine = 1 + (size_t) get_random_integer(nRandTopics);
// If the RAND_SAY file can't be opened, just return.
if((fp = fopen(RAND_SAY, "r")) == NULL)
return(0);
while(fgets(r_reply, STRING_SHORT, fp))
{
// Ignore comments
if((*r_reply != '/' ) && (*r_reply != '\n'))
nIndex++;
else
continue;
stripline(r_reply);
if(nIndex != nLine)
continue;
else
{
// This is our line.
fclose(fp);
nLength = (size_t) strlen(r_reply);
nIndex = 0;
data[0] = 0;
while(nLength > 0)
{
nIndex++;
nLength--;
switch(r_reply[nLength])
{
case '^':
snprintf(temp, sizeof(temp), "%s%s", nick, data);
break;
case '%':
snprintf(temp, sizeof(temp), "\2%s", data);
break;
case '&':
snprintf(temp, sizeof(temp), "\37%s", data);
break;
case '~':
snprintf(temp, sizeof(temp), "\26%s", data);
break;
default:
snprintf(temp, sizeof(temp), "%c%s", r_reply[nLength], data);
break;
}
strncpy(data, temp, sizeof(data));
}
// Return our fully parsed line.
return(data);
}
}
// Unable to find a match
fclose(fp);
// A space is returned to prevent crashing
return(" ");
}
#ifdef ENABLE_RANDQ
/*
* do_randq():
*
* Types = RANDQ_NORMAL, RANDQ_CASE, RANDQ_RAND
*/
struct chanserv_output *do_randq(char *text, const int type, const char *target, const char *nick)
{
struct chanserv_output *result = NULL;
FILE *fp = 0;
size_t nLine = 0, length = 0, nNumMatches = 0,
nIndex2 = 0, nIndex3 = 0;
int nIsAction = 0;
char *b2 = NULL;
char temp [STRING_SHORT] = { 0 };
char szBuffer[STRING_LONG] = { 0 };
/*
* Check for RANDQ_RAND, and just do_random_stuff() if it's specified.
*/
if (type == RANDQ_RAND)
{
do_random_stuff ();
return result;
}
if (text == NULL)
{
if(((nNumMatches = count_lines(RAND_FILE)) == -1) || (nNumMatches == 0))
return chanserv_asprintf(NULL, "There are no randomstuffs, or %s cannot be accessed.", RAND_FILE);
result = chanserv_asprintf(result, "there %s %d randomstuff%s",
nNumMatches == 1 ? "is" : "are",
nNumMatches,
nNumMatches == 1 ? "." : "s."
);
return result;
}
/* Remove the temporary file. */
remove(RANDQ_TEMPFILE);
if((fp = fopen(RAND_FILE, "r")) == NULL)
return chanserv_asprintf(result, "I was unable to open %s for reading.", RAND_FILE);
while(!feof(fp))
{
while(fgets(szBuffer, STRING_LONG, fp))
{
if(*szBuffer == '/')
continue;
stripline(szBuffer);
/*
* If type is specified as being case sensitive, use strstr,
* otherwise, use strcasestr
*/
if (type == RANDQ_CASE)
{
if (strstr(szBuffer, text))
{
nNumMatches++;
db_log(RANDQ_TEMPFILE, "%s\n", szBuffer);
}
}
else /* if (type == RANDQ_NORMAL) */
{
if (strcasestr(szBuffer, text) != 0)
{
nNumMatches++;
db_log(RANDQ_TEMPFILE, "%s\n", szBuffer);
}
}
}
}
// Close randomstuff file.
fclose(fp);
// If no matches are present, return that.
if(nNumMatches == 0)
return chanserv_asprintf(result, "I didn't find any matches for your search.");
nLine = 1 + (size_t) get_random_integer(nNumMatches);
// If we can't open the temporary file, complain about it.
if((fp = fopen(RANDQ_TEMPFILE, "r")) == 0)
return chanserv_asprintf(result, "I was unable to open %s for reading.", RANDQ_TEMPFILE);
while(!feof(fp))
{
while(fgets(szBuffer, STRING_LONG, fp))
{
if((*szBuffer != '/' ) || (*szBuffer != '\n'))
nIndex2++;
else
continue;
stripline(szBuffer);
// This is the line we have chosen.
if(nIndex2 == nLine)
{
// Check if this is an action.
nIsAction = (*szBuffer == '+' ? 1 : 0);
length = strlen(szBuffer);
nIndex3 = 0;
memset(data, 0, sizeof(data));
while(length > 0)
{
nIndex3++;
length--;
if(szBuffer[length] == '~')
{
// Replace occurance of this char with chan name
snprintf(temp, sizeof(temp), "%s%s", target, data);
}
else
{
snprintf(temp, sizeof(temp), "%c%s", szBuffer[length], data);
}
strncpy(data, temp, sizeof(data));
}
// Make sure the file is closed.
fclose (fp);
if(nIsAction == 1)
{
b2 = data;
b2++;
return chanserv_asprintf(result, "\1ACTION %s (%d/%d)\1\n", b2, nLine, nNumMatches);
}
else
return chanserv_asprintf(result, "(%d/%d): %s\n", nLine, nNumMatches, data);
}
}
}
fclose(fp);
return result;
}
#endif
diff --git a/source/raw.c b/source/raw.c
index 4e2fca4..bfd3fd4 100644
--- a/source/raw.c
+++ b/source/raw.c
@@ -1,220 +1,231 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
void
check_files (void)
{
FILE *fp;
if ((fp = fopen (PERFORM, "r")) == NULL)
{
if ((fp = fopen (PERFORM, "w")) == NULL)
{
printf ("Can't read/write %s! Exiting ...\n", PERFORM);
exit (EXIT_FAILURE);
}
else
fclose (fp);
}
if ((fp = fopen (URL2, "r")) == NULL)
{
if ((fp = fopen (URL2, "w")) == NULL)
{
printf ("Can't read/write %s! Exiting ...\n", URL2);
exit (EXIT_FAILURE);
}
else
fclose (fp);
}
fclose(fp);
}
void *check_nick_parameter(struct setup_parameter *parameter, char *ptr)
{
if (strspn (ptr, LEGAL_NICK_TEXT) != strlen (ptr))
{
printf("The nickname %s contains illegal characters.", ptr);
return NULL;
}
strncpy (s_Mynick, ptr, sizeof (s_Mynick));
snprintf(NICK_COMMA, sizeof (NICK_COMMA), "%s,", s_Mynick);
snprintf(COLON_NICK, sizeof (COLON_NICK), "%s:", s_Mynick);
snprintf(BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", s_Mynick);
S("NICK %s\n", s_Mynick);
if(LOG_PRIVMSG)
snprintf (privmsg_log, sizeof (privmsg_log), "%s%s-privmsg.log", LOG_DIR, s_Mynick);
return ptr;
}
/**
* 6/23/00 Dan:
* - Initialized all variables
*/
void
raw_now (char *type)
{
FILE *fp = NULL;
long i = 0, counter = 0;
char str[STRING_LONG] = { 0 }, *dat = NULL, *ptr = NULL, *tmp1 =
NULL, *tmp2 = NULL, *tmp3 = NULL;
if (strcasecmp (type, "PERMBAN") == 0)
if ((fp = fopen (PERMBAN, "r")) == NULL)
return;
if (strcasecmp (type, "DEOP") == 0)
if ((fp = fopen (DEOP, "r")) == NULL)
return;
if (strcasecmp (type, "SERVERS") == 0)
if ((fp = fopen (SERVERS, "r")) == NULL)
{
printf ("%s not found. You must create the file with format:\n", SERVERS);
printf ("server port ...this list can be as long as you want.\n");
exit (0);
}
if (strcasecmp (type, "SETUP") == 0)
if ((fp = fopen (SETUP, "r")) == NULL)
{
printf ("Unable to locate %s! You must run configure!.\n", SETUP);
exit (0);
}
while (!feof (fp))
{
if (strcasecmp (type, "SETUP") == 0)
{
SeeN = true;
while (fgets (str, STRING_LONG, fp))
{
stripline (str);
set_parameter(str);
}
}
else if (strcasecmp (type, "PERMBAN") == 0)
{
while (fgets (str, STRING_LONG, fp))
{
stripline (str);
/* Allow comments */
if (*str == '#')
continue;
tmp1 = strtok (str, " ");
if (tmp1 == NULL)
continue;
tmp2 = strtok (NULL, " ");
if (tmp2 == NULL)
tmp2 = "0";
tmp3 = strtok (NULL, "");
if (tmp3 == NULL)
tmp3 = "Permbanned!";
strlwr (tmp1);
counter = atoi (tmp2);
add_permban (tmp1, counter, tmp3);
}
}
else if (strcasecmp (type, "SERVERS") == 0)
{
printf ("Loading %s file ", SERVERS);
while (fgets (str, STRING_LONG, fp))
{
/* Ignore comment lines */
if (*str == '#' || *str == '/')
continue;
printf (".");
fflush (stdout);
stripline (str);
/* Watch out for blank lines. Since fgets
returns on NULL, we're checking for NULL
within the fget'd data, which would indicate
a line containing NULL data in the file, not
EOF (Wrote this as a reminder). Ignore these
lines and move on.
*/
if ((tmp1 = strtok (str, " ")) == NULL)
continue;
else
tmp2 = strtok (NULL, " ");
i++;
if (tmp2 == NULL)
{
printf ("%s has no matching port in %s!\n", tmp1, SERVERS);
exit (0);
}
tmp3 = strtok (NULL, "");
add_s25 (tmp1, atoi (tmp2), tmp3);
}
if (i > 0)
printf ("done(%d).\n", (int) i);
else
{
printf ("ERROR! No servers found in %s! Please edit this file. Aborting!\n", SERVERS);
exit (0);
}
}
else if (fgets (str, STRING_LONG, fp))
S ("%s\n", str);
}
fclose (fp);
}
void
run_perform (void)
{
FILE *fp;
char str [STRING_LONG] = {0},
temp [STRING_LONG] = {0};
size_t len = 0;
if ((fp = fopen (PERFORM, "r")) == NULL)
return;
while (fgets (str, sizeof (str), fp))
{
/* Allow comments */
if (*str == '#')
continue;
len = strlen (str);
memset (data, 0, sizeof (data));
while (len > 0)
{
len--;
if ((str[len] == '~') && (str[len-1] == 'B'))
{
len--;
snprintf (temp, sizeof (temp), "%s%s", Mynick, data);
}
else
{
snprintf (temp, sizeof (temp), "%c%s", str[len], data);
}
strncpy (data, temp, sizeof (data));
}
if (data != NULL)
{
S ("%s\n", data);
}
}
fclose (fp);
}
diff --git a/source/reserved.c b/source/reserved.c
index 59550f6..5835c59 100644
--- a/source/reserved.c
+++ b/source/reserved.c
@@ -1,50 +1,61 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
void
call_reserved_1 ( char *source, char *target, char *param )
{
FILE *fp;
char buffer[STRING_SHORT] = { 0 };
char input[STRING_SHORT] = { 0 };
if ( strlen ( param ) == 0 )
return;
snprintf ( buffer, sizeof ( buffer ), "./cdecl -a -q explain \"%s\"\n", param );
if ( ( fp = popen ( buffer, "r" ) ) == NULL )
return;
if (fgets(input, sizeof(input), fp))
{
if (strlen(input) > 0)
S("PRIVMSG %s :%s%s\n", target, rand_reply(source), input);
}
pclose ( fp );
}
void
call_reserved_2 ( char *source, char *target, char *param )
{
FILE *fp;
char buffer[STRING_SHORT] = { 0 };
char input[STRING_SHORT] = { 0 };
if ( strlen ( param ) == 0 )
return;
snprintf ( buffer, sizeof ( buffer ), "./cdecl -a -q declare \"%s\"\n", param );
if ((fp = popen(buffer, "r")) == NULL)
return;
if (fgets(input, sizeof(input), fp))
{
if (strlen(input) > 0)
S("PRIVMSG %s :%s%s\n", target, rand_reply(source), input);
}
pclose(fp);
}
diff --git a/source/seen.c b/source/seen.c
index 6b0f558..d07e293 100644
--- a/source/seen.c
+++ b/source/seen.c
@@ -1,146 +1,157 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
void
count_seen (char *source, char *target)
{
FILE *fp = 0;
char temp [STRING_LONG] = { 0 };
size_t nCount = 0;
// Complain if we can't open the file.
if ((fp = fopen (SEEN_FILE, "r")) == NULL)
{
L003 (source, SEEN_FILE);
return;
}
while (fgets (temp, STRING_LONG, fp))
{
++nCount;
}
fclose (fp);
L004 (target, source, nCount);
}
struct chanserv_output *show_seen (char *nick, char *source, char *target)
{
struct chanserv_output *result = NULL;
FILE *fp = 0;
char temp[STRING_LONG] = { 0 }, *intime = NULL, *r_nick = NULL, *uh =
NULL, *chan = NULL, *ptr = NULL;
time_t unixtime = 0;
if ((nick == NULL) || (strlen(nick) > MAX_NICK_LENGTH))
return result;
// Looking for yourself, eh?
if (strcasecmp (nick, source) == 0)
{
L005 (target, source);
return result;
}
if ((ptr = strchr (nick, '?')) != NULL)
memmove (ptr, ptr + 1, strlen (ptr + 1) + 1);
if ((fp = fopen (SEEN_FILE, "r")) == NULL)
{
L003 (source, SEEN_FILE);
return result;
}
while (fgets (temp, STRING_LONG, fp))
{
stripline (temp);
r_nick = strtok (temp, " ");
if (strcasecmp (nick, r_nick) == 0)
{
uh = strtok (NULL, " ");
chan = strtok (NULL, " ");
if ((uh == NULL) || (chan == NULL))
continue;
intime = strtok (NULL, " ");
if (intime == NULL)
continue;
unixtime = time (NULL) - atoi (intime);
if (unixtime > 86400)
result = chanserv_asprintf(result, "%s, I last saw %s (%s) %d day%s, %02d:%02d ago in %s",
source, r_nick, uh, unixtime / 86400, (unixtime / 86400 == 1) ? "" : "s",
(unixtime / 3600) % 24, (unixtime / 60) % 60, chan);
else if (unixtime > 3600)
result = chanserv_asprintf(result, "%s, I last saw %s (%s) %d hour%s, %d min%s ago in %s",
source, r_nick, uh, unixtime / 3600, unixtime / 3600 == 1 ? "" : "s",
(unixtime / 60) % 60, (unixtime / 60) % 60 == 1 ? "" : "s", chan);
else
result = chanserv_asprintf(result, "PRIVMSG %s :%s, I last saw %s (%s) %d minute%s, %d sec%s ago in %s",
source, r_nick, uh, unixtime / 60, unixtime / 60 == 1 ? "" : "s", unixtime % 60,
unixtime % 60 == 1 ? "" : "s", chan);
fclose (fp);
return result;
}
}
fclose (fp);
L006 (target, source, nick, SEEN_REPLY);
return result;
}
long
save_seen (char *nick, char *uh, char *chan)
{
FILE *fp = 0;
char temp[STRING_LONG] = { 0 }, *r_nick = NULL, *r_chan = NULL, *r_uh = NULL, *r_time = NULL;
long toggle = 0;
time_t unixtime = 0;
printf ("\n*** Writing seen file: %s (%s) [%s]\n", CHAN, SEEN_FILE, date ());
unlink (TMP_FILE);
if ((fp = fopen (SEEN_FILE, "r")) == NULL)
{
db_log (SEEN_FILE, "%s %s %s %d\n", nick, uh, chan, (time_t) time (NULL));
return (-1);
}
while (fgets (temp, STRING_LONG, fp))
{
stripline (temp);
r_nick = strtok (temp, " ");
if (strcasecmp (nick, r_nick) == 0)
{
toggle = 1;
db_log (TMP_FILE, "%s %s %s %d\n", nick, uh, chan, (time_t) time (NULL));
}
else
{
r_uh = strtok (NULL, " ");
r_chan = strtok (NULL, " ");
r_time = strtok (NULL, " ");
if (r_uh == NULL || r_chan == NULL || r_time == NULL)
continue;
unixtime = (time_t) time (NULL) - (time_t) atoi (r_time);
if (unixtime < MAX_LASTSEEN)
db_log (TMP_FILE, "%s %s %s %s\n", r_nick, r_uh, r_chan, r_time);
}
}
fclose (fp);
if (toggle == 0)
{
db_log (TMP_FILE, "%s %s %s %d\n", nick, uh, chan, (time_t) time (NULL));
}
rename (TMP_FILE, SEEN_FILE);
return toggle;
}
diff --git a/source/server.c b/source/server.c
index ed369fd..2c8feb7 100644
--- a/source/server.c
+++ b/source/server.c
@@ -1,49 +1,60 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
void
gs26 (void)
{
long i = 0;
struct sl124 *c;
c = sh124;
spr++;
if (spr > snr)
spr = 1;
while (c != NULL)
{
i++;
if (i == spr)
{
strncpy (BS, c->name, sizeof (BS));
BP = c->port;
strncpy (BPASS, c->pass, sizeof (BPASS));
}
c = c->next;
}
}
void add_s25 (char *server, long port, char *pass)
{
struct sl124 *n;
n = malloc (sizeof (struct sl124));
if (n == NULL)
{
db_log ("error.log", "AHHH! No ram left! in add_s25!\n");
return;
}
memset (n, 0, sizeof (struct sl124));
snr++;
if (n != NULL)
{
strncpy (n->name, server, sizeof (n->name));
n->port = port;
if (pass != NULL)
strncpy (n->pass, pass, sizeof (n->pass));
n->next = sh124;
sh124 = n;
}
}
diff --git a/source/signals.c b/source/signals.c
index 4f27a4a..fcf904c 100644
--- a/source/signals.c
+++ b/source/signals.c
@@ -1,182 +1,193 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
// FIXME: This needs a rewrite. Should not do all that stuff inside a signal handler, but pass the work to the main loop instead via a single bool.
void
sig_alrm (int notUsed)
{
alarmed = 1;
alarm (AIL);
check_dbtimers (); /* timers :) */
AIL8 += AIL;
#ifdef ENABLE_QUIZ
if (quiz_halt == 1)
{
AIL13++;
if (AIL13 >= QUIZ_REPEAT_TIMER)
{
AIL13 = 0;
quiz_halt = 0;
}
}
if (quiz_answer == 1 && quiz_halt == 0)
{
if (quiz_timer >= QUIZ_TIMER)
{
quiz_answer = 0;
quiz_timer = 0;
quiz_halt = 1;
run_quiz_answer ();
}
else
quiz_timer++;
}
#endif
if (AIL8 >= SEND_DELAY)
{
AIL8 = 0;
Send ();
}
LastInput += AIL;
if (LastInput >= 500)
{
LastInput = 0;
#ifdef ENABLE_STONED_CHECK
L088 (BS);
printf ("\nNo response from %s in 5 mins, reconnecting...\n", BS);
prepare_bot ();
register_bot ();
#endif
}
AIL10 += AIL;
if (AIL10 >= 900)
{ /* 15 mins */
AIL10 = 0;
if (MARK_CHANGE == 1)
{
MARK_CHANGE = 0;
save_setup (); /* save settings */
}
}
AIL666 += AIL;
if (AIL666 >= 60)
{ /* 60 sec timer */
AIL666 = 0;
S ("PING :%s\n", BS);
}
AIL9 += AIL;
if (AIL9 >= 30)
{
AIL9 = 0;
if (strcasecmp (s_Mynick, Mynick) != 0)
{
S ("NICK %s\n", s_Mynick);
strncpy (Mynick, s_Mynick, sizeof (Mynick));
snprintf (NICK_COMMA, sizeof (NICK_COMMA), "%s,", Mynick);
snprintf (COLON_NICK, sizeof (COLON_NICK), "%s:", Mynick);
snprintf (BCOLON_NICK, sizeof (BCOLON_NICK), "%s\2:\2", Mynick);
}
}
if (Sleep_Toggle == 1)
{
AIL4 += AIL;
if (AIL4 >= Sleep_Time)
{
Sleep_Toggle = 0;
AIL4 = 0;
L089 (sleep_chan);
}
}
AIL2 += AIL;
AIL3 += AIL;
#ifdef ENABLE_RANDOM
Rand_Idle++;
if (RAND_IDLE <= Rand_Idle)
{
Rand_Idle = 0;
do_random_stuff ();
get_rand_stuff_time ();
}
Rand_Stuff -= AIL;
if (Rand_Stuff <= 0)
{
if (Sleep_Toggle != 1)
do_random_stuff ();
get_rand_stuff_time ();
}
#endif
#ifdef ENABLE_CHANNEL
if (AIL3 >= AUTOTOPIC_TIME)
{
AIL3 = 0;
do_autotopics ();
}
#endif
AIL5 += AIL;
if (AIL5 >= 600)
{
if (ANTI_IDLE)
S ("PRIVMSG ! :\2\n");
AIL5 = 0;
}
if (AIL2 >= 300)
{
AIL2 = 0;
#ifdef ENABLE_STATUS
S ("LUSERS\n");
#endif
S ("MODE %s %s\n", Mynick, DEFAULT_UMODE);
S ("JOIN %s\n", CHAN);
reset_ ();
save_changes ();
if (PERFORM_TIMER)
run_perform ();
}
}
void
sig_segv (int notUsed)
{
long uptime2 = 0, p = 0;
uptime2 = time (NULL) - uptime;
printf
("ERROR! Aborting program. (SIG_SEGV) Uptime: %d hour%s, %d min%s\n",
(int) (uptime2 / 3600),
(uptime2 / 3600 == 1) ? "" : "s",
(int) ((uptime2 / 60) % 60), ((uptime2 / 60) % 60) == 1 ? "" : "s");
Snow ("QUIT :Caught SIG_SEGV! Aborting connection. Uptime: %d hour%s, %d min%s\n",
uptime2 / 3600,
uptime2 / 3600 == 1 ? "" : "s", (uptime2 / 60) % 60, (uptime2 / 60) % 60 == 1 ? "" : "s");
db_sleep (2);
p = getpid ();
// FIXME: Not sure about this, maybe we can live without the fork, maybe without the kills.
if (fork () > 0)
{
db_log ("error.log", "Caught SIGSEGV.. Sent kill -3 and kill -9...\n");
kill (p, 3); /* SIGQUIT - terminate process and dump core. */
kill (p, 9); /* SIGKILL */
}
db_sleep (1);
exit (0);
}
void
sig_hup (int notUsed)
{
char temp[STRING_LONG];
int ret;
S ("QUIT :SIGHUP - Restarting %s ...\n", dbVersion);
snprintf (temp, sizeof (temp), "sleep 2; %s", DARKBOT_BIN);
ret = system (temp);
db_sleep (1);
exit (0);
}
diff --git a/source/sockets.c b/source/sockets.c
index 11b0187..2496878 100644
--- a/source/sockets.c
+++ b/source/sockets.c
@@ -1,123 +1,134 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Write a character array to a socket connection.
* 6/22/00 Dan
* Method argument now pointer to const data.
*/
int
writeln (const char *b)
{
return (write (socketfd, b, strlen (b)) < 0) ? 0 : 1;
}
int
readln (void)
{
char ch = 0;
int i = 0;
do
{
if (read (socketfd, &ch, 1) < 1)
return 0;
if (ch >= 32 || ch <= 126)
if (i < 524 - 1)
L[i++] = ch;
}
while (ch != '\n');
L[i] = '\0';
return 1;
}
/**
* 6/23/00 Dan
* - Changed method argument to be pointer to const data
* - Initialized variables when declared
* - Changed b to a power of 2
*/
void
S (const char *format, ...)
{
va_list arglist;
char b[STRING_LONG] = { 0 };
struct sendq *n = 0;
va_start (arglist, format);
vsprintf (b, format, arglist);
va_end (arglist);
if (send_tog == 0)
{
send_tog = 1;
if (DebuG == 1)
{
printf ("OUT: %s", b);
}
writeln (b);
return;
}
n = malloc (sizeof (struct sendq));
if (n == NULL)
{
db_log ("error.log", "AHH! no ram left! in S!\n");
return;
}
memset (n, 0, sizeof (struct sendq));
strncpy (n->data, b, sizeof (n->data));
if (sendqhead == NULL)
{
sendqhead = sendqtail = n;
}
else
{
sendqtail->next = n;
sendqtail = sendqtail->next;
}
}
/**
* 6/23/00 Dan
* - Changed method argument to be pointer to const data
* - Initialized b
*/
int
Snow (const char *format, ...)
{
va_list arglist;
char b[STRING_LONG] = { 0 };
va_start (arglist, format);
vsprintf (b, format, arglist);
va_end (arglist);
if (DebuG == 1)
printf ("OUT: %s", b);
return (writeln (b));
}
int
Send ()
{
struct sendq *c;
char output[STRING_LONG];
c = sendqhead;
get_sendq_count (0);
if (c == NULL)
{
send_tog = 0;
return -1;
}
if (DebuG == 1)
printf ("OUT: %s", c->data);
#ifdef DEBUG2
db_log ("darkbot_debug.log", "OUT: %s", c->data);
#endif
strncpy (output, c->data, sizeof (output));
del_sendq (0);
return (writeln (output));
}
diff --git a/source/stats.c b/source/stats.c
index cab2b82..8a644ec 100644
--- a/source/stats.c
+++ b/source/stats.c
@@ -1,166 +1,177 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#ifdef ENABLE_STATS
struct chanserv_output *get_stats (char *target, char *user)
{
struct chanserv_output *result = NULL;
struct statslist *c;
char temp[50] = { 0 };
char *ptr = NULL;
long total = 0;
time_t oldtime = 0;
time_t added_time = 0;
time_t last_time = 0;
c = statshead;
if (c)
oldtime = c->added_time;
while (c)
{
if (user == NULL)
{
total += c->total;
if (c->added_time < oldtime)
oldtime = c->added_time;
}
else
{
if (strcasecmp (c->nick, user) == 0)
{
added_time = c->added_time;
last_time = c->last_time;
strncpy (temp, ctime (&added_time), sizeof (temp));
if ((ptr = strchr (temp, '\n')) != NULL)
*ptr = '\0';
result = chanserv_asprintf(result, "%s has asked %ld questions since %s, %s's last question was asked on %s", user, c->total, temp, user, ctime (&last_time));
return;
}
}
c = c->next;
}
if (user)
{
result = chanserv_asprintf(result, "I have no data on %s\n", user);
}
else
{
result = chanserv_asprintf(result, "There have been %ld questions asked by %ld people, since I began recording on %s", total, NUM_USER, ctime (&oldtime));
}
return result;
}
void
add_stats (char *nick, char *uh, long total, long added_time, long last_time)
{
struct statslist *n, *c;
c = statshead;
if (strlen (uh) > 399)
uh[399] = '\0';
while (c)
{
if (strcasecmp (c->nick, nick) == 0)
{
strncpy (c->uh, uh, sizeof (c->uh));
c->total++;
c->last_time = last_time;
save_changes ();
return;
}
c = c->next;
}
n = malloc (sizeof (struct statslist));
if (n == NULL)
{
db_log ("error.log", "AHHH! No ram left! in add_stats!\n");
return;
}
NUM_USER++;
memset (n, 0, sizeof (struct statslist));
if (n != NULL)
{
strncpy (n->nick, nick, sizeof (n->nick));
strncpy (n->uh, uh, sizeof (n->uh));
strlwr (n->uh);
n->total = total;
n->added_time = added_time;
n->last_time = last_time;
n->next = statshead;
statshead = n;
}
save_changes ();
}
void
load_stats (void)
{
FILE *fp;
char b[STRING_LONG] = { 0 }, *user_host = NULL;
char *nick = NULL, *w_total = NULL, *w_added_time = NULL, *w_last_time = NULL;
long last_time = 0, added_time = 0, i = 0, total = 0;
if ((fp = fopen (STATS_FILE, "r")) == NULL)
{
if ((fp = fopen (STATS_FILE, "w")) == NULL)
{
printf ("Unable to create %s!\n", STATS_FILE);
exit (0);
}
fclose (fp);
return;
}
while (fgets (b, STRING_LONG, fp))
{
if (b == NULL)
continue;
stripline (b);
if (*b == '/')
continue;
i++;
printf (".");
fflush (stdout);
nick = strtok (b, " ");
if (nick == NULL)
continue;
user_host = strtok (NULL, " ");
if (user_host == NULL)
continue;
w_total = strtok (NULL, " ");
if (w_total == NULL)
continue;
w_added_time = strtok (NULL, " ");
if (w_added_time == NULL)
continue;
w_last_time = strtok (NULL, "");
if (w_last_time == NULL)
continue;
if (w_total != NULL)
total = atoi (w_total);
else
total = 0;
if (w_added_time != NULL)
added_time = atoi (w_added_time);
else
added_time = 0;
if (w_added_time != NULL)
last_time = atoi (w_last_time);
else
last_time = 0;
if (DebuG == 1)
printf
("loading statslist: %s %s total:%ld add:%ld last:%ld\n",
nick, user_host, total, added_time, last_time);
add_stats (nick, user_host, total, added_time, last_time);
}
printf ("done(%d), ", (int) i);
fclose (fp);
if (DebuG == 1)
db_sleep (2);
}
#endif
diff --git a/source/topics.c b/source/topics.c
index def37c1..d415d71 100644
--- a/source/topics.c
+++ b/source/topics.c
@@ -1,176 +1,187 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
/**
* Remove the autotopic for a particular channel.
* 6/23/00 Dan:
* - Method argument is now pointer to const data
* - All variables are now initialized when declared
* - Changed size of b to be power of 2
* - Changed variable types of toggle and x in accordance
* with their use
*/
void
del_autotopic (const char *chan)
{
FILE *fp;
char b[STRING_LONG] = { 0 }, *r_chan = 0, *r_data = 0;
bool toggle = false;
size_t x = 0;
remove (TMP_FILE);
fp = fopen (AUTOTOPIC_F, "r");
if (NULL == fp)
{
return;
}
while (fgets (b, STRING_LONG, fp))
{
x++;
stripline (b);
r_chan = strtok (b, " ");
r_data = strtok (NULL, "");
if (strcasecmp (r_chan, chan) == 0)
{
/* Found the channel */
toggle = true;
}
else
{
db_log (TMP_FILE, "%s %s\n", r_chan, r_data);
}
}
fclose (fp);
if (x == 1 && toggle)
{
/* The autotopic file is now empty */
remove (AUTOTOPIC_F);
remove (TMP_FILE);
return;
}
if (toggle)
{
/* We found the topic, change the temp file to the
* the name of the autotopic file */
rename (TMP_FILE, AUTOTOPIC_F);
}
else
{
/* We were unable to find the channel, just
* return */
remove (TMP_FILE);
}
}
void
do_autotopics (void)
{
FILE *fp;
char b[STRING_LONG] = { 0 }, *r_chan = NULL, *r_data = NULL;
if ((fp = fopen (AUTOTOPIC_F, "r")) == NULL)
return;
while (fgets (b, STRING_LONG, fp))
{
stripline (b);
r_chan = strtok (b, " ");
r_data = strtok (NULL, "");
if (*r_data != '0')
{
db_sleep (1);
S ("TOPIC %s :%s\n", r_chan, r_data);
}
}
fclose (fp);
}
long
ifexist_autotopic (char *chan)
{
FILE *fp;
char b[STRING_LONG] = { 0 }, *r_chan = NULL;
if ((fp = fopen (AUTOTOPIC_F, "r")) == NULL)
return -1;
while (fgets (b, STRING_LONG, fp))
{
stripline (b);
if (*b == '/')
continue;
r_chan = strtok (b, " ");
if (strcasecmp (r_chan, chan) == 0)
{
fclose (fp);
return 1; /* exists */
}
}
fclose (fp);
return 0; /* doesn't exist */
}
void
set_autotopic (char *source, char *target, char *topic)
{
long exist = 0;
exist = ifexist_autotopic (target);
if (exist == 0 && *topic == '0')
{ /* never existed, lets humor
* the guy */
L007 (source, target);
return;
}
else if (exist == 1 && *topic == '0')
{ /* delete it! */
L008 (source, target);
S ("TOPIC %s :\n", target);
del_autotopic (target);
return;
}
if (strlen (topic) >= 400) /* make sure no overflow */
topic[400] = '\0';
if (exist == 0)
{ /* no such autotopic, so add it */
L009 (source, target, topic);
db_log (AUTOTOPIC_F, "%s %s\n", target, topic);
return;
}
/* only thing left is if topic exists and you want to update it */
del_autotopic (target);
L010 (source, target, topic);
S ("TOPIC %s :%s\n", target, topic);
db_log (AUTOTOPIC_F, "%s %s\n", target, topic);
}
char *
revert_topic (char *input)
{
char *ptr = NULL, b[STRING_SHORT] = { 0 };
ptr = strtok (input, "+");
snprintf (f_tmp, sizeof (f_tmp), "%s", ptr);
if (ptr != NULL)
{
while (ptr != NULL)
{
ptr = strtok (NULL, "+");
if (ptr != NULL)
{
snprintf (b, sizeof (b), "%s %s", f_tmp, ptr);
snprintf (f_tmp, sizeof (f_tmp), "%s", b);
}
}
return f_tmp;
}
else
return f_tmp;
}
diff --git a/source/tree.c b/source/tree.c
index 3ee1a77..cc69092 100644
--- a/source/tree.c
+++ b/source/tree.c
@@ -1,248 +1,259 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include <sys/types.h>
#include "tree.h"
/* Just a quick and dirty tree implemtation that will likely get replaced by
* something much saner at a later date. I wrote most of this while falling
* asleep. It will probably scare me when I wake up. B-)
*
* This was originally written for Enlightenment.
*
* The trees will be tiny.
* They only store strings.
* There is no insertion or deletion, only append.
* Append order must be maintained.
* The trees will only ever be accessed sequentially, from begining to end.
* The tree data will come in two ways, all in one big string, or a bunch of
* seperate strings, one per element. Any particular tree might have both.
*
* No duplicates in the tree,
* This is the nasty part of this tree implementation.
* Insertions involve a linear search for dupes, most of the
* time there won't be any dupes, so the tree is searched in
* it's entirety. These trees will be really small, and only created at
* the begining, so no big drama there.
* The tree may allow duplicates.
*/
Tree *tree_new(char *buffer)
{
Tree *tree;
tree = E_NEW(Tree, 1);
if ((tree) && (buffer))
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = strdup(buffer);
}
return tree;
}
Tree *tree_add(Tree * tree, const char *element)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof(Tree_Element));
tree->elements[tree->size].element = (char*)element;
tree->elements[tree->size++].type = TREE_ELEMENT_TYPE_STRING;
return tree;
}
Tree *tree_extend(Tree * tree, const char *element)
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = strdup(element);
tree = tree_add(tree, tree->buffers[tree->buffers_size - 1]);
return tree;
}
void tree_track(Tree * tree, void *element)
{
tree->buffers = (char **)realloc(tree->buffers, (tree->buffers_size + 1) * sizeof(char *));
tree->buffers[tree->buffers_size++] = element;
}
/* OK, so we need an insert after all, and it falls into the dumb category. */
Tree *tree_insert(Tree * tree, int before, void *element, Tree_Element_Type type)
{
int i;
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof(Tree_Element));
tree->size++;
for (i = tree->size - 1; i > before; i--)
{
tree->elements[i].element = tree->elements[i - 1].element;
tree->elements[i].type = tree->elements[i - 1].type;
}
tree->elements[before].element = element;
tree->elements[before].type = type;
return tree;
}
/* OK, so we need a tree merge after all, and it falls into the dumb category. */
Tree *tree_merge(Tree * tree, int before, Tree * element)
{
int i, size;
size = element->size;
if (size)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + size) * sizeof(Tree_Element));
tree->size += size;
for (i = tree->size - 1; (i > before) && ((i - size) > 0); i--)
{
tree->elements[i].element = tree->elements[i - size].element;
tree->elements[i].type = tree->elements[i - size].type;
}
for (i = 0; i < size; i++)
{
tree->elements[before + i].element = element->elements[i].element;
tree->elements[before + i].type = element->elements[i].type;
}
}
/* Careful, this might screw up the freeing order if that is important. */
size = element->buffers_size;
if (size)
{
/*
tree->buffers = (char **) realloc(tree->buffers, (tree->buffers_size + size) * sizeof(char *));
tree->buffers_size += size;
for (i = 0; i < size; i++)
{
tree->buffers[tree->buffers_size + i] = element->buffers[i];
element->buffers[i] = NULL;
}
*/
}
return tree;
}
Tree *tree_add_child(Tree * tree, Tree * element)
{
tree->elements = (Tree_Element *) realloc(tree->elements, (tree->size + 1) * sizeof (Tree_Element));
tree->elements[tree->size].element = element;
tree->elements[tree->size++].type = TREE_ELEMENT_TYPE_TREE;
element->parent = tree;
return tree;
}
void tree_remove(Tree * tree, int element)
{
if (tree->size > element)
{
tree->elements[element].type = TREE_ELEMENT_TYPE_NULL;
tree->elements[element].element = NULL;
}
}
int tree_exist(Tree * tree, char *element)
{
int exist = 0;
int i;
/* This is the dumb part of the tree, a linear search. */
for (i = 0; i < tree->size; i++)
{
if ((tree->elements[i].type == TREE_ELEMENT_TYPE_STRING) && (strcmp((char *)tree->elements[i].element, element) == 0))
{
exist = 1;
break;
}
}
return exist;
}
int tree_foreach(Tree * tree, int level, int (*func) (const void *data, Tree * tree, int element, int level), const void *data)
{
int result = 0;
int i;
for (i = 0; i < tree->size; i++)
{
if (tree->elements[i].type == TREE_ELEMENT_TYPE_TREE)
{
if (tree_foreach((Tree *) tree->elements[i].element, level + 1, func, data))
result = 1;
}
else if (tree->elements[i].type == TREE_ELEMENT_TYPE_NULL)
{
/* This falls into the dumb category. */
int j = i;
int k = i;
int moved = 0;
/* Find the next non NULL element. */
while ((j < tree->size) && (tree->elements[j].type == TREE_ELEMENT_TYPE_NULL))
j++;
/* Move the next batch of non NULL up. */
while ((j < tree->size) && (tree->elements[j].type != TREE_ELEMENT_TYPE_NULL))
{
moved = 1;
tree->elements[k].type = tree->elements[j].type;
tree->elements[k].element = tree->elements[j].element;
tree->elements[j].type = TREE_ELEMENT_TYPE_NULL;
tree->elements[j].element = NULL;
j++;
k++;
}
if (moved)
i--;
else
tree->size = i;
}
else
{
if (func(data, tree, i, level))
result = 1;
}
}
return result;
}
void tree_dump(Tree * tree, int level)
{
int i;
for (i = 0; i < tree->size; i++)
{
int j;
for (j = 0; j < level; j++)
printf(".");
switch (tree->elements[i].type)
{
case TREE_ELEMENT_TYPE_NULL:
printf("NULL\n");
break;
case TREE_ELEMENT_TYPE_STRING:
printf("%s\n", (char *)tree->elements[i].element);
break;
case TREE_ELEMENT_TYPE_TREE:
printf("TREE ELEMENT TYPE\n");
tree_dump((Tree *) tree->elements[i].element, level + 1);
break;
default:
printf("UNKNOWN ELEMENT TYPE!\n");
break;
}
}
}
void tree_del(Tree * tree)
{
int i;
for (i = tree->size - 1; i >= 0; i--)
{
if (tree->elements[i].type == TREE_ELEMENT_TYPE_TREE)
tree_del((Tree *) tree->elements[i].element);
}
E_FREE(tree->elements);
for (i = tree->buffers_size - 1; i >= 0; i--)
E_FREE(tree->buffers[i]);
E_FREE(tree);
}
diff --git a/source/tree.h b/source/tree.h
index 0003bc7..3f477f5 100644
--- a/source/tree.h
+++ b/source/tree.h
@@ -1,68 +1,79 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#ifndef _TREE_H
# define _TREE_H
#include <sys/types.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#define E_FN_DEL(_fn, _h) if (_h) { _fn(_h); _h = NULL; }
#define E_REALLOC(p, s, n) p = (s *)realloc(p, sizeof(s) * n)
#define E_NEW(s, n) (s *)calloc(n, sizeof(s))
#define E_NEW_BIG(s, n) (s *)malloc(n * sizeof(s))
#define E_FREE(p) { if (p) {free(p); p = NULL;} }
enum _Tree_Element_Type
{
TREE_ELEMENT_TYPE_NULL = 0,
TREE_ELEMENT_TYPE_STRING = 1,
TREE_ELEMENT_TYPE_TREE = 2,
};
typedef enum _Tree_Element_Type Tree_Element_Type;
struct _Tree_Element
{
void *element; /* A pointer to the element. */
Tree_Element_Type type; /* The type of the element. */
};
typedef struct _Tree_Element Tree_Element;
typedef struct _Tree Tree;
struct _Tree
{
Tree_Element *elements; /* An array of elements. */
int size; /* The size of the array. */
char **buffers; /* An array of pointers to the bits of data. */
int buffers_size; /* The size of the array. */
Tree *parent; /* Parent if this is a child. */
};
# ifdef __cplusplus
extern "C"
{
# endif
Tree *tree_new(char *buffer);
Tree *tree_add(Tree * tree, const char *element);
void tree_track(Tree * tree, void *element);
Tree *tree_extend(Tree * tree, const char *element);
Tree *tree_insert(Tree * tree, int before, void *element, Tree_Element_Type type);
Tree *tree_merge(Tree * tree, int before, Tree *element);
Tree *tree_add_child(Tree * tree, Tree *element);
void tree_remove(Tree * tree, int element);
int tree_exist(Tree * tree, char *element);
int tree_foreach(Tree * tree, int level, int (*func) (const void *data, Tree *tree, int element, int level), const void *data);
void tree_dump(Tree * tree, int level);
void tree_del(Tree * tree);
Tree *xmlame_new(char *buffer);
Tree *xmlame_get(char *file);
Tree *xmlame_from_string(char *data);
# ifdef __cplusplus
}
# endif
#endif
diff --git a/source/url.c b/source/url.c
index 48795ce..0ed7ff2 100644
--- a/source/url.c
+++ b/source/url.c
@@ -1,648 +1,659 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
int
check_existing_url (const char *source, char *topic, char *target)
{
FILE *fp;
char b[STRING_LONG] = { 0 }, *subj = NULL;
if ((fp = fopen (URL2, "r")) == NULL)
{
L003 (source, URL2);
return 0;
}
while (fgets (b, STRING_LONG, fp))
{
stripline (b);
subj = strtok (b, " ");
if (strcasecmp (subj, topic) == 0)
{
fclose (fp);
return 1;
}
}
fclose (fp);
return 0;
}
void
find_url (const char *nick, char *topic, char *target)
{
FILE *fp = NULL;
long i = 0, FOUND = 0, x = 0;
char b [STRING_LONG] = {0}, DATA [STRING_SHORT] = {0};
char *subj = NULL, *ptr2 = NULL;
if (strlen (topic) > MAX_TOPIC_SIZE)
topic[MAX_TOPIC_SIZE] = '\0';
strlwr (topic);
if ((fp = fopen (URL2, "r")) == NULL)
{
L003 (nick, URL2);
return;
}
while (fgets (b, STRING_LONG, fp))
{
x++;
if (*b == '\n')
continue; /* Just pass over empty lines */
stripline (b);
subj = strtok (b, " ");
strlwr (subj);
ptr2 = strstr (subj, topic);
if (ptr2 != NULL)
{
i++;
FOUND = 1;
sprintf (DATA, "%s %s", DATA, subj);
if (strlen (DATA) >= MAX_SEARCH_LENGTH)
break;
}
}
fclose (fp);
if (FOUND == 0)
{
L021 (target, NO_TOPIC, topic, x);
}
else if (i > 19)
{
L022 (target, i, DATA);
}
else if (i == 1)
{
L023 (target, nick, DATA);
}
else
L024 (target, i, nick, DATA);
}
struct chanserv_output *display_url (char *target, char *nick, char *topic)
{
struct chanserv_output *result = NULL;
FILE *fp;
long x = 0;
char b[STRING_LONG] = { 0 }, *subj = NULL, *ptr = NULL;
strlwr (topic);
if ((fp = fopen (URL2, "r")) == NULL)
{
result = chanserv_asprintf(result, "there was an error displaying data for \"%s\".", topic);
return result;
}
while (fgets (b, STRING_LONG, fp))
{
x++;
stripline (b);
subj = strtok (b, " ");
ptr = strtok (NULL, "");
if (strcasecmp (subj, topic) == 0 || !match_wild (subj, topic) == 0)
{
QUESTIONS++;
result = chanserv_asprintf(result, "Raw data for %s is: %s", topic, ptr);
fclose (fp);
return result;
} /* Subject match */
}
fclose (fp);
result = chanserv_asprintf(result, "I do not know of any topic named %s\n", topic);
return result;
}
void
delete_url (const char *nick, char *topic, char *target)
{
FILE *fp = 0;
size_t i = 0;
size_t FOUND = 0;
char b [STRING_LONG] = { 0 };
char DATA [STRING_SHORT] = { 0 };
char *subj = NULL;
char *ptr = NULL;
if (*topic == '~')
{
topic++;
if (topic != NULL)
strlwr (topic);
snprintf (DATA, sizeof (DATA), "%s/%s.rdb", RDB_DIR, topic);
if (strspn (topic, LEGAL_TEXT) != strlen (topic))
{
if (strcasecmp (nick, target) == 0)
S ("NOTICE %s :%s, rdb files are made up of letters and or numbers, no other text is accepted.\n", nick, nick);
else
S ("PRIVMSG %s :%s, rdb files are made up of letters and or numbers, no other text is accepted.\n", target, nick);
return;
}
if ((fp = fopen (DATA, "r")) == NULL)
{
if (strcasecmp (nick, target) == 0)
S ("NOTICE %s :%s, %s.rdb does not exist.\n", nick, nick, topic);
else
S ("PRIVMSG %s :%s, %s.rdb does not exist.\n", target, nick, topic);
return;
}
fclose (fp);
remove(DATA);
if (strcasecmp (nick, target) == 0)
S ("NOTICE %s :I have unlinked %s.\n", nick, DATA);
else
S ("PRIVMSG %s :I have unlinked %s.\n", target, DATA);
return;
}
if ((fp = fopen (TMP_URL, "w")) == NULL) /* fixes the 'must have at least 1 topic' problem. */
{
L003 (nick, TMP_URL);
return;
}
fclose (fp);
if ((fp = fopen (URL2, "r")) == NULL)
{
L003 (nick, URL2);
return;
}
while (fgets (b, STRING_LONG, fp))
{
stripline (b);
subj = strtok (b, " ");
ptr = strtok (NULL, "");
i++;
if (strcasecmp (subj, topic) == 0)
{
FOUND = 1;
DELETIONS++;
if (strcasecmp (nick, target) == 0)
L029n (nick, nick, i, topic);
else
L029 (target, nick, i, topic);
}
else if (strstr (subj, " ") == NULL)
db_log (TMP_URL, "%s %s\n", subj, ptr);
}
fclose (fp);
remove(URL2);
rename(TMP_URL, URL2);
if (FOUND == 0)
{
if (strcasecmp (nick, target) == 0)
L030n (nick, nick, topic);
else
L030 (target, nick, topic);
}
}
struct chanserv_output *show_url (char *nick, char *topic, char *target, long donno, long floodpro, char *uh, long no_pipe)
{
struct chanserv_output *result = NULL;
FILE *fp;
long x = 0, length = 0, toggle = 0, A = 0, gotit = 0, D = 0, F = 0, Tog = 0;
char b[STRING_LONG] = { 0 }, *subj = NULL, *ptr = NULL;
char temp[STRING_LONG] = { 0 };
char Data[STRING_LONG] = { 0 }, *ptr8 = NULL;
char crm1[STRING_LONG] = { 0 };
char crm2[STRING_LONG] = { 0 }, bFirst = 1;
strlwr (topic);
/* removes the question mark */
if ((ptr = strchr (topic, '?')) != NULL)
memmove (ptr, ptr + 1, strlen (ptr + 1) + 1);
if ((fp = fopen (URL2, "r")) == NULL)
{
if (donno == 1)
L003 (nick, URL2);
return result;
}
while (fgets (b, STRING_LONG, fp))
{
x++;
stripline (b);
subj = strtok (b, " ");
if (subj == NULL)
continue;
ptr = strtok (NULL, "");
if (ptr == NULL)
continue;
if (strcasecmp (subj, topic) == 0 || !match_wild (subj, topic) == 0)
{
QUESTIONS++;
if (floodpro == 1)
if (cf (uh, nick, nick))
{
fclose (fp);
return result;
}
gotit = 1;
if (*ptr == '+')
{
ptr++;
A = 1;
}
else if (*ptr == '-')
{
if (strstr (nick, "|") != NULL)
return result;
if (no_pipe == 1)
{
fclose (fp);
return result;
}
ptr++;
D = 1;
}
else if (*ptr == '~')
{
ptr++;
fclose (fp);
do_randomtopic (NORMALR, target, ptr, nick, topic);
return result;
}
length = strlen (ptr);
if (length > 3)
{
if (ptr[0] == 'i' && ptr[1] == 'l' && ptr[2] == 'c')
{
toggle++;
}
}
while (length > 0)
{
length--;
if (Tog == 1)
{
Tog = 0;
if (ptr[length] == 'N')
{ /* nick */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", nick, Data);
}
else if (ptr[length] == 'C')
{ /* chan */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", target, Data);
}
else if (ptr[length] == '1'
|| ptr[length] == '2'
|| ptr[length] == '3'
|| ptr[length] == '4'
|| ptr[length] == '5'
|| ptr[length] == '6'
|| ptr[length] == '7' || ptr[length] == '8' || ptr[length] == '9')
{
toggle++;
/* The first time around, we just store the topic in a
"safe place" */
if (bFirst == 1)
{
strncpy (crm1, topic, sizeof (crm1));
bFirst = 0;
}
/* Each time around, get a new copy from the "safe place." */
strncpy (crm2, crm1, sizeof (crm2));
snprintf (temp, sizeof (temp), "%s%s", get_word (ptr[length], crm2, "+"), Data);
}
else if (ptr[length] == 'H')
{ /* u@h of user */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", uh, Data);
}
else if (ptr[length] == 'h')
{ /* u@h (no ident) */
toggle++;
if (*uh == '~')
{
uh++;
}
snprintf (temp, sizeof (temp), "%s%s", uh, Data);
}
else if (ptr[length] == 'T')
{ /* time */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", date (), Data);
}
else if (ptr[length] == 't')
{ /* unixtime */
toggle++;
snprintf (temp, sizeof (temp), "%ld%s", (long)time (NULL), Data);
}
else if (ptr[length] == 'W')
{ /* WWW page */
toggle++;
snprintf (temp, sizeof (temp), "http://darkbot.sourceforge.net%s", Data);
}
else if (ptr[length] == 'S')
{ /* server */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", BS, Data);
}
else if (ptr[length] == 'R')
{ /* rand */
toggle++;
/* The first time around, we just store the topic in a
"safe place" */
if (bFirst == 1)
{
strncpy (crm1, topic, sizeof (crm1));
bFirst = 0;
}
// Don't do random nicknames if the target isn't a channel!!
snprintf (temp, sizeof (temp), "%s%s",
((*target != '#') ? "R~" : get_rand_nick (target)),
Data);
}
else if (ptr[length] == 'P')
{ /* port */
toggle++;
snprintf (temp, sizeof (temp), "%ld%s", BP, Data);
}
else if (ptr[length] == 'Q')
{ /* question */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", revert_topic (topic), Data);
}
else if (ptr[length] == 'V')
{ /* version */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", dbVersion, Data);
}
else if (ptr[length] == '!')
{ /* cmdchar */
toggle++;
snprintf (temp, sizeof (temp), "%c%s", *CMDCHAR, Data);
}
else if (ptr[length] == 'B')
{ /* mynick */
toggle++;
snprintf (temp, sizeof (temp), "%s%s", Mynick, Data);
}
else
snprintf (temp, sizeof (temp), "%c~%s", ptr[length], Data);
}
else if (ptr[length] == '~')
{
Tog = 1;
}
else
snprintf (temp, sizeof (temp), "%c%s", ptr[length], Data);
strncpy (Data, temp, sizeof (Data));
} /* While */
if (D == 1)
{
ptr8 = strtok (Data, "|");
while (ptr8 != NULL)
{
if (ptr8[0] == ' ')
ptr8++;
if (ptr8[0] == 'B' && ptr8[1] == 'A' && ptr8[2] == 'N')
{ /* ban user */
S ("MODE %s +b *%s\n", target, uh);
}
if (ptr8[0] == 'T' && ptr8[1] == 'E' && ptr8[2] == 'M' &&
ptr8[3] == 'P' && ptr8[4] == 'B' && ptr8[5] == 'A' && ptr8[6] == 'N')
{ /* temp ban user for 60 sec */
S ("MODE %s +b *%s\n", target, uh);
snprintf (temp, sizeof (temp), "%s/%ld", DBTIMERS_PATH, (long)time (NULL) + 60);
db_log (temp, "MODE %s -b *%s\n", target, uh);
}
ptr8[0] = tolower (ptr8[0]);
ptr8[1] = tolower (ptr8[1]);
if (ptr8[0] == 'p' && ptr8[1] == 'r')
F = 1;
if (ptr8[0] == 'k' && ptr8[1] == 'i' && !is_op(nick, target))
F = 1;
if (ptr8[0] == 'n' && ptr8[1] == 'o')
F = 1;
if (ptr8[0] == 't' && ptr8[1] == 'o')
F = 1;
if (F == 1)
S ("%s\n", ptr8);
F = 0;
ptr8 = strtok (NULL, "|");
}
fclose (fp);
return result;
}
// TODO - It's entirely possible that some of these need to be targeted to NOTICE / PRIVMSG.
if (toggle == 0)
{
#ifdef ENABLE_STATS
add_stats (nick, uh, 1, time (NULL), time (NULL));
#endif
if (A == 0)
{
if ((*target == '#') || (*target == '+') || (*target == '&'))
result = chanserv_asprintf(result, "%s%s", rand_reply (nick), Data);
else
{
result = chanserv_asprintf(result, "%s%s", rand_reply(target), temp, Data);
}
}
else if ((*target == '#') || (*target == '+') || (*target == '&'))
result = chanserv_asprintf(result, "\1ACTION %s\1", Data);
else
{
result = chanserv_asprintf(result, "%s%s", rand_reply(target), Data);
}
}
else if (A == 0)
{
#ifdef ENABLE_STATS
add_stats (nick, uh, 1, time (NULL), time (NULL));
#endif
if ((*target == '#') || (*target == '+') || (*target == '&'))
result = chanserv_asprintf(result, Data);
else
{
result = chanserv_asprintf(result, Data);
}
}
else if ((*target == '#') || (*target == '+') || (*target == '&'))
{
#ifdef ENABLE_STATS
add_stats (nick, uh, 1, time (NULL), time (NULL));
#endif
result = chanserv_asprintf(result, "\1ACTION %s\1\n", Data);
}
else if (MSG_RESPONSES)
{
#ifdef ENABLE_STATS
add_stats (nick, uh, 1, time (NULL), time (NULL));
#endif
result = chanserv_asprintf(result, Data);
}
fclose (fp);
return result;
} /* Subject match */
}
fclose (fp);
if (donno == 1)
{
if (strlen (topic) > 3)
{
strlwr (topic);
if (topic[0] == 'i' && topic[1] == 'l' && topic[2] == 'c')
{
if ((*target == '#') || (*target == '+') || (*target == '&'))
result = chanserv_asprintf(result, "I found no matching ILC for that channel.");
return result;
}
}
if ((*target == '#') || (*target == '+') || (*target == '&'))
{
if (RANDOM_DUNNO == true)
do_randomtopic (DUNNOR, target, DUNNO_FILE, nick, topic);
else
result = chanserv_asprintf(result, DUNNO_Q);
}
else
result = chanserv_asprintf(result, DUNNO_Q);
}
return result;
}
char *
get_multiword_topic (char *first)
{
char *tmp2 = NULL;
tmp2 = strtok (NULL, " ");
if (tmp2 != NULL)
{
sprintf (f_tmp, "%s", first);
while (tmp2 != NULL)
{
sprintf (f_tmp, "%s+%s", f_tmp, tmp2);
tmp2 = strtok (NULL, " ");
}
return f_tmp;
}
else
return first;
}
void
datasearch (const char *nick, char *topic, char *target)
{
FILE *fp = NULL;
size_t i = 0, FOUND = 0, x = 0;
char b[STRING_LONG] = { 0 }, *dorf = NULL, *subj = NULL, *ptr2 = NULL, DATA[STRING_SHORT] =
{
0};
/* Make sure topic is not NULL.*/
if (topic == NULL)
{
return;
}
if (strlen (topic) > MAX_TOPIC_SIZE)
topic[MAX_TOPIC_SIZE] = '\0';
strlwr (topic);
if ((fp = fopen (URL2, "r")) == NULL)
{
L003 (nick, URL2);
return;
}
while (fgets (b, STRING_LONG, fp))
{
x++;
if (*b == '\n')
continue; /* Just pass over blank lines */
stripline (b);
strlwr (b);
subj = strtok (b, " ");
dorf = strtok (NULL, "");
ptr2 = strstr (dorf, topic);
if (ptr2 != NULL)
{
i++;
FOUND = 1;
sprintf (DATA, "%s %s", DATA, subj);
if (strlen (DATA) >= MAX_SEARCH_LENGTH)
break;
}
}
fclose (fp);
if (FOUND == 0)
{
L021 (target, NO_TOPIC, topic, x);
}
else if (i > 19)
{
L022 (target, i, DATA);
}
else if (i == 1)
{
L023 (target, nick, DATA);
}
else
L024 (target, i, nick, DATA);
}
char *
get_word (long number, char *string, char *seperator)
{ /* gets a specific word requested */
long i = 0;
char *ptr = NULL;
number = number - 49;
ptr = strtok (string, "+");
strncpy (f_tmp, ptr, sizeof (f_tmp));
if (ptr != NULL)
{
while (ptr != NULL)
{
i++; /* word number */
ptr = strtok (NULL, seperator);
if (ptr != NULL)
{
if (i == number)
{
snprintf (f_tmp, sizeof (f_tmp), "%s", ptr);
return f_tmp;
}
}
}
return f_tmp;
}
else
{ /* only one word */
if (number == 1)
{
return f_tmp;
}
else
return ""; /* no match */
}
}
diff --git a/source/users.c b/source/users.c
index f61f48e..290219b 100644
--- a/source/users.c
+++ b/source/users.c
@@ -1,269 +1,280 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
void
scan_chan_users (char *chan, char *nick, char *banned)
{
struct userlist *c;
c = userhead;
if (banned[0] == '*' && banned[1] == '!' && banned[2] == '*' && banned[3] == '\0')
{
S ("MODE %s -ob %s %s\n", chan, nick, banned);
return;
}
#ifdef ENABLE_CHANNEL
if (KICK_ON_BAN)
{
while (c)
{
if (!match_wild (banned, c->uh) == 0)
{
if (strcasecmp (c->nick, Mynick) != 0)
{
S ("KICK %s %s :BANNED\n", chan, c->nick);
}
else
{
S ("MODE %s -ob %s %s\n", chan, nick, banned);
return;
}
}
c = c->next;
}
}
#endif
}
void
delete_user (const char *nick, char *chan)
{
struct userlist *pNode, *pPrev;
pNode = userhead;
pPrev = NULL;
while (pNode)
{
if (strcasecmp (pNode->nick, nick) == 0 && strcasecmp (pNode->chan, chan) == 0)
{
save_seen (pNode->nick, pNode->uh, pNode->chan);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
userhead = pNode->next;
}
free (pNode);
pNode = NULL;
break;
}
pPrev = pNode;
pNode = pNode->next;
}
}
void
add_user (char *chan, char *nick, char *uh, long tog)
{
/* toggle of 0 means to unidle the client */
struct userlist *n, *c;
c = userhead;
if (strlen (uh) > 399)
uh[399] = '\0';
while (c)
{ /* don't readd data that already exists */
if (tog == 0)
{
if (strcasecmp (c->nick, nick) == 0 && strcasecmp (c->chan, chan) == 0)
{
c->idle = time (NULL);
}
}
if (tog == 1)
{
if (strcasecmp (c->nick, nick) == 0 && strcasecmp (c->chan, chan) == 0)
{
/* If user is somehow already here, just update his data instead
of readding */
strncpy (c->chan, chan, sizeof (c->chan));
strncpy (c->uh, uh, sizeof (c->uh));
strlwr (c->uh);
strncpy (c->nick, nick, sizeof (c->nick));
c->idle = time (NULL);
c->level = 0;
return;
}
}
c = c->next;
}
if (tog == 0)
{
/* all we wanted to do was unidle, so we can quit now */
return;
}
n = malloc (sizeof (struct userlist));
if (n == NULL)
{
db_log ("error.log", "AHHH! No ram left! in add_user!\n");
return;
}
memset (n, 0, sizeof (struct userlist));
if (n != NULL)
{
strncpy (n->chan, chan, sizeof (n->chan));
strncpy (n->uh, uh, sizeof (n->uh));
strlwr (n->uh);
strncpy (n->nick, nick, sizeof (n->nick));
n->idle = time (NULL);
n->level = 0;
n->next = userhead;
userhead = n;
}
}
void
delete_user_ram (char *source, char *uh)
{
struct helperlist *pNode, *pPrev;
pNode = helperhead;
pPrev = NULL;
while (pNode)
{
if (strcasecmp (pNode->uh, uh) == 0)
{
L015 (source, pNode->uh, pNode->level, pNode->num_join);
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
helperhead = pNode->next;
free (pNode);
pNode = NULL;
break;
}
pPrev = pNode;
pNode = pNode->next;
}
save_changes ();
}
char *mask_from_userhost (char *uh)
{
char *ptr1 = NULL;
char *ptr2 = NULL;
char *user = NULL;
char *host = NULL;
char userhost [STRING_LONG] = {0};
size_t nParts = 0;
if (userhost == NULL)
return(" ");
strcpy (userhost, mask_tmp);
if ((user = strtok (userhost, "@")) == NULL)
return (" ");
// Strip off any tilde on the username.
if (*user == '~')
user++;
// Hostname
host = strtok (NULL, " ");
// If there are less than three parts to this hostname, return
// the full hostname.
if ((nParts = count_char (host, '.')) < 3)
{
snprintf (mask_tmp, sizeof (mask_tmp), "*%s@%s", user, host);
return (mask_tmp);
}
// If the host is composed entirely of numbers and dots, assume
// it is a numeric IP. Parse that accordingly (203.203.203.*)
if (strspn (host, "1234567890.") == strlen (host))
{
reverse (host);
ptr1 = strtok (host, ".");
ptr1 = strtok (NULL, " ");
reverse (ptr1);
snprintf (mask_tmp, sizeof (mask_tmp), "*%s@%s.*", user, ptr1);
return (mask_tmp);
}
// It has to be an actual hostname now, so let's parse it.
reverse (host);
ptr2 = strtok (host, ".");
ptr1 = strtok (NULL, ".");
reverse (ptr2);
reverse (ptr1);
snprintf (mask_tmp, sizeof (mask_tmp), "*%s@*.%s.%s", user, ptr1, ptr2);
return (mask_tmp);
}
long is_op(char *who, const char *chan)
{
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, c->chan))
{
return (c->flags & FLAG_CHANOP);
}
}
return (0);
}
void
do_op(char *who, const char *chan, long tog)
{
struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, c->chan))
{
if (tog == 1)
c->flags |= FLAG_CHANOP;
else
c->flags &= ~FLAG_CHANOP;
}
}
return;
}
char *uh_from_nick (char *who, const char *chan)
{
const struct userlist *c = userhead;
for (; c != NULL; c = c->next)
{
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, "#*"))
{
strcpy (mask_tmp, c->uh);
return (mask_tmp);
}
if (!strcasecmp (who, c->nick) && !strcasecmp (chan, c->chan))
{
strcpy (mask_tmp, c->uh);
return (mask_tmp);
}
}
return (0);
}
char *mask_from_nick (char *who, const char *chan)
{
char *s;
if ((s = uh_from_nick(who, chan)) == NULL)
return (who);
return (mask_from_userhost (s));
}
diff --git a/source/vars.c b/source/vars.c
index f015731..bffe51f 100644
--- a/source/vars.c
+++ b/source/vars.c
@@ -1,468 +1,479 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
int wsock = 0;
int sockerr = 0;
int optlen = sizeof(sockerr);
size_t nRandStuffs = 0;
long QUESTIONS = 0;
long ADDITIONS = 0;
long DELETIONS = 0;
long uptime = 0;
long NO_FLOOD = 0;
long NUM_SERV = 0;
long L_CLIENTS = 0;
long IRCOPS = 0;
long xtried = 0;
long G_USERS = 0;
long rt = 120;
long fc = 0;
long spr = 0;
long snr = 0;
long BP = 6667;
long CHECKED = 1;
long SEND_DELAY = 1;
long send_tog = 0;
long NUM_HELPER = 0;
long NUMLINESSEEN = 0;
long NUM_USER = 0;
#ifdef ENABLE_QUIZ
long quiz_timer = 0;
long quiz_line = 0;
bool quiz_answer = 0;
bool quiz_halt = 0;
char quiz_target[STRING_SHORT] = { 0 };
long recent_questions[10] = { 0 };
#endif
#ifdef ENABLE_RANDOM
long Rand_Stuff = 0;
long Rand_Idle = 0;
#endif
long AIL4 = 0;
long Sleep_Toggle = 0;
long Sleep_Time = 0;
long AIL3 = 0;
long AIL2 = 0;
long AIL5 = 0;
long JOINs = 0;
long PERMBAN_counter = 0;
long ram_load_time = 0;
long AIL9 = 0;
long AIL666 = 0;
long AIL8 = 0;
#ifdef ENABLE_QUIZ
long AIL13 = 0;
#endif
long LastInput = 0;
long AIL10 = 0;
long MARK_CHANGE = 0;
long html_counter = 0;
char NICK_COMMA[32] = { 0 };
char COLON_NICK[33] = { 0 };
char pass_data[512] = { 0 };
char pass_pass[STRING_SHORT] = { 0 };
char rword[STRING_SHORT] = { 0 };
char lc1[STRING_SHORT] = "0";
char lc2[STRING_SHORT] = "0";
char lc4[STRING_SHORT] = "0";
char lc3[STRING_SHORT] = "0";
char BPASS[STRING_SHORT] = "0";
char mask_tmp[STRING_LONG] = "0";
long lcn1 = 0;
long lcn2 = 0;
long lcn4 = 0;
long lcn3 = 0;
bool SeeN = false;
long DebuG = 0;
char slc1[STRING_SHORT] = "0";
char slc2[STRING_SHORT] = "0";
char slc4[STRING_SHORT] = "0";
char slc3[STRING_SHORT] = "0";
long slcn1 = 0;
long slcn2 = 0;
long slcn4 = 0;
long slcn3 = 0;
#ifdef WIN32
char *rp391 = "niW-4cr8 tobkraD";
#else
char *rp391 = "4cr8 tobkraD";
#endif
char BCOLON_NICK[STRING_SHORT] = { 0 };
char DARKBOT_BIN[STRING_SHORT] = { 0 };
char URL2[STRING_SHORT] = { 0 };
char DBTIMERS_PATH[STRING_SHORT] = { 0 };
char LOG_DIR[STRING_SHORT] = { 0 };
char RDB_DIR[STRING_SHORT] = { 0 };
#ifdef ENABLE_STATS
char STATS_FILE[STRING_SHORT] = { 0 };
#endif
char SEEN_FILE[STRING_SHORT] = { 0 };
char BACKUP_DUP[STRING_SHORT] = { 0 };
char ADD_DELETES[STRING_SHORT] = { 0 };
char AUTOTOPIC_F[STRING_SHORT] = { 0 };
char HELPER_LIST[STRING_SHORT] = { 0 };
char QUIZ_FILE[STRING_SHORT] = { 0 };
char PERFORM[STRING_SHORT] = { 0 };
char DEOP[STRING_SHORT] = { 0 };
char RAND_SAY[STRING_SHORT] = { 0 };
char RAND_FILE[STRING_SHORT] = { 0 };
char RANDQ_TEMPFILE[STRING_SHORT] = { 0 };
char RAND_BACKUP_FILE[STRING_SHORT] = { 0 };
char SERVERS[STRING_SHORT] = { 0 };
char PERMBAN[STRING_SHORT] = { 0 };
char SETUP[STRING_SHORT] = { 0 };
char DAT_DIR[STRING_SHORT] = { 0 };
char r_reply[STRING_SHORT] = { 0 };
char data[STRING_SHORT] = { 0 };
char g_chan[STRING_SHORT] = { 0 };
char dbVersion[STRING_SHORT] = { 0 };
char strbuff[STRING_SHORT] = { 0 };
char f_tmp[STRING_LONG] = { 0 };
char UID[STRING_SHORT] = "database";
char BS[STRING_SHORT] = "irc.freenode.net";
char CMDCHAR[2] = "!";
char CHAN[STRING_SHORT] = "#darkbot";
char s_Mynick[STRING_SHORT] = "darkbot";
char g_host[STRING_SHORT] = { 0 };
char Mynick[STRING_SHORT] = "darkbot";
char sleep_chan[STRING_SHORT] = { 0 };
char VHOST[STRING_SHORT] = "0";
char REALNAME[STRING_SHORT] = "http://darkbot.sourceforge.net";
char privmsg_log[STRING_SHORT] = { 0 };
long CONNECT_WAIT_TIMEOUT = 10;
bool PERFORM_TIMER = true;
char DEFAULT_UMODE[STRING_SHORT] = "+i-ds";
bool ANTI_IDLE = false;
bool DISPLAY_SYNC = false;
bool SORT = false;
bool FIND_DUPS = false;
bool SAVE_DUPS = true;
bool GENERAL_QUESTIONS = true;
//bool ALLOW_ADD_IN_MSG = false;
//bool ALLOW_DEL_IN_MSG = false;
bool MSG_RESPONSES = false;
bool LOG_ADD_DELETES = true;
bool LOG_PRIVMSG = true;
long SLEEP_TIME = 300;
char GOSLEEP_ACTION[STRING_SHORT] = "\1ACTION falls asleep... ZzzZZzzZZzz\1";
char WAKEUP_ACTION[STRING_SHORT] = "\1ACTION wakes up from a snooze..\1";
long LASTCOMM_TIME = 5;
long OUTPUT1_COUNT = 4;
long OUTPUT1_DELAY = 1;
long OUTPUT2_COUNT = 6;
long OUTPUT2_DELAY = 2;
long OUTPUT3_DELAY = 3;
long OUTPUT_PURGE_COUNT = 7;
char EXISTING_ENTRY[STRING_SHORT] = "Sorry, there is an existing entry under keyword";
char NO_ENTRY[STRING_SHORT] = "I was unable to find entry:";
//char CANT_FIND[STRING_SHORT] = "Was unable to find"; /* ... */
char NO_TOPIC[STRING_SHORT] = "Sorry, I don't have any entry for"; /* ... */
char TRY_FIND[STRING_SHORT] = "What am I trying to find";
char WHUT[STRING_SHORT] = "hmmm?";
char DUNNO_Q[STRING_SHORT] = "*shrug*";
bool RANDOM_DUNNO = true;
bool RANDOM_WHUT = true;
#ifdef ENABLE_RANDOM
//bool RANDOM_STUFF = true;
long RAND_STUFF_TIME = 3600;
long RAND_IDLE = 1800;
//long RAND_LEVEL = 2;
//bool RANDQ = true;
bool BACKUP_RANDOMSTUFF = false;
#endif
bool JOIN_GREET = true;
long SLASTCOMM_TIME = 60;
bool VOICE_USERS_ON_JOIN = false;
bool OP_USERS_ON_LOGIN = false;
bool DO_WHOIS = false;
long MAX_LASTSEEN = 604800;
char SEEN_REPLY[STRING_SHORT] = "in the last 7 days.";
char COMPLAIN_REASON[STRING_SHORT] = "grrr, kick me again and I'm going to...";
bool BITCH_ABOUT_DEOP = false;
char BITCH_DEOP_REASON[STRING_SHORT] = "grr, someone op me!";
long AUTOTOPIC_TIME = 1800;
char DEFAULT_KICK[STRING_SHORT] = "Requested!";
bool KICK_ON_BAN = false;
bool KICK_ON_CHANNEL_NOTICE = true;
bool BAN_ON_CHANNEL_NOTICE = false;
bool BAN_BY_HOST = false;
bool FLOOD_KICK = true;
char FLOOD_REASON[STRING_SHORT] = "Don't flood!";
#ifdef ENABLE_QUIZ
long QUIZ_TIMER = 25;
long QUIZ_REPEAT_TIMER = 20;
#endif
bool HELP_GREET = false;
bool AUTOHELP_GUESTS = false;
char mySetinfo[STRING_SHORT] = "My !setinfo variables are: ^ nick, % Number of joins, & \
Channel, $ user@host. Example: !setinfo ^ has joined & % times!! (also, if \
you make the first char of your SETINFO a \"+\" the setinfo will be shown \
as an ACTION)";
char myVariables[STRING_SHORT] = "Data variables are: N~ (Nick), C~ (Chan), T~ \
(Time/date) B~ (Botnick), Q~ (Question asked), R~ (random nick), !~ \
(command char), S~ (current Server), P~ (current port) V~ (botVer), W~ \
(db WWW site), H~ (u@h), t~ (unixtime), BAN (sets a ban), TEMPBAN (bans \
for 60 sec)";
struct rusage r_usage;
struct ignorelist *ignorehead = NULL;
struct sendq *sendqhead = NULL, *sendqtail = NULL;
struct userlist *userhead = NULL;
struct helperlist *helperhead = NULL;
struct permbanlist *permbanhead = NULL;
struct old ood[STRING_SHORT];
struct sl124 *sh124 = NULL;
#ifdef ENABLE_STATS
struct statslist *statshead = NULL;
#endif
struct webinfo
WEBSEARCH_webinfo = { "WEBSEARCH", "api.duckduckgo.com", 80, "/?format=xml&q=" } ,
METAR_webinfo = { "METAR", "www.aviationweather.gov", 80, "/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=" } ,
TAF_webinfo = { "TAF", "www.aviationweather.gov", 80, "/adds/dataserver_current/httpparam?dataSource=tafs&requestType=retrieve&format=xml&hoursBeforeNow=3&mostRecent=true&stationString=" } ,
WEATHER_webinfo = { "WEATHER", "mobile.wunderground.com", 80, "/cgi-bin/findweather/getForecast?brand=mobile&query=" };
struct setup_parameter parameters[] =
{
// I managed to eliminate these options when I rewrote chansrv.c.
// {ST_BOOLEAN, 3, sizeof(ALLOW_ADD_IN_MSG), {"ALLOW_ADD_IN_MSG", NULL, NULL, NULL, NULL}, "allowing ADD command in private", &ALLOW_ADD_IN_MSG, NULL},
// {ST_BOOLEAN, 3, sizeof(ALLOW_DEL_IN_MSG), {"ALLOW_DEL_IN_MSG", NULL, NULL, NULL, NULL}, "allowing DEL command in private", &ALLOW_DEL_IN_MSG, NULL},
{ST_BOOLEAN, 3, sizeof(ANTI_IDLE), {"ANTI_IDLE", NULL, NULL, NULL, NULL}, "idling for less than ten minutes", &ANTI_IDLE, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(BITCH_ABOUT_DEOP), {"BITCH_DEOP", NULL, NULL, NULL, NULL}, "bitch about deop", &BITCH_ABOUT_DEOP, NULL},
{ST_STRING, 3, sizeof(BITCH_DEOP_REASON), {"BITCH_DEOP_TEXT", NULL, NULL, NULL, NULL}, "deop complaint", BITCH_DEOP_REASON, NULL},
#endif
{ST_STRING, 3, sizeof(COMPLAIN_REASON), {"BITCH_KICK_TEXT", NULL, NULL, NULL, NULL}, "bot kicked message", COMPLAIN_REASON, NULL},
{ST_STRING, 3, sizeof(CMDCHAR), {"BOT_CMD_CHAR", NULL, NULL, NULL, NULL}, "bot's command char", CMDCHAR, NULL},
{ST_STRING, 3, sizeof(Mynick), {"BOT_NICK", NULL, NULL, NULL, NULL}, "bot's nickname", Mynick, check_nick_parameter},
{ST_STRING, 3, sizeof(REALNAME), {"BOT_NAME", NULL, NULL, NULL, NULL}, "bot's real name", REALNAME, NULL},
{ST_STRING, 3, sizeof(UID), {"BOT_USER_ID", NULL, NULL, NULL, NULL}, "bot's user ID", UID, NULL},
{ST_STRING, 3, sizeof(DEFAULT_UMODE), {"BOT_USER_MODE", NULL, NULL, NULL, NULL}, "bot's user modes", DEFAULT_UMODE, NULL},
{ST_STRING, 3, sizeof(VHOST), {"BOT_VHOST", NULL, NULL, NULL, NULL}, "bot's virtual host", VHOST, NULL},
{ST_INTEGER, 3, sizeof(CONNECT_WAIT_TIMEOUT), {"CONNECT_TIME", NULL, NULL, NULL, NULL}, "server connection timeout", &CONNECT_WAIT_TIMEOUT, NULL},
{ST_STRING, 3, sizeof(CHAN), {"DEFAULT_CHANNEL", NULL, NULL, NULL, NULL}, "channel", CHAN, NULL},
{ST_BOOLEAN, 3, sizeof(DISPLAY_SYNC), {"DISPLAY_SYNC", NULL, NULL, NULL, NULL}, "tell channel bot has finished syncing", &DISPLAY_SYNC, NULL},
{ST_BOOLEAN, 3, sizeof(DO_WHOIS), {"DO_WHOIS", NULL, NULL, NULL, NULL}, "questionable channel alert", &DO_WHOIS, NULL},
{ST_STRING, 3, sizeof(DUNNO_Q), {"DUNNO_TEXT", NULL, NULL, NULL, NULL}, "no answer complaint", DUNNO_Q, NULL},
{ST_BOOLEAN, 3, sizeof(RANDOM_DUNNO), {"DUNNO_RANDOM_TEXT", NULL, NULL, NULL, NULL}, "random no answer complaint", &RANDOM_DUNNO, NULL},
{ST_BOOLEAN, 3, sizeof(FIND_DUPS), {"DUPS_REMOVE", NULL, NULL, NULL, NULL}, "remove duplicates in hatabase", &FIND_DUPS, NULL},
{ST_BOOLEAN, 3, sizeof(SAVE_DUPS), {"DUPS_SAVE", NULL, NULL, NULL, NULL}, "save duplicates in database", &SAVE_DUPS, NULL},
{ST_STRING, 3, sizeof(EXISTING_ENTRY), {"ENTRY_EXISTS_TEXT", NULL, NULL, NULL, NULL}, "replacing existing complaint", EXISTING_ENTRY, NULL},
{ST_STRING, 3, sizeof(NO_ENTRY), {"ENTRY_NOT_EXIST_TEXT", NULL, NULL, NULL, NULL}, "non-existing topic complaint", NO_ENTRY, NULL},
{ST_STRING, 3, sizeof(NO_TOPIC), {"FIND_NO_TEXT", NULL, NULL, NULL, NULL}, "no topic search complaint", NO_TOPIC, NULL},
{ST_STRING, 3, sizeof(TRY_FIND), {"FIND_WHAT_TEXT", NULL, NULL, NULL, NULL}, "try find search complaint", TRY_FIND, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(KICK_ON_CHANNEL_NOTICE), {"FLOOD_NOTICE_KICK", NULL, NULL, NULL, NULL}, "kick on channel notice flood", &KICK_ON_CHANNEL_NOTICE, NULL},
{ST_BOOLEAN, 3, sizeof(BAN_ON_CHANNEL_NOTICE), {"FLOOD_NOTICE_BAN", NULL, NULL, NULL, NULL}, "ban on channel notice flood", &BAN_ON_CHANNEL_NOTICE, NULL},
{ST_BOOLEAN, 3, sizeof(BAN_BY_HOST), {"FLOOD_NOTICE_BAN_HOST", NULL, NULL, NULL, NULL}, "ban by host on channel notice flood", &BAN_BY_HOST, NULL},
{ST_BOOLEAN, 3, sizeof(FLOOD_KICK), {"FLOOD_KICK", NULL, NULL, NULL, NULL}, "kick if bot is flooded", &FLOOD_KICK, NULL},
{ST_STRING, 3, sizeof(FLOOD_REASON), {"FLOOD_TEXT", NULL, NULL, NULL, NULL}, "flooded bot complaint", FLOOD_REASON, NULL},
#endif
{ST_BOOLEAN, 3, sizeof(AUTOHELP_GUESTS), {"GREET_GUESTS_TEXT", NULL, NULL, NULL, NULL}, "give guests help", &AUTOHELP_GUESTS, NULL},
{ST_BOOLEAN, 3, sizeof(HELP_GREET), {"GREET_NEW_TEXT", NULL, NULL, NULL, NULL}, "give new users help", &HELP_GREET, NULL},
{ST_BOOLEAN, 3, sizeof(JOIN_GREET), {"GREET_USER_TEXT", NULL, NULL, NULL, NULL}, "registered user greeting", &JOIN_GREET, NULL},
{ST_INTEGER, 3, sizeof(LASTCOMM_TIME), {"IGNORE_TIME", NULL, NULL, NULL, NULL}, "seconds to ignore repeated topics", &LASTCOMM_TIME, NULL},
{ST_INTEGER, 3, sizeof(SLASTCOMM_TIME), {"IGNORE_USER_TIME", NULL, NULL, NULL, NULL}, "registered user delay seconds", &SLASTCOMM_TIME, NULL},
#ifdef ENABLE_CHANNEL
{ST_STRING, 3, sizeof(DEFAULT_KICK), {"KICK_TEXT", NULL, NULL, NULL, NULL}, "kick message", DEFAULT_KICK, NULL},
{ST_BOOLEAN, 3, sizeof(KICK_ON_BAN), {"KICK_ON_BAN", NULL, NULL, NULL, NULL}, "kick when banned", &KICK_ON_BAN, NULL},
#endif
{ST_BOOLEAN, 3, sizeof(LOG_ADD_DELETES), {"LOG_CHANGES", NULL, NULL, NULL, NULL}, "logging of database changes", &LOG_ADD_DELETES, NULL},
{ST_BOOLEAN, 3, sizeof(LOG_PRIVMSG), {"LOG_PRIVATE", NULL, NULL, NULL, NULL}, "logging of private messages", &LOG_PRIVMSG, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(OP_USERS_ON_LOGIN), {"OP_ON_LOGIN", NULL, NULL, NULL, NULL}, "op users on login", &OP_USERS_ON_LOGIN, NULL},
#endif
{ST_INTEGER, 3, sizeof(OUTPUT1_COUNT), {"OUTPUT1_COUNT", NULL, NULL, NULL, NULL}, "output delay threshold", &OUTPUT1_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT1_DELAY), {"OUTPUT1_TIME", NULL, NULL, NULL, NULL}, "output delay seconds", &OUTPUT1_DELAY, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT2_COUNT), {"OUTPUT2_COUNT", NULL, NULL, NULL, NULL}, "long output delay threshold", &OUTPUT2_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT2_DELAY), {"OUTPUT2_TIME", NULL, NULL, NULL, NULL}, "long output delay seconds", &OUTPUT2_DELAY, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT_PURGE_COUNT), {"OUTPUT_PURGE_COUNT", NULL, NULL, NULL, NULL}, "purge output delay threshold", &OUTPUT_PURGE_COUNT, NULL},
{ST_INTEGER, 3, sizeof(OUTPUT3_DELAY), {"OUTPUT3_TIME", NULL, NULL, NULL, NULL}, "purge output delay seconds", &OUTPUT3_DELAY, NULL},
{ST_BOOLEAN, 3, sizeof(PERFORM_TIMER), {"PERFORM_TIME", NULL, NULL, NULL, NULL}, "sending perform.ini to server reqularly", &PERFORM_TIMER, NULL},
{ST_BOOLEAN, 3, sizeof(GENERAL_QUESTIONS), {"QUESTIONS_GENERAL", NULL, NULL, NULL, NULL}, "bot responds without being asked", &GENERAL_QUESTIONS, NULL},
{ST_BOOLEAN, 3, sizeof(MSG_RESPONSES), {"QUESTIONS_PRIVATE", NULL, NULL, NULL, NULL}, "bot responds to private questions", &MSG_RESPONSES, NULL},
#ifdef ENABLE_QUIZ
{ST_INTEGER, 3, sizeof(QUIZ_TIMER), {"QUIZ_TIME", NULL, NULL, NULL, NULL}, "quiz answer seconds", &QUIZ_TIMER, NULL},
{ST_INTEGER, 3, sizeof(QUIZ_REPEAT_TIMER), {"QUIZ_REPEAT_TIME", NULL, NULL, NULL, NULL}, "next quiz delay seconds", &QUIZ_REPEAT_TIMER, NULL},
#endif
#ifdef ENABLE_RANDOM
// This one is currently ./configure --enable-random
// {ST_BOOLEAN, 3, sizeof(RANDOM_STUFF), {"RANDOM_STUFF", NULL, NULL, NULL, NULL}, "random utterences", &RANDOM_STUFF, NULL},
{ST_BOOLEAN, 3, sizeof(BACKUP_RANDOMSTUFF), {"RANDOM_BACKUP", NULL, NULL, NULL, NULL}, "enable random stuff auto backups", &BACKUP_RANDOMSTUFF, NULL},
{ST_INTEGER, 3, sizeof(RAND_IDLE), {"RANDOM_IDLE_TIME", NULL, NULL, NULL, NULL}, "seconds idle before random utterences", &RAND_IDLE, NULL},
// This one is currently ./configure --with-random=level
// {ST_INTEGER, 3, sizeof(RAND_LEVEL), {"RANDOM_LEVEL", NULL, NULL, NULL, NULL}, "level for adding random things", &RAND_LEVEL, NULL},
// This one is currently ./configure --enable-randq
// {ST_BOOLEAN, 3, sizeof(RANDQ), {"RANDOM_Q", NULL, NULL, NULL, NULL}, "enable RANDQ command", &RANDQ, NULL},
{ST_INTEGER, 3, sizeof(RAND_STUFF_TIME), {"RANDOM_TIME", NULL, NULL, NULL, NULL}, "seconds between random utterences", &RAND_STUFF_TIME, NULL},
#endif
{ST_BOOLEAN, 3, sizeof(SeeN), {"SEEN_MODE", NULL, NULL, NULL, NULL}, "seen mode", &SeeN, NULL},
{ST_INTEGER, 3, sizeof(MAX_LASTSEEN), {"SEEN_TIME", NULL, NULL, NULL, NULL}, "maximum last seen seconds", &MAX_LASTSEEN, NULL},
{ST_STRING, 3, sizeof(SEEN_REPLY), {"SEEN_TEXT", NULL, NULL, NULL, NULL}, "maximum last seen reply", SEEN_REPLY, NULL},
{ST_STRING, 3, sizeof(mySetinfo), {"SETINFO_TEXT", NULL, NULL, NULL, NULL}, "setinfo variables help text", mySetinfo, NULL},
{ST_INTEGER, 3, sizeof(SLEEP_TIME), {"SLEEP_TIME", NULL, NULL, NULL, NULL}, "seconds to sleep for", &SLEEP_TIME, NULL},
{ST_STRING, 3, sizeof(GOSLEEP_ACTION), {"SLEEP_TEXT", NULL, NULL, NULL, NULL}, "sleep action", GOSLEEP_ACTION, NULL},
{ST_STRING, 3, sizeof(WAKEUP_ACTION), {"SLEEP_WAKE_TEXT", NULL, NULL, NULL, NULL}, "wakeup action", WAKEUP_ACTION, NULL},
{ST_BOOLEAN, 3, sizeof(SORT), {"SORT_DB", NULL, NULL, NULL, NULL}, "sort database on startup", &SORT, NULL},
#ifdef ENABLE_CHANNEL
{ST_INTEGER, 3, sizeof(AUTOTOPIC_TIME), {"TOPIC_TIME", NULL, NULL, NULL, NULL}, "topic setting seconds", &AUTOTOPIC_TIME, NULL},
#endif
{ST_STRING, 3, sizeof(myVariables), {"VARIABLES_TEXT", NULL, NULL, NULL, NULL}, "data variables help text", myVariables, NULL},
#ifdef ENABLE_CHANNEL
{ST_BOOLEAN, 3, sizeof(VOICE_USERS_ON_JOIN), {"VOICE_ON_JOIN", NULL, NULL, NULL, NULL}, "voice users on join", &VOICE_USERS_ON_JOIN, NULL},
#endif
{ST_STRING, 3, sizeof(WHUT), {"WHUT_TEXT", NULL, NULL, NULL, NULL}, "no text complaint", WHUT, NULL},
{ST_BOOLEAN, 3, sizeof(RANDOM_WHUT), {"WHUT_RANDOM_TEXT", NULL, NULL, NULL, NULL}, "random no text complaint", &RANDOM_WHUT, NULL},
// Cant find CANT_FIND. B-)
// {ST_STRING, 3, sizeof(CANT_FIND), {"CANT_FIND", NULL, NULL, NULL, NULL}, "can't find search complaint", CANT_FIND, NULL},
{ST_STRING, 4, 0, {NULL, NULL, NULL, NULL, NULL}, NULL, NULL, NULL}
};
struct setup_parameter *
set_parameter(char *input)
{
struct setup_parameter *result = NULL;
/* ignore comments. */
if (*input != '#')
{
int i, found = -1;
char *dat = NULL, *ptr = NULL;
dat = strdup(input);
if ((ptr = strchr(dat, '=')) != NULL)
*ptr++ = '\0';
for (result = &parameters[0]; result->parameter[0] != NULL; result++)
{
for (i = 0; result->parameter[i] != NULL; i++)
{
if (strcasecmp(dat, result->parameter[i]) == 0)
{
found = i;
break;
}
}
if (found != -1)
break;
}
if (found == -1)
result = NULL;
else
{
if ((ptr) && (result->func))
{
ptr = result->func(result, ptr);
if (ptr == NULL)
result = NULL;
}
if (ptr)
{
#ifdef ENABLE_VERBOSE
printf("Setting %s = %s\n", result->summary, ptr);
#endif
switch (result->type)
{
case ST_BOOLEAN :
{
bool *variable = result->value;
*variable = isBoolean(ptr);
break;
}
case ST_INTEGER :
{
long *variable = result->value;
*variable = atoi(ptr);
break;
}
case ST_STRING :
{
char *variable = result->value;
strncpy(variable, ptr, result->max_size);
break;
}
}
}
}
free(dat);
}
return result;
}
void
save_setup (void)
{
struct setup_parameter *result = NULL;
printf("*** Writing setup file: %s (%s)\n", SETUP, date());
remove(TMP_FILE);
for (result = &parameters[0]; result->parameter[0] != NULL; result++)
{
switch (result->type)
{
case ST_BOOLEAN :
{
bool *variable = result->value;
db_log(TMP_FILE, "%s=%d\n", result->parameter[0], (*variable) ? 1 : 0);
break;
}
case ST_INTEGER :
{
long *variable = result->value;
db_log(TMP_FILE, "%s=%ld\n", result->parameter[0], *variable);
break;
}
case ST_STRING :
{
char *variable = result->value;
db_log(TMP_FILE, "%s=%s\n", result->parameter[0], variable);
break;
}
}
}
rename(TMP_FILE, SETUP);
}
diff --git a/source/vars.h b/source/vars.h
index b9045cf..c2d9b31 100644
--- a/source/vars.h
+++ b/source/vars.h
@@ -1,363 +1,374 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#define STRING_SHORT 512
#define STRING_LONG 2048
#define FLAG_CHANOP 0x0001
#define FLAG_CHANVOICE 0x0002
extern int wsock;
extern int sockerr;
extern int optlen;
extern size_t nRandStuffs;
extern long QUESTIONS;
extern long ADDITIONS;
extern long DELETIONS;
extern long uptime;
extern long NO_FLOOD;
extern long NUM_SERV;
extern long L_CLIENTS;
extern long IRCOPS;
extern long xtried;
extern long G_USERS;
extern long rt;
extern long fc;
extern long spr;
extern long snr;
extern long BP;
extern long CHECKED;
extern long SEND_DELAY;
extern long send_tog;
extern long NUM_HELPER;
extern long NUM_USER;
extern long NUMLINESSEEN;
extern long Rand_Stuff;
extern long Rand_Idle;
extern long AIL4;
extern long Sleep_Toggle;
extern long Sleep_Time;
extern long AIL3;
extern long AIL2;
extern long AIL5;
extern long JOINs;
extern long PERMBAN_counter;
extern long RAND_CHANS;
extern long ram_load_time;
extern long AIL9;
extern long AIL666;
extern long AIL8;
#ifdef ENABLE_QUIZ
extern long AIL13;
#endif
extern long LastInput;
extern long AIL10;
extern long MARK_CHANGE;
extern long html_counter;
extern long lcn1;
extern long lcn2;
extern long lcn4;
extern long lcn3;
extern bool SeeN;
extern long DebuG;
#ifdef ENABLE_QUIZ
extern long quiz_timer;
extern long quiz_line;
extern bool quiz_answer;
extern bool quiz_halt;
extern long recent_questions[10];
#endif
extern char NICK_COMMA[32];
extern char COLON_NICK[33];
extern char BPASS[STRING_SHORT];
extern char pass_data[512];
extern char pass_pass[STRING_SHORT];
extern char rword[STRING_SHORT];
extern char lc1[STRING_SHORT];
extern char lc2[STRING_SHORT];
extern char lc4[STRING_SHORT];
extern char lc3[STRING_SHORT];
extern char slc1[STRING_SHORT];
extern char slc2[STRING_SHORT];
extern char slc4[STRING_SHORT];
extern char slc3[STRING_SHORT];
extern char mask_tmp[STRING_LONG];
extern char quiz_target[STRING_SHORT];
extern long slcn1;
extern long slcn2;
extern long slcn4;
extern long slcn3;
extern char *rp391;
extern char BCOLON_NICK[STRING_SHORT];
extern char DARKBOT_BIN[STRING_SHORT];
extern char URL2[STRING_SHORT];
extern char DBTIMERS_PATH[STRING_SHORT];
extern char LOG_DIR[STRING_SHORT];
extern char RDB_DIR[STRING_SHORT];
#ifdef ENABLE_STATS
extern char STATS_FILE[STRING_SHORT];
#endif
extern char SEEN_FILE[STRING_SHORT];
extern char BACKUP_DUP[STRING_SHORT];
extern char ADD_DELETES[STRING_SHORT];
extern char AUTOTOPIC_F[STRING_SHORT];
extern char HELPER_LIST[STRING_SHORT];
extern char QUIZ_FILE[STRING_SHORT];
extern char PERFORM[STRING_SHORT];
extern char DEOP[STRING_SHORT];
extern char RAND_SAY[STRING_SHORT];
extern char RAND_FILE[STRING_SHORT];
extern char RANDQ_TEMPFILE[STRING_SHORT];
extern char RAND_BACKUP_FILE[STRING_SHORT];
extern char SERVERS[STRING_SHORT];
extern char PERMBAN[STRING_SHORT];
extern char SETUP[STRING_SHORT];
extern char DAT_DIR[STRING_SHORT];
extern char r_reply[STRING_SHORT];
extern char data[STRING_SHORT];
extern char g_chan[STRING_SHORT];
extern char dbVersion[STRING_SHORT];
extern char strbuff[STRING_SHORT];
extern char f_tmp[STRING_LONG];
extern char UID[STRING_SHORT];
extern char BS[STRING_SHORT];
extern char CMDCHAR[2];
extern char CHAN[STRING_SHORT];
extern char s_Mynick[STRING_SHORT];
extern char g_host[STRING_SHORT];
extern char Mynick[STRING_SHORT];
extern char sleep_chan[STRING_SHORT];
extern char VHOST[STRING_SHORT];
extern char REALNAME[STRING_SHORT];
extern char privmsg_log[STRING_SHORT];
extern long CONNECT_WAIT_TIMEOUT;
extern bool PERFORM_TIMER;
extern char DEFAULT_UMODE[STRING_SHORT];
extern bool ANTI_IDLE;
extern bool DISPLAY_SYNC;
extern bool SORT;
extern bool FIND_DUPS;
extern bool SAVE_DUPS;
extern bool GENERAL_QUESTIONS;
extern bool ALLOW_ADD_IN_MSG;
extern bool ALLOW_DEL_IN_MSG;
extern bool MSG_RESPONSES;
extern bool LOG_ADD_DELETES;
extern bool LOG_PRIVMSG;
extern long SLEEP_TIME;
extern char GOSLEEP_ACTION[STRING_SHORT];
extern char WAKEUP_ACTION[STRING_SHORT];
extern long LASTCOMM_TIME;
extern long OUTPUT1_COUNT;
extern long OUTPUT1_DELAY;
extern long OUTPUT2_COUNT;
extern long OUTPUT2_DELAY;
extern long OUTPUT3_DELAY;
extern long OUTPUT_PURGE_COUNT;
extern char EXISTING_ENTRY[STRING_SHORT];
extern char NO_ENTRY[STRING_SHORT];
//extern char CANT_FIND[STRING_SHORT]; /* ... */
extern char NO_TOPIC[STRING_SHORT]; /* ... */
extern char TRY_FIND[STRING_SHORT];
extern char WHUT[STRING_SHORT];
extern bool RANDOM_WHUT;
extern char DUNNO_Q[STRING_SHORT];
extern bool RANDOM_DUNNO;
#ifdef ENABLE_RANDOM
//extern bool RANDOM_STUFF;
extern long RAND_STUFF_TIME;
extern long RAND_IDLE;
//extern long RAND_LEVEL;
//extern bool RANDQ;
extern bool BACKUP_RANDOMSTUFF;
#endif
extern bool JOIN_GREET;
extern long SLASTCOMM_TIME;
#ifdef ENABLE_CHANNEL
extern bool VOICE_USERS_ON_JOIN;
extern bool OP_USERS_ON_LOGIN;
#endif
extern bool DO_WHOIS;
extern long MAX_LASTSEEN;
extern char SEEN_REPLY[STRING_SHORT];
extern char COMPLAIN_REASON[STRING_SHORT];
#ifdef ENABLE_CHANNEL
extern bool BITCH_ABOUT_DEOP;
extern char BITCH_DEOP_REASON[STRING_SHORT];
extern long AUTOTOPIC_TIME;
extern char DEFAULT_KICK[STRING_SHORT];
extern bool KICK_ON_BAN;
extern bool KICK_ON_CHANNEL_NOTICE;
extern bool BAN_ON_CHANNEL_NOTICE;
extern bool BAN_BY_HOST;
extern bool FLOOD_KICK;
extern char FLOOD_REASON[STRING_SHORT];
#endif
#ifdef ENABLE_QUIZ
extern long QUIZ_TIMER;
extern long QUIZ_REPEAT_TIMER;
#endif
extern bool HELP_GREET;
extern bool AUTOHELP_GUESTS;
extern char mySetinfo[STRING_SHORT];
extern char myVariables[STRING_SHORT];
extern struct rusage r_usage;
extern struct ignorelist
{
char nick[STRING_SHORT];
struct ignorelist *next;
}
*ignorehead;
extern struct sendq
{
char data[STRING_SHORT];
struct sendq *next;
}
*sendqhead, *sendqtail;
extern struct userlist
{ /* internal userlist */
char chan[STRING_SHORT];
char nick[STRING_SHORT];
char uh[STRING_SHORT];
long flags; /* op/voice/etc */
long level; /* auth */
short global; /* Global user? */
long idle;
struct userlist *next;
}
*userhead;
extern struct helperlist
{
char chan[STRING_SHORT];
char uh[STRING_SHORT];
char nick[STRING_SHORT];
long level;
size_t num_join;
char greetz[STRING_SHORT];
char pass[STRING_SHORT];
struct helperlist *next;
}
*helperhead;
/**
* 6/23/00 Dan
* - Changed permbanlist to have dynamically allocated
* userhost and reason fields.
* - Changed type of counter to size_t, this should be an
* unsigned type.
*/
extern struct permbanlist
{
char *uh;
char *reason;
size_t counter;
struct permbanlist *next;
}
*permbanhead;
extern struct old
{
char host[200];
long time;
int count;
int value;
int kick;
}
ood[STRING_SHORT];
extern struct sl124
{
char name[STRING_SHORT];
long port;
char pass[STRING_SHORT];
struct sl124 *next;
}
*sh124;
#ifdef ENABLE_STATS
extern struct statslist
{
char nick[STRING_SHORT];
char uh[STRING_SHORT];
long total;
long added_time;
long last_time;
struct statslist *next;
}
*statshead;
#endif
extern struct randstats
{
char chan [STRING_SHORT];
size_t Rand_Stuff;
size_t Rand_Idle;
size_t refnum;
size_t nCount; /* Number of times we outputted to this channel. */
struct randstats *next;
/* struct randstats *prev; */
}
*randstatshead;
struct chanserv_output
{
char *output;
struct chanserv_output *next;
};
extern struct webinfo
{
char trigger[STRING_SHORT];
char host[STRING_SHORT];
int port;
char url[STRING_SHORT];
}
WEBSEARCH_webinfo, METAR_webinfo, TAF_webinfo, WEATHER_webinfo;
enum setup_type
{
ST_BOOLEAN = 0,
ST_INTEGER = 1,
ST_STRING = 2
};
enum chanserv_invoke_type
{
DIRECT_INVOKE = 0, // command
ADDRESS_INVOKE = 1, // bot: command
MSG_INVOKE = 2, // /msg bot command
CHAR_INVOKE = 3 // !command
};
extern struct setup_parameter
{
enum setup_type type;
int access; /* Access level required to change the value. */
size_t max_size;
char *parameter[5];
char *summary;
void *value; /* Where the value is stored. */
void *(*func) (struct setup_parameter *parameter, char *ptr); /* Optional function that can do other things with the value, and veto the change by returning NULL. */
}
parameters[];
diff --git a/source/web.c b/source/web.c
index 3285a64..2957e0a 100644
--- a/source/web.c
+++ b/source/web.c
@@ -1,629 +1,640 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "defines.h"
#include "tree.h"
#include "vars.h"
#include "prototypes.h"
#if defined ENABLE_WEBSEARCH || defined ENABLE_METAR || defined ENABLE_TAF || defined ENABLE_WEATHER
static void init_sockaddr (struct sockaddr_in *, char *, unsigned short int);
static int web_open_socket (char *host, int port);
static int web_write_server (int filedes, char *format,...);
static struct chanserv_output *web_read_server (char *source, char *uh, char *target, int filedes, char *host, struct chanserv_output *output);
static struct chanserv_output *websearch_parse_query (char *source, char *uh, char *target, char *data, struct chanserv_output *output);
static int _websearch_parse (const void *data, Tree *tree, int element, int level);
static struct chanserv_output *weather_parse_query (char *source, char *uh, char *target, char *data, struct chanserv_output *output);
static struct chanserv_output *metar_parse_query (char *source, char *uh, char *target, char *data, struct chanserv_output *output);
static int _metar_parse (const void *data, Tree *tree, int element, int level);
static struct chanserv_output *taf_parse_query (char *source, char *uh, char *target, char *data, struct chanserv_output *output);
struct chanserv_output *web_post_query(char *trigger, char *source, char *uh, char *target, char *query, int size)
{
struct chanserv_output *result = NULL;
char *ptr = NULL;
char *mem = NULL;
struct webinfo *wi = NULL;
if(strcasecmp (trigger, WEBSEARCH_webinfo.trigger) == 0)
{
wi = (struct webinfo *) &WEBSEARCH_webinfo;
}
else if(strcasecmp (trigger, METAR_webinfo.trigger) == 0)
{
wi = (struct webinfo *) &METAR_webinfo;
}
else if(strcasecmp (trigger, TAF_webinfo.trigger) == 0)
{
wi = (struct webinfo *) &TAF_webinfo;
}
else if(strcasecmp (trigger, WEATHER_webinfo.trigger) == 0)
{
wi = (struct webinfo *) &WEATHER_webinfo;
}
else
{
return result;
}
size++; // for null
if((ptr = calloc(size, sizeof(char))) == NULL)
{
return chanserv_asprintf(result, "ERR_CANT_MALLOC");
}
mem = ptr;
if(web_open_socket(wi->host, wi->port) != SUCCESS)
{
free (mem);
return chanserv_asprintf(result, "ERR_OPEN_SOCKET");
}
snprintf(ptr, size + 1, "%s", query);
while(*ptr != '\0')
{
if(*ptr == ' ')
{
*ptr = '+';
}
ptr++;
}
// TODO - we really should URL encode mem.
if(web_write_server(wsock, "GET %s%s HTTP/1.0\r\nHost: %s:%d\r\nUser-Agent: Darkbot\r\nAccept: text/plain\r\n\r\n", wi->url, mem, wi->host, wi->port) != SUCCESS)
{
free (mem);
return chanserv_asprintf(result, "ERR_WRITE_SOCKET");
}
/* i'm passing the trigger instead of the host to web_read_server
because the hostnames could be equal (see METAR & TAF) */
result = web_read_server(source, uh, target, wsock, wi->trigger, result);
close(wsock);
free (mem);
return result;
}
static void
init_sockaddr (struct sockaddr_in *name, char *host, unsigned short int port)
{
struct hostent *hostinfo;
name->sin_family = AF_INET;
name->sin_port = htons (port);
hostinfo = gethostbyname (host);
if (!hostinfo)
{
return;
}
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
}
static int
web_open_socket(char *host, int port)
{
extern void init_sockaddr (struct sockaddr_in *name, char *host, unsigned short int port);
struct sockaddr_in name;
struct timeval timeout;
int result = 0;
int esc = 0;
fd_set set;
if((wsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
return ERR_CANT_CONNECT;
}
if((result = fcntl(wsock, F_SETFL, O_NONBLOCK)) < 0)
{
return ERR_CANT_CONNECT;
}
init_sockaddr (&name, host, port);
if(connect(wsock, (struct sockaddr *) & name, sizeof(name)) != -1)
{
return ERR_CANT_CONNECT;
}
if(errno != EINPROGRESS)
{
return ERR_CANT_CONNECT;
}
while(!esc)
{
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&set);
FD_SET(wsock, &set);
switch(select(FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
case 0:
return ERR_TIMED_OUT;
case -1:
break;
default:
esc++;
switch(getsockopt(wsock, SOL_SOCKET, SO_ERROR, &sockerr, &optlen))
{
case -1:
break;
case 0:
switch(sockerr)
{
case ECONNREFUSED:
break;
case EADDRNOTAVAIL:
break;
case ENETUNREACH:
break;
case SUCCESS:
if((result = fcntl(wsock, F_SETFL, 0)) < 0)
{
return ERR_CANT_CONNECT;
}
return SUCCESS;
}
}
}
}
return SUCCESS;
}
static int
web_write_server (int filedes, char *format,...)
{
int nbytes = 0;
va_list arglist;
char message[STRING_LONG] = {0};
struct timeval timeout;
fd_set set;
va_start(arglist, format);
vsprintf(message, format, arglist);
va_end(arglist);
while(1)
{
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&set);
FD_SET(filedes, &set);
switch (select(FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
case 0:
close(filedes);
return ERR_SERVER_BUSY;
case -1:
if (!alarmed)
{
db_sleep(RECHECK);
}
else
{
alarmed = 0;
}
break;
default:
if((nbytes = write(filedes, message, strlen(message) + 1)) < 0)
{
return ERR_SERVER_BUSY;
}
else
{
return SUCCESS;
}
}
}
}
static struct chanserv_output *web_read_server(char *source, char *uh, char *target, int filedes, char *host, struct chanserv_output *output)
{
int nbytes = 0;
int esc = 0;
char packet[STRING_LONG] = { 0 };
char *mem = NULL;
char *ptr = NULL;
struct timeval timeout;
fd_set set;
if((mem = calloc(sizeof(packet) + 1, sizeof(char))) == NULL)
return chanserv_asprintf(output, "ERR_READ_SOCKET");
alarm(0);
while(!esc)
{
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&set);
FD_SET(filedes, &set);
switch(select(FD_SETSIZE, &set, (fd_set *) NULL, (fd_set *) NULL, &timeout))
{
case 0:
close(filedes);
alarm(AIL);
free (mem);
return chanserv_asprintf(output, "ERR_SERVER_BUSY");
case -1:
break;
default:
alarm(AIL);
esc = 1;
break;
}
}
while((nbytes = recv(filedes, packet, sizeof(packet), 0)) > 0)
{
strncat(mem, packet, sizeof(packet));
if((ptr = realloc(mem, strlen(mem) + sizeof(packet) + 1)) == NULL)
{
free ( mem );
return chanserv_asprintf(output, "ERR_CANT_MALLOC");
}
else
mem = ptr;
memset(packet, 0, sizeof(packet));
}
if(nbytes < 0)
{
free ( mem );
return chanserv_asprintf(output, "ERR_SERVER_BUSY");
}
close(filedes);
if(strcasecmp (host, WEBSEARCH_webinfo.trigger) == 0)
output = websearch_parse_query(source, uh, target, mem, output);
else if(strcasecmp (host, METAR_webinfo.trigger) == 0)
output = metar_parse_query(source, uh, target, mem, output);
else if(strcasecmp (host, TAF_webinfo.trigger) == 0)
output = taf_parse_query(source, uh, target, mem, output);
else if (strcasecmp (host, WEATHER_webinfo.trigger) == 0)
output = weather_parse_query (source, uh, target, mem, output);
free(mem);
return output;
}
static struct chanserv_output *weather_parse_query (char *source, char *uh, char *target, char *data, struct chanserv_output *output)
{
char *s1 = NULL, *s2 = NULL;
char *tmp = NULL, *temp = NULL, *city = NULL;
char *humid = NULL, *dew = NULL;
char *wind = NULL, *pres = NULL, *cond = NULL;
char *vis = NULL, *cloud = NULL, *wind2 = NULL;
char *sunr = NULL, *suns = NULL;
char sub1[] = "<b>";
char sub2[] = "<span class=\"nowrap\"><b>";
if ((s1 = strstr (data, "Observed at")) != NULL)
{
s2 += 8;
if ((s2 = strstr (s1, sub1)) != NULL)
{
city = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Temperature")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
temp = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Humidity")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
humid = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Dew Point")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
dew = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Wind")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
wind = strtok (s2, "</b>");
data = strtok (NULL, "");
if ((tmp = strstr (data, sub2)) != NULL)
{
tmp += strlen (sub2);
wind2 = strtok (tmp, "</b>");
data = strtok (NULL, "");
}
}
}
if ((s1 = strstr (data, "Pressure")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
pres = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Conditions")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
cond = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Visibility")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
vis = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Clouds")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
cloud = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Sunrise")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
sunr = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
if ((s1 = strstr (data, "Sunset")) != NULL)
{
if ((s2 = strstr(s1, sub1)) != NULL)
{
s2 += strlen (sub1);
suns = strtok (s2, "</b>");
data = strtok (NULL, "");
}
}
/* Display stuff to target. */
output = chanserv_asprintf(output, "%s: Temperature (%s%cF) Humidity (%s) DewPoint (%s%cF) Wind (%s at %smph) Pressure (%s in) Conditions (%s) Visibility (%s miles) Clouds (%sft) Sunrise (%s) Sunset (%s)",
city, temp, 176, humid, dew, 176, wind, wind2, pres, cond, vis, cloud, sunr, suns);
return output;
}
static struct chanserv_output * websearch_parse_query(char *source, char *uh, char *target, char *data, struct chanserv_output *output)
{
char url[STRING_LONG] = { 0 };
Tree *result_xml = xmlame_from_string(data);
if (result_xml)
{
tree_foreach(result_xml, 0, _websearch_parse, &url);
output = chanserv_asprintf(output, "%s%s", rand_reply(source), url);
#ifdef ENABLE_STATS
add_stats (source, uh, 1, time (NULL), time (NULL));
#endif
}
else
output = chanserv_asprintf(output, "Sorry, your search did not match any documents.");
return output;
}
static int _websearch_parse(const void *data, Tree *tree, int element, int level)
{
char *url = (char *)data;
int result = 0;
if (tree->elements[element].type == TREE_ELEMENT_TYPE_STRING)
{
char *string;
string = (char *)tree->elements[element].element;
if ((strlen(url) + strlen(string) + 3) < STRING_LONG)
{
if (strncmp(string, "http://", 7) == 0)
{
strcat(url, string);
strcat(url, " ");
result = 1;
}
else if (strncmp(string, "https://", 8) == 0)
{
strcat(url, string);
strcat(url, " ");
result = 1;
}
}
}
return result;
}
struct _metar_data
{
char *temp, *city, *time, *humid, *dew, *wind, *pres, *cond, *vis, *cloud, *wind2, *sunr, *suns;
};
static struct chanserv_output *metar_parse_query(char *source, char *uh, char *target, char *data, struct chanserv_output *output)
{
struct _metar_data _data;
Tree *result_xml = xmlame_from_string(data);
if (result_xml)
{
memset(&_data, 0, sizeof(struct _metar_data));
tree_foreach(result_xml, 0, _metar_parse, &_data);
output = chanserv_asprintf(output, "%s: Observation time (%s) Temperature (%s%cC) DewPoint (%s%cC) Wind (%s%c at %sknots) Visibility (%s statute miles)",
_data.city, _data.time, _data.temp, 176, _data.dew, 176, _data.wind, 176, _data.wind2, _data.vis);
#ifdef ENABLE_STATS
add_stats (source, uh, 1, time (NULL), time (NULL));
#endif
E_FN_DEL(tree_del, (result_xml));
}
else
output = chanserv_asprintf(output, "Sorry, no METAR data available.");
return output;
}
// TODO - There's more that can be decoded, see -
// http://www.aviationweather.gov/adds/dataserver/metars/MetarFieldDescription.php
// http://www.aviationweather.gov/adds/dataserver/tafs/TafsFieldDescription.php
static int _metar_parse(const void *data, Tree *tree, int element, int level)
{
struct _metar_data *_data = (struct _metar_data *)data;
char temp[PATH_MAX];
int result = 0;
if (tree->elements[element].type == TREE_ELEMENT_TYPE_STRING)
{
char *string;
string = (char *)tree->elements[element].element;
if (strcmp(string, "<station_id") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->city = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<observation_time") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->time = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<issue_time") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->time = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<temp_c") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->temp = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<dewpoint_c") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->dew = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<wind_dir_degrees") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->wind = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<wind_speed_kt") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->wind2 = tree->buffers[tree->buffers_size - 1];
result = 1;
}
else if (strcmp(string, "<visibility_statute_mi") == 0)
{
sprintf(temp, "%s", (char *)tree->elements[element + 1].element);
tree_extend(tree, temp);
_data->vis = tree->buffers[tree->buffers_size - 1];
result = 1;
}
}
return result;
}
static struct chanserv_output *taf_parse_query(char *source, char *uh, char *target, char *data, struct chanserv_output *output)
{
struct _metar_data _data;
Tree *result_xml = xmlame_from_string(data);
if (result_xml)
{
memset(&_data, 0, sizeof(struct _metar_data));
tree_foreach(result_xml, 0, _metar_parse, &_data);
output = chanserv_asprintf(output, "%s: Issue time (%s) Wind (%s%c at %sknots) Visibility (%s statute miles)",
_data.city, _data.time, _data.wind, 176, _data.wind2, _data.vis);
#ifdef ENABLE_STATS
add_stats (source, uh, 1, time (NULL), time (NULL));
#endif
E_FN_DEL(tree_del, (result_xml));
}
else
output = chanserv_asprintf(output, "Sorry, no TAF data available.");
return output;
}
#endif
diff --git a/source/xmlame.c b/source/xmlame.c
index 531d4a9..ac960cb 100644
--- a/source/xmlame.c
+++ b/source/xmlame.c
@@ -1,125 +1,136 @@
+/*
+ * Copyright (C) 1996 Darkbot Project.
+
+ * This program is free software, you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+ */
+
+
#include "tree.h"
#include <fcntl.h>
#include <ctype.h>
#include <sys/stat.h>
/** xmlame.c Extensively Mocked Language Approximately Mangled for Enlightenment.
*
* This is NOT a real XML parser. It assumes the XML file is properly formed, and smallish.
*
* The final '>' of a tag is replaced with a '\0', but it's existance can be implied.
*/
static char *_xmlame_parse(Tree * tree, char *buffer);
Tree *xmlame_new(char *buffer)
{
return tree_new(buffer);
}
Tree *xmlame_get(char *file)
{
int size = 0;
char *buffer;
struct stat st;
Tree *tree = NULL;
if (stat(file, &st) >= 0)
size = st.st_size;
buffer = (char *)malloc(size + 1);
if (buffer)
{
int fd;
buffer[0] = '\0';
fd = open(file, O_RDONLY);
if (fd != -1)
{
if (read(fd, buffer, size) == size)
buffer[size] = '\0';
}
tree = xmlame_new(buffer);
if (tree)
{
/* Have the file name as the first item on the tree, for later reference. */
tree_extend(tree, file);
_xmlame_parse(tree, buffer);
}
}
return tree;
}
Tree *xmlame_from_string(char *data)
{
Tree *tree = NULL;
tree = xmlame_new(data);
if (tree)
_xmlame_parse(tree, data);
return tree;
}
static char *_xmlame_parse(Tree * tree, char *buffer)
{
while (*buffer != '\0')
{
char *text;
/* Skip any white space at the beginning. */
while ((*buffer != '\0') && (isspace(*buffer)))
buffer++;
text = buffer;
/* Find the beginning of a tag. */
while ((*buffer != '<') && (*buffer != '\0'))
buffer++;
/* Check for data between tags. */
if (buffer != text)
{
char t;
t = *buffer;
*buffer = '\0';
tree_extend(tree, text);
*buffer = t;
}
if (*buffer != '\0')
{
char *begin;
begin = buffer++;
/* Find the end of the tag. */
while ((*buffer != '>') && (*buffer != '\0'))
buffer++;
/* We have our tag, do something with it. */
if (*buffer != '\0')
{
*buffer++ = '\0';
if (begin[1] == '/')
{ /* The end of an element. */
tree_add(tree, begin);
break;
}
else if ((begin[1] == '!') || (begin[1] == '-') || (*(buffer - 2) == '/'))
{ /* This is a script, a comment, or a stand alone tag. */
tree_add(tree, begin);
}
else
{ /* The beginning of an element. */
Tree *new_tree;
new_tree = xmlame_new(NULL);
if (new_tree)
{
tree_add_child(tree, new_tree);
tree_add(new_tree, begin);
buffer =
_xmlame_parse(new_tree, buffer);
}
}
}
}
}
return buffer;
}
diff --git a/testing.sh b/testing.sh
index f98ead1..354d793 100755
--- a/testing.sh
+++ b/testing.sh
@@ -1,8 +1,17 @@
#! /bin/sh
+# Copyright (C) 1996 Darkbot Project.
+
+# This program is free software, you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2. 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 COPYING file for details.
+
+
make='make'
if which gmake; then make='gmake'; fi
test ! -r build/configure && sh bootstrap.sh
cd build && sh configure -C --prefix=$HOME/darkbot --enable-testing "$@" && $make && $make install && cd ..

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 15:58 (9 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2991057
Default Alt Text
(674 KB)

Event Timeline