Page MenuHomeDevCentral

No OneTemporary

diff --git a/beta/docs/TODO b/beta/docs/TODO
index 424ca30..e83dab2 100644
--- a/beta/docs/TODO
+++ b/beta/docs/TODO
@@ -1,185 +1,189 @@
----------------------------------------------------------
The TO-DO List For Darkbot
----------------------------------------------------------
These are features that are in the planning stages, or
that haven't been completely worked out, yet. Also, any
suggestions that people have made, that are planning to
be added, will be listed here.
Features and bugs are also being tracked via the sf.net
trackers at http://sourceforge.net/projects/darkbot
----------------------------------------------------------
+- chanserv_topic function needs to be a private message
+ command and accept channel arguments (easy, but to
+ remember for later).
+
- atoi needs to be swapped for strtol in all places
since atoi isn't as safe.
- Some kind of solution for large numbers needs to be
worked out for use with the unixtime user command.
Implementations with 32 bit instead of 64 bit longs
are limited to time representations in a range
consisting of only up to one more place value than
the current unixtime, and is a system dependant
value.
- Add some kind of escape sequence or special parsing
for topics that start with key words like "WHAT", these
words are also recognized internally by the bot for
answering questions.
- Multi-channel randomstuffs. I want to make it possible
for every channel specified in setup.ini as the home
channel, in the case of multiple home channels, has
their own randomstuff timers that output randomstuffs
according to the action going on, for each specific
channel.
- Fix broken commands. weather.
- Write things to replace the stuff that Windows can't do.
Backup command, etc.
- Make the output of the MEM command more useful and friendly.
- Make the google command (and maybe all other web
lookup commands) more robust.
- Add internet movie database (http://www.imdb.com) and
slashdot news (http://slashdot.org) searches.
- Single login, remembered across channel part/joins etc.
- Changing the bot's nick needs some testing and tweaking.
- IPv6.
- Merge acronym, 21, lurker, syndet, pantheon, and serv
into darkbot. All are linked to from the darkbot pages.
----------------------------------------------------------
onefang's TO-DO List For Darkbot
----------------------------------------------------------
Add a show parameters command.
Deal with scripts/dbcron one way or another.
Update the INSTALL instructions.
Double check the in code summaries for setup parameters.
Allow multiple command characters - SETCHAR !'~
Convert use of the obsolete gethostbyname() to getaddrinfo().
The alarm() may not be portable enough. Replace multiple alarm() calls
with a single setitimer() call. Give alarm() the benefit of the doubt
for now.
The first argument passed to the various select() calls could be better,
it's more efficient to actually calculate that.
Add a callback to the webinfo structure and otherwise restructure the
web stuff so that disabling a web command can #ifdef out all the code for
that command.
Merge all the scripts plus convertdb into darkbot so that all admin
stuff can be done from IRC, command line, or text UI.
Make the replaceable params in responses consistant. X~ and %X.
If possible, make all !set foo=bar stuff change the current state of the
bot rather than requiring a restart.
Scripting or modules. Scripting using embryo is a really good option.
A limited subset could be used for the calc command as well.
Find a cross pratform Windows/unix GUI toolkit we can live with and
create a GUI for darkbot admin.
Make multiple random responses easier to setup.
admin: bot add foo bar | baz | some other response
user: foo is also blah
admin: bot add foo | another answer
Menu in PM. Plain one liner, colour one liner, multiple lines, colour multiple lines.
user: /msg bot menu
>bot<: Main menu - 1) factiod comands, 2) user commands, 3) channel commands, B) backup one menu, Q) quit menu.
user: /msg bot menu big
>bot<: Main menu -
>bot<: 1) factiod comands
>bot<: 2) user commands
>bot<: 3) channel commands
>bot<: B) backup one menu
>bot<: Q) quit menu.
Don't give long answers in channel, only in PM. Instead, give a summary
in channel, and inform user that a longer response is available via PM.
bot: summary of foo bar. (PM "foo bar" for more.)
luser: PM "foo bar"
bot: PM "foo bar" means to send me a private message you idiot. Try this command "/msg bot foo bar".
Make the bot gender definable, defaulting to female. Allow users to
register their gender. Auto convert all relevant text to proper gender.
Add memos "tell onefang that foo", as opposed to factoid telling "tell
onefang about bah". Allow memos to yourself. Fix alarm and tie that in
as well, alarms to others and to self. Limit memos & alarms to karma
memos & alarms per hour to limit abuse.
Allow unlogged in users to create factiods, and change these factoids, plus
make additions to factoids.
luser: blah is humbug.
user: blah?
bot: luser tells me that blah is humbug. luser may have been drunk at the time.
luser: known fact is wrong.
user: what is known fact?
bot: Known fact is correct. On the other hand, luser thinks that known fact is wrong.
Channel logging, and playback to PM.
wtf, add a karma system.
use it to sort the unlogged user added factoids.
bot: luser tells me that blah is humbug. Others have more to say, but I trust luser more. (PM "blah" for more.)
Use it to refer people to the highest karma person.
bot: Dunno, ask High_Karma_Dude.
Use no karma and negative karma as extra security levels. No karma = -1, negative karma = (karma / 100) - 2
Keep track of how much she has been fed, deny taking food from strangers
(low/no karama users). This implies that botsnack become an information command.
data include files.
Keep track of what database include files are not used for a while, and unload
them, keeping the questions and a pointer to the file though.
Multiple server/channel support like xchat.
Allow different data per server/channel, using includes for common stuff.
Allow different setup per server/channel.
Keep track of unanswered questions, for two reasons -
So the admin can look through it later and add factiods if needed.
If the user is still around (and given a suitable timeout) answer the
question if an answer arrives.
Implement the Porter-Stemmer algorithm to improve English-language
searching as per the drupal module of the same name. It reduces each
word in the index to its basic root or stem (e.g. 'blogging' to 'blog')
so that variations on a word ('blogs', 'blogger', 'blogging', 'blog')
are considered equivalent when searching. This generally results in
more relevant results. Also, start by stripping out all punctuation.
On the other hand, question marks mean it is more likely to be a
question. Same applies to use of the W words near the beginning, they
are more likely to be questions.
Add a locale to weather codes database or search facility. Combine all
the weather commands into one. Make it return metric results.
Command to guess a users timezone, and show time in that zone.
Random greetings, random channel topics, etc.
Interface other shell commands, but be secure. In fact, setup a chroot
for arbitrary shell commands.
Allow DCC to and from a file server.
Channel protection - mass join, mass kick.
diff --git a/beta/docs/WHATSNEW b/beta/docs/WHATSNEW
index e864e17..d3c2903 100644
--- a/beta/docs/WHATSNEW
+++ b/beta/docs/WHATSNEW
@@ -1,915 +1,925 @@
*******************************************************
Warnings, errors, malfunctions, code patches, suggestions
Support Forum: http://www.freezedown.org/forum
(order is reverse-chronologic)
*******************************************************
-Darkbot 8rc3: Feb 03 2008
+Darkbot 8rc3: Aug 18 2008
+ - Changed all command function parsing. Things should hopefully
+ work more correctly again.
+ - HLIST (Helperlist) command now allows multiple arguments.
+ For instead if you want to list all users level 3 and level 3,
+ you would do !HLIST 3 2.
+ - Fixed tell command to tell people about topics without having
+ do delimit them with '+' signs, so it runs like normal text now.
+ - Fixed sleep command. It now actually sleeps for the specified
+ amount of time, if any is specified.
+ - Part message now accepted as a parameter to PART command.
- More work on unixtime function. It now has more complex error
checking for strtol. More work on this to come.
- Renamed pluralize function to plural.
Darkbot 8rc3: Jan 16 2008
- Alarmclock function uses time_t variable now instead of long.
Also now accepts arguments specified in seconds.
- Bot no longer crashing during start if there's blank lines in
the servers file. It now ignores blank lines and comments
starting with '#' and '/'. If the server file is blank, it
aborts and tells the user to edit the file.
- Added pluralize() function for beautification purposes. See more
in general.c.
Darkbot 8rc2: June 07, 2007
- The STATS command, and all overhead produced by this command
can now be disabled during compile like so:
./configure --disable-stats
OR
./configure --enable-stats=no
- Changed the RANDOMSTUFF command to be a NORMAL_COMMAND, so you
can use this command with ADDRESS_INVOKE again (address the bot
directly).
- Added a little thing at the top of docs/WHATSNEW that indicates
which order the lines therein consist of according to when the
changes they represent were implemented. Made this sound more
technical than it should for no reason at all.
- If the input type is ADDRESS_INVOKE (the bot was called upon by
name), the bot responds anyway now, because it's going to output
an "I don't know" response if the topic doesn't exist. This doesn't
happen with DIRECT_INVOKE because the text may have been normal
channel conversation that was mistakenly parsed as a command.
- Commands which require 0 parameters now act accordingly again
when supplied with too many arguments. In other words, "dbtest
info things" would trigger the info command before. Now, it
uses check_existing_url and outputs a response if the topic
exists, otherwise, it just ignores it.
Darkbot 8rc2: December 09, 2006
- Updated server and user lists.
- More fixes to random whut.
- Tweaked random number generation.
- Consistant random number generation throughout the code.
Darkbot 8rc2: December 04, 2006
- Fixed some variable checking that was checking for integers
instead of bool values (random whut is fixed by this, flood
kick)
- Fixed Makefile.am file to produce DOS 8.3 file format
compliant config.h pre-file, and the copyright thingo
in the same file.
Darkbot 8rc2: October 11, 2006
- Fixed some divide by zero errors.
- Cleaned up the logging.
- Cleaned up the output of the build system.
- Cleaned up the parameter names.
- Cleaned up some help text.
- Script for building minimal darkbot.
- Disabled more channel code.
- Started documenting what darkbot works on.
Darkbot 8rc2: June 11, 2006
- Added docs/SETUP.
Darkbot 8rc2: May 31, 2006
- A busy month.
- Completed the autofoo.
- Added compat directory full of replacement functions for
when autofoo decides that the users OS is missing stuff.
- Added a testing mode for developers.
- Cleaned up most OS dependant things so that they now work
everywhere.
- Converted some defines.h things into ./configure --enable-X
--with-X=Y things.
- Added !set foo=bar infrastructure and command. The contents
of setup.ini is now under the control of generic, array based
code. To add things to setup.ini, just add them to the array.
- Added setup.ini parameters to the internal help system.
- Moved the rest of defines.h to setup.ini.
- General clean up and lots of minor things that get fixed in
passing.
- Added docs/HACKING.
- Re arranged some files.
- New building scripts.
- Darkbot and convertdb are much cleverer about finding the data
files.
- Cleaned up vars.c and vars.h.
- Have the help system deal with the command character as needed.
Darkbot 8rc2: May 04, 2006
- Cleaned generated files out of cvs and updated .cvsignore
files to match.
Darkbot 8rc2: Apr 21, 2006
- Added most of the help command summaries.
Darkbot 8rc2: Apr 19, 2006
- Fine tuned what commands can be done where. In particular
any password related commands can only be done in private
now.
- Made some commands behave consistantly no matter where they
are invoked from.
- Added HELP COMMANDS.
- Don't try to send oversize messages, split at a space.
Darkbot 8rc2: Apr 16, 2006
- Rewrote chansrv.c to use an array of pointers instead
of a huge if-else-if.
- Added patch from nak that stops ops from kicking
themselves via a topic kick.
- Added HELP <command>.
- Added isop <nick>.
- Added level <nick>.
Darkbot 8rc2: Mar 09, 2006
- Added !WEATHER <zipcode> command.
Darkbot 8rc2: Nov 07, 2005
- Fixed spelling errors, the word 'queue' was mispelled
throughout the code and in comments.
- I apparently broke show_banlist() a few releases back
trying to eliminate a type conversion warning, so it's
fixed again.
- B~ (bot nickname) variable can now be used in perform.ini
- OS command now works on windows.
- Fixed google command. A search string used to determine
successful replies was changed by google.
- Changed "ugly" message responses.
- Restart and rehash commands should now work on all operating
systems, including Windows.
Darkbot 8rc1: Mar 04, 2005
- Removed an unneeded line in main.c, that was used to "hide"
warnings on WIN32, which is a very bad idea.
- Changed check_dbtimers() so it ignores the CVS directory,
which contains information for the CVS server. This
fixes a situation that seems to have only presented itself
in FreeBSD, where it thinks the CVS directory is a
timer, and sends out random garble every few seconds.
- configure.ac and source/Makefile.am; very minor updates.
- Fixed randq, which I accidentally broke when adding the
-I switch. This also fixes some problems that turned up
on FreeBSD.
- Fixed a warning that came up in permbans.c about mixing
types when compiling on OS X. I changed %d on line 198
to %ud.
- configure now checks for clock_t.
- configure now automatically checks for snprintf, and
uses a replacement if it's not found.
- docs/INSTALL.txt is now INSTALL in the toplevel dir.
Another thing for automake to stop complaining about.
- The original configure script is now located in the
scripts directory, and is called "Setup".
- docs/contributors.txt is now called AUTHORS in the
top level of the distribution. Another thing automake
complains about. I also worked on the appearance of
this file, hopefully it looks a little better now.
- README.txt in the toplevel is now called "README".
Automake complains about this file also, if it's not
found.
- This file is now called ChangeLog, and has been moved
to the toplevel distribution dir. The reason for this
is that automake complains, if it can't find this file.
- configure now checks for the presence of windows.h,
and defines WIN32, if it's found. This removes the
need to do "make win". Until I add the noconsole
option again, you can run darkbot with no console by
doing "./darkbot &" in your cygwin shell.
- The configure.ac file is not yet complete, and most
of the definitions listed in config.h are not completely
implemented into the code yet. If you have problems,
please let me know, and these files will become completely
implemented as demand is met.
- Included premade Makefiles and configure script.
- Added "make convertdb", which will compile the database
conversion utility, which encrypts the passwords in your
userlist.db file.
- I added a Makefile.am in the toplevel, and in the source
directory. These files are used in conjunction with
GNU Automake to produce a Makefile.
- Added Makefile.ams and configure.ac for autoconf/automake.
Darbkot 7f2: April 05, 2004
- Fixed the google function. Google changed some text that
the bot was using to tell if the search was successful.
Darkbot 7f1: Mar 06th, 2004
- Made a short dirty fix for "!randq *" crashing the bot.
If you do a randq query consisting entirely of * and ?
characters, the bot will now just spit out a random quote.
This needs to be fixed better, obviously, but this will
keep peoples' bots from crashing until the issue can be
properly addressed.
- Changed unlink() calls to remove(). remove() is ANSI C.
- Private message responses no longer have that "sent by"
thing on them. It was annoying, and pointless.
- Renamed the log() function db_log() to avoid a conflict
with a function internal with gcc. Apparently this only
affects newer versions of gcc.
- Removed two unused variables in convertdb.c. I also changed
'unlink' to 'remove', to comply with the ANSI standard.
- - Changed forum URL to http://forum.freezedown.org, since that
+ - Changed forum URL to http://forum.darkbot.org, since that
works too, looks cooler, and is shorter. :)
- Fixed a bug that caused the bot to never respond to anything
after being killed. The same problem was also fixed in a
number of other situations that it was popping up. gs26()
was being called both before, and during prepare_bot(), so
I made the call happen only during prepare_bot().
- Fixed a minor flaw in convertdb.c. It said the syntax was
"convertdb -convert", even if the executable wasn't named
convertdb.
- Taiwanish file got dumped somehow, it's back now.
- New setting in defines.h, AUTOHELP_GUESTS, makes the bot send
a message to the channel, whenever a user with the word "Guest"
in their nickname joins, asking them if they need help. This
can be used in help channels, to avoid Guest users just joining
the channel, and moving on because nobody is talking.
- I'm fairly sure I have dbcron fixed now. I can't test it,
because I don't have a system with crond, but the fix was
made using basic shell syntax. >> instead of >. :)
- Please remember to include which operating system you're using
when reporting bugs. This information is crucial because (all?)
operating systems have subtle differences that can cause any
number of problems in various situations. It's impossible to
keep all of these conditions in mind when writing code, because
there's just so many of them. Any other information that you can
provide will, more than likely, be greatly appreciated.
- I don't see why this is a development version anymore, so
I've moved it to final. As always, any malfunctions or
problems may be reported via the forum.
- darkbot.info isn't resolving anymore, so references to this
site have been removed. I left the support emails, until
updated email addresses are known of. If your email needs
to be updated anywhere in the code, and I didn't realize it,
let me know.
- Changed setup.ini, WHATSNEW, according to previous statement.
- Updated some text in defines.h
- Updated the title screen in main.c
- Removed references of "make cygwin". Just use "make win"
from now on.
- Fixed a typo in the Makefile.
- You can use comments in the performs file now by appending
a '#' to the beginning of the line.
Darkbot 7.0-RC9: Oct 19th, 2003
- Added new channel command, "QUOTE". All this does right
now is display a random line from randomstuff.ini on
command.
Darkbot 7.0-RC9: Oct 5th, 2003
- This feature was already added, but I never documented it...
The R~ variable (random nickname) now works in RDB topic
responses. Look for randomstuff compatibility in the near
future, but first i have to rewrite do_random_stuff() to
accept a channel arguement.
- I was reading through this WHATSNEW file, and corrected
a few typos that were made.
- I removed the run_deop() code. It didn't work very
well anyway, or at all actually. I plan on reintroducing
this whenever I can get some free time.
- Fixed Ebonic language file.
- Added Taiwanish language option.
Darkbot 7.0-RC8: June 20th, 2003
- I screwed up the Makefile by accident, adding some
new features, and I hadn't finished yet when I
committed. OOPS. Fixed now.
- Updated more depricated URL strings.
- Updated language files.
- Minor changes on startup splash screen.
- - Support forum URL is now http://www.freezedown.org/forum
+ - Support forum URL is now http://www.darkbot.org/forum
- Updated the default servers.ini file to reflect the
changes.
- You can now use Darkbot on servers which require a
connection password. Check servers.ini for an
example.
- Updated some outdated text in the configure script.
- - Darkbots now default to irc.freezedown.org #darkbot.
+ - Darkbots now default to irc.darkbot.org #darkbot.
Please edit your setup.ini and servers.ini files to
minimize traffic, since that is also our help channel.
Darkbot 7.0-RC7: June 2nd, 2003
- Updated the INSTALL.txt file to reflect some support
changes.
- Fix for possible problems with counting in datasearch
algorithm. long was changed to size_t.
- Fixed bug that prevented ACTIONs from being used on
RDB responses.
- Suppressed more warnings when compiling on Solaris
from chan.c, in the do_math function.
- Removed another unused variable from url.c
- Removed an unused variable from random.c
- Removed the .runonce script from executing during the
"make" process. The funcionality this script produced
is depricated. Also removed this file from the distro.
- Darkbot will now properly compile on Solaris. To make
this happen, you need to manually edit source/Makefile,
and remove a comment symbol before the word "LIBS".
- Suppressed a warning message from main.h that happened
when compiling on Solaris.
- Makefile now works correctly on Solaris.
- The MEM command is now limited to only users with admin
(level 3) access on the bot.
- On startup, we now run_performs() BEFORE we join our home
channel. This fixes an issue that happened chiefly on
Undernet, and allows the bot to authenticate and set
umode +x, before it joins any channels. I hope to fix
this in a better way, but for now it's driving me nuts.
- The startup screen now actually reflects what version this
is. Sorry, I forgot all about that startup screen, because
it's hard coded. hehe.
- The Q~ variable in topic replies now works correctly. It
was chopping all but the first word off, before.
- Added MrSiMo to the list of contributors for his Arabic
translation.
- The sleep command now accepts an arguement for the number
of seconds you want the bot to sleep for.
- DEFAULT_UMODE is now set immediately upon connection.
Several users said this was not being done, it was. It was
just waiting >300 seconds, for whatever reason. Also, the
bot command PERFORMS now sets DEFAULT_UMODE in addition
to running the performs file.
- New command line option.
-I now specifies the location of the directory containing
the data files (by default, dat/).
- Multiple command line arguements are now supported.
I have no clue why this wasn't done before.
- The .debug and .debug2 scripts were missing from the
distribution. They're back now.
- Found another place where the bot wasn't deleting old
userlist entries. This has been fixed.
- Added the CHANUSERS command. All this does is return
a list of users on either the specified channel, or
the current channel, if none is specified. I may
remove this eventually, as i'm just using it for
debugging purposes right now.
- CHANINFO command will output to whatever channel it
received the command from now, instead of the channel
it's showing data about.
- The CHANINFO command now supports a channel name
parameter. Dunno why it didn't have that before...
- Darkbot is on CVS now at SourceForge!
- Soapta revamped the google module.
- The MEM command now displays the correct process. I removed
the -x flag from the ps command it was issuing, and it fixed
it. If anyone sees any reason the -x flag should be used,
let me know and i'll recode the whole thing.
- Added SETHOST alias for the VHOST command.
- Updates to the Ebonic and French languages which define
Lbadtopic and Lbadtopic2 now. Other languages still need
this added.
- The RDB command, which gives information about the number
of RDB files, can now be used with an arguement, to tell
how many lines are in a specific RDB file. It was supposed
to do this before, but it didn't work properly. This
command is still unavailable in Windows.
- Removed a warning concerning do_randq that happened if you
compiled with RANDOM_STUFF undefined.
- Fixed another bug that was causing the bot to never remove
old entries from it's internal user list. This time it wasn't
parsing the channel name for PARTs correctly. I also removed
some parsing being done on an unused variable whenever
someone parted a channel.
- Fix for RDB command... i forgot to change this when I moved
all of the RDB files to their own directory. OOPS! :)
Darkbot 7.0-RC6: Oct 30th, 2002
- Added Arabic language.
- You can now toggle the use of encrypted userlist.db passwords.
Check defines.h for this.
- Fix for the bot not executing performs when it connects to
a server which does not have an MOTD. Also cleaned up a small
amount of redundant code dealing with performs.
- The bot will no longer crash if it encounters blank lines in
the info2.db during data searches (DSEARCH and SEARCH commands).
Darkbot 7.0-RC5: Sep 24th, 2002
- Fixed do_randomtopic(), so it's now possible to output the first
quote. it never did this before (oops).
- Fixed the socket connection routines for windows.
- Fixed a rather large bug that caused the bot to never actually delete
users from the internal user list when necessary.
This also fixes another problem where the bot would put return a
nickname from R~ that is not actually on the channel.
- RDB topics now support the use of tokenized responses. This includes
the use of tokenized responses in the WHUT and DUNNO replies.
- Added timers directory to the distribution, it was missing.
- Got rid of the do_randomtopic2() function for the random dunno, and
random whut replies. do_randomtopic() now handles everything. This
cut down the size of the code a bit, and should have been how it was
done originally, anyway. This also means variables and also raw
commands can now be used in the replies for whut, and dunno, also.
- Added a level 3 helper command, "PERFORMS", which just executes all
all commands that are in the bot's performs.ini file, at any time.
- Fixed minor oversight that I created when adding a check for illegal
characters in !nick, it now lets you use all legal characters.
- RDB topic responses can now contain raw commands.
- RDB files are now stored in their own directory. By default, this is
dat/rdb.
- Changed get_word() function to make it a little more useful.
- Changed some error replies in the RANDQ function, and added a response
for the condition of randomstuff.ini being empty.
- Cleaned up the prototypes.h file, it looked really ugly. :)
This also reduced the total amount of code by a bit, but i'm not going
to bother checking just how much. :P
- Fixed an issue in seen, that might cause the bot to improperly count
the number of seens in the database.
- Fixed minor bug in add_randstuff() that caused the bot to say there was
one more randomstuff in the file it's adding to than there actually was.
- Fixed a bug in do_random_stuff() that prevented the bot from outputting
randomstuffs, in very rare instances. This suspectedly was causing some
strangeness noted in Debian, and some other OSs.
- Added a new alias for randomstuff, RS.
- Fixed a bug in !USERLIST, that caused the bot to flood itself, and not
show of all of the users it was supposed to show.
!USERLIST now works correctly, and hopefully on ALL OS.
- Fixed a bug in !BANLIST that caused it to not output correctly on some
OS.
- Due to abuse and channel cluttering, the !VARIABLES command now messages
the user with the output, instead of sending it to the current channel.
- Fixed a compilation error concerning BITCH_DEOP_REASON being undeclared.
What i did is remove this, and now if BITCH_ABOUT_DEOP is turned on, it
just runs the list of commands in deop.ini. If BITCH_ABOUT_DEOP is turned
off, it does nothing when the bot is deoped. Apparently, before this
version, it ALWAYS ran deop.ini, and the BITCH_ABOUT_DEOP just toggled the
bot saying whatever line was defined in BITCH_DEOP_REASON. That seemed kind
of pointless, to me, but i never noticed it before now.
Darkbot 7.0-RC4: Jun 24th, 2002
Again, Ron did a couple necessary and urgent changes and fixes:
- Finally, the bug in windows concerning DEL and REPLACE has
been corrected. A function which checks readability and
writeability was leaving the info2.db file open at startup,
and causing all sorts of problems, since the new code structure
was implemented.
- NO NEED FOR TOP LINE WITH NUMBER ANYMORE on random phrase files.
... After yet even more problems with randomstuffs being counted
improperly, I've recoded the entire randomstuff routine.
They no longer rely on any number at the top of the file, which
means you can remove that number from your randomstuff.ini.
Optimizations made to make randomstuff more random, also.
- Fixed a bug where Darkbot would crash when you use !nick
with illegal characters.
- Patched a socket issue in create_connection() that appeared
only in windows.
- Eliminated a warning dealing with the redefinition of size_t
when compiling the bot in windows.
- Eliminated all of the casting done on malloc in the program.
Casting malloc is totally unnecessary, and can mask other
errors.
- Improved the fix for topics that consist entirely of "*"
characters. It now checks for "?" also. This prevents
segmentation faults, and topics which are entirely wild-
cards are seriously annoying anyway. Sorry if it's in any
inconvenience to anyone.
- Minor cosmetic fix to the output of DBSIZE, it'll now say
that the database is "1 byte in size", instead of "1 bytes
in size", if it's only 1 byte. This should never happen,
but if it does, it'll look nice. :)
- Added #define MSG_RESPONSES to defines.h to have Darkbot
answering or not to private queries. Check next 2 defines.
(default is OFF)
- Added #define ALLOW_ADD_IN_MSG to turn ON or OFF the
possibility of ADDing database entries to Darkbot in
private message. (default = OFF)
- Added #define ALLOW_DEL_IN_MSG to turn ON or OFF the
possibility of DELeting database entries from Darkbot in
private message. (default = OFF)
- Added RANDQ function and alias RANDQUOTE, to output a random
line from your randomstuff.ini that contains a specified search
string.
RANDQ output returns a (11/23) type thing at the beginning of
the line, which tells which quote it's showing, out of how many
were matched in your search.
RANDQ can be used from any channel, and in MSG. It wont output
An obvious side effect to this, is that the ~ variable in
randomstuffs will evaluate to a nickname, if it's used in private
message (The nickname of whoever invoked it).
To make the function toggleable a directive with the same name
was made on defines.h (default = ON)
Try it out, !RANDQ <stuff>
- Added RANDQ2 command, which is the same as RANDQ, only it
matches case sensitively.
- Added BACKUP_RANDOMSTUFF define to backup randomstuff.ini
file every time a random phrase is added. This was done due
to missing contents when adding an entry on a file with a high
ammount of phrases. Latest fixes resolves the problem but this
define will stay to play on the safe side and/or if user likes
to backup changed files.
- Added hostmask code, where the bot converts hostmasks to
*jason@*.superlink.net, or *jason@203.203.203.*.
- After lots of complaints, the second line in the info reply
only shows up with the stats command now.
Shell utilities
- Adjusted check-integrity to the non necessity anymore of top
line with number of random entries on random phrases files.
- configure script now forces entering at least one server
and at least one user level 3, on servers.ini and userlist.db
files respectively, in case those files are empty.
(working on checking errors on user input).
- added an option on 'configure' to import servers.ini and
userlist.db from another location.
- Added BSDs compatibility to all shell scripts.
- Added Cygwin compatibility to AddServer, AddUser,
check-integrity and download-databases scripts (live-update
and dbcron not fully tested yet).
Darkbot 7.0-RC3: May 22nd, 2002
- ron@freezedown.org has worked on the following 4 issues:
+ ron@darkbot.org has worked on the following 4 issues:
- Fixed a bug that caused crashes if the bot responds to a
topic containing R~ in private message.
- Fixed a bug that caused excess floods if the bot were to
send private messages to itself.
- Fixed a bug concerning topics that consists entirely of the
'*' character, which caused segmentation faults. Darkbot
will not allow you to add a topic like this now.
- Fixed the Makefile, on my computer it kept compiling all
of the source files seperately and then compiling them all
together instead of linking the .o files it made.
- Added directory logs lost in action. It is now within dat directory
- Fixed .Stripdb and .Stripdb2 - so now points to the correct bin path
Shell utilities: (all changed/improved - read docs/README_UTILS)
- Added README_UTILS to docs directory with information about shell utils
- Added compatibility to wget (besides lynx) on scripts that needs to
connect to internet
- All utility scripts now share working directory .scriptutils instead of
having dynamic files all over scripts directory
- download-databases now integrated on live-update (besides standalone)
(if updated on RC3 the change will take effect next time live-update
is executed)
- Added a couple more features and improved others for more accuracy on
check-integrity engine. USE IT before asking for help or going into
paranoia if you suspect you have data errors or even if you are not
sure eventual errors became from bad entries on data files.
- Added a few features to AddUser utility
- configure script now bypasses previously configured items. Just hit
ENTER key to go to the next setup. Also it gets already configured
parameters and use it as session defaults instead of the usual Darkbot
defaults. The script is now linked to AddUser and AddServer with all
features those utilities now have.
Darkbot 7.0-RC2: Apr 13th, 2002
- Windows port. Not much to do at this time. Last changes
on the core code made some commands not working properly.
Any interested coder... the affected commands
are DELETE, which do not delete, and REPLACE, which leaves
in info2.db 2 entries with the same topic. I should remind
all coders that the source must be sent together with it's
executable/bin files. Any coder willing to participate use
the email on top of this info or directly to me
at LuizCB@darkbot.info . (only development matters please)
- The following are a couple Unix scripts to help on Darkbot
management. Most are complete, some needs small adjustments
or more features. I've used basic sh technics on it's making,
I should say, while learning the language on the fly.
Please test them and send any modiffs in case you are able
to. The idea of these shell scripts is mainly to open a door
to C coders to implement them so it will be possible to port
it to other platforms.
- A more featured AddServer. Downloads and installs servers
of the network you choose. Thanks to the folks at the
International Federation of IRC - http://ifirc.com
for a job well done on your site! The merit of that will
go to our web page on the credits area as soon as stable
version 7 is released.
- New crontab setup utility. Run dbcron on scripts dir and
if crontab is active on your shell the script will do
everything for you (10 mins interval cron job).
- Implemented a new update utility. On scripts
directory type ./live-update -h for help on it's
usage. At this stage the update engine will not
transfer your previous directives on defines.h
or darkbot.c to the new file, so you'll have to
edit defines.h manually and compile Darkbot.
The script is compatible with all Darkbot releases
and can be launched standalone providing it's in
scripts directory. To install it ( in case you don't have
it with your Darkbot) type
lynx -source http://live-update.darkbot.info > live-update
then chmod +x live-update
(get-latest will no longer be available)
- New download-databases utility. ( it will be integrated soon on
live-update engine but can also work standalone).
- New file-integrity utility ( still needs some ajustments and
more features but you can use it already - works with
download-databases utility or by itself). Type
./check-integrity to check info2.db. Due to unpredictable
user entries on info2.db this utility could behave
abnormally on some special characters. Please send me all
info2.db file in case anything like that happens so I can
make exclusions on the code.
Changes applied by reet:
- Fixed major bug when adding users - the password wasn't
encrypted, thus user could never login.
- Added new commands IGNORE & UNIGNORE syntax is:
<bot> ignore <nick>
<bot> unignore <nick>
The ignore list is only stored in RAM, changing
nicks will get around this ignore. This is useful
to ignore people who query the bot too much.
- Applied code optimization patches on info and check_permban,
submited by Neil Darlow
- Preview for next full release: adjustments on shell utilities
and a full featured menu GUI might be finished. Minor
changes in meanwhile can be updated using live-update
engine.
Darkbot 7.0-RC1: Mar 2nd, 2002
- Fixed get-latest script; besides checking for code updates
also looks for latest news. Database files updates
will be also done/actualized soon. It's not linked
anywhere by now so if you want to use it type it's
name.
- Organized file structure; all scripts are now on scripts
directory, documents on docs except README which is
now on Darkbot's root dir. A new contributors file
was created with the list of colaborators.
- defines.h is now organized in different way and prepared
to a "shell GUI" to be released soon.
- Organized 'configure' in a different way. Now it starts
with defines.h editing and then it goes to data files.
- scripts/dbcron - a new script to execute crontab. There is
plenty of help how to use in it. Read it. Soon the
reconnection process will me automated.
- Updated makefile to reflect the new directory tree.
- Code contributors please use this release as the base of
your changes.
- The next changes are code modifications also in preparation
for release 7, mostly adapted, updated or implemented
by reet, paul @ darkbot.info
- Added GOOGLE feature. Simply type:
<bot> google <search string>
The bot will then return the first URL google
returns.
#define GOOGLE ON to use this feature.
- ********** IMPORTANT **********************************
- userlist.db passwords are now *ENCRYPTED*
If you are using an older version userlist.db
you MUST set all the passwords to 0 *** OR ***
Cygwin/Windows users run convert.exe
UNIX users run ./convert
and your userlist.db will be converted
*******************************************************
- #define PERFORM_TIMER ON if you want darkbot to send its
PERFORM.INI to the IRC server every 60 seconds, useful
if your bot is banned from a channel, or couldn't
log in to channel services due to a net split etc.
It's in defines.h
Darkbot 7 (alpha 2.1): Dec 23rd, 2001
- Fixed 'INFO2.DB must have at least one topic' problem. Bot
should work normally, even if INFO2.DB is empty.
- Added 'stats' support to darkbot, <botnick> stats will return
total number of questions asked since it started
recording. You can also do <botnick> stats <nickname>
to get indivdual stats from a user. dat/stats.db holds
the data.
- Added 'quiz' support to darkbot, <botnick> quiz to execute
the quiz, it will pick a random question/answer from
dat/quiz.db. The format of the question answer in the
file should be <question>@<answer>
e.g. What is 1+1?@The answer is 2!
quiz is still in experimental stages, check defines.h
to enable/set it up.
Darkbot 7 (alpha 2): Dec 17th, 2001
- New define - #define VOICE_USERS_ON_JOIN [on/off]
- New commands: /msg bot infosize or /msg bot dbsize
or in channel: bot infosize or bot dbsize
returns the file size of INFO2.DB
- New command: bot whisper <nick> about <topic>
darkbot will NOTICE the user, instead of PRIVMSG
- Moved source code and Makefile to source directory -
this keeps the root tree of darkbot clean, nothing
changes for the user, they still type make in the
darkbot root, and the binary will be copied there.
- Repaired get_rand_nick() problem - bot was still returning
it's own nick - *should* be ok now.
- Added Ron's random whut, and dunno function.
Darkbot 7 (alpha 2): Dec 16th, 2001
- Removed #ifdef WIN32 references for sprintf/snprintf,
have included the function snprintf() in general.c,
for older compilers - #define SNPRINTF_SUPPORT should
be switched OFF if your compiler supports snprintf()
this is quite a change.
- Due to lots of people not reading #defines.h and complaining
about make error (clock_t), the configure script
will display an alert about this just before defines.h
is about to be edited.
- New defines - #define CONNECT_WAIT_TIMEOUT [seconds]
#define OP_USERS_ON_LOGIN [on/off]
- New PRIVMSG commands - OP, DEOP, VOICE/V, DEVOICE/DEV/DV/,
DVOICE, KICK/WACK/K, DELETE/REMOVE/
FORGET/DEL, TELL, ADD/REMEMBER/SAVE,
WHERE/WHO, ADDUSER, DIE
Some of them aren't new, but didn't work, and are now fixed.
Just /msg bot tell nick about topic, these commands
usually NOTICE the user, rather than PRIVMSG.
- The connection routine to the server should be better -
instead of quitting after failing to connect, it
will constantly cycle all the servers.
- I've added CYGWIN support in the Makefile - just to hide
those size_t warnings if you get them. If you use
CYGWIN, just use make cygwin
- Permban bug fixed.
- Info/Info2 bug fixed.
- NICK bug fixed - bot will keep the new nick until it quits.
- There is a bug/feature where if a nick has a pipe (|) and
requests a topic that has raw - commands, it ignores
them - looking in to this.
diff --git a/beta/source/chansrv.c b/beta/source/chansrv.c
index e7c109e..ca47b6a 100755
--- a/beta/source/chansrv.c
+++ b/beta/source/chansrv.c
@@ -1,2394 +1,2519 @@
#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
};
enum chanserv_invoke_type
{
DIRECT_INVOKE = 0, // command
ADDRESS_INVOKE = 1, // bot: command
MSG_INVOKE = 2, // /msg bot command
CHAR_INVOKE = 3 // !command
};
struct chanserv_command
{
enum chanserv_command_type type;
int access;
int arg_count;
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;
};
struct chanserv_output
{
char *output;
struct chanserv_output *next;
};
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 *s = NULL;
+ char str [STRING_LONG] = { 0 }, topic [STRING_LONG] = {0};
if (args[0] == NULL)
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(args[0], "*?") == strlen(args[0]))
+ if (strspn(topic, "*?") == strlen(topic))
return chanserv_asprintf(NULL, "Sorry, but support for that topic has been removed.");
- if (strlen(args[0]) > MAX_TOPIC_SIZE)
+ /* 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)
{
- args[0][MAX_TOPIC_SIZE] = '\0';
+ topic[MAX_TOPIC_SIZE] = '\0';
result = chanserv_asprintf(NULL, "Topic is over the limit, and has had characters truncated.");
}
- s = strtok (NULL, "");
- if (s == NULL)
- return chanserv_asprintf(result, "What info is to be added for %s?", args[0]);
- if (strlen(s) > MAX_DATA_SIZE)
- s[MAX_DATA_SIZE] = '\0';
- strlwr(args[0]);
- if (*args[0] == '~')
+
+ 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 (check_existing_url(source, args[0], target) == 1)
- return chanserv_asprintf(result, "%s \37%s\37\n", EXISTING_ENTRY, args[0]);
+
if (LOG_ADD_DELETES)
- db_log(ADD_DELETES, "[%s] %s!%s ADD %s %s\n", date(), source, userhost, args[0], s);
+ db_log(ADD_DELETES, "[%s] %s!%s ADD %s %s\n", date(), source,
+ userhost, topic, str);
+
ADDITIONS++;
- if (args[0][0] == 'i' && args[0][1] == 'l' && args[0][2] == 'c')
- db_log(URL2, "%s ([%s] %s!%s): %s\n", args[0], date(), source, userhost, s);
+
+ if ((stricmp (topic, "ILC")) == 0)
+ {
+ db_log(URL2, "%s ([%s] %s!%s): %s\n", topic, date(),
+ source, userhost, str);
+ }
else
- db_log(URL2, "%s %s\n", args[0], s);
+ {
+ 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[0] == NULL || args[1] == NULL || args[2] == NULL || args[3] == NULL)
return result;
sn = atoi(args[2]);
if (sn > 10 || sn <= 0)
return result;
if (strlen(args[1]) < 7)
return result;
sprintf(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[0] == NULL) || (args[1] == NULL) || (strlen(args[0]) < 2))
return result;
/* Check for valid numbers. */
if (strspn (args[0], NUMBER_LIST) != strlen (args[0]))
return chanserv_asprintf(NULL, "Time must be a number.");
if (*args[0] == 'd')
{
/* Days. */
sn = 86400;
args[0]++;
}
else if (*args[0] == 'h')
{
/* Hours */
sn = 3600;
args[0]++;
}
else if (*args[0] == 'm')
{
/* Minutes */
sn = 60;
args[0]++;
}
else if (*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", target, 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;
if (args[0] == NULL)
return result;
set_autotopic (source, target, args[0]);
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 };
snprintf(temp, sizeof (temp), "/bin/cp -f %s %s_`date +%%F_%%R.bak`\n", URL2, URL2);
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)
{
struct chanserv_output *result = NULL;
show_banlist (source);
return result;
}
#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[0] == NULL)
return result;
if (strlen(args[0]) > 200)
args[0][200] = '\0';
do_math(source, target, args[0]);
return result;
}
#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[0] == NULL)
show_chaninfo (source, target, target);
else
/* If args[0] is not a valid channel name, just use the current channel */
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[0] == NULL)
show_chanusers (source, target);
else
/* If args[0] is not a valid channel name, just use the current channel. */
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[0] == NULL)
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 *s = NULL;
-
- s = strtok (NULL, " ");
- if (s == NULL)
+ char str [STRING_LONG] = {0};
+ int i = 0;
+
+ /* Check for channel list parameter being specified. */
+ if (!args[0])
{
- S("PART %s\n", target);
- S("JOIN %s\n", target);
+ 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]);
- result = chanserv_asprintf(NULL, "Cycling %s.", s);
}
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[0] == NULL)
return chanserv_asprintf(NULL, "What should I be %sing for?", cmd);
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[0] == NULL)
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[0] == NULL)
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[0] == NULL)
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 *s = NULL;
+ char str [STRING_LONG] = {0}, chan[STRING_LONG] = {0};
+ /* Make sure first arg, which should be target chan, is there. */
if (args[0] == NULL)
return result;
- s = strtok (NULL, "");
- if ((invoked == MSG_INVOKE) || (*args[0] == '#'))
+
+ 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, args[0], 0, source) >= 3)
+ if (check_access (userhost, chan, 0, source) >= 3)
{
- if (s == NULL)
+ if (str[0] == '\0')
return result;
- S ("MODE %s -oooooo %s\n", args[0], s);
+ S ("MODE %s -oooooo %s\n", chan, str);
}
}
else
{
- if (s == NULL)
- S ("MODE %s -oooooo %s\n", target, args[0]);
+ if (str[0] == '\0')
+ S ("MODE %s -oooooo %s\n", target, chan);
else
- S ("MODE %s -oooooo %s %s\n", target, args[0], s);
+ 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 *s = NULL;
+ char chan [STRING_LONG] = {0}, str [STRING_LONG] = {0};
if (args[0] == NULL)
return result;
- s = strtok (NULL, "");
- if ((invoked == MSG_INVOKE) || (*args[0] == '#'))
+
+ strncpy (chan, args[0], sizeof (chan));
+ args++;
+ db_argstostr (str, args, 0, ' ');
+
+ if ((invoked == MSG_INVOKE) || (*chan == '#'))
{
- if (check_access (userhost, args[0], 0, source) >= 3)
+ if (check_access (userhost, chan, 0, source) >= 3)
{
- if (s == NULL)
+ if (str[0] == '\0')
return result;
- S ("MODE %s -vvvvvv %s\n", args[0], s);
+ S ("MODE %s -vvvvvv %s\n", chan, str);
}
}
else
{
- if (s == NULL)
- S ("MODE %s -vvvvvvv %s\n", target, args[0]);
+ if (str[0] == '\0')
+ S ("MODE %s -vvvvvvv %s\n", target, chan);
else
- S ("MODE %s -vvvvvvv %s %s\n", target, args[0], s);
+ 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 *s = NULL;
- long unixtime = 0;
+ char str [STRING_LONG] = {0};
+ long unixtime = 0;
- s = strtok (NULL, "");
- if (s == NULL)
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
Snow("QUIT :K\2\2illed (%s (cause I say so!))\n", source);
else
- Snow("QUIT :K\2\2illed (%s (%s))\n", source, s);
+ 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[0] == NULL)
return 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);
}
#ifdef ENABLE_GOOGLE
struct chanserv_output *chanserv_google(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
if(args[0] == NULL)
return chanserv_asprintf(NULL, "Google what?");
web_post_query(cmd, source, userhost, target, args[0], strlen(args[0]));
return result;
}
#endif
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 *s = NULL;
+ char str [STRING_LONG] = {0};
- s = strtok (NULL, " ");
- if (s == NULL)
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
{
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))
+ 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://www.freezedown.org/ .",
+ 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://www.darkbot.org/ .",
NICK_COMMA, NICK_COMMA, NICK_COMMA);
}
else
- result = chanserv_show_help(s, check_access(userhost, (invoked == MSG_INVOKE) ? "#*" : target, 0, source));
+ 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[0] == NULL)
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[0] == NULL)
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)
{
struct chanserv_output *result = NULL;
show_info2 (target, source);
return result;
}
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[0] == NULL)
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[0] == NULL)
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 *s = NULL;
+ char server [STRING_LONG] = {0}, str [STRING_LONG] = {0};
long sn = 0;
if (args[0] == NULL)
return result;
- s = strtok (NULL, " ");
- if (s == NULL)
+
+ strncpy (server, args[0], sizeof (server));
+ args++;
+
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
sn = 6667;
else
- sn = atoi(s);
- S ("QUIT :Jumping to %s:%d\n", args[0], sn);
+ sn = atoi(str);
+
+ S ("QUIT :Jumping to %s:%d\n", server, sn);
db_sleep (1);
- strcpy (BS, args[0]);
+
+ 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 *s2 = NULL, *s3 = NULL;
+ char chan[STRING_LONG] = {0}, nick[STRING_LONG] = {0},
+ reason [STRING_LONG] = {0};
if (args[0] == NULL)
return chanserv_asprintf(NULL, "Specify a nick/channel!");
+
if (invoked == MSG_INVOKE)
{
- if (check_access (userhost, args[0], 0, source) >= 3)
+ /* 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)
{
- s2 = strtok (NULL, " ");
- s3 = strtok (NULL, "");
- if (s2 == NULL)
- return chanserv_asprintf(NULL, "You must specity a nick to kick from!");
- if (s3 == NULL)
- S ("KICK %s %s %s\n", args[0], s2, DEFAULT_KICK);
- else
- S ("KICK %s %s %s\n", args[0], s2, s3);
+ 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] != '&')
{
- s2 = strtok (NULL, "");
- if (s2 == NULL)
- {
- if (strcasecmp (args[0], Mynick) == 0)
+ strncpy (nick, args[0], sizeof (nick));
+ args++;
+
+ if (strcasecmp (nick, Mynick) == 0)
S ("KICK %s %s :hah! As *IF*\n", target, source);
- else
- S ("KICK %s %s :\2%s\2'ed: %s\n", target, args[0], cmd, DEFAULT_KICK);
- }
- else if (strcasecmp (args[0], Mynick) == 0)
- S ("KICK %s %s :%s\n", target, args[0], s2);
- else
- S ("KICK %s %s :\2%s\2'ed: %s\n", target, args[0], cmd, s2);
+ 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
{
- s2 = strtok (NULL, " ");
- if (s2 == NULL)
- result = chanserv_asprintf(result, "You must specify a nick to kick from!");
- else
- {
- s3 = strtok (NULL, "");
- if (s3 == NULL)
- {
- if (strcasecmp (s2, Mynick) == 0)
- S ("KICK %s %s :hah! As *IF*\n", args[0], source);
- else
- S ("KICK %s %s :\2%s\2ed: %s\n", args[0], s2, cmd, DEFAULT_KICK);
- }
- else
- {
+ if (!args[0] || !args[1])
+ return chanserv_asprintf(result, "You must specify a nickname to kick!");
- if (strcasecmp (s2, Mynick) == 0)
- S ("KICK %s %s :hah! As *IF* (%s)\n", args[0], source);
- else
- S ("KICK %s %s :\2%s\2ed: %s\n", args[0], s2, cmd, s3);
- }
- }
+ 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 *s = NULL;
+ char chan [STRING_LONG] = {0},
+ reason [STRING_LONG] = {0};
- s = strtok (NULL, " ");
- if (s == NULL)
+ if (!args[0])
S ("PART %s\n", target);
else
{
- S ("PART %s\n", s);
- result = chanserv_asprintf(result, "Leaving %s.", s);
+ strncpy (chan, args[0], sizeof chan);
+ args++;
+
+ /* Don't bother telling the channel we left about it. */
+ if ((stricmp (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;
+ 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;
if (args[0] == NULL)
return result;
return chanserv_asprintf(NULL, "It was %d chars long.", strlen (args[0]));
}
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[0] == NULL)
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[0] == NULL)
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)
{
struct chanserv_output *result = NULL;
if(args[0] == NULL)
return result;
return chanserv_asprintf(NULL, " %s", 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 };
const char *ptr = NULL;
snprintf(temp, sizeof (temp), "ps u -p %d\n", getpid());
if ((ptr = run_program (temp)) == 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[0] == NULL)
return chanserv_asprintf(NULL, "Metar what?");
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[0] == NULL)
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]);
strncpy(Mynick, args[0], 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);
// FIXME: This should be sent before the NICK attempt, and/or complain if the NICK doesn't work.
result = chanserv_asprintf(result, "Attempting to /nick %s.", Mynick);
S("NICK %s\n", Mynick);
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 *s = NULL;
+ char nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0};
+ int ischan = 0;
- if (args[0] == NULL)
- return result;
- s = strtok (NULL, "");
- if ((invoked == MSG_INVOKE) || (*args[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] == '&'))
{
- if (check_access (userhost, args[0], 0, source) >= 3)
+ 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)
{
- if (s == NULL)
- return result;
- S ("MODE %s +oooooo %s\n", args[0], s);
+ S ("MODE %s +oooooo %s\n", chan, nicks);
+ return result;
}
}
else
- {
- if (s == NULL)
- S ("MODE %s +oooooo %s\n", target, args[0]);
- else
- S ("MODE %s +oooooo %s %s\n", target, args[0], s);
- }
-
+ 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)
{
char temp[1024] = { 0 };
#ifdef WIN32
snprintf (temp, sizeof (temp), "cmd /c ver;uname\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 *s = NULL;
+ char reason [STRING_LONG] = {0}, host [STRING_LONG] = {0};
- if (args[0] == NULL)
+ if (!args[0])
return result;
- s = strtok (NULL, "");
- if (s == NULL)
- s = "Permbanned!";
- add_permban(args[0], 0, s);
- result = chanserv_asprintf(result, "Added in permban #%d, %s; reason: %s.", PERMBAN_counter, args[0], s);
+ 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, args[0]);
+ 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)
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)
{
struct chanserv_output *result = NULL;
do_randq(args[0], RANDQ_RAND, target, source);
return result;
}
struct chanserv_output *chanserv_random_quote(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
// RANDQ_NORMAL
do_randq(args[0], RANDQ_NORMAL, target, source);
return result;
}
struct chanserv_output *chanserv_random_quote_2(char *source, char *target, char *cmd, char **args, enum chanserv_invoke_type invoked, char *userhost)
{
struct chanserv_output *result = NULL;
// RANDQ_CASE
do_randq(args[0], RANDQ_CASE, target, source);
return result;
}
#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 *s = NULL;
+ char str [STRING_LONG] = {0};
-// FIXME: Check this, it may be wrong. The help may not be correct either.
- if (args[0] == NULL)
+ /* Fill argument buffer, if it's empty we return a message to
+ * the user asking for input. */
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf(NULL, "What do you want to add?");
+
if (invoked == MSG_INVOKE)
{
- if (check_access (userhost, args[0], 0, source) >= RAND_LEVEL)
+ if (check_access (userhost, "#*", 0, source) >= RAND_LEVEL)
{
- s = strtok (NULL, "");
- if (s == NULL)
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
return chanserv_asprintf(NULL, "What do you want to add?");
- add_randomstuff(source, source, s);
+ add_randomstuff(source, source, str);
}
}
else
- add_randomstuff(source, target, args[0]);
+ 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 *s = NULL;
+ char str [STRING_LONG] = {0};
+
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
+ return result;
- s = strtok (NULL, "");
- if (s != NULL)
- S("%s\n", s);
+ S("%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 *s = NULL;
+ char str [STRING_LONG] = {0};
- s = strtok (NULL, " ");
- if (s == NULL)
+ /* Check for arguments */
+ if ((db_argstostr (str, args, 0, ' ')) < 1)
{
snprintf(temp, sizeof (temp), "ls %s/*.rdb | wc\n", RDB_DIR);
result = chanserv_asprintf(result, "RDB: %s.", run_program(temp));
}
else
{
- if (strspn(s, SAFE_LIST) != strlen(s))
+ 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, s);
- result = chanserv_asprintf(result, ":%s", run_program(temp));
+ 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;
if (args[0] == NULL || args[1] == NULL || args[2] == NULL)
return result;
sn = atoi (args[0]);
sn2 = atoi (args[1]);
while (sn > 0)
{
S ("%s\n", args[2]);
sn--;
db_sleep (sn2);
}
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 *s = NULL;
+ char topic [STRING_LONG] = {0}, str [STRING_LONG] = {0};
if (args[0] == NULL)
return chanserv_asprintf(NULL, "Replace what?");
+
if (strlen(args[0]) > MAX_TOPIC_SIZE)
args[0][MAX_TOPIC_SIZE] = '\0';
- s = strtok (NULL, "");
- if (s == NULL)
- return chanserv_asprintf(NULL, "What info should replace %s?", args[0]);
- if (strlen(s) > MAX_DATA_SIZE)
- s[MAX_DATA_SIZE] = '\0';
- strlwr(args[0]);
- if (check_existing_url(source, args[0], target) != 1)
- return chanserv_asprintf(NULL, "%s \37%s\37", NO_ENTRY, args[0]);
- delete_url (source, args[0], target);
+
+ /* 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, args[0], s);
+ db_log (ADD_DELETES, "[%s] %s!%s REPLACE %s %s\n", date (), source, userhost, topic, str);
+
ADDITIONS++;
- db_log (URL2, "%s %s\n", args[0], s);
- return chanserv_asprintf(NULL, "%s has been updated.", args[0]);
+ 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[0] == NULL)
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[0] == NULL)
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 };
S("QUIT :Restarting %s ...\n", dbVersion);
db_sleep(2);
snprintf(temp, sizeof (temp), "%s", DARKBOT_BIN);
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[0] == NULL)
{
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[0] == NULL)
{
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]);
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[0] == NULL)
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;
int i = 0, j = 0;
char *ptr = NULL, *arglist = NULL;
if (args[0] == NULL)
return chanserv_asprintf(NULL, "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).");
/* Allocate space for arglist string. */
if ((arglist = malloc (STRING_LONG)) == NULL)
return chanserv_asprintf (NULL, "Memory allocation failure in chanserv_setinfo().");
/* Quick fix here. */
if ((ptr = strtok (NULL, "")) == NULL)
strcpy (arglist, args[0]);
else
{
strcpy (arglist, args[0]);
strcat (arglist, " ");
strcat (arglist, ptr);
}
update_setinfo (userhost, arglist, source);
save_changes ();
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 *s = NULL;
+ char str [STRING_LONG] = {0};
Sleep_Toggle = 1;
- if ((s = strtok (NULL, "")) == NULL)
+ /* 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, ' ')) < 1)
Sleep_Time = SLEEP_TIME;
- else if ((Sleep_Time = strtol (s, (char **) NULL, Sleep_Time)) < 1)
+ else if ((Sleep_Time = strtol (str, (char **) NULL, 10)) < 1)
Sleep_Time = SLEEP_TIME;
S ("PRIVMSG %s :%s\n", target, GOSLEEP_ACTION);
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");
}
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;
- get_stats(target, strtok (NULL, " "));
-
+ 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[0] == NULL)
return chanserv_asprintf(NULL, "Taf what?");
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[0] == NULL)
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 *s = NULL;
+ char str [STRING_LONG] = {0};
if (args[0] == NULL)
return chanserv_asprintf(NULL, "Tell who?");
if (args[1] == NULL)
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)
{
- s = strtok (NULL, " ");
- if (s == NULL)
+ if ((db_argstostr (str, args, 2, '+')) < 1)
return chanserv_asprintf(NULL, "Tell %s about what?", args[0]);
- strlwr(s);
+
+ strlwr(str);
if (invoked == MSG_INVOKE)
- show_url (source, get_multiword_topic (s), args[0], 1, 0, userhost, 1);
+ show_url (source, get_multiword_topic (str), args[0], 1, 0, userhost, 1);
else
- show_url (args[0], get_multiword_topic (s), target, 1, 0, userhost, 1);
+ show_url (args[0], get_multiword_topic (str), target, 1, 0, userhost, 1);
}
else
{
- strlwr(args[1]);
+ if ((db_argstostr (str, args, 1, '+')) < 1)
+ return chanserv_asprintf (NULL, "Tell %s about what?", args[0]);
+
+ strlwr(str);
+
if (invoked == MSG_INVOKE)
- show_url (source, get_multiword_topic (args[1]), args[0], 1, 0, userhost, 1);
+ show_url (source, get_multiword_topic (str), args[0], 1, 0, userhost, 1);
else
- show_url (args[0], get_multiword_topic (args[1]), target, 1, 0, userhost, 1);
+ 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 *s = NULL;
+ char str [STRING_LONG] = {0};
- s = strtok (NULL, "");
- if (s == NULL)
- S ("TOPIC %s :\n", target);
+ 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, s);
+ 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[0] == NULL)
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[0] == NULL)
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 *s = NULL;
-
- if ((s = strtok (NULL, " ")) != NULL)
- show_helper_list (source, atoi (s));
- else
+ char str [STRING_LONG] = {0};
+ int i = 0;
+
+ if (!args[0])
+ {
show_helper_list (source, 0);
+ return result;
+ }
+ else
+ {
+ int level = 0;
+ for (i = 0; args[i]; i++)
+ show_helper_list (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://www.freezedown.org\1.");
+ return chanserv_asprintf(NULL, "\1VERSION Hi, I'm a Darkbot. Download me from http://www.darkbot.org\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 *s = NULL;
+ char nicks [STRING_LONG] = {0}, chan [STRING_LONG] = {0},
+ str [STRING_LONG] = {0};
+ int ischan = 0;
- if (args[0] == NULL)
+ if (!args[0])
return result;
- s = strtok (NULL, "");
- if ((invoked == MSG_INVOKE) || (*args[0] == '#'))
+
+ db_argstostr (str, args, 0, ' ');
+
+ /* Check for channel name specified, set up args accordingly. */
+ if ((*args[0] == '#') || (*args[0] == '&'))
{
- if (check_access (userhost, args[0], 0, source) >= 3)
- {
- if (s == NULL)
- return result;
- S ("MODE %s +vvvvvv %s\n", args[0], s);
- }
+ ischan = 1; /* channel specified */
+ strncpy (chan, args[0], sizeof chan);
+ args++;
}
- else
+
+ 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 (s == NULL)
- S ("MODE %s +vvvvvvv %s\n", target, args[0]);
- else
- S ("MODE %s +vvvvvvv %s %s\n", target, args[0], s);
+ /* 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[0] == NULL)
return chanserv_asprintf(NULL, "Show weather from where?");
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 *s = NULL;
+ char str [STRING_LONG] = {0};
char *ptr3 = NULL;
if (args[0] == NULL)
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)
{
- s = strtok (NULL, " ");
- if (s == NULL)
+ 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);
- show_url (source, get_multiword_topic (s), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
+ show_url (source, get_multiword_topic (str), (invoked == MSG_INVOKE) ? source : target, 1, 0, userhost, 0);
}
else
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 *s = NULL;
+ char str [STRING_LONG] = {0};
if (args[0] == NULL)
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)
{
- s = strtok (NULL, " ");
- if (s == NULL)
+ if ((db_argstostr (str, args, 2, ' ')) < 1)
return chanserv_asprintf(NULL, "Whisper to %s about what?", args[0]);
- strlwr(s);
- show_url(source, get_multiword_topic(s), args[0], 1, 0, userhost, 1);
+ strlwr(str);
+ show_url(source, get_multiword_topic(str), args[0], 1, 0, userhost, 1);
}
else
{
strlwr (args[1]);
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, chanserv_add, {"ADD", "REMEMBER", "SAVE", "STORE", NULL}, "<topic> <text>", "Add a topic and it's text."},
{PASSWORD_COMMAND, 3, 4, chanserv_add_user, {"ADDUSER", NULL, NULL, NULL, NULL}, "<#channel|#*> <user@host> <level> [password]", "Add a user to the access list."},
{SAFE_COMMAND, 2, 2, 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, 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, chanserv_backup, {"BACKUP", NULL, NULL, NULL, NULL}, NULL, "Create a backup of the database."},
//#endif
#ifdef ENABLE_CHANNEL
{INFO_COMMAND, 1, 0, chanserv_ban_list, {"BANLIST", NULL, NULL, NULL, NULL}, NULL, "Displays permanent bans."},
#endif
#ifdef ENABLE_MATH
{INFO_COMMAND, 0, 1, chanserv_calc, {"CALC", "MATH", NULL, NULL, NULL}, "<expression>", "Very basic calculator."},
#endif
{INFO_COMMAND, 0, 1, chanserv_chan_info, {"CHANINFO", NULL, NULL, NULL, NULL}, "<#channel>", "Displays number of users in channel and in ram."},
{INFO_COMMAND, 0, 1, chanserv_chan_users, {"CHANUSERS", NULL, NULL, NULL, NULL}, "<#channel>", "Displays names of users in channel."},
{INFO_COMMAND, 0, 1, chanserv_char, {"CHAR", NULL, NULL, NULL, NULL}, "<character>", "Show the ascii code of the character."},
{INFO_COMMAND, 0, 0, chanserv_char_show, {"CMDCHAR?", NULL, NULL, NULL, NULL}, NULL, "Show command character."},
{INFO_COMMAND, 0, 0, chanserv_cpu_show, {"CPU?", NULL, NULL, NULL, NULL}, NULL, "Show the cpu usage of the bot."},
{DANGER_COMMAND, 2, 0, chanserv_cycle, {"CYCLE", "CYC", NULL, NULL, NULL}, "[#channel]", "Leave and rejoin the channel."},
{INFO_COMMAND, 0, 1, chanserv_data_search, {"DATASEARCH", "DSEARCH", "DFIND", NULL, NULL}, "<topic>", "Search in the replies."},
{INFO_COMMAND, 0, 0, chanserv_date, {"DATE", "TIME", NULL, NULL, NULL}, NULL, "Show the current date and time."},
{DANGER_COMMAND, 0, 1, chanserv_reserved_2, {RESERVED2, NULL, NULL, NULL, NULL}, "<>", ""},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, chanserv_delban, {"DELBAN", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the permanent ban list."},
#endif
{NORMAL_COMMAND, DEL_LEVEL, 1, chanserv_delete, {"DELETE", "DEL", "REMOVE", "FORGET", NULL}, "<topic>", "Delete a topic."},
{DANGER_COMMAND, 3, 1, chanserv_deluser, {"DELUSER", NULL, NULL, NULL, NULL}, "<user@host>", "Delete a user from the access list."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, chanserv_deop, {"DEOP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Remove channel operator status from users."},
{NORMAL_COMMAND, 3, 1, chanserv_devoice, {"DEVOICE", "DV", "DEV", "DVOICE", NULL}, "[#channel] <nicks>", "Remove channel voice status from users."},
#endif
{DANGER_COMMAND, 3, 0, chanserv_die, {"DIE", "QUIT", NULL, NULL, NULL}, NULL, "Stop bot from running."},
{INFO_COMMAND, 0, 1, chanserv_display, {"DISPLAY", NULL, NULL, NULL, NULL}, "<topic>", "Display the text for a topic."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 0, chanserv_down, {"DOWN", NULL, NULL, NULL, NULL}, NULL, "Remove channel operator status from yourself."},
#endif
{INFO_COMMAND, 0, 0, chanserv_darkbot, {"\2\2DARKBOT", NULL, NULL, NULL, NULL}, NULL, ""},
{DANGER_COMMAND, 0, 1, chanserv_reserved_1, {RESERVED1, NULL, NULL, NULL, NULL}, "<>", ""},
#ifdef ENABLE_GOOGLE
{NORMAL_COMMAND, 0, 1, chanserv_google, {"GOOGLE", NULL, NULL, NULL, NULL}, "<text>", "Look up the text on google."},
#endif
{INFO_COMMAND, 0, 0, chanserv_help, {"HELP", NULL, NULL, NULL, NULL}, "[command]", "Show some help text to the user."},
{INFO_COMMAND, 0, 1, chanserv_idle, {"IDLE", NULL, NULL, NULL, NULL}, "<nick>", "Shows how long the user has been idle."},
{DANGER_COMMAND, 1, 1, chanserv_ignore, {"IGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to ignore a user."},
{INFO_COMMAND, 0, 0, chanserv_info, {"INFO", NULL, NULL, NULL, NULL}, NULL, "Shows some information about bot and it's activity."},
{INFO_COMMAND, 0, 0, chanserv_info_2, {"INFO2", NULL, NULL, NULL, NULL}, NULL, "Shows when the bot was compiled, and lines processed since startup."},
{INFO_COMMAND, 2, 0, chanserv_info_size, {"INFOSIZE", "DBSIZE", NULL, NULL, NULL}, NULL, "Show size of the database."},
{INFO_COMMAND, 0, 1, chanserv_isop, {"ISOP", NULL, NULL, NULL, NULL}, "<nick>", "Is user a channel op?"},
{DANGER_COMMAND, 2, 1, chanserv_join, {"JOIN", "J", NULL, NULL, NULL}, "<#channel>", "Get bot to join a channel."},
{INFO_COMMAND, 0, 0, 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, chanserv_kick, {"KICK", "WHACK", "K", "NAIL", NULL}, "[#channel] <nick> [reason]", "Kick a user off the channel."},
#endif
{INFO_COMMAND, 0, 0, chanserv_language, {"LANGUAGE", "LANG", NULL, NULL, NULL}, NULL, "Shows the language that bot is currently speaking."},
{DANGER_COMMAND, 2, 0, chanserv_leave, {"LEAVE", "PART", "L", "P", NULL}, "[#channel]", "Get bot to leave the channel."},
{INFO_COMMAND, 0, 1, chanserv_length, {"LENGTH", NULL, NULL, NULL, NULL}, "<text>", "Show the length of the text."},
{INFO_COMMAND, 0, 1, chanserv_level, {"LEVEL", NULL, NULL, NULL, NULL}, "<nick>", "Show users level."},
{INFO_COMMAND, 0, 0, chanserv_location_show, {"LOCATION?", NULL, NULL, NULL, NULL}, NULL, "Shows what servers are available and in use."},
{PASSWORD_COMMAND, 0, 1, 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, chanserv_users_list, {"LUSERS", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
{INFO_COMMAND, 0, 1, chanserv_mask, {"MASK", NULL, NULL, NULL, NULL}, "<nick>", "Show the users user@host mask."},
//#ifndef WIN32
{INFO_COMMAND, 3, 0, chanserv_memory, {"MEM", "RAM", NULL, NULL, NULL}, NULL, "Shows some memory usage and process statistics."},
//#endif
#ifdef ENABLE_METAR
{NORMAL_COMMAND, 0, 1, chanserv_metar, {"METAR", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw METAR weather data."},
#endif
{DANGER_COMMAND, 3, 1, chanserv_nick, {"NICK", "N", NULL, NULL, NULL}, "<newnick>", "Change bot's nickname, but not the default."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 3, 1, chanserv_op, {"OP", NULL, NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel operator status to users."},
#endif
{INFO_COMMAND, 0, 0, chanserv_os_show, {"OS", NULL, NULL, NULL, NULL}, NULL, "Show the operating system that bot is running on."},
{PASSWORD_COMMAND, 0, 2, chanserv_password, {"PASSWORD", "PASS", "PASSWD", NULL, NULL}, "<old password> <new password>", "Change your bot access list password."},
{DANGER_COMMAND, 3, 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, chanserv_perm_ban, {"PERMBAN", "SHITLIST", NULL, NULL, NULL}, "<user@host> [reason]", "Adds a user to the permanent ban list."},
{INFO_COMMAND, 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, chanserv_ping, {"\1PING", NULL, NULL, NULL, NULL}, "<>", ""},
#endif
{INFO_COMMAND, 0, 0, chanserv_ping2, {"PING", NULL, NULL, NULL, NULL}, NULL, "Replies with \"PONG\" to see how lagged the bot is.."},
{INFO_COMMAND, 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, chanserv_quiz, {"QUIZ", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
#ifdef ENABLE_RANDQ
{NORMAL_COMMAND, 0, 1, chanserv_quote, {"QUOTE", NULL, NULL, NULL, NULL}, "[text]", "Shows a random quote."},
{NORMAL_COMMAND, 0, 1, chanserv_random_quote, {"RANDQUOTE", "RANDQ", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
{NORMAL_COMMAND, 0, 1, chanserv_random_quote_2, {"RANDQUOTE2", "RANDQ2", NULL, NULL, NULL}, "[text]", "Shows a random quote."},
#endif
#ifdef ENABLE_RANDOM
{NORMAL_COMMAND, RAND_LEVEL, 1, chanserv_random_stuff, {"RANDOMSTUFF", "RANDSTUFF", "RS", NULL, NULL}, "<text>", "Add random stuff to say."},
{INFO_COMMAND, 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, chanserv_raw, {"RAW", NULL, NULL, NULL, NULL}, "<raw data>", "Get bot to send raw IRC data."},
//#ifndef WIN32
{INFO_COMMAND, 0, 0, chanserv_rdb, {"RDB", NULL, NULL, NULL, NULL}, "[topic]", "Display information about the random databases."},
//#endif
{DANGER_COMMAND, 3, 3, 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, chanserv_replace, {"REPLACE", NULL, NULL, NULL, NULL}, "<topic> <text>", "Replace the text of a topic."},
{DANGER_COMMAND, 3, 0, chanserv_restart, {"RESTART", "REHASH", NULL, NULL, NULL}, NULL, "Restart the bot."},
{INFO_COMMAND, 0, 1, chanserv_search, {"SEARCH", "LOOK", "FIND", NULL, NULL}, "<text>", "Search in the topics."},
{INFO_COMMAND, 0, 1, chanserv_seen, {"SEEN", NULL, NULL, NULL, NULL}, "<nick>", "Show the last time a user was seen."},
{DANGER_COMMAND, 3, 1, chanserv_jump, {"SERVER", "JUMP", NULL, NULL, NULL}, "<server> [port]", "Switch bot to a different server."},
{DANGER_COMMAND, 3, 1, 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, 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, 0, chanserv_sleep, {"SLEEP", "HUSH", NULL, NULL, NULL}, NULL, "Deactivate bot for a period."},
#ifdef ENABLE_STATS
{INFO_COMMAND, 0, 0, chanserv_stats, {"STATS", NULL, NULL, NULL, NULL}, "[nick]", "Shows statistics about questions answered."},
#endif
#ifdef ENABLE_TAF
{NORMAL_COMMAND, 0, 1, chanserv_taf, {"TAF", NULL, NULL, NULL, NULL}, "<city or code>", "Get raw TAF weather data."},
#endif
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 1, chanserv_teaseop, {"TEASEOP", "TO", NULL, NULL, NULL}, "<nick>", "Tease a user with channel operator status."},
#endif
{INFO_COMMAND, 0, 2, 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, chanserv_topic, {"TOPIC", "T", NULL, NULL, NULL}, "<channel topic>", "Change the channels topic."},
#endif
{DANGER_COMMAND, 1, 1, chanserv_unignore, {"UNIGNORE", NULL, NULL, NULL, NULL}, "<nick>", "Get bot to stop ignoring a user."},
{INFO_COMMAND, 0, 1, chanserv_unixtime, {"UNIXTIME", NULL, NULL, NULL, NULL}, "<time>", "Shows unixtime."},
#ifdef ENABLE_CHANNEL
{DANGER_COMMAND, 2, 0, chanserv_up, {"UP", NULL, NULL, NULL, NULL}, NULL, "Add channel operator status to yourself."},
#endif
//#ifndef WIN32
{INFO_COMMAND, 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, chanserv_user_list, {"USERLIST", "HLIST", "ACCESS", NULL, NULL}, NULL, "Show the bot's access list."},
{INFO_COMMAND, 0, 0, chanserv_variables, {"VARIABLES", NULL, NULL, NULL, NULL}, NULL, "Displays variables you can use."},
#ifdef ENABLE_CTCP
{INFO_COMMAND, 0, 0, chanserv_version, {"\1VERSION\1", NULL, NULL, NULL, NULL}, NULL, ""},
#endif
#ifdef ENABLE_CHANNEL
{NORMAL_COMMAND, 3, 1, chanserv_voice, {"VOICE", "V", NULL, NULL, NULL}, "[#channel] <nicks>", "Add channel voice status to users."},
#endif
{SAFE_COMMAND, SLEEP_LEVEL, 0, chanserv_wakeup, {"WAKEUP", NULL, NULL, NULL, NULL}, NULL, "Reactivates bot from sleep mode."},
#ifdef ENABLE_WEATHER
{NORMAL_COMMAND, 0, 1, chanserv_weather, {"WEATHER", NULL, NULL, NULL, NULL}, "<city or code>", "Get decoded weather data."},
#endif
{SAFE_COMMAND, 0, 2, chanserv_where, {"WHAT", "WHO", "WHERE", NULL, NULL}, "<IS> [A|AN] <topic>", "Recall a topic."},
{SAFE_COMMAND, 0, 2, chanserv_whisper, {"WHISPER", NULL, NULL, NULL, NULL}, "<nick> [ABOUT] <topic>", "Get bot to recall a topic to a user privately."},
{INFO_COMMAND, 4, 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, j, found = -1, command = 0, wakeup = 0, exempt = 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.
*/
strcpy (oldbuf, buf);
ptr = oldbuf;
if (*ptr == ':')
*ptr++;
cmd = strtok (buf, " ");
if (cmd == NULL)
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, " ");
}
else if (*cmd == *CMDCHAR)
input_type = CHAR_INVOKE;
if (cmd != NULL)
{
if (*cmd == *CMDCHAR)
{
cmd++;
command = 1;
}
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;
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;
// Not sure why this is here.
// else if ((input_type == ADDRESS_INVOKE) && (command != 1))
// 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 more_needed = 0, too_many = 0;
int k = 0;
- j = chanserv_commands[found].arg_count;
-
/* 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 less than the actual number of words 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.
*/
- k = count_char (ptr, ' ');
+ k = (count_char (ptr, ' ') + 1);
+ j = chanserv_commands[found].arg_count;
- if (j > 0)
+ if (k > 0)
{
- args = calloc(j, sizeof(char *));
+ args = calloc(k, sizeof(char *));
if (args)
{
- for (i = 0; i < j; i++)
+ for (i = 0; i < k; i++)
{
args[i] = strtok(NULL, " ");
- if (args[i] == NULL)
+
+ /* Check for more arguments needed, but don't
+ * bail out, we'll take care of it later. */
+ if ((i < j) && (args[i] == NULL))
{
more_needed = 1;
break;
}
}
}
else // FIXME: Should bitch about lack of ram.
return;
}
else
{
/* args read is equal to 0, so we need to do special
* handling here to avoid problems. Certain commands are
* exempted if matched from a list declared in the
* check_exempt function.
*/
if (((input_type == ADDRESS_INVOKE) && k > (j+1)) ||
(input_type == DIRECT_INVOKE) && (k > j) ||
(input_type == MSG_INVOKE) && (k > j))
{
if (check_exempt(cmd) == 1)
exempt = 1;
else
too_many = 1;
}
}
if (too_many == 1 && exempt != 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))
{
show_url(source, ptr,
((input_type == MSG_INVOKE)
? source : target), 1, 0, userhost, 0);
return;
}
return;
}
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)
{
struct chanserv_output *output = result;
i = 1;
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';
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);
}
S("PRIVMSG %s :%s: %s\n", target, source, s);
}
output = output->next;
}
chanserv_output_free(result);
}
else if (more_needed && (chanserv_commands[found].syntax))
{
if (input_type == MSG_INVOKE)
S("NOTICE %s :SYNTAX - %s%s %s\n", source, command ? "!" : "", cmd, chanserv_commands[found].syntax);
else
S("PRIVMSG %s :%s: SYNTAX - %s%s %s\n", target, source, command ? "!" : "", cmd, chanserv_commands[found].syntax);
}
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 != NULL))
{
show_url(source, get_multiword_topic(cmd),
(input_type == MSG_INVOKE) ? source : target,
(! (input_type == DIRECT_INVOKE)),
(input_type == DIRECT_INVOKE),
userhost, 0);
}
}
}
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[] = {
#ifdef ENABLE_STATS
"STATS",
#endif
+ "CYCLE",
"HELP",
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/beta/source/general.c b/beta/source/general.c
index 9515f48..007f532 100755
--- a/beta/source/general.c
+++ b/beta/source/general.c
@@ -1,564 +1,595 @@
#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, c->level, 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;
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 (args[0] == NULL)
+ 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/beta/source/prototypes.h b/beta/source/prototypes.h
index 094865b..a6a35cd 100755
--- a/beta/source/prototypes.h
+++ b/beta/source/prototypes.h
@@ -1,174 +1,175 @@
/* ------------ 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 show_seen (char *, char *, char *),
count_seen (char *, char *),
show_info2 (const char *, const char *);
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
void do_randq (char *, const int, const char *, const char *);
#endif
void datasearch (const char *, char *, char *),
display_url (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
void 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);
void show_helper_list (const char *, long),
set_paths (void),
show_banlist (const char *),
chanserv (char *, char *, char *),
raw_now (char *),
find_url (const char *, char *, char *),
save_changes (void),
show_url (char *, char *, char *, long, long, char *, long);
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 *, ...);
void show_chaninfo (const char *, const char *, const char *);
void 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);
void get_stats (char *, char *);
#endif
#ifdef ENABLE_QUIZ
void run_quiz_question (char *);
void run_quiz_answer (void);
#endif
void check_files (void);
void run_perform (void);
int 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);

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 15:32 (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2260460
Default Alt Text
(150 KB)

Event Timeline