]> git.donarmstrong.com Git - infobot.git/commitdiff
* Merge changes from prposed changes
authordondelelcaro <dondelelcaro@c11ca15a-4712-0410-83d8-924469b57eb5>
Sat, 26 Apr 2008 07:40:45 +0000 (07:40 +0000)
committerdondelelcaro <dondelelcaro@c11ca15a-4712-0410-83d8-924469b57eb5>
Sat, 26 Apr 2008 07:40:45 +0000 (07:40 +0000)
 * Add back in a few custom patches

git-svn-id: https://svn.code.sf.net/p/infobot/code/branches/don/dpkg@1811 c11ca15a-4712-0410-83d8-924469b57eb5

172 files changed:
AUTHORS
BUGS
ChangeLog
FAQ [new file with mode: 0644]
INSTALL
INSTALL.mysql [deleted file]
INSTALL.patches [deleted file]
INSTALL.pgsql [deleted file]
INSTALL.sqlite [deleted file]
README
README.quick
THANKS [new file with mode: 0644]
TODO
VERSION [new file with mode: 0644]
blootbot [deleted file]
doc/USAGE [new file with mode: 0644]
doc/infobot.config.pod [new file with mode: 0644]
doc/infobot.users.pod [new file with mode: 0644]
files/.cvsignore [deleted file]
files/blootbot.help [deleted file]
files/blootbot.lang [deleted file]
files/blootbot.lart [deleted file]
files/blootbot.randtext [deleted file]
files/infobot.help [new file with mode: 0644]
files/infobot.lang [new file with mode: 0644]
files/infobot.lart [new file with mode: 0644]
files/infobot.randtext [new file with mode: 0644]
files/sample/blootbot.chan [deleted file]
files/sample/blootbot.config [deleted file]
files/sample/blootbot.countdown [deleted file]
files/sample/blootbot.servers [deleted file]
files/sample/blootbot.users [deleted file]
files/sample/infobot.chan [new file with mode: 0644]
files/sample/infobot.config [new file with mode: 0644]
files/sample/infobot.countdown [new file with mode: 0644]
files/sample/infobot.servers [new file with mode: 0644]
files/sample/infobot.users [new file with mode: 0644]
files/unittab [deleted file]
infobot [new file with mode: 0755]
log/.cvsignore [deleted file]
patches/WWW_Search.patch [new file with mode: 0644]
patches/WWW_Search.patch.old [new file with mode: 0644]
scripts/backup_table-master.sh
scripts/backup_table-slave.pl
scripts/botchk.sh
scripts/dbm2mysql.pl
scripts/dbm2txt.pl
scripts/findparam.pl [changed mode: 0644->0755]
scripts/fixbadchars.pl [changed mode: 0644->0755]
scripts/insertDB.pl [changed mode: 0644->0755]
scripts/irclog2html.pl
scripts/makepasswd
scripts/mysql2txt.pl
scripts/oreilly_dumpvar.pl [changed mode: 0644->0755]
scripts/oreilly_prettyp.pl [changed mode: 0644->0755]
scripts/output_stats.sh [changed mode: 0644->0755]
scripts/parse_warn.pl
scripts/showvars.pl [changed mode: 0644->0755]
scripts/symname.pl
scripts/txt2mysql.pl
scripts/vartree.pl [changed mode: 0644->0755]
scripts/webbackup.pl
setup/README [new file with mode: 0644]
setup/botmail.sql [deleted file]
setup/connections.sql [deleted file]
setup/factoids.sql [deleted file]
setup/freshmeat.sql [deleted file]
setup/mysql/botmail.sql [new file with mode: 0644]
setup/mysql/factoids.sql [new file with mode: 0644]
setup/mysql/onjoin.sql [new file with mode: 0644]
setup/mysql/rootwarn.sql [new file with mode: 0644]
setup/mysql/seen.sql [new file with mode: 0644]
setup/mysql/stats.sql [new file with mode: 0644]
setup/news.sql [deleted file]
setup/onjoin.sql [deleted file]
setup/pgsql/botmail.sql [new file with mode: 0644]
setup/pgsql/factoids.sql [new file with mode: 0644]
setup/pgsql/onjoin.sql [new file with mode: 0644]
setup/pgsql/rootwarn.sql [new file with mode: 0644]
setup/pgsql/seen.sql [new file with mode: 0644]
setup/pgsql/stats.sql [new file with mode: 0644]
setup/rootwarn.sql [deleted file]
setup/seen.sql [deleted file]
setup/setup.pl
setup/sqlite/botmail.sql [new file with mode: 0644]
setup/sqlite/factoids.sql [new file with mode: 0644]
setup/sqlite/onjoin.sql [new file with mode: 0644]
setup/sqlite/rootwarn.sql [new file with mode: 0644]
setup/sqlite/seen.sql [new file with mode: 0644]
setup/sqlite/stats.sql [new file with mode: 0644]
setup/sqlite2/botmail.sql [new file with mode: 0644]
setup/sqlite2/factoids.sql [new file with mode: 0644]
setup/sqlite2/onjoin.sql [new file with mode: 0644]
setup/sqlite2/rootwarn.sql [new file with mode: 0644]
setup/sqlite2/seen.sql [new file with mode: 0644]
setup/sqlite2/stats.sql [new file with mode: 0644]
setup/stats.sql [deleted file]
setup/uptime.sql [deleted file]
src/CLI/Support.pl
src/CommandStubs.pl
src/DynaConfig.pl
src/Factoids/Core.pl
src/Factoids/DBCommon.pl
src/Factoids/Norm.pl
src/Factoids/Question.pl
src/Factoids/Reply.pl
src/Factoids/Statement.pl
src/Factoids/Update.pl
src/Files.pl
src/IRC/Irc.pl
src/IRC/IrcHelpers.pl
src/IRC/IrcHooks.pl
src/IRC/Schedulers.pl
src/Misc.pl
src/Modules/BZFlag.pl
src/Modules/Debian.pl
src/Modules/DebianBugs.pm
src/Modules/DebianExtra.pl
src/Modules/Dict.pl
src/Modules/DumpVars.pl
src/Modules/DumpVars2.pl
src/Modules/Exchange.pl
src/Modules/Factoids.pl
src/Modules/HTTPDtype.pl
src/Modules/Kernel.pl
src/Modules/Math.pl
src/Modules/NewUnits.pl [deleted file]
src/Modules/News.pl
src/Modules/OnJoin.pl
src/Modules/Plug.pl
src/Modules/Quote.pl
src/Modules/RSSFeeds.pl [new file with mode: 0644]
src/Modules/RootWarn.pl
src/Modules/Rss.pl
src/Modules/Search.pl
src/Modules/Topic.pl
src/Modules/Units.pl
src/Modules/Uptime.pl
src/Modules/UserDCC.pl
src/Modules/UserInfo.pl
src/Modules/W3Search.pl
src/Modules/Weather.pl
src/Modules/Wingate.pl
src/Modules/Zippy.pl
src/Modules/babelfish.pl
src/Modules/botmail.pl
src/Modules/case.pl
src/Modules/countdown.pl
src/Modules/dice.pl
src/Modules/dns.pl
src/Modules/hex2ip.pl [new file with mode: 0644]
src/Modules/insult.pl
src/Modules/md5.pl
src/Modules/nickometer.pl
src/Modules/pager.pl
src/Modules/piglatin.pl
src/Modules/reverse.pl
src/Modules/scramble.pl
src/Modules/slashdot.pl
src/Modules/spell.pl
src/Modules/wikipedia.pl
src/Modules/wtf.pl
src/Modules/zfi.pl
src/Modules/zsi.pl
src/Net.pl
src/Process.pl
src/Shm.pl
src/UserExtra.pl
src/core.pl
src/dbi.pl
src/logger.pl
src/modules.pl

diff --git a/AUTHORS b/AUTHORS
index 5efe7784f1fd9abd6aaf1e28acf2f9a944428245..ec8e1ccfbecf00aba85029dde03cdfdf4b73dd87 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,30 +1,49 @@
-Blootbot:
-    License: Artistic
-    Main Author:
-       - Tim Riker <Tim@Rikers.org>
-    Other Contributors:
-       - David Sobon <dms@users.sourceforge.net>
-       - Danny Jabbour [GmLB] <danny@opticaldelusion.org>
+# $Id$
 
 
-Module-Reload: (idea taken)
-    License: Artistic
-       - Doug MacEachern <???>
-       - Joshua Pritikin <???>
+                                 -------------
+                                 -- AUTHORS --
+                                 -------------
 
 
-Module-Units:
-    License: GPL
-       - M-J. Dominus <mjd-perl-units-id-iut+buobvys+@plover.com>
+Infobot original:
 
 
-Infobot:
     License: As perl (GPL & Artistic)
     License: As perl (GPL & Artistic)
-       - Kevin A. Lenzo [oznoid] <lenzo@cs.cmu.edu>
-       - Patrick Cole [ltd] <???>
+        - Kevin A. Lenzo [oznoid] <lenzo@cs.cmu.edu>
+        - Patrick Cold [ltd] <???>
+
+Later forked as Blootbot (and now remerged back):
+
+    License: Artistic
+        Tim Riker [TimRiker] <Tim@Rikers.org>
+
+Is currently maintained by:
+
+    - Tim Riker [TimRiker] <Tim@Rikers.org>
+    - Don Armstrong [dondelelcaro] <dondelelcaro@users.sourceforge.net>
+    - Dan McGrath [troubled] <djmcgrath@users.sourceforge.net>
+    - Simon Cote [simonrvn] <simonraven@users.sourceforge.net>
+
+and has previously been maintained by:
+
+    - Adam Kennedy <adamkennedy@users.sourceforge.net>
+    - Corey Edwards <tensai@zmonkey.org>
+    - Danny Jabbour [GmLB] <danny@opticaldelusion.org>
+    - Dave Brown <dagbrown@users.sourceforge.net>
+    - Dave Paris <a-mused@users.sourceforge.net>
+    - David Sobon <dms@users.sourceforge.net>
+    - Doug MacEachern <???>
+    - Joshua Pritikin <???>
+    - Kevin Meltzer <kdm@users.sourceforge.net>
+    - M-J. Dominus <mjd-per-units-id-iut+buobvys+@plover.com>
+    - Martijin van Beers <lotr@users.sourceforge.net>
+    - Masque <qid@users.sourceforge.net>
+    - Peter Sergeant <sheriff_pete@users.sourceforge.net>
+    - Rich Lafferty <rich_lafferty@users.sourceforge.net>
+    - Richard Harman <rharman@users.sourceforge.net>
+    - Roderick Schertler <rschertler@users.sourceforge.net>
+    - Tony <sh3mh4mf0r4sh@users.sourceforge.net>
 
 
-OnJoin:
-       - Corey Edwards <tensai@zmonkey.org>
 
 
-Patches:
-       - ...
+Countless other people have contributed to Infobot (see THANKS), provided code
+and/or helped troubleshoot problems. Many thanks to all of them.
 
 
-Quotes file (files/blootbot.randtext):
-       - ??? Ask netgod/larne/is for dpkg's tcl
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/BUGS b/BUGS
index 684c8c4adb5bebbb8129c2da50396e65890f39c2..48d079cae0bb331caf5dc8c0bca83f7bff222681 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -1 +1,20 @@
-allows adding a "cmd:foo (.*)" factoid but not removing it
+Known bugs that should be dealt with soon as possible:
+
+    * Older CMD: foo's cannot be used or removed. Must be removed manually from
+    the database with SQL
+
+    * !+topic list gives and incorrect error Failed. "You (#botpark) are not in
+    #botpark, hey?"
+
+    * Bot tries to ask chanserv for OP's on any channel. Should be a chanset
+    setting on a per channel basis
+
+    * News is currently stored in a file rather than the SQL table created for it
+
+    * !help has size issues. Add's extra lines with only 1 or 2 help commands
+    instead of one maximum size IRC msg
+
+    * Bot can be flooded offline with a crash if !+factstats help and /msg nick
+    factstats help, are used at the same time
+
+# vim:ts=4:sw=4:expandtab:tw=80
index baed181fe42dc80b63c134ec17a7e6d1706c1415..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-
-2005-02-18 00:00  timriker
-
-       * CMD: is now cmd:
-
-2005-02-18 00:00  timriker
-
-       * src/Factoids/Question.pl: minVolunteerLength now per channel
-       * src/core.pl: getChanConf checks _default too
-       * src/: "s/hasParam/IsChanConfOrWarn/"
-       * src/: add handling for channel specific factoids:
-         "#botpark logs" -> http://ibot.rikers.org/botpark
-         factoidSearch is a space delimited list of prefixes to try
-       * src/: kill %myModules - loadMyModule expects the CORRECT CASE basename
-       * .: a ton of other crap that TimRiker never documented here
-
-2001-04-28 22:04  dms
-
-       * src/IRC/: IrcHelpers.pl, IrcHooks.pl, Schedulers.pl: hookMode:
-       change chan to nick.  if deopped by chanserv, check it dont change
-       channel limits during netsplit.
-
-2001-04-26 22:37  dms
-
-       * src/: DynaConfig.pl, Process.pl, UserExtra.pl, core.pl,
-       Factoids/Statement.pl, IRC/Irc.pl, IRC/IrcHelpers.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl, Modules/News.pl: "~forget blah"
-       now works. thanks to ElectricElf documented user flags
-       public/private/notice send limit now configurable. thanks to EE
-       added "countrystats" command.
-       "blootbot: are you fixed now? :)" -- fixed. found by greycat
-       use hasParam instead of IsParam in UserExtra.pl/userCommands()
-       command "ord" handling fixed.
-
-2001-04-24 20:58  dms
-
-       * src/: logger.pl, IRC/Irc.pl, IRC/IrcHelpers.pl, IRC/IrcHooks.pl,
-       IRC/Schedulers.pl: fix more warnings
-       set $ident in nick()
-
-2001-04-23 20:14  dms
-
-       * src/: Process.pl, UserExtra.pl, logger.pl, IRC/Irc.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl: allow join to join irrelevent of being on chan
-       chanstats: count stats if exist - make perl happy
-       misc cleanup of status()
-       add time taken to join all channels, useless stats.
-       disable notify code
-       leakCheck: show stats on hash chanstats
-       mkBackup: show age of file.
-
-2001-04-22 22:58  dms
-
-       * src/IRC/IrcHooks.pl: fix on_targettoofast once and for all, hopefully.
-
-2001-04-22 22:01  dms
-
-       * src/: UserExtra.pl, logger.pl: make sure chanstats don't flood
-       don't throttle if it's a perl warn message
-
-2001-04-22 21:52  dms
-
-       * src/Factoids/Reply.pl: woops... forgot this aswell
-
-2001-04-22 21:48  dms
-
-       * src/Factoids/Reply.pl: disabled literal if factoid is requested via /msg by author; use literal
-       instead
-
-2001-04-22 20:25  dms
-
-       * src/IRC/: Irc.pl, IrcHooks.pl, Schedulers.pl: don't call chanservcheck in joinnextchan
-       call chanservcheck in on_endofnames
-       ircCheck "resets" itself if it thinks so
-
-2001-04-22 20:17  dms
-
-       * src/: Factoids/Question.pl, Factoids/Reply.pl, IRC/Irc.pl,
-       Modules/UserDCC.pl: part now warns if we're on a channel - allow it anyway.
-       added "reset" to DCC CHAT
-
-2001-04-21 22:37  dms
-
-       * TODO: todo list, for those who want to know what "new" features will be coming
-
-2001-04-20 21:27  dms
-
-       * src/: Process.pl, IRC/Schedulers.pl: we didn't set modified_time for deleted factoids - fixed
-       also... if final delete factoid list is >50... don't do it!
-
-2001-04-20 21:16  dms
-
-       * src/: UserExtra.pl, IRC/Irc.pl: chagned notice lines/sec to 3
-       made connectivity percentage 5 significant decimal places.
-
-2001-04-20 20:54  dms
-
-       * src/: CommandStubs.pl, DynaConfig.pl, Misc.pl, Process.pl,
-       UserExtra.pl, Factoids/Question.pl, Factoids/Reply.pl,
-       Factoids/Statement.pl, IRC/Irc.pl, IRC/IrcHelpers.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl, Modules/Debian.pl,
-       Modules/DebianExtra.pl, Modules/Factoids.pl, Modules/Topic.pl,
-       Modules/Units.pl, Modules/Uptime.pl, Modules/UserDCC.pl: converted %{$blah{$blah}} to %{ $blah{$blah} }
-       added IRC hooks to catch failed channel joins
-       chanserv function moved to joinNextChan
-       created chanserv function for "common" use, chanServCheck
-       changed cache{chanlimitChange} hash a little
-       chanserv check removed from on_endofnames
-       typo on on_invite - fixed.
-       chanserv/ops removed from ircCheck()
-       joinNextChan removed from ircCheck()
-       added preliminary debian BTS frontend support
-
-2001-04-19 20:11  dms
-
-       * src/Modules/News.pl: news: don't list new items if they don't have Text.
-
-2001-04-18 23:07  dms
-
-       * src/: CommandStubs.pl, IRC/Irc.pl, IRC/IrcHooks.pl,
-       IRC/Schedulers.pl: fixed seen ""
-       added where debugging messages came from (functions)
-       fixed reversed use of % in if statement, stupid me :)
-       changed backup times for files again
-
-2001-04-18 22:51  dms
-
-       * src/IRC/Irc.pl: forgot this one
-
-2001-04-18 22:50  dms
-
-       * src/: UserExtra.pl, core.pl, IRC/Irc.pl, IRC/Schedulers.pl: added flood protection for notice()
-       added connectivity percentage to ircstats.
-       other changes forgotten
-
-2001-04-18 22:41  dms
-
-       * src/IRC/IrcHooks.pl: fixed the following bugs:
-       [57419] on_ttf: X1 Target change too fast. Please wait 50 seconds.
-       [57604] !WARN! IsChanConf: lowercased chan. (Read error to
-               boren-[adsl-63-197-68-132.dsl.snfc21.pacbell.net]: EOF from client)
-
-2001-04-18 22:30  dms
-
-       * src/: core.pl, IRC/IrcHelpers.pl, IRC/Schedulers.pl,
-       Modules/W3Search.pl: fix chanlimitChange time
-       w3search => "blah for blah" fails - fixed.
-
-2001-04-17 23:56  dms
-
-       * src/IRC/IrcHelpers.pl: ok... use "" around hashes that use _ bare.
-
-2001-04-17 23:34  dms
-
-       * src/: core.pl, Modules/News.pl: ...
-
-2001-04-17 22:03  dms
-
-       * src/Modules/News.pl: forgot to use \d+ for read shortcut
-       other changes that the last commit missed or something
-
-2001-04-17 20:35  dms
-
-       * src/core.pl: another round of useless changes
-
-2001-04-16 21:45  dms
-
-       * src/: CommandStubs.pl, DynaConfig.pl, core.pl, IRC/Irc.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl, Modules/News.pl: chanset: fixed the following problem.
-               .chanset #debian +babeflish
-               .chanset #debian -babeflish
-               -chanunset #debian babelflish
-       - yet another minor bug, use !msgType for dcc chat aswell.
-       - selfflood proteciton for /msg
-               - like 4/sec or 1k/sec
-               - msgcount, msgbyte, msgtime
-               - pubcount, pubbyte, pubtime
-       - fixed other bugs.... weeeeeeee....
-
-2001-04-14 22:48  dms
-
-       * src/IRC/: IrcHelpers.pl, Schedulers.pl: prevent erratic (multiple) changes of chan limit in short space of time.
-       this would be a major problem in chanlimitVerify@IrcHelpers.pl since
-       it's called for every join.  Better safe than sorry.
-
-2001-04-14 20:17  dms
-
-       * src/: Process.pl, core.pl, IRC/Irc.pl, IRC/IrcHooks.pl,
-       IRC/Schedulers.pl, Modules/News.pl: IRC/IrcHooks.pl
-               - forgot to reset msgType/who/chan
-                 after hookMsg in on_msg and on_public.
-               - on_join: if bot joins, don't do wingate/bans
-                 and other useless stuff
-               - on_join: set msgType for ICC.
-               - on_part: set msgType/chan/who
-               - on_quit: set msgType/chan/who
-               - on_public: make chan global for ICC
-               => should fix all bugs.
-               => I have no idea how this worked so brokenly.
-       News.pl - more more changes
-
-2001-04-14 00:45  dms
-
-       * src/: core.pl, IRC/IrcHelpers.pl, IRC/IrcHooks.pl,
-       IRC/Schedulers.pl, Modules/News.pl: another round of changes, damn it was hard to figure out why news wasn't
-       appearing properly - I think we still have that problem but it's semi
-       rare.
-       - Also fixed netsplit problems, forgot a next line.
-       - don't run all funky commands in on_join if netsplit is enabled.
-       - other tiny things not worth mentioning.
-
-2001-04-13 23:23  dms
-
-       * src/: IRC/IrcHelpers.pl, IRC/IrcHooks.pl, IRC/Schedulers.pl,
-       Modules/Factoids.pl, Modules/News.pl: news: can make news compulsory (chanset +newsNotifyAll)
-             and opt-out (news unnotify)
-       irchooks: splitted into IrcHelpers.pl so we can reload it on the fly.
-       factoids: added debugging for short factoids that may be botched up
-             references
-
-2001-04-12 21:12  dms
-
-       * src/: UserExtra.pl, db_mysql.pl, IRC/Schedulers.pl,
-       Modules/News.pl, Modules/UserDCC.pl: news: added news->factoid redirection
-       ton load of minor changes or bug fixes that cannot really be summarized
-
-2001-04-11 22:34  dms
-
-       * src/: Process.pl, UserExtra.pl, db_mysql.pl, modules.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl, Modules/Debian.pl,
-       Modules/News.pl: A round of fixes:
-               - added dbReplace but it's broken
-               - debian infopackages shows dist
-               - news user cache now works properly
-               - "+" now works for all commands, not only for factoids
-
-2001-04-07 23:59  dms
-
-       * src/Misc.pl: isStale is basically used by Debian.pl and we were using age in terms of
-       seconds but the actual function was assuming it was in days - fixed.
-
-2001-04-07 20:07  dms
-
-       * src/: modules.pl, IRC/Schedulers.pl: - now backup news file just in case.
-       - Other changes we've not documented or small enough not to mention
-
-2001-04-07 20:07  dms
-
-       * src/Modules/News.pl: - load file if we enabled option on the fly before re-run.
-
-2001-04-07 20:06  dms
-
-       * src/CommandStubs.pl: - we now check if CODEREF exists.
-
-2001-04-07 20:06  dms
-
-       * src/UserExtra.pl: - forgot Module for news.
-
-2001-04-07 20:05  dms
-
-       * src/core.pl: - write opened files on shutdown/hup
-
-2001-04-06 22:05  dms
-
-       * src/Modules/News.pl: When we did a symlink to all the set commands, the string was made
-       static (set to "Text") so it was broken.
-       also added link from Desc to Text
-
-2001-04-06 21:56  dms
-
-       * src/Modules/News.pl: Just some more minor changes, to make some people happy, heh.
-
-2001-04-03 20:06  dms
-
-       * src/: DynaConfig.pl, modules.pl, IRC/IrcHooks.pl,
-       IRC/Schedulers.pl, Modules/News.pl: More clean ups, forgotten what they were, heh.
-
-2001-04-01 23:25  dms
-
-       * src/Modules/News.pl: forgot to add this file, heh.
-
-2001-04-01 23:16  dms
-
-       * src/modules.pl: finally nailed this "random" bug noticed by asuffield.
-
-2001-04-01 23:00  dms
-
-       * files/blootbot.help: added help for news
-
-2001-04-01 23:00  dms
-
-       * src/: Misc.pl, IRC/IrcHooks.pl: Second round of News changes and bug fixes, kudos to greycat
-
-2001-03-31 22:19  dms
-
-       * src/: CommandStubs.pl, DynaConfig.pl, Process.pl, UserExtra.pl,
-       core.pl, modules.pl, Factoids/Statement.pl, Factoids/Update.pl,
-       IRC/Irc.pl, IRC/IrcHooks.pl, IRC/Schedulers.pl, Modules/UserDCC.pl: Many changes, basically added and integrated News, and bug fixes.
-       Some more notes:
-         CommandStubs.pl     - fixed "kernel blah"
-         Modules/UserDCC.pl  - dont print $user when undefined.
-         modules.pl          - added News.pl
-         Modules/News.pl     - new feature.
-         Process.pl          - "blootbot: ok is <reply> :)" -- FIXED.
-
-2001-02-28 20:17  dms
-
-       * src/IRC/Irc.pl: removed msg/say repeating code.
-
-2001-02-28 20:17  dms
-
-       * src/Process.pl: don't backup #DEL# factoids. asuffield.
-
-2001-02-28 20:17  dms
-
-       * src/Factoids/Question.pl: fix for endless loop. asuffield.
-
-2001-02-28 20:12  dms
-
-       * src/IRC/IrcHooks.pl: msgtime updated in on_msg
-
-2001-02-28 20:10  dms
-
-       * src/IRC/Schedulers.pl: make dead-connect detection better.
-
-2001-02-23 20:26  dms
-
-       * src/CommandStubs.pl: strip trailing whitespaces, force use of quotes to enable trailing
-       whitespace. requested by asuffield and \broken?.
-
-2001-02-23 20:25  dms
-
-       * src/Process.pl: now use "or" instead of "and" operator for "rename".
-
-2001-02-23 20:24  dms
-
-       * src/IRC/Irc.pl: closedcc debug
-
-2001-02-23 20:24  dms
-
-       * src/IRC/Schedulers.pl: downlink check update?
-
-2001-02-20 21:01  dms
-
-       * src/Factoids/Question.pl: - recursive factoid linking added.
-
-2001-02-20 21:01  dms
-
-       * src/IRC/IrcHooks.pl: - lobotomy check in hookMsg
-
-2001-02-20 21:00  dms
-
-       * src/Factoids/Update.pl: - reformatted totally
-       - added preliminary append-to-linked-factoid support.
-       - all return calls now return appropriately.
-
-2001-02-20 21:00  dms
-
-       * src/: Misc.pl, UserExtra.pl: - added mkcrypt, fixed up "crypt" cmd.
-
-2001-02-20 20:59  dms
-
-       * src/: CommandStubs.pl, core.pl, modules.pl: minor updates, warn fixes, removed comments
-
-2001-02-20 20:59  dms
-
-       * src/IRC/Schedulers.pl: - lobotomy cache flush.
-       - disable uptime if not loaded.
-       - minor output update.
-
-2001-02-20 20:58  dms
-
-       * src/Process.pl: - lobotomy warning now cached
-       - use &mkcrypt()
-
-2001-02-20 20:58  dms
-
-       * src/DynaConfig.pl: - preliminary check of masks in chan for matches.
-       - ckpasswd, clean up.
-
-2001-02-20 20:58  dms
-
-       * src/Modules/UserDCC.pl: - changed "m" to "n". asu.
-       - flush lobotomy cache on "unlobotomy"
-       - now use &mkcrypt()
-
-2001-02-17 21:42  dms
-
-       * src/IRC/Schedulers.pl: - minor output update.
-
-2001-02-17 21:41  dms
-
-       * src/UserExtra.pl: - removed '' from returns
-       - preliminary stats for on/off-line time
-
-2001-02-17 21:41  dms
-
-       * src/Modules/UserDCC.pl: - ".op" fixed. found by Rev
-       - ".-ban" now removes the ban from the chan.
-
-2001-02-17 21:40  dms
-
-       * src/IRC/Irc.pl: - sub "op" fixed.
-       - added sub "unban"
-
-2001-02-17 21:40  dms
-
-       * src/IRC/IrcHooks.pl: - added first time run checks.
-       - on/off-line time stats
-       - on_join ban now kicks with custom reason.
-
-2001-02-17 21:40  dms
-
-       * src/Factoids/Reply.pl: literal update
-
-2001-02-17 21:39  dms
-
-       * src/Process.pl: - typo in if statement for "forget" when users
-         don't have +r flag. found by Rev
-       - added "pass" cmd.
-       - added "literal" factoid ask.
-
-2001-02-17 21:36  dms
-
-       * src/core.pl: memusage support for open/free/net bsd added. patch from Kuma/Rev
-
-2001-02-13 23:50  dms
-
-       * src/core.pl: update version of bot
-
-2001-02-13 23:47  dms
-
-       * src/IRC/IrcHooks.pl: make nickserv work on more servers. requested by asuffield
-
-2001-02-13 23:35  dms
-
-       * src/IRC/IrcHooks.pl: on-ban reason does not work... added debugging
-
-2001-02-13 23:28  dms
-
-       * files/blootbot.help: updates from asuffield@OPN
-
-2001-02-13 23:18  dms
-
-       * src/Modules/babel.pl: main:: fixes
-
-2001-02-13 23:04  dms
-
-       * src/UserExtra.pl: - 'ascii' updates.
-       - hex now honours "allowConv"
-       - found by asuffield.
-       - redir of a redir fixed.
-
-2001-02-13 22:30  dms
-
-       * src/IRC/IrcHooks.pl: added reason on ban.
-
-2001-02-13 22:18  dms
-
-       * src/Process.pl: safe delete did not run delFactoid, hah! found by asuffield
-
-2001-02-13 22:07  dms
-
-       * src/IRC/Irc.pl: ban fixes.
-
-2001-02-13 22:06  dms
-
-       * src/Modules/UserDCC.pl: - moved read-only stuff from DynaConfig to here.
-       - added newpass
-       - .chpass didn't use arg[0] for user.
-
-2001-02-13 22:03  dms
-
-       * src/DynaConfig.pl: - now prevent ".chanset +blah 10"
-       - recoded it a bit.
-
-2001-02-13 22:02  dms
-
-       * src/IRC/IrcHooks.pl: - use "right way" to get keys from hash by checking if the hash ref
-         even exists... perl automatically "creates" this and causes problems
-         later on. (perldoc -f exists or defined)
-       - anti-repeat should not apply to /msg
-       - option to do kick on repeat... preliminary support.
-       - casing fixes to DCC CHAT. (reported by Revenge@OPN)
-
-2001-02-13 22:01  dms
-
-       * src/IRC/Schedulers.pl: errors from Schedulers (chanlimitcheck) are cached and shown only once.
-
-2001-02-13 22:00  dms
-
-       * src/Modules/Factoids.pl: - added support to factstats (requested,requesters) of "total" value.
-
-2001-02-13 21:59  dms
-
-       * src/Modules/babel.pl: debugging added
-
-2001-02-13 21:58  dms
-
-       * src/Misc.pl: added debian-specific debug to isStale
-
-2001-02-11 22:25  dms
-
-       * src/: CommandStubs.pl, Misc.pl, modules.pl, IRC/Schedulers.pl,
-       Modules/Debian.pl: remaining stuff... should fix factoids problem I hope
-
-2001-02-10 00:47  dms
-
-       * src/Modules/babel.pl: typo
-
-2001-02-10 00:29  dms
-
-       * src/core.pl: slight change to ChanConfList to make schedulers work again
-
-2001-02-09 23:02  dms
-
-       * src/: IRC/IrcHooks.pl, Process.pl: fixed up ignore code. discovered by debian@OPN
-
-2001-02-09 22:51  dms
-
-       * src/IRC/Irc.pl: woops, use while instead of foreach for ircloop
-
-2001-02-09 22:48  dms
-
-       * src/: Files.pl, core.pl: use static value for ircservers file
-
-2001-02-09 22:18  dms
-
-       * src/core.pl: don't write user/chan file on HUP/restart. confirmed by asuffield
-
-2001-02-09 21:44  dms
-
-       * src/Modules/UserDCC.pl: we did a sort() when we should not have for '.sched'
-
-2001-02-09 21:40  dms
-
-       * src/CommandStubs.pl: changed FlatArg to ArrayArgs to make more sense. by default, we use flat-args
-
-2001-02-09 21:37  dms
-
-       * src/IRC/IrcHooks.pl: forgot to set nuh for on_join; fixed up ban check on join.
-
-2001-02-09 21:23  dms
-
-       * src/Process.pl: moved nick lock checking to lock only. detected by irq@OPN
-
-2001-02-09 21:18  dms
-
-       * src/IRC/Irc.pl: added debugging info to ircloop... if irc() does not return ever, we'll have to take another approach to do connect-next-server-if-cant-connect
-
-2001-02-09 21:10  dms
-
-       * src/UserExtra.pl: substitute the right vars in getReply when used in tell. found by asuffield
-
-2001-02-09 00:02  dms
-
-       * src/IRC/IrcHooks.pl: this should fix ignores on global channels. found by 'debian'@OPN
-
-2001-02-08 23:51  dms
-
-       * src/IRC/Schedulers.pl: divide by zero fix. thought I fixed it 2 weeks ago
-
-2001-02-08 23:50  dms
-
-       * src/IRC/IrcHooks.pl: - pointless regex in on_dcc_chat_open that I was going to deal with on
-         failed WHOIS (nuh) lookups... now we just compare against "GETTING-NOW"
-       - on_quit debug info much cleaner now.
-
-2001-02-08 22:09  dms
-
-       * src/CommandStubs.pl: we did not use flat args for forkers. found by asuffield.
-
-2001-02-08 22:00  dms
-
-       * src/CommandStubs.pl: fix delayed task mechanism to verstats... we have to cache chan/nick/msgType.
-
-2001-02-08 21:57  dms
-
-       * src/Shm.pl: possible fix for fork crashing and not detecting a crash from parent. warning included
-
-2001-02-08 21:52  dms
-
-       * src/IRC/: IrcHooks.pl, Schedulers.pl: chan limit check code should now be disabled/re-enabled in relation to netsplits. discovered by asuffield
-
-2001-02-07 22:12  dms
-
-       * src/Modules/UserDCC.pl: - list all schedulers and their respective time-of-next-run
-
-2001-02-07 22:11  dms
-
-       * src/IRC/Schedulers.pl: - use CORE::system
-
-2001-02-07 22:11  dms
-
-       * src/: Modules/Debian.pl, CommandStubs.pl: - finally (about three times) fixed search for "*bin*ssh*" for example,
-         kudos to bod@OPN
-       - also make searchDesc return list of packages and searchDescFE to output it.
-       - use searchDescFE
-
-2001-02-06 21:10  dms
-
-       * src/Modules/Debian.pl: Fixed by swapping dists hash around.
-
-2001-02-06 20:42  dms
-
-       * src/Modules/Debian.pl: debugging added.
-
-2001-02-06 20:42  dms
-
-       * src/Modules/Topic.pl:  ok from "topic -mod" => /msg only!
-
-2001-02-06 20:42  dms
-
-       * src/IRC/Schedulers.pl: - added auto backup of user/chan files
-       - factoidCheck updates.
-       - nick-in-use timer update.
-
-2001-02-06 20:41  dms
-
-       * src/: Process.pl, core.pl: - converted %joinverb to %cache
-
-2001-02-06 20:41  dms
-
-       * src/UserExtra.pl: - added 'unique user count' to chanstats.
-       - wantnick updates
-
-2001-02-06 20:27  dms
-
-       * src/IRC/IrcHooks.pl: - on_chat, forgot to set '$who'
-       - clean up aswell.
-       - converted %jointime to %cache
-       - we check limit on each on_join now.
-
-2001-02-06 20:23  dms
-
-       * src/DynaConfig.pl: split off chanset from UserDCC to here to do multiple chans
-       - look at 1.19->1.20 to see changes
-
-2001-02-06 20:22  dms
-
-       * src/Modules/UserDCC.pl: - Moved most of chanset to DynaConfig
-       - Should be able to do multiple chans now, like ".chanset #chan1 #chan2
-         #chan3 +autojoin"
-       - if _default has option and ".chanunset #blah blah" or ".-chan #blah
-         blah", set vars on all other channels but remove on the channel
-         specific.
-       - if '.-chan blah' is done and does not exist on _default, remove
-         option from all channels.
-       - command to list which chans have option defined/set for.
-       - with respective values.
-       - ".chanset <value>"
-
-2001-02-06 00:09  dms
-
-       * src/Process.pl: final cruft from old static configuration file fixed... found by irq
-
-2001-02-06 00:04  dms
-
-       * src/CommandStubs.pl: ok, that failed. lets now set $chan aswell
-
-2001-02-06 00:00  dms
-
-       * src/CommandStubs.pl: verstats was using dynamic chan var...
-
-2001-02-05 23:45  dms
-
-       * src/IRC/IrcHooks.pl: dont overwrite nuh{} if it already exists.
-
-2001-02-05 23:43  dms
-
-       * src/Factoids/: Norm.pl, Question.pl: - remove front/rear whitespaces
-       - trailing symbols should work now.
-
-2001-02-05 23:30  dms
-
-       * src/IRC/IrcHooks.pl: - endofnames: chanserv ops should work now.
-       - store topic irrevelent of setting.
-       - call ->whois() if nuh is not found.
-
-2001-02-05 23:29  dms
-
-       * src/Modules/UserDCC.pl: - prevent dupe uses of ".+chan"
-       - when adding new chan, set autojoin.
-
-2001-02-05 23:29  dms
-
-       * src/IRC/Schedulers.pl: - ircCheck => 120 interval.
-       - dccStatus now only shows chan info where the dcc chat user is on
-         _only_
-       - added checking of %dcc hash for nuh hash checking.
-
-2001-02-05 22:32  dms
-
-       * src/IRC/Schedulers.pl:  defer leakCheck, increase interval.
-
-2001-02-05 22:31  dms
-
-       * src/core.pl: comment out debugging
-
-2001-02-05 22:31  dms
-
-       * src/IRC/IrcHooks.pl: - fixed when chan (msgType = private) is undefined.
-
-2001-02-04 20:23  dms
-
-       * src/IRC/Irc.pl: reconnect if join fails
-
-2001-02-04 20:17  dms
-
-       * src/IRC/Irc.pl: - output update
-
-2001-02-04 20:16  dms
-
-       * src/IRC/IrcHooks.pl: - if in private, "is addressing" => "is /msg'ing".
-       - dccStatus fix ups.
-       - use ScheduleThis where possible.
-
-2001-02-04 20:14  dms
-
-       * src/IRC/Schedulers.pl: typo for dccStatus fix :)
-
-2001-02-04 20:14  dms
-
-       * src/Shm.pl: delForked: warn if name is source file.
-
-2001-02-04 20:13  dms
-
-       * src/IRC/Schedulers.pl: - output update.
-       - prevent "unknown msg" for shm.
-       - typo for dcc hash. fixed.
-       - forgot about users,chops,bans define in dccStatus. fixed.
-
-2001-02-04 20:13  dms
-
-       * src/CommandStubs.pl: if more than 1/4 users from channel gave version replies, verstats is active.
-
-2001-02-04 20:12  dms
-
-       * src/core.pl: remove mem increase from DCC CHAT - annoying.
-
-2001-02-04 00:01  dms
-
-       * src/: IRC/Schedulers.pl, Modules/Slashdot3.pl: more configuration crud and not-thinking-correctly design errors
-
-2001-02-03 23:51  dms
-
-       * src/UserExtra.pl: added support for old Modules() for telling.
-
-2001-02-03 23:48  dms
-
-       * src/Misc.pl: added IsParam back to hasParam together with isChanConf
-
-2001-02-03 23:33  dms
-
-       * src/Factoids/Statement.pl: minor typo when fixing this before
-
-2001-02-03 23:21  dms
-
-       * src/Modules/Debian.pl: validPackage or indirectly generateIndex should work now for the time being
-
-2001-02-03 23:09  dms
-
-       * src/Modules/Debian.pl: woops forgot a few old config vars; converted to new format
-
-2001-02-03 23:06  dms
-
-       * src/Modules/Debian.pl: converted to new gCCD
-
-2001-02-03 22:46  dms
-
-       * src/Modules/UserDCC.pl: more fixups.
-
-2001-02-03 22:35  dms
-
-       * src/Modules/UserDCC.pl: now use delete in place of undef
-
-2001-02-03 22:23  dms
-
-       * src/IRC/IrcHooks.pl: looks like the final touches to fully exploit dynamic configuration have been made
-
-2001-02-03 22:10  dms
-
-       * src/IRC/IrcHooks.pl: debugging info
-
-2001-02-03 22:06  dms
-
-       * src/Process.pl: move identify code before outsider checking
-
-2001-02-03 22:03  dms
-
-       * src/: IRC/Irc.pl, IRC/IrcHooks.pl, Misc.pl: - $nuh{} fix up.
-       - created on_dcc_open_chat for whois reply to get nuh.
-       - getRandomInt - allow decimal.
-
-2001-02-03 20:52  dms
-
-       * src/: Shm.pl, IRC/Schedulers.pl: - time stamping added.
-       - dead/stale shm removal now works more intelligently.
-         However, older code will attempt to hijack and remove it anyway.
-       - check debian files with gzip -t.
-       - all schedulers should be deferred now.
-
-2001-02-03 20:51  dms
-
-       * src/IRC/IrcHooks.pl: don't allow those without HOSTS in the user file to DCC CHAT.
-
-2001-02-03 20:51  dms
-
-       * src/Modules/UserDCC.pl: fixed '.chanset' code.
-
-2001-02-03 20:50  dms
-
-       * src/IRC/Irc.pl: added _default to chan mask.
-
-2001-02-02 22:03  dms
-
-       * src/IRC/Schedulers.pl: I think this is the set of missed old->dynamic config changes that had to be done
-
-2001-02-02 22:03  dms
-
-       * src/Modules/UserDCC.pl: compress config params as muc has possible per line
-
-2001-02-02 21:42  dms
-
-       * src/core.pl: forgot to initialize counter for Moron
-
-2001-02-02 21:42  dms
-
-       * src/Misc.pl: check if int is defined for fixPlural
-
-2001-02-02 21:38  dms
-
-       * src/: DynaConfig.pl, Misc.pl, core.pl, modules.pl,
-       Factoids/Norm.pl, Factoids/Question.pl, Factoids/Reply.pl,
-       Factoids/Update.pl: tiny changes that I've missed
-
-2001-02-02 21:36  dms
-
-       * src/IRC/: IrcHooks.pl, Schedulers.pl: temporary ignores can be removed automatically once expired
-
-2001-02-02 21:21  dms
-
-       * src/Process.pl: typo for ckpasswd
-
-2001-02-02 21:12  dms
-
-       * src/Shm.pl: - if shmRead fails, try openSHM.
-
-2001-02-02 21:12  dms
-
-       * src/Process.pl: - fixup for question handling.
-
-2001-02-02 21:12  dms
-
-       * src/UserExtra.pl: - tell: command redirection added.
-
-2001-02-02 21:12  dms
-
-       * src/Modules/UserDCC.pl: - fix undefined for '.chanset'
-       - minor output update to '.bans'
-
-2001-02-02 21:11  dms
-
-       * src/DynaConfig.pl: - undefining vars in wrong subs; fixed.
-       - fixes reading user/chan files finally, again.
-
-2001-02-02 21:10  dms
-
-       * src/: CommandStubs.pl, Modules/babel.pl: - fixes for babelfish
-       - typo of IsChanConf for wwwsearch.
-       - parseCmdHooks return vals fixed.
-       - babel.pl: regex fixed -- works!!!
-
-2001-02-02 21:09  dms
-
-       * src/: Modules/RootWarn.pl, Modules/Wingate.pl, IRC/Irc.pl,
-       IRC/IrcHooks.pl, IRC/Schedulers.pl: - more fixes to new-style config, should be 99% of it.
-       - convert IsParam() to IsChanConf()
-       - IRC/IrcHooks.pl: minor output update
-       - IRC/Schedulers.pl:
-               - minor update.
-               - make getChanConfDefault(PARAM,VALUE,CHAN) instead for convenience.
-               - temp ignore removal checking loop fixed.
-
-2001-02-01 22:21  dms
-
-       * src/core.pl: - write user/chan file in 'shutdown'
-
-2001-02-01 22:18  dms
-
-       * src/Modules/UserDCC.pl: - wrong order in .+ignore
-       - ".chanset #chan" fixup.
-
-2001-02-01 22:17  dms
-
-       * src/IRC/Irc.pl: - getJoinChans, don't add _default
-       - joinNextChan() - check nickServ_pass
-
-2001-02-01 22:15  dms
-
-       * src/DynaConfig.pl: - prevent /^[+-]/ options being loaded.
-       - ignore/ban lists now saved properly.
-       - forgot about \+ :-)
-       - verifyUser does caching now!
-
-2001-02-01 22:13  dms
-
-       * src/IRC/Schedulers.pl: - SC for uptimeCycle
-       - renamed *Cycle to *Loop
-
-2001-02-01 22:11  dms
-
-       * src/IRC/IrcHooks.pl: - minor output (debug) removed.
-       - new config conversion for rootWarn
-
-2001-02-01 22:06  dms
-
-       * src/Process.pl: now use pass auth for 'identify'.
-
-2001-02-01 22:05  dms
-
-       * src/Modules/Debian.pl: regex support for 'query' in &searchDesc()
-
-2001-01-31 22:53  dms
-
-       * src/CommandStubs.pl: nickometer: there could be multiple results with the same version
-       percentage - fixed. Also don't merge same percentages together like in
-       other list (formListReply) statements.
-
-2001-01-31 22:31  dms
-
-       * src/CommandStubs.pl: nickometer and verstats: sort descendingly
-       nickometer: fix undefined warning
-
-2001-01-31 21:31  dms
-
-       * src/Modules/Debian.pl: make $refresh global in this file... removed all duplicates of getting
-       debianRefreshInterval config var.
-
-2001-01-31 21:28  dms
-
-       * src/IRC/: Irc.pl, IrcHooks.pl: make $nickserv global and set to zero in Irc.pl
-
-2001-01-31 21:26  dms
-
-       * src/Misc.pl: check if $age is NULL in &isStale()
-
-2001-01-31 21:18  dms
-
-       * src/core.pl: &ChanConfList() typos
-
-2001-01-31 21:18  dms
-
-       * src/Process.pl: added 'identify <PASS> [nick]'
-
-2001-01-31 21:18  dms
-
-       * src/IRC/Irc.pl: added retval to &ban()
-
-2001-01-31 21:17  dms
-
-       * src/Modules/UserDCC.pl: minor fix for ignoreAdd()
-
-2001-01-31 21:17  dms
-
-       * src/DynaConfig.pl: prevent repetion in verifyUser.
-
-2001-01-31 21:17  dms
-
-       * src/Modules/Freshmeat.pl: - now use gCCD
-
-2001-01-31 21:17  dms
-
-       * src/IRC/IrcHooks.pl: - ignore code cleaned up.
-       - ban on join added.
-       - added 'b' to &hookMode()'s stats keeping.
-
-2001-01-31 21:16  dms
-
-       * src/IRC/Schedulers.pl: - forgot about interval for floodCycle.
-       - added nuh{} check to &leakCheck()
-       - added chanserv checking to &ircCheck()
-
-2001-01-30 21:19  dms
-
-       * src/Modules/Debian.pl: support for new dynamic configuration infrastructure
-
-2001-01-30 20:47  dms
-
-       * src/IRC/Schedulers.pl: - typo for already-run check. should work now.
-
-2001-01-30 20:46  dms
-
-       * src/Modules/UserDCC.pl: - added '.sched'
-
-2001-01-30 20:46  dms
-
-       * src/Misc.pl: - pSReply hack for &help().
-
-2001-01-30 20:46  dms
-
-       * src/Process.pl: - typo for return val of &Modules()
-
-2001-01-30 20:46  dms
-
-       * src/DynaConfig.pl: - added removal of possible duplicate configuration entries when bot
-         exits.
-
-2001-01-30 20:45  dms
-
-       * src/: Shm.pl, core.pl, modules.pl, Modules/Uptime.pl: - minor update (output and redundant vars)
-
-2001-01-30 20:44  dms
-
-       * src/IRC/IrcHooks.pl: prevent dupes in verstats collection.
-
-2001-01-30 20:44  dms
-
-       * src/CommandStubs.pl: - added 'unknown/cloaked' stats item to verstats.
-       - nickometer chan code cleanup.
-
-2001-01-29 23:04  dms
-
-       * src/CommandStubs.pl: added 'verstats'
-
-2001-01-29 23:03  dms
-
-       * src/Misc.pl: - strip ^chars update.
-
-2001-01-29 23:03  dms
-
-       * src/IRC/Schedulers.pl: - fixed undefined stuff.
-       - put return's in wrong position; fixed.
-
-2001-01-28 22:34  dms
-
-       * src/core.pl: removed obsoleted old dyn code
-
-2001-01-28 22:03  dms
-
-       * files/sample/sample.config.proposed: - obsoleted... why was it even added in the first place.
-
-2001-01-28 22:02  dms
-
-       * ChangeLog, ChangeLog.old: - finally generated ChangeLog from CVS
-       - moved old changelog to ChangeLog.old
-
-2001-01-28 22:00  dms
-
-       * patches/: Connection.pm, Net::IRC.patch: - removed obsoleted files: it's now done in the bot code.
-
-2001-01-28 21:35  dms
-
-       * files/: infobot.help, infobot.ignore, infobot.lang, infobot.lart,
-       infobot.randtext, infobot.users, sample.config, sample.countdown,
-       sample.insert: - obsoleted files removed
-
-2001-01-28 21:32  dms
-
-       * src/: Misc.pl, Process.pl, Shm.pl, db_mysql.pl,
-       Factoids/Question.pl, Factoids/Reply.pl, Factoids/Statement.pl,
-       Factoids/Update.pl, IRC/Irc.pl, Modules/Debian.pl,
-       Modules/DebianExtra.pl, Modules/Dict.pl, Modules/Factoids.pl,
-       Modules/Freshmeat.pl, Modules/Kernel.pl, Modules/Quote.pl,
-       Modules/Search.pl, Modules/Slashdot3.pl, Modules/Topic.pl,
-       Modules/Units.pl, Modules/Uptime.pl, Modules/W3Search.pl,
-       Modules/Wingate.pl, Modules/babel.pl, Modules/insult.pl,
-       Modules/nickometer.pl: - Remaining files that were changed due to removal of $noreply or
-         indirectly caused by the change over to dynamic configuration
-
-2001-01-28 21:15  dms
-
-       * src/IRC/Schedulers.pl: - added dccStatus
-
-2001-01-28 21:14  dms
-
-       * src/UserExtra.pl: - if - is used before -about, don't tell us about what was told.
-       - ignorelist removed.
-
-2001-01-28 21:14  dms
-
-       * src/modules.pl: - if core moduels fail to load, exit out properly.
-
-2001-01-28 21:14  dms
-
-       * files/blootbot.help: - removed FIXME entries.
-       - added several new entries for UserDCC. still incomplete.
-
-2001-01-28 21:13  dms
-
-       * files/blootbot.ignore: -REMOVED
-
-2001-01-28 21:12  dms
-
-       * src/IRC/IrcHooks.pl: - when someone attempts dcc chat, if verbosity > 1,
-               show all info regarding that person.
-
-2001-01-28 21:12  dms
-
-       * src/logger.pl: pre-config fix.
-
-2001-01-28 21:11  dms
-
-       * src/Modules/UserDCC.pl: - added frontend to dynamic user/chan.
-
-       - remove 99% of $noreply.               WORKS
-       - change 'main::' to '::'               WORKS
-
-       - ".set" and ".unset" obsoleted.        WORKS
-       - ".save"                               WORKS
-       - ".chanset #chan +bool"        WORKS
-       - ".chanset #chan -bool"        WORKS
-       - ".chanset #chan"              WORKS
-       - ".chanunset #chan"            WORKS
-       - ".chanunset #chan WHAT"       WORKS
-       - ".chpass <user> [pass]"       WORKS
-       - ".chattr [user] +flag-flag"   WORKS
-       - ".chnick [user] [new-user]"   WORKS
-       - ".+host [user] [new mask]"    WORKS
-       - ".-host [user] [del mask]"    WORKS
-       - ".+ban [mask] [chan] [time] [reason]" WORKS
-       - ".-ban [mask]"                WORKS
-       - ".whois [user]"               WORKS
-       - ".bans [chan]" (BOT)          WORKS
-       - ".banlist" (CHAN)             DONE,TODO
-       - ".+ignore <mask> [#channel] [time] <comment>" WORKS
-       - ".-ignore <mask>"             WORKS
-       - ".ignore [chan]"              WORKS,
-       - ".adduser <nick>"             DONE,TODO
-       - ".deluser <nick>"             DONE,TODO
-       - ".+user <nick> <hostmask>"    WORKS
-       - ".-user <nick>"               WORKS
-       - ".chatset [channel] <setting>"        DONE
-       - ".+chan <#chan>"                      WORKS
-       - ".-chan <#chan>"                      WORKS
-       - ".chaninfo"                           WORKS
-
-2001-01-28 21:08  dms
-
-       * files/sample/: sample.chan, sample.config, sample.config.example,
-       sample.config.proposed, sample.countdown, sample.insert,
-       sample.users: - new directory for sample configuration
-
-2001-01-28 21:04  dms
-
-       * files/: blootbot.chan, blootbot.users: - NEW style config file.
-
-2001-01-28 21:02  dms
-
-       * src/core.pl: - NEW dynamic user/chan stuff.
-       - prevent doExit running twice.
-       - loadMyModulesNow after chanfile!
-       - added IsChanConf() and getChanConfList
-
-2001-01-28 21:00  dms
-
-       * src/DynaConfig.pl: - NEW dynamic user/chan stuff.
-
-2001-01-28 20:50  dms
-
-       * src/: User.pl, UserFile.pl: - REMOVED FILES.
-
-2001-01-28 20:50  dms
-
-       * src/Files.pl: - removed userfile code.
-       - removed ignore code.
-
-2001-01-28 20:49  dms
-
-       * src/CommandStubs.pl: - aCH: don't remake hook hash.
-       - pCH: warn if multiple matches are found.
-       - added nickometer for channel.
-
-2001-01-18 21:46  dms
-
-       * src/Modules/Debian.pl: ca.d.o does not do non-US any more
-
-2001-01-17 20:22  dms
-
-       * src/Modules/Factoids.pl: used \* instead of / for days, founded by fooz
-
-2001-01-15 21:11  dms
-
-       * src/Factoids/Update.pl: added checking of NULL rhs just in case.
-
-2001-01-15 21:10  dms
-
-       * src/Modules/Factoids.pl: - fix for null factoids in factinfo.
-       - added 'factstats nullfactoids'.
-
-2001-01-14 21:04  dms
-
-       * src/Modules/Topic.pl: topic info now includes length
-
-2001-01-10 22:57  dms
-
-       * src/IRC/Irc.pl: - cosmetic (useless) update.
-
-2001-01-10 22:56  dms
-
-       * src/UserExtra.pl: - update to 'cpustats'.
-
-2001-01-10 22:55  dms
-
-       * src/Misc.pl: - forgot [] around gettimeofday.
-       - select() added before first fork msg.
-
-2001-01-10 22:55  dms
-
-       * src/Shm.pl: - minor mods to addForked wrt time.
-       - proper detection of dead forks.
-
-2001-01-10 22:54  dms
-
-       * src/Modules/Debian.pl: quote typo@18,default==unstable
-
-2001-01-10 22:54  dms
-
-       * src/modules.pl: - AUTOLOAD to ignore __
-       - use eval on 'require'.
-
-2001-01-06 20:55  dms
-
-       * src/Factoids/Reply.pl: - added smart_replace, finally fixed SARs for sure.
-         still need to move numeric range replacement into the loop.
-
-2001-01-06 20:54  dms
-
-       * src/: Net.pl, Modules/Debian.pl, Modules/Factoids.pl,
-       Modules/Freshmeat.pl, Modules/Search.pl: - new time delta function
-       - Debian.pl: \Q\E in validPackage
-
-2001-01-06 20:53  dms
-
-       * src/IRC/Irc.pl:  clearIRCVars update
-
-2001-01-06 20:53  dms
-
-       * src/modules.pl: DNS.pl removed.
-
-2001-01-06 20:52  dms
-
-       * src/Modules/DNS.pl: Removed this file.
-
-2001-01-06 20:52  dms
-
-       * src/: CommandStubs.pl, UserExtra.pl: - more updates.
-       - UserExtra.pl: added cpustats
-       - CommandStubs: added UserFlag support
-
-2001-01-06 20:51  dms
-
-       * src/: Misc.pl, Shm.pl, IRC/IrcHooks.pl: - forker (POSIX::_exit) fixes.
-       - Misc.pl: added timedelta(renamed from gettimeofday),timeget.
-
-2001-01-03 21:44  dms
-
-       * src/Net.pl: - &system typo.
-
-2001-01-03 21:43  dms
-
-       * src/modules.pl: - DESTROY code removed.
-
-2001-01-03 21:42  dms
-
-       * src/Misc.pl: - topic minor fix.
-       - POSIX::_exit(0) added: fixes fork problem.
-
-2001-01-03 21:42  dms
-
-       * src/Factoids/Update.pl: - allow SARing of factoids on _long_ factoids providing the new string
-         is shorter than the subst string.
-
-2001-01-03 21:37  dms
-
-       * files/blootbot.lang: - moron reply added.
-
-2001-01-03 21:37  dms
-
-       * src/Factoids/Reply.pl: - Finally added proper recursive SARs
-
-2001-01-03 21:36  dms
-
-       * src/Modules/Factoids.pl: - add 'days' to created_time output.
-
-2001-01-03 21:35  dms
-
-       * src/Modules/Debian.pl: - "testing" changes (broken)
-       - make search packages case insensitive.
-       - non-US fixed... about time.
-
-2001-01-03 21:34  dms
-
-       * src/Process.pl: - unified hook changes.
-       - ignore >64 questions.
-       - support moron language.
-
-2001-01-03 21:33  dms
-
-       * src/UserExtra.pl: - start using hooks.
-       - added moron counter to 'status'.
-
-2001-01-03 21:32  dms
-
-       * src/CommandStubs.pl: - unified for global command hooks
-
-2001-01-03 21:31  dms
-
-       * src/IRC/: Irc.pl, IrcHooks.pl: - floodjoinCheck.
-       - note on endofmotd.
-       - Moved ircstats from Irc.pl to on_endofmotd#IrcHooks.pl
-
-2000-12-29 22:46  dms
-
-       * src/Process.pl: for join, ignore whether on a channel if we have power
-
-2000-12-29 22:05  dms
-
-       * src/IRC/IrcHooks.pl: lowercase chan in on_kick, found by xsdg!
-
-2000-12-19 21:06  dms
-
-       * src/Factoids/Reply.pl: forgot about int() in randnick - found by lunartear
-
-2000-12-18 21:40  dms
-
-       * src/core.pl: debug to restart
-
-2000-12-18 21:38  dms
-
-       * src/Net.pl: Remove &ERROR() since it's done by WARN.
-
-2000-12-18 21:35  dms
-
-       * src/Modules/Debian.pl: stop searching if found>100
-
-2000-12-18 21:33  dms
-
-       * src/Process.pl: ignore long unparseable messages.
-
-2000-12-16 20:32  dms
-
-       * src/core.pl: hrm
-
-2000-12-16 20:31  dms
-
-       * src/modules.pl: minor fix to loadmymodules
-
-2000-12-16 20:31  dms
-
-       * LICENSE: - new file for license.
-
-2000-12-16 20:30  dms
-
-       * src/Files.pl: userlist display now verbosity>1
-
-2000-12-16 20:30  dms
-
-       * src/IRC/IrcHooks.pl: - use dccsay
-       - show flags on dcc chat connection.
-       - set type on on_dcc*
-
-2000-12-16 20:29  dms
-
-       * src/IRC/Irc.pl: - &dccsay() added.
-       - &dcc_close() added.
-       - use dccsay in performStrictReply()
-
-2000-12-15 23:36  dms
-
-       * src/Misc.pl: very nice typo for regex, Angel indirectly found this :)
-
-2000-12-15 22:39  dms
-
-       * src/User.pl: forgot to reset userHandle
-
-2000-12-15 22:28  dms
-
-       * src/core.pl: forgot about / in tempDir
-
-2000-12-15 22:25  dms
-
-       * src/Modules/UserDCC.pl: added '.mode' for Netsnipe
-
-2000-12-12 23:12  dms
-
-       * src/core.pl: change ~ to ENV{HOME}
-
-2000-12-11 20:26  dms
-
-       * src/IRC/Schedulers.pl: chanlimitcheck: removed netsplit check
-
-2000-12-11 20:24  dms
-
-       * src/IRC/IrcHooks.pl: netsplit timer added
-
-2000-12-10 20:55  dms
-
-       * src/Shm.pl: &showProc in delForked()
-
-2000-12-10 20:54  dms
-
-       * src/IRC/IrcHooks.pl: userHandle now global var
-
-2000-12-10 20:53  dms
-
-       * src/User.pl: verifyUser finally fixed
-
-2000-12-10 20:52  dms
-
-       * src/core.pl: tempdir fix
-
-2000-12-10 20:51  dms
-
-       * src/Modules/: Freshmeat.pl, Kernel.pl, Slashdot3.pl: temp dir unified
-
-2000-12-10 20:49  dms
-
-       * src/Modules/Debian.pl: - 'find *bin*ssh*' should work.
-       - temp dir unified.
-
-2000-12-10 20:48  dms
-
-       * src/Modules/Factoids.pl: - 'seefix' checks for self-redirects and removes if successful.
-       - 'deadredir' reject long vals.
-       - 'listfix' added.
-
-2000-12-09 21:26  dms
-
-       * src/Modules/Topic.pl: removed/convert debug messages
-
-2000-12-09 21:04  dms
-
-       * src/IRC/IrcHooks.pl: changed debug to status line
-
-2000-12-09 21:01  dms
-
-       * src/IRC/Schedulers.pl: forgot to return for limitcheck + netsplit
-
-2000-12-08 21:09  dms
-
-       * src/IRC/Schedulers.pl: renamed limitCheck to chanlimitCheck
-
-2000-12-04 21:31  dms
-
-       * src/IRC/Schedulers.pl: Typos galore for logCycle, should be fixed
-
-2000-12-03 21:52  dms
-
-       * src/IRC/Schedulers.pl: output cleanup
-
-2000-12-03 21:51  dms
-
-       * src/Modules/Debian.pl: fallback on * properly
-
-2000-12-03 21:50  dms
-
-       * src/Modules/W3Search.pl: Moved w3 regex here
-
-2000-12-03 21:48  dms
-
-       * src/CommandStubs.pl: typo fixed
-
-2000-12-03 21:47  dms
-
-       * src/CommandStubs.pl: Removed W3 regex
-
-2000-12-03 21:46  dms
-
-       * src/Modules/Factoids.pl: Added 'factstats seefix'
-
-2000-12-03 21:46  dms
-
-       * src/Misc.pl: validFactoid.
-
-2000-11-24 22:26  dms
-
-       * src/Modules/Debian.pl: Contents for non-US is broken!
-
-2000-11-24 22:02  dms
-
-       * src/Modules/Debian.pl: typo
-
-2000-11-24 20:23  dms
-
-       * src/Misc.pl: - validFactoid.
-       - fixString
-
-2000-11-24 20:17  dms
-
-       * src/Modules/Freshmeat.pl: - prevent dupe errors.
-       - support bz2/gz for appindex.
-
-2000-11-24 20:10  dms
-
-       * src/Shm.pl: if name undefined, bail out
-
-2000-11-24 20:07  dms
-
-       * src/modules.pl: use modulebase instead of modulefile for delForked()
-
-2000-11-23 23:10  dms
-
-       * src/CommandStubs.pl: made freshmeat fork always
-
-2000-11-23 22:53  dms
-
-       * src/Modules/Freshmeat.pl: changed core to www
-
-2000-11-23 22:22  dms
-
-       * src/CommandStubs.pl: @args changed to flat
-
-2000-11-23 22:21  dms
-
-       * src/: Misc.pl, Net.pl: debug messages removed
-
-2000-11-23 22:21  dms
-
-       * src/Modules/Debian.pl: more cleanups. ^blah and blah$ workspico Debian.pl!
-
-2000-11-19 22:56  dms
-
-       * src/Modules/Debian.pl: debug
-
-2000-11-19 22:56  dms
-
-       * src/modules.pl: use AUTOLOAD to prevent crashes
-
-2000-11-19 22:55  dms
-
-       * src/Net.pl: Reduced timeout by 10x
-
-2000-11-19 22:54  dms
-
-       * src/UserExtra.pl: Fixed up tell to allow target == 'us'.
-
-2000-11-19 22:49  dms
-
-       * src/IRC/IrcHooks.pl: Exit process if on_public hook is activated under fork
-
-2000-11-01 21:59  dms
-
-       * src/UserExtra.pl: - fixed up tell.
-       - 'cycle' changed a bit.
-
-2000-11-01 21:55  dms
-
-       * src/IRC/Irc.pl: debug msg for mixed-case chan
-
-2000-11-01 21:54  dms
-
-       * src/IRC/Schedulers.pl: - make sure we reschedule everything unless it's a non-recoverable error.
-       - disable limit if split active in limitcheck.
-       - enabled 'unlink' in logcycle.
-
-2000-10-04 00:08  dms
-
-       * src/CommandStubs.pl: - we shifted args before using args[0]. fixed.
-       - fixed broken 'convert' cmd.
-
-2000-10-03 01:33  dms
-
-       * src/core.pl: version update
-
-2000-10-03 01:29  dms
-
-       * src/modules.pl: minor change to reloadModule
-
-2000-10-03 01:26  dms
-
-       * src/db_mysql.pl: added sth->finish in an attempt to prevent leaks
-
-2000-10-03 01:26  dms
-
-       * src/CommandStubs.pl: alias to fm for freshmeat forgotten
-
-2000-10-03 01:23  dms
-
-       * src/db_dbm.pl: minor update
-
-2000-10-03 01:20  dms
-
-       * src/Modules/Freshmeat.pl: cleanup of comments
-
-2000-10-03 01:19  dms
-
-       * src/IRC/Irc.pl: change timeout value for scheduler interval
-
-2000-10-03 01:12  dms
-
-       * src/IRC/IrcHooks.pl: fixed - typo for join()
-
-2000-09-29 23:39  dms
-
-       * src/CommandStubs.pl: tiny cleanup
-
-2000-09-29 23:10  dms
-
-       * src/Modules/UserDCC.pl: Minor cleanup
-
-2000-09-29 23:03  dms
-
-       * src/IRC/IrcHooks.pl: DCC fixed
-
-2000-09-25 20:08  dms
-
-       * src/IRC/Irc.pl: fixed up performReply to be more intelligent
-       when doing random stuff.
-
-2000-09-25 20:07  dms
-
-       * src/Factoids/Question.pl: notfound uses @query now; removed origQuery
-
-2000-09-25 00:20  dms
-
-       * src/logger.pl: close log then statuspico logger.pl!
-
-2000-09-24 19:53  dms
-
-       * src/CommandStubs.pl: more changes
-
-2000-09-24 19:51  dms
-
-       * src/Modules/Dict.pl: moved a few lines from CommandStubs.pl here
-
-2000-09-24 19:50  dms
-
-       * src/Factoids/Question.pl: added 'debianForFactoid'.
-       fixed question 'you suck'. found by cerb.
-
-2000-09-24 19:49  dms
-
-       * src/core.pl: forgot 'next' in dir check
-
-2000-09-23 22:18  dms
-
-       * scripts/setup_sql.pl: closed 114944 -- karma can't be a negative int
-
-2000-09-23 22:15  dms
-
-       * src/core.pl: added check for dirs on startup
-
-2000-09-23 22:12  dms
-
-       * src/Modules/Slashdot3.pl: moved temp dir check to core.pl
-
-2000-09-23 20:46  dms
-
-       * src/Modules/Freshmeat.pl: removed some debug lines
-
-2000-09-23 20:45  dms
-
-       * src/modules.pl: fixed up return vals for loadMyModule()
-
-2000-09-23 20:45  dms
-
-       * src/Modules/RootWarn.pl: non-mysql stub
-
-2000-09-23 20:44  dms
-
-       * src/CommandStubs.pl: more conversion to new code
-
-2000-09-23 20:43  dms
-
-       * src/IRC/Schedulers.pl: one too many parens for seen stats; cleanup.
-
-2000-09-23 20:30  dms
-
-       * src/logger.pl: repeat throttling added
-
-2000-09-22 19:56  dms
-
-       * src/Modules/Debian.pl: minor update
-
-2000-09-22 19:56  dms
-
-       * src/CommandStubs.pl: moved more functions to new hook scheme
-
-2000-09-22 19:55  dms
-
-       * src/Shm.pl: forgot shmFlush() in closeSHM()
-
-2000-09-22 18:51  dms
-
-       * files/sample.config: 'undelete' option
-
-2000-09-22 18:50  dms
-
-       * src/IRC/Schedulers.pl: periodically check to delete deleted factoids
-
-2000-09-22 18:49  dms
-
-       * src/Process.pl: added undelete command
-
-2000-09-22 18:49  dms
-
-       * src/Files.pl: removed some verbosity.
-
-2000-09-22 18:48  dms
-
-       * src/modules.pl: verbose on reload (time ago, delta time)
-
-2000-09-18 21:37  dms
-
-       * src/IRC/Irc.pl: op (mode) does not work?
-
-2000-09-18 20:01  dms
-
-       * src/Modules/Debian.pl: typo for searchDesc list element
-
-2000-09-18 19:47  dms
-
-       * src/Misc.pl: minor text cleanup.
-       removed checkPing.
-
-2000-09-18 19:47  dms
-
-       * src/CommandStubs.pl: minor cleanup.
-       Preliminary command hooks (event handlers) working!
-
-2000-09-18 19:46  dms
-
-       * src/IRC/Schedulers.pl: Chanserv 2nd stage fail protection
-       Added seen stats.
-
-2000-09-18 19:45  dms
-
-       * src/Modules/Debian.pl: Added NULL check for &search*();
-       Added stubs for archived revisions.
-
-2000-09-18 19:44  dms
-
-       * src/Factoids/Question.pl: Trailing symbols (.!) ignored on question
-       Founded by Flugh
-
-2000-09-18 19:43  dms
-
-       * src/db_mysql.pl: sqldebug clean up; forgot a return line for GetCol
-
-2000-09-18 19:37  dms
-
-       * src/IRC/Irc.pl: chanserv update to &joinNextChan()
-
-2000-09-18 19:36  dms
-
-       * src/IRC/IrcHooks.pl: minor update
-
-2000-09-18 19:34  dms
-
-       * src/User.pl: removed repetitive debug line
-
-2000-09-18 19:30  dms
-
-       * src/Process.pl: removed feedback addressing. Issue raised by Flugh
-
-2000-09-16 22:12  dms
-
-       * src/CommandStubs.pl: added ddesc for desc search
-
-2000-09-16 22:11  dms
-
-       * src/Modules/Debian.pl: added &searchDesc() if &searchContents() fails
-
-2000-09-16 22:10  dms
-
-       * src/IRC/Schedulers.pl: added NULL irc channel check
-
-2000-09-16 22:09  dms
-
-       * src/core.pl: removed loggingstatus
-
-2000-09-16 21:57  dms
-
-       * src/logger.pl: &status() changes. removed loggingstatus in favour of fileno().
-
-2000-09-16 21:23  dms
-
-       * scripts/setup_sql.pl: another attempt for a fix
-
-2000-09-14 21:29  dms
-
-       * scripts/: setup_sql.pl, setup_tables.pl, setup_users.pl: script merge, doc update
-
-2000-09-14 20:13  dms
-
-       * src/: Files.pl, UserFile.pl, Modules/UserDCC.pl: status() -> &status()
-
-2000-09-14 20:12  dms
-
-       * src/IRC/IrcHooks.pl: minor text fixup for umode
-
-2000-09-14 20:11  dms
-
-       * src/IRC/Schedulers.pl: Added miscCheck(), now does reloadAllModules()
-
-2000-09-14 20:07  dms
-
-       * src/modules.pl: ability to reload extra modules automatically
-
-2000-09-14 00:39  dms
-
-       * src/Modules/Debian.pl: another installed-size prob fix
-
-2000-09-13 22:18  dms
-
-       * src/Factoids/Reply.pl: Removed FIXME
-
-2000-09-13 22:07  dms
-
-       * src/Misc.pl: stat used wrong time, [8] instead of [9]
-
-2000-09-13 22:03  dms
-
-       * src/Misc.pl: changed some text, more debugging
-
-2000-09-13 22:02  dms
-
-       * src/Modules/Debian.pl: hopefully last time it will be fixed
-
-2000-09-13 21:39  dms
-
-       * src/Modules/Freshmeat.pl: forgot about blootbot_pid
-
-2000-09-13 21:38  dms
-
-       * src/Modules/Debian.pl: non-us fixed!
-
-2000-09-13 21:36  dms
-
-       * src/modules.pl: removed two debugging lines or so
-
-2000-09-13 21:19  dms
-
-       * src/Modules/Debian.pl: Removed fixNonUS; added a hack for no contents file for woody non-US i386 at least.
-
-2000-09-13 21:03  dms
-
-       * src/core.pl: bot: spit out memory change messages in DCC CHAT. TODO: DCCBroadcast should allow userflag arg.
-
-2000-09-12 23:33  dms
-
-       * src/Modules/Topic.pl: Another regex topic fix
-
-2000-09-12 23:12  dms
-
-       * src/db_mysql.pl: Fixed up stub dbGetRowInfo
-
-2000-09-10 22:40  dms
-
-       * src/logger.pl: was opening sql debug file for read, not write. typo
-
-2000-09-10 01:09  dms
-
-       * src/IRC/Schedulers.pl: changed verb level from 2 to 1 for seenFlush
-
-2000-09-10 00:36  dms
-
-       * src/IRC/Schedulers.pl: debug for seenflush
-
-2000-09-10 00:30  dms
-
-       * files/sample.config: SQLDebug line
-
-2000-09-10 00:28  dms
-
-       * src/modules.pl: forgot to set module age if successfully loaded. split reloadModules into reloadAllModules and reloadModule. &reloadModule() now called by loadMyModule()
-
-2000-09-10 00:24  dms
-
-       * src/logger.pl: supressed subroutine redefined warning. Added sql debug support (open/close)
-
-2000-09-10 00:19  dms
-
-       * src/db_mysql.pl: Added sql debug support (print)
-
-2000-09-10 00:16  dms
-
-       * src/Modules/UserDCC.pl: fixed/added global factoid SAR
-
-2000-09-09 22:41  dms
-
-       * src/Modules/Topic.pl: fixed regex line, founded by Flugh
-
-2000-09-06 23:00  dms
-
-       * src/Factoids/Update.pl: minor change
-
-2000-09-06 22:59  dms
-
-       * src/logger.pl: 'use strict' issue
-
-2000-09-06 22:57  dms
-
-       * src/Modules/UserDCC.pl: global SAR. only avail to +n and DCC.
-
-2000-09-06 22:56  dms
-
-       * src/core.pl: fixed due to changes. (re: Flugh)
-
-2000-09-05 23:47  dms
-
-       * scripts/: dbm2mysql.pl, mysql2txt.pl, setup_tables.pl,
-       setup_users.pl, txt2mysql.pl: forgot to update these files in the root dir overhaul
-
-2000-09-05 01:55  dms
-
-       * scripts/setup_users.pl: fixed up a bit
-
-2000-09-05 01:28  dms
-
-       * src/logger.pl: stupid typo (carelessness) on my behalf
-
-2000-09-01 22:21  dms
-
-       * src/UserExtra.pl: debug info for ircstats hash list
-
-2000-09-01 22:19  dms
-
-       * src/IRC/IrcHooks.pl: added disconnect and connect stats, just debug info for now
-
-2000-09-01 21:18  dms
-
-       * src/Modules/Topic.pl: prevent dupes to be added; added debugging info if bot is not permitted to add topics (+t/-o).
-
-2000-09-01 20:58  dms
-
-       * src/IRC/Schedulers.pl: ircCheck now checks @joinchan for chans left to join, but should never happen.
-
-2000-09-01 20:56  dms
-
-       * src/Modules/Debian.pl: debian: fixed broken files for woody's non-US
-
-2000-08-31 22:45  dms
-
-       * src/CommandStubs.pl: lame warning fix for babel
-
-2000-08-31 22:41  dms
-
-       * src/logger.pl: forgot a )
-
-2000-08-30 21:33  dms
-
-       * src/Modules/Uptime.pl: Added catch just in case if forked
-
-2000-08-30 21:14  dms
-
-       * src/Shm.pl: changes due to Debian.pl
-
-2000-08-30 21:12  dms
-
-       * src/Modules/Debian.pl: minor changes, removed 'slink', changed 'stable' for 'potato'
-
-2000-08-30 21:09  dms
-
-       * src/Factoids/Update.pl: added debugging info for '.,' and '.,' problems
-
-2000-08-30 20:42  dms
-
-       * src/logger.pl: added $forkedtime, for debugging
-
-2000-08-30 20:19  dms
-
-       * src/CommandStubs.pl: preliminary command hook support added
-
-2000-08-20 22:17  dms
-
-       * src/Modules/UserDCC.pl: closed 17554 -- re-add part/leave to DCC CHAT only
-
-2000-08-20 21:58  dms
-
-       * src/Modules/Debian.pl: we don't stop if debianDownload fails unless none of the files exist locally
-
-2000-08-20 21:46  dms
-
-       * src/Modules/Debian.pl: shouldn't recursively call sP
-
-2000-08-20 21:33  dms
-
-       * src/Misc.pl: double fork -> VERB(2), minor cosmetics
-
-2000-08-20 21:28  dms
-
-       * src/IRC/IrcHooks.pl: if statement of seen swapped.   DCC CHAT close ignored if forked.
-
-2000-08-20 21:25  dms
-
-       * src/Factoids/Reply.pl: added randnick
-
-2000-08-20 21:24  dms
-
-       * src/Modules/Debian.pl: check for stality in sP()
-
-2000-08-19 20:10  dms
-
-       * files/sample.config: closed 17225 -- result of fixed bug
-
-2000-08-19 19:24  dms
-
-       * src/: User.pl, IRC/IrcHooks.pl: closed 17225 -- seen only stores addressed messages. Also moved seen code from User.pl to IrcHooks.pl
-
-2000-08-19 18:44  dms
-
-       * src/Modules/Topic.pl: closed 17447 -- 'topic info' should give more info
-
-2000-08-15 19:27  dms
-
-       * src/Misc.pl: warning (typo) fixed
-
-2000-08-15 19:26  dms
-
-       * files/sample.config: deprecated weather option/feature removed
-
-2000-08-15 19:24  dms
-
-       * src/IRC/Schedulers.pl: ircCheck(): added full path for ipcs,ipcrm
-
-2000-08-15 19:21  dms
-
-       * src/IRC/IrcHooks.pl: on_disconnect schedules ircCheck*( for 1800s
-
-2000-08-12 20:45  dms
-
-       * src/UserExtra.pl: don't prevent wantnick from working in any case
-
-2000-08-12 20:43  dms
-
-       * src/IRC/Schedulers.pl: Added getNickInUse()
-
-2000-08-12 20:42  dms
-
-       * src/IRC/IrcHooks.pl: on_nick_taken calls getNickInUse() now
-
-2000-08-12 20:41  dms
-
-       * src/logger.pl: use getPath() for create logdir for openLog()
-
-2000-08-12 20:38  dms
-
-       * src/Misc.pl: typo for file in loadHelp() ... added getPath() for openLog()
-
-2000-08-11 21:28  dms
-
-       * src/Factoids/Update.pl: closed 17031 -- Fix up appending to factoids
-
-2000-08-11 21:21  dms
-
-       * src/Factoids/: Reply.pl, Update.pl: closed 17187 -- <factoid> are also <info>' doesn't work...   also removed mailto:
-
-2000-08-11 21:10  dms
-
-       * src/Modules/Math.pl: closed 17344 -- Maths.pl is borked in a way
-
-2000-08-11 20:53  dms
-
-       * src/IRC/IrcHooks.pl: close 17091 completely... fix up on_nick IRC hook
-
-2000-08-11 20:48  dms
-
-       * src/IRC/Schedulers.pl: closed 17091 -- chaninfo stats inconsistent after time
-
-2000-08-11 20:11  dms
-
-       * src/modules.pl: Fixed problem with loadMyModules() caused by delForked()
-
-2000-08-11 20:10  dms
-
-       * src/Modules/W3Search.pl: closed 17379 -- W3Search.pl gives duplicate output
-
-2000-08-04 23:19  dms
-
-       * src/Factoids/Statement.pl: at -> mailto remnants from stock infobot removed
-
-2000-08-03 22:19  dms
-
-       * src/logger.pl: status did not print output if config file was not loaded. Fixed by initializing VERBOSITY to 1
-
-2000-08-03 22:11  gmlb
-
-       * INSTALL.patches: Readme update.
-
-2000-08-03 21:53  dms
-
-       * src/Modules/Kernel.pl: forgot about blootbot -> bot
-
-2000-08-03 01:04  gmlb
-
-       * INSTALL.mysql, INSTALL: Fixed some documentation typOs. (in the install docs)
-
-2000-08-01 21:41  dms
-
-       * src/CommandStubs.pl: userinfo had wrong argument # set
-
-2000-07-31 22:57  gmlb
-
-       * infobot:
-       Removed old infobot. We are now using blootbot as the main script
-
-2000-07-31 22:37  dms
-
-       * src/: IRC/Irc.pl, IRC/IrcHooks.pl, IRC/Schedulers.pl,
-       Modules/Countdown.pl, Modules/Factoids.pl, Modules/Freshmeat.pl,
-       Modules/Kernel.pl, Modules/Units.pl, Modules/Uptime.pl,
-       Modules/Wingate.pl, Modules/babel.pl: cvs commit borked, continuing
-
-2000-07-31 22:31  dms
-
-       * AUTHORS, INSTALL, README, blootbot, doc/old/TODO,
-       files/blootbot.help, files/blootbot.ignore, files/blootbot.lang,
-       files/blootbot.lart, files/blootbot.randtext, files/blootbot.users,
-       files/ircII.servers, files/sample.config, scripts/botchk.sh,
-       scripts/dbm2mysql.pl, scripts/insertDB.pl, scripts/mysql2txt.pl,
-       scripts/setup_tables.pl, scripts/setup_users.pl,
-       scripts/txt2mysql.pl, src/Misc.pl, src/Process.pl, src/core.pl,
-       src/modules.pl, src/Factoids/Question.pl, src/Factoids/Reply.pl,
-       src/Factoids/Statement.pl, src/Factoids/Update.pl: Changed $infobot_ to $bot_
-       Changed infobot to blootbot where needed
-       Renamed *infobot* to *blootbot*
-
-2000-07-31 20:47  dms
-
-       * src/logger.pl: Added functionality to cycle all logs if exceeds specified size
-
-2000-07-31 20:33  dms
-
-       * src/: CommandStubs.pl, UserExtra.pl, Modules/Topic.pl: changed NOREPLY to dollar noreply
-
-2000-07-31 20:10  dms
-
-       * src/Modules/UserDCC.pl: send DCC message when using 'op'
-
-2000-07-30 08:33  gmlb
-
-       * doc/README_TODO: Added README_TODO. It contains important info on the TODO list. READ!
-
-2000-07-30 08:01  gmlb
-
-       * doc/: BUGS, Connection.pm, EXAMPLES, FAQ, Google.pm, TODO, USAGE,
-       mysql.txt, notes.txt, pgsql.txt: Removing old doucments in /doc. They are archived in /doc/old. The newest documents will be on the website. See /doc/README_NOW for more information.
-
-2000-07-30 07:56  gmlb
-
-       * doc/old/: BUGS, Connection.pm, EXAMPLES, FAQ, Google.pm, TODO,
-       USAGE, mysql.txt, notes.txt, pgsql.txt: Moving documentation to /doc/old
-
-2000-07-30 07:51  gmlb
-
-       * doc/README_NOW: Adding README_NOW. Please read it, as it contains very important DOC information
-
-2000-07-30 07:02  blootbot
-
-       * AUTHORS: Updated personal info in AUTHORS file. Must talk to XK about title :)
-
-2000-07-30 00:11  dms
-
-       * AUTHORS, patches/Connection.pm, patches/Google.pm: new/moved files
-
-2000-07-30 00:09  dms
-
-       * INSTALL.patches, README, doc/USAGE, doc/modules.txt,
-       files/sample.config, scripts/backup_table-slave.pl, src/Files.pl,
-       src/Misc.pl, src/Net.pl, src/Shm.pl, src/UserExtra.pl, src/core.pl,
-       src/db_dbm.pl, src/db_mysql.pl, src/db_pgsql.pl, src/logger.pl,
-       src/modules.pl, src/Factoids/DBCommon.pl, src/Factoids/Update.pl,
-       src/IRC/Irc.pl, src/IRC/IrcHooks.pl, src/IRC/Schedulers.pl,
-       src/Modules/Countdown.pl, src/Modules/Debian.pl,
-       src/Modules/DebianExtra.pl, src/Modules/Dict.pl,
-       src/Modules/DumpVars.pl, src/Modules/Factoids.pl,
-       src/Modules/Freshmeat.pl, src/Modules/Kernel.pl,
-       src/Modules/RootWarn.pl, src/Modules/Slashdot3.pl,
-       src/Modules/Topic.pl, src/Modules/Uptime.pl,
-       src/Modules/UserDCC.pl, src/Modules/UserInfo.pl,
-       src/Modules/Wingate.pl: changed email address
-
-2000-07-28 23:26  dms
-
-       * files/infobot.config, files/sample.config, src/core.pl: loadConfig to spurt out correct message when infobot.config does not exist on fresh install
-
-2000-07-28 23:11  dms
-
-       * MrInfo.uptime: delete stale files not needed for fresh installation
-
-2000-07-28 00:59  blootbot
-
-       * ChangeLog: Added a line to ChangeLog. I hope to keep this more uptodate and start documentatio. -GmLB
-
-2000-07-28 00:10  blootbot
-
-       * INSTALL, INSTALL.dbm, INSTALL.mysql, INSTALL.patches,
-       INSTALL.pgsql, README, infobot, ChangeLog, MrInfo.uptime, doc/BUGS,
-       doc/Connection.pm, doc/EXAMPLES, doc/FAQ, doc/Google.pm, doc/TODO,
-       doc/USAGE, doc/modules.txt, doc/mysql.txt, doc/notes.txt,
-       doc/pgsql.txt, files/infobot.config, files/infobot.help,
-       files/infobot.ignore, files/infobot.lart, files/infobot.users,
-       files/ircII.servers, files/sample.countdown,
-       patches/Net::IRC.patch, patches/WWW::Search.patch,
-       scripts/backup_table-master.sh, scripts/backup_table-slave.pl,
-       scripts/botchk.sh, scripts/dbm2mysql.pl, scripts/dbm2txt.pl,
-       scripts/fixbadchars.pl, scripts/insertDB.pl, scripts/makepasswd,
-       scripts/mysql2txt.pl, scripts/oreilly_dumpvar.pl,
-       scripts/oreilly_prettyp.pl, scripts/parse_warn.pl,
-       scripts/setup_tables.pl, scripts/setup_users.pl,
-       scripts/showvars.pl, scripts/txt2mysql.pl, scripts/vartree.pl,
-       scripts/webbackup.pl, files/infobot.randtext, files/infobot.lang,
-       files/sample.config, files/sample.insert, files/unittab,
-       src/CommandStubs.pl, src/Files.pl, src/Misc.pl, src/Net.pl,
-       src/Process.pl, src/Shm.pl, src/User.pl, src/UserExtra.pl,
-       src/core.pl, src/db_dbm.pl, src/db_mysql.pl, src/db_pgsql.pl,
-       src/interface.pl, src/logger.pl, src/modules.pl, src/IRC/Irc.pl,
-       src/IRC/IrcHooks.pl, src/IRC/Schedulers.pl,
-       src/Modules/Countdown.pl, src/Modules/DNS.pl,
-       src/Modules/Debian.pl, src/Modules/Dict.pl,
-       src/Modules/Freshmeat.pl, src/Modules/Kernel.pl,
-       src/Modules/Quote.pl, src/Modules/RootWarn.pl,
-       src/Modules/Search.pl, src/Modules/Slashdot3.pl,
-       src/Modules/Topic.pl, src/Modules/Units.pl, src/Modules/Uptime.pl,
-       src/Modules/UserInfo.pl, src/Modules/W3Search.pl,
-       src/Factoids/DBCommon.pl, src/Factoids/Norm.pl,
-       src/Factoids/Question.pl, src/Factoids/Reply.pl,
-       src/Factoids/Statement.pl, src/Factoids/Update.pl,
-       src/Modules/DebianExtra.pl, src/Modules/DumpVars.pl,
-       src/Modules/Factoids.pl, src/Modules/Math.pl,
-       src/Modules/UserDCC.pl, src/Modules/Wingate.pl,
-       src/Modules/babel.pl, src/Modules/insult.pl,
-       src/Modules/nickometer.pl:
-       Trying to add 1.0.0. I hope it works. --GmLB
-
-2000-07-28 00:10  blootbot
-
-       * INSTALL, INSTALL.dbm, INSTALL.mysql, INSTALL.patches,
-       INSTALL.pgsql, README, infobot, ChangeLog, MrInfo.uptime, doc/BUGS,
-       doc/Connection.pm, doc/EXAMPLES, doc/FAQ, doc/Google.pm, doc/TODO,
-       doc/USAGE, doc/modules.txt, doc/mysql.txt, doc/notes.txt,
-       doc/pgsql.txt, files/infobot.config, files/infobot.help,
-       files/infobot.ignore, files/infobot.lart, files/infobot.users,
-       files/ircII.servers, files/sample.countdown,
-       patches/Net::IRC.patch, patches/WWW::Search.patch,
-       scripts/backup_table-master.sh, scripts/backup_table-slave.pl,
-       scripts/botchk.sh, scripts/dbm2mysql.pl, scripts/dbm2txt.pl,
-       scripts/fixbadchars.pl, scripts/insertDB.pl, scripts/makepasswd,
-       scripts/mysql2txt.pl, scripts/oreilly_dumpvar.pl,
-       scripts/oreilly_prettyp.pl, scripts/parse_warn.pl,
-       scripts/setup_tables.pl, scripts/setup_users.pl,
-       scripts/showvars.pl, scripts/txt2mysql.pl, scripts/vartree.pl,
-       scripts/webbackup.pl, files/infobot.randtext, files/infobot.lang,
-       files/sample.config, files/sample.insert, files/unittab,
-       src/CommandStubs.pl, src/Files.pl, src/Misc.pl, src/Net.pl,
-       src/Process.pl, src/Shm.pl, src/User.pl, src/UserExtra.pl,
-       src/core.pl, src/db_dbm.pl, src/db_mysql.pl, src/db_pgsql.pl,
-       src/interface.pl, src/logger.pl, src/modules.pl, src/IRC/Irc.pl,
-       src/IRC/IrcHooks.pl, src/IRC/Schedulers.pl,
-       src/Modules/Countdown.pl, src/Modules/DNS.pl,
-       src/Modules/Debian.pl, src/Modules/Dict.pl,
-       src/Modules/Freshmeat.pl, src/Modules/Kernel.pl,
-       src/Modules/Quote.pl, src/Modules/RootWarn.pl,
-       src/Modules/Search.pl, src/Modules/Slashdot3.pl,
-       src/Modules/Topic.pl, src/Modules/Units.pl, src/Modules/Uptime.pl,
-       src/Modules/UserInfo.pl, src/Modules/W3Search.pl,
-       src/Factoids/DBCommon.pl, src/Factoids/Norm.pl,
-       src/Factoids/Question.pl, src/Factoids/Reply.pl,
-       src/Factoids/Statement.pl, src/Factoids/Update.pl,
-       src/Modules/DebianExtra.pl, src/Modules/DumpVars.pl,
-       src/Modules/Factoids.pl, src/Modules/Math.pl,
-       src/Modules/UserDCC.pl, src/Modules/Wingate.pl,
-       src/Modules/babel.pl, src/Modules/insult.pl,
-       src/Modules/nickometer.pl: Initial revision
-
-v1.0.0 (20000725): bug fixes mainly.
-       - GmLB found that scripts/setup_*.pl didn't work. Fixed.
-       - Fixed warning in Modules/Uptime.pl for clean install.
-       - More fixes for scripts/*mysql*.pl from GmLB.
-       - Added command 'hex'.
-       - GmLB fixed mysql2txt.pl and txt2mysql.pl. You can now import and
-         export to inforbot 'factpacks'.-
-
-v1.0.0RC3 (20000720): bug fixes mainly.
-       - Debian.pl's infoPackages() now checks for incoming
-         automatically and shows the new file.
-       - irq/dan found the bot wouldn't run if a stale (invalid) pid
-         file exists. Fixed.
-       - Created &closeDCC(), &closePID()
-       - Added factoid SAR of (3-123) => 53
-
-v1.0.0RC2 (20000707):
-       - Ported back Berkerley DBM support. 95% of it works :)
-       - Also added pgSQL support.  Will not work out-of-the-box.
-       - Updated README.
-       - Fixed up 'modules.pl' a bit so if anything fails, it exits
-         gracefully.  Module reloading should work better now.
-       - DCC CHAT commands now must have '.' prepended otherwise all text
-         will me broadcasted to the dcc chat arena.
-       - Removed command 'part'.  Use 'kick' instead :)
-       - 'random|cookie' now takes argument to narrow down randomness.
-       - Merged 90% of MbM's@OPN modifications. Thanks.
-               => bug fixes here and there
-               => 'tell' fixed.
-               => checks for owner of factoids for delete/modify factoids
-       - Moved Factoids/db* to .
-       - Misc stuff here and there.
-
-v1.0.0RC1 (20000701):
-       - Added several hacks (run away fork) due to bot misbehaving.
-       - Added deop.
-       - Added ability to disable factoid support.
-       - Reorganized source tree to be more modular.
-               - Created dirs: IRC, Factoids.
-               - moved partial core.pl and PerlMod.pl to modules.pl
-               - renamed Modules.pl to CommandStubs.pl
-       - Added command 'cycle'.
-       - hardguy/max noted that insult was borked.  It wasn't converted
-         to the new fork format. Fixed but untested.
-       - Added 'ircstats' command. forgot about DisconnectReason
-       - Added to-expire-time on 'ignorelist'
-       - Forgot to clear %ignoreList on loading the list.
-       - moved 'ignorelist' from DCC-only to public/private msg.
-
-v1.0.0pre11 (20000601):
-       - we call &ircloop() if we want to reconnect. Any harm to perl?
-       - Wingate fixed yet again. maximum time for response is 6secs in
-         order to cache maximum number of hosts.
-       - Added ban() for Wingate.
-       - Forgot about virtual host support when changed over to Net::IRC
-       - process() still calls shmCycle() just in case.
-       - Added limit to how many random things we can have in a factoid
-         to prevent endless loops from occurring.
-       - All debian stuff now fully forks -- good.
-       - Failure on &loadMyModule() now deletes $forked{$label}.
-       - if instructed to join a channel "manually", tell who did it on
-         join.
-       - Debian module now searches woody's non-US properly. Misc fixes
-         here and there.
-       - Removed non-working mysql table locking code.
-       - Freshmeat.pl now uses LWP::Simple's getstore. How to load the
-         file on-the-fly?
-       - Looked at Modules-Reload and implemented idea in the bot.
-       - Forgot about flushing uptime in scheduler.
-       - Added unit conversion feature to bot, based on Units-Convert
-         package (at CPAN).
-       - Converted several scalars to hashes.
-       - Added slashdot,freshmeat and kernel announcements of new stuff.
-       - merged chanstats into one line, added top msg stats.
-       - Wingate now does intelligent on-the-fly caching and flushing to
-         a wingate file to prevent dupes. UNTESTED
-       - "find pident potato" now works after few mods/hacks :)
-       - ...
-
-v1.0.0pre10 (20000523):
-       - Fixed minor problems in Debian.pl, I hope.
-         => DebianDownload now calls generateIndex() if a download is
-               successful.
-         => More clean ups.
-         => generateIncoming() forgot about checking stale of idxfile.
-       - Modules in Modules/* now dynamically loaded. Using about ~200k
-         less ram now.
-       - Added support of user modes with param{ircUMODE}. Requested by
-         Flugh.
-       - hookMsg modified, we don't check ignore list if we're not
-         addressed or minvollength is defined. flooding is now
-         configurable by repeated message and total message, expire time
-         and count, like eggdrop.
-       - nickometer didn't reset the score. noticed by greycat+others.
-       - &setupScheduler() scheduler is only called once.
-       - UIS now supports proper locking and lock check.
-       - verifyUser didn't set userHandle to 'default' if not found.
-       - Added factoid reply support of '(blah1|blah2)?'
-       - Added 'FAQ'.
-       - Added DebianExtra.pl module to list bugs. a hack and ugly!
-       - Finally fixed list of old topics in Topic.pl, courtesy of mux
-         and nicholas_.
-       - Removed usage of quotemeta, replaced with \Q\E pair for regex.
-       - Included patches to modify stock-brokeness of perl modules.
-         'cd /usr/lib/perl5; cat *.patch| patch -p0'
-       - Setup option whether to cache user online stats. Disabling will,
-         for sure, won't bloat the bot by 2-4megs (but why that much?).
-
-v1.0.0pre9 (20000512):
-       - Typo for outsider checking. Noticed when #debian flooder came
-         back yet again :)
-       - seenCycle was in minutes instead of days. fixed.
-       - Added User Information Services module. requested by Flugh.
-               => 'uinfo <nick>'
-               => 'uinfo set <type> <what>'
-               => 'uinfo unset <type>'
-       - Added &IsNickInAnyChan($nick);
-       - Added &DCCBroadcast($txt) to broadcast messages to all members
-         of DCC CHAT.
-       - &say() now changes '0' to 'zero' due to Net::IRC bug.
-       - Added &GetNickInChans($nick);
-       - Merged fooz's wingate scanner.
-       - Added 'ignoreAutoExpire' to differentiate time for ignore due to
-         flooding instead of 'ignore' through DCC CHAT.
-         => remove time for 'ignore' through DCC CHAT?
-       - Added &debianCheck() to check state of gzip'd files.
-       - ...
-
-v1.0.0pre8 (20000505):
-       - usual backlash from upgrade.
-       - added 'useStrict' option to infobot.config.
-       - added 'reload', to reload Core and Extras Modules. Does it
-         reload only if the file has changed?
-       - added preliminary (debug) code for ftpGet() for truncated
-         downloads. regetting will be added soon afterwards.
-       - minor fix for Debian.pl where a package exists but an
-         incomplete Packages file may not have info on that package.
-       - Modified on-the-fly ignore to be temporary. temporary ignore
-         requested by jCommons.
-       - added 'factstats requester'.
-       - preliminary use of scheduler for &checkPing() in &on_init().
-               no event hook on 'pong' :(((
-       - Timers now use Net::IRC's scheduler, woohoo. Nice change over.
-         Moved ProcessExtras.pl to Schedulers.pl.
-       - Added 'factstats deadredir'.
-       - Don't prevent auto-reconnecting due to disconnection.
-       - Forgot initialization before any new IRC connection.
-       - Added scheduler for checking IRC connection.
-       - Fixed problem in Freshmeat module, if forked to download, would
-         not continue with query. => now it does, nice hack.
-       - Debian module should generate incoming index if does not exist.
-       - Chatting can be done through DCC CHAT.
-       - ...
-
-v1.0.0pre7 (20000426):
-       - INSTALL and README updated.
-       - auto-request for ops after joining all channels instead of after
-         each channel join.
-       - If factoid is requested by someone, show literally (no
-         evaluation) if owner of factoid matches aswell as if requested
-         privately(good idea?)
-       - on_notice fixed and debugging info removed.
-       - Added reconnect on HUP if we're not connected. I hope that it is
-         set to 0 otherwise this solution is dead.
-       - ';' added as address char.
-       - maths bug found by NoNix4.
-               eg: 6000.0/9.000 - 6.000/9.000 - 666.00001
-       - nickometer bug (pi not defined) found by ddent. 'strict' cleanup.
-       - Preliminary CLI code included. Good for local use.
-       - typo in Topic.pl, found by jCommons. Fix for NULL topic.
-       - minor Debian.pl update to deal with 'missing files' on download.
-       - multi-shmwrite support added. looks like it doesn't "refresh"
-         the value properly if written many times.
-       - &verifyUser() only used if addressed.
-       - Applied 'use strict' to all code. Also used 'use vars qw()'.
-       - Added 'backlog #' to DCC CHAT. requested by jCommons.
-       - ctcp version reply wrong; FIXED. found by fooz.
-
-v1.0.0pre6 (20000407):
-       - README updated.
-       - Added retry on failure to reconnect through on_disconnect();
-         REMOVED -- this spun an endless loop.
-       - Found why Googling didn't work. See README for fix.
-       - Forgot about channel casing bugs (on_{join|part}) after
-         changeover to Net::IRC.
-       - Changed addForked() to cycle through fork list and delete stale
-         forks in case a forked child dies unexpectedly.
-       - Renamed allowOutsiders to disallowOutsiders just in case if the
-         option is removed from the configuration.
-
-v1.0.0pre5 (20000331):
-       - setup_users.pl. DBI*() => sql*().
-       - 'topic add BLAH' on empty topic would bork. Why didn't I pick
-         this up before?
-       - Somehow I removed (or it wasn't there) 'my @results' from
-         searchTable();
-       - nickometer now uses loadPerlModule()... another 500 kB saved :)
-       - repeat flood detection prevention added.
-       - Added el-cheapo hash key counter... possible leak detector.
-       - Added 'factstats lame' for short and most probably stupid
-         factoids.
-       - Weather module removed
-       - Renamed 'join' to 'joinchan' to due warning//conflict raised
-         with perl 5.005 (on potato not slink).
-       - Disabled syscall (removes 300 kB on slink, 3megs on potato)
-
-v1.0.0pre4 (20000323): pseudo AutoLoader support.
-       - 'infobot' now first loads core.pl and logger.pl.
-       - timerExpire() fixed.
-       - Added unique maintainer count to 'dstats'.
-       - Added demand-on-load of external perl modules. Now we need
-         dynamic(on demand) loading of 'Modules/*.pl' modules ;)
-
-v1.0.0pre3 (20000319):
-       - Fixed Freshmeat.pl not to show duplicate packages found by
-         'name' and 'oneliner' search. Made showPackage() function.
-       - Debian modules now does multi distro. (woody's non-us appears to
-         be different structure so does not work :(, very crude hack...
-         may not even work).
-       - Added subfactoid randomising. eg: '(one|two|three)'.
-       - 'dauthor' now works!
-       - karma fixed... used the wrong var name.
-       - Fixed doubling of text when message from 'nick' is ignored.
-       - Added 'redir' to designate one factoid as master and duplicates
-         as redirectors//slaves.
-       - Added addressing recognition character(s) support. eg "!status".
-       - Seen info now cached and flushed at intervals or upon exiting.
-       - Added 'EXAMPLES' file to doc/.
-       - Removed ancient '&channel()'.
-       - Bug fixes after offshore installation of bot.
-       - Debian output of 'info' fixed. looks like 'fm', heh.
-       - Debian distro stats added. I'm competing with larne and his mods
-         to dpkg@OPN#debian :) so far so good.
-       - Forgot to close shm upon exit, heh :) However this does not
-         prevent leakage when the bot crashes.
-       - Parameter 'forking' now works, courtesy of generic &Forker()
-         function, woohoo! Now we use &Forker() for _everything_.
-         I had this in the todo list, removed it and decided to implement
-         it once and for all.
-       - More bug fixes when moved changes to 'apt'. Several "bug
-         reports" sent from #debian, thanks!
-       - Moved infobot communications _after_ ignore checking code.
-       - babelfish changed format? disabled for the time being.
-       - ...
-
-v1.0.0pre2 (20000310): BETA TEST RELEASE
-       - Hacked multiple mysql connection support in.
-       - Renamed DBI to SQL, including functions.
-       - Added $ishost.
-       - Added backup scripts to create and mirror tables.
-       - listauth fixed.
-       - Added parse_warn.pl to decipher warn messages from logs.
-       - shm* now works. no more fork floods ;)
-       - Applied fork protection on all forking modules.
-       - Dict feature now supports specific retrival of definition,
-         however, default is still random.
-       - Debian feature now supports multiple sub distributions. This can
-         be further extended to architecture (perhaps easily).
-       - Added (but commented) larne's regex for debian search.
-       - Added &hasParam() to include notification that a feature
-         (command) requested is disabled in configuration.
-       - Added dumping of memory stats.
-       - Fixed broken timerExpire().
-       - Added auto shutdown of bot if too much ram is used.
-       - Modified seen feature, set to off by default.
-               - UPDATE: fixed, about time.
-       - Improved parse_warn.pl to be like "diff".
-       - Dollar variable addition?? suggestions by ddent.
-       - 'factstats dupe' now ignores '<REPLY> see'.
-               - UPDATE: fixed.
-       - Added random factoid timer.
-       - Don't redownload file via getFTP() if local and remote sizes are
-         the same.
-       - Added $count{'Dunno'} for unanswered questions.
-       - Fixed 'blah is also or' since we didn't allow 'or'.
-       - Added 'factstats redir' to display factoid redirections.
-       - Grep nick from list of nicks in IsNickInChan(). Bug found by
-         Mercury.
-       - Time taken and final xfer rate displayed in FTP.
-       - Fixed bug where 'or' is eval'd in Math.pl. Return '' if eval()
-         is not done. Bug found by dent.
-       - Added 'factstats redir' to list working and non-working
-         redirected (symlink) factoids.
-       - cmdstats now sorted by highest->lowest usage.
-       - ...
-
-v1.0.0pre1 (20000130):
-       - Mostly converted to Net::IRC, quite nice, like the dbm to mysql
-         change over :)
-       - Removed IrcHooks.pl and CTCP.pl.
-       - Moved hooks stuff to IrcHooks.pl.
-       - Moved IrcExtras.pl to Irc.pl.
-       - Removed ansi_control option. colors can be stripped within
-         &status() anyway, like for logging.
-       - Added DCC CHAT and DCC SEND support base.
-               - DCC SEND: null file. due to fork()? Fixed anyway.
-               - DCC CHAT: person's responsibility to close DCC CHAT.
-
-v0.99pre12 (20000125):
-       - Added intelligent flood protection and removed factoid
-         repetition prevention.
-       - Modified Math.pl...
-       - Unified tell code in Process.pl.
-       - Moved variable fix and addresing code to IrcHooks.pl
-       - Moved tell code from Question.pl to UserExtra.pl.
-       - Found that % and \ were double backslashed; added it to invalid
-         factoids. May have been caused by whoever unbacked up 'apt',
-         cerb? :) May want to add a function to automatically fix badly
-         formed factoids.
-       - Added 'factstats profanity', with &hasProfanity($str).
-       - Added functions for shared memory usage.
-         Uses: prevent exploitation of forked processes.
-       - Added 'factstats unrequested'.
-       - stale variables (vhost_name) forgotten in changeover.
-       - UPDATE:
-       - Fixed major leak with cycling of flood messages, typo :)
-
-v0.99pre11 (20000123):
-       - Fixes here and there...
-       - Debian find now searches Package names. Fallback automatically
-         to contents file search.
-       - Fixed typo related to log cycling.
-       - Added netsplit detection code.
-       - Started DCC support... very early stages.
-       - Replaced several 'foreach' statements with 'if' for efficiency.
-         About 5 instances of code...
-       - Debian contents search ignores man pages (unless search string
-         obvious for man page). Suggested by sgore.
-       - 'factstats locked' returns list instead of only count.
-       - &DoModes() bug found by larne.
-       - Used '$nick' instead of 'lc $nick' for $channels.
-         Found by larne.
-
-v0.99pre10 (20000119):
-       - Fixed bugs found when moved code to 'apt':
-               - added '^' and '|' to $isnick.
-               - removed 'local' and 'my' for some global vars.
-               - Typos of some variable names.
-               - More typos.
-       - Debian.pl contents search is better now.
-               - UPDATE: made changes suggested by greycat.
-               - Added Packages query now...
-       - Added &getRandomLineFromFile()
-       - Added LART, random text, Channel limit adjuster.
-               TODO => Wingate checker (NOT COMPLETED)...
-       - Added &iseq() and &isne().
-       - Help info is not cached any more => loaded each time help() is
-         called.
-       - Added %timer hash, timestamp when something was last done. The
-         hash name is incorrectly named, eh?
-       - Moved parts of Process.pl to ProcessExtra.pl.
-       - Moved parts of User.pl to UserExtra.pl.
-       - Moved myRoutines.pl to UserExtra.pl.
-       - Moved Extras.pl to Modules.pl.
-       - Removed fortran math due to poor code style.
-       - Moved parts of Question.pl to UserExtra.pl.
-
-v0.99pre9 (20000115):
-       - Added messagecount column for 'seen'. Not used as yet. It
-         appears to be pointless, yes?
-       - Cleaned up DBI.pl: made use of $dbh->quote(); added
-         &DBIRawReturn(), &DBIInsert(), &DBIUpdate().
-       - Forgot to clear $tell_obj after successful 'tell'. Founded by
-         solomon.
-       - Extra modules loaded only if enabled in config, may save some
-         ram.
-       - Math.pl cleaned up.
-       - Added DumpVars.pl, now we know where things are being leaked.
-               - Removed duplicate 'use IO::Socket'.
-       - Typo in "disabled" locking code which didn't work :) Founded by
-         washort.
-
-v0.99pre8 (20000110):
-       - Bailout if critical configuration variables are not found.
-       - Dict.pl works well now.
-       - Topic.pl now uses %topic or @topic. Added 'topic info' which
-         contains who and time info. How does @{$hash{$key}} work?
-       - Used 'use diagnostics;'. Fixed most warnings.
-       - Added &WARN().
-       - Minor typo in &IsInvalid() on last statement, heh.
-       - Fixed (DAILY) logging, finally. Was broken too many times.
-       - Added &getLineFromFile() for debugging purposes. BROKEN
-       - Added Debian search-engine frontend => Debian.pl.
-         UPDATE: forget mysql, takes too long.
-       - Added Countdown => Countdown.pl.
-       - Made use of 'unless' instead of 'if !'.
-       - Added &DBIRaw().
-       - Addressing required on all commands.
-       - Added &fixFileList() to simplify files with common directories.
-               - RevHippie stumped me with the best method to write this,
-                 heh. Why do I always try to do things in 1 loop instead
-                 of 2 loops?
-
-v0.99pre7 (19991230):
-       - Renamed some setup/DBI calls.
-       - Simplified nickserv/chanserv code. chanserv opping may break
-         though. Experimentation?
-       - Fixed broken stuff scripts/* due to src/* modification.
-       - Added table locking support. BROKEN.
-       - param{'ident'} deprecated.
-       - Removed param{'dbname'}, please rename the main table (with
-         factoids) to factoids.*
-       - Added ircII.servers support.
-       - Fixed infobot, Setup.pl and Files.pl.
-       - Freshmeat.pl fixed. Set the update time _before_ we update.
-       - Added factoid renaming. "rename 'from' 'to'".
-       - Added DBISetRow() for first time inserts, for Freshmeat.
-         Removed (rather used raw) use of fixmysqlbug for DBISetRow()
-       - Added 'seen random'; fixed randKey to work with 'seen'.
-       - Added preliminary code for whatis frontend.
-       - Added SIGHUP code for $SIG{HUP}.
-       - Added more error protection in DBI.pl.
-       - Moved logDate logging support to &status@Misc.pl.
-       - Confirmed logging does not duplicate from child any more.
-       - Added 'partialdupe' (not recommended) and '2long' to
-         &FactStats();
-       - ...
-
-v0.99pre6 (19991223):
-       - Dict now fixed, courtesy of RevHippie and myself.
-       - Applied patch from RevHippie.
-               - Removed auto continuation code.
-               - Fixed learn =~ /HUNGRY/;
-               - Added $talkok and $learnok.
-       - Removed $param{'nick'} in favour of $ident. Added $safeIdent for
-         regex and made use of it.
-       - Moved Help.pl, Ignore.pl, Params.pl and part of User.pl to
-         Files.pl.
-       - Removed Internic.pl and Traceroute.pl.
-       - Fixed $isnick, renamed and fixed &purifyNick(). Added nick
-         compliancy checks when connecting to IRC server.
-       - Rewritten 'spell' code.
-
-v0.99pre5 (19991220): bug fix release.
-       - setupmysql.pl, slightly different for potato.
-       - dbm2mysql.pl
-       - performReply(), removed $trailing. FIX LATER.
-       - Freshmeat.pl, forgot about &main::, again.
-       - logType, broken date value.
-       - Fixed broken 'tell blah about what', readded $answer var.
-       - minLengthBeforePrivate superseeds preferReply.
-       - Forgot to use 'my' on three instances of $sth.
-
-v0.99pre4 (19991219):
-       - Added 'dupe' for factstats.
-       - Added illegal character detection in Statement.pl.
-       - Unified output (and duplication) of factstats (and other) code
-         to use one function, &formListReply(). Reduced code by at least
-         2k :)))
-       - Minor modifications to &DBIGetCol();
-       - Move +s flag to 'set search' in infobot.config.
-       - Altered talkMethod to allow 'private' or 'default'. Made no
-         sense to have it on public-only, heh.
-       - friendlyBots will be kept to be compatible with other stock
-         infobots but soon enough multiple mysql database support will be
-         added. Will be quite nice once done.
-       - Added maxListReplyCount and maxListReplyLen. Read infobot.config
-         for details.
-       - Replaced $refresh with freshmeatRefreshInterval to config.
-       - Changed learn setting from ALWAYS to HUNGRY.
-       - Reorganised Extras.pl, we shouldn't bail out if the command
-         can be disabled as the person who runs the bot should have
-         brains.
-       - Moved some Process.pl stuff to myRoutines.pl.
-       - ---
-       - &searchBy*() allows ^ and $, like in regex (basically sar'd).
-         removed $notexact variable.
-       - Fixed 'no,blah is blah' bug.
-       - Changed 'is also' char to ';;'.
-       - Added &IsInvalid(); to unify Statement (when creating) and
-         factstats/broken (when checking/verifying). Works like a charm
-         :)))
-       - Removed sane stuff; added infobot.ignore. I hope lenzo's
-         ignoreList code works.
-       - Fixed setupmysql.pl
-       - Moved repeatIgnoreInterval to minRepeat*Reply where * is Private
-         or Public.
-       - Now preferReply works. Wasn't hard as it first looked.
-       - Added global '+' flag support.
-       - Fixed logging: added logType param; if logType =~ /DAILY/, new
-         log is created daily. Date is time-of-day, aswell.
-       - added &fixMySQLBug() => adds backslash to special chars.
-
-v0.99pre3 (19991216):
-       - Fix connection bug where if host does not resolve, it appears
-         that it's connection refused. Now non-resolving hosts are
-         detected earlier. Found by some *.it (or .es??) guy.
-       - Added 'sync in #s' when the bot has joined a channel... just
-         like in BitchX.
-       - Added txt2mysql.pl.
-       - Removed instances of '^\s*' to '^' since $message can be
-         manipulated in Process.pl.
-       - Fixed Statement.pl so that it doesn't catch queries... it's a
-         stupid idea any way.
-       - Removed 'confused' in favour of 'dunno'.
-       - Funny hack in performReply(). Stupid but it works.
-       - Added 'host' column in seen table.
-       - Made use of &gettimeofday() for freshmeat and search function.
-
-v0.99pre2 (19991213):
-       - Made use of new database (directory) not to interfere with other
-         crucial dbs.
-       - Re-added &getKeys(), mysql's RLIKE wouldn't like "'" in the
-         statement. If several of similar queries are required, better
-         off using &getKeys().
-       - Added two more conversion scripts.
-
-v0.99pre1 (19991211): personal release. MAJOR CHANGES.
-       - create a script to add the blootbot user to the mysql server and
-         prepare tables for use with the bot.
-       - butchered Question.pl, Reply.pl, Statement.pl and Reply.pl.
-       - main factoid db ported over; barely tested.
-       - seen ported over; appears to work.
-       - karma ported over; not tested at all.
-       - freshmeat ported over; fix brokeness.
-       - search (listvals and listkeys) ported over.
-       - rootwarn ported over.
-
-       - Use quotemeta in DBI.pl on special chars, especially ' :)
-       - Added factstats 'broken' function.
-       - Made use of multiple connections to avoid clashing... does
-         clashing only occur when there's an INSERT/UPDATE or SELECT or
-         both?
-       - Changed $factoid to $faqtoid... good idea? how about $lhs?
-       - Changed getKeys to countKeys to take advantage of mysql.
-       - Added randKey to get random primkey,key from table.
-       - Removed process() when msgType == 'public action'. Why would we
-         want to care about actions anyway?
-       - Fix public action; Added private action to &status().
-       - Added &ERROR();
-       - Made message and who flooding independent in IrcHooks.pl. Now we
-         use %flood... should be expanded to use %ignoreList;
-
-       NOTES...
-       - DBI.pl has more functions than what DBMExtra.pl had in order to
-         implement a table-like hash list.
-       - &DBISet() always verifies if an entry already exists and does an
-         UPDATE instead of an INSERT... flaw in mysql or my code???
-       - &DBISet() can only set one (in UPDATE, two in INSERT), variable
-         at a time. Does this impose a performance hit? like on seen.
-       - ...
-
-       TODO...
-       - infobot.cgi not ported over.
-       - weather not ported over.
-       - add alarm call between while in Dict.pl.
-
-*************************************************
-************* CHANGE OVER TO MySQL **************
-*************************************************
-
-v0.18.2 (199912??): dropped.
-       - Fix for Weather.pl.
-       - Fix for Dict.pl.
-       - ...
-
-v0.18.1 (19991130): last public release before database change over.
-       - Modified &IsNickInChan() so that a foreach is done case
-         insensitively against nick to prevent misses.
-       - Added server "jump" support, requested by larne.
-       - Added seenMaxDays, maximum number of days to keep seen info on
-         someone, otherwise delete it.
-       - Forgot to use $main:: in Freshmeat.pl and Weather.pl; fixed.
-       - Changed userList format to $userList{$user}{$flag}{$what} = 1;
-         Converted all code to use this userList format.
-       - Changed version string to include OSname.
-       - Replaced $locWho with $who or $origWho.
-       - Removed hidden whitespaces and tabs at and of statments.
-
-v0.18.0 (19991128):
-       - Post release typo fixes here and there.
-       - Changed lc() to tr/A-Z/a-z/ where suitable.
-       - Redid join command in Process.pl.
-       - Cleaned up regex (mainly .* => \S+).
-       - Found $ischan to be broken; fixed.
-       - Changed Slashdot3.pl to have "joining" code like in DBMExtra.pl.
-       - Made use of &nick() and &IsChan();
-       - Added &kick() to Misc.pl; kick command to User.pl.
-       - Added &IsNickInChan();
-       - Fixed loading Param file before pidfile and other file related
-         stuff.
-       - User.pl
-               - Revamped; removed unused functions.
-               - Moved Set.pl to here.
-               - Moved 4op code here.
-               - Moved some functions from Process.pl to here.
-               - Rewrote rehash command.
-       - More casing fixes; debugging info _should_ help to find more.
-       - Changed infobot.users.
-
-v0.17.0 (19991126):
-       - Netsplit code prevented stats of signoffs; fixed.
-       - Messed around with logging code to prevent control chars.
-       - Removed exchange and excuse module because of brokeness.
-       - Applied patch from RevHippie. Thanks!
-               - Added delimiter support in addressing of hello msg.
-               - Removed 'score' in karma.
-               - Added 'learn' (ALWAYS or ADDRESSED) support. Normal
-                 operation == ADDRESSED. Bot won't respond voluntarily to
-                 factoids but will respond to learning.
-               - Ability to turn off minVolunteerLength.
-               - More changes to prevent chatter in unaddressed manner.
-       - We remove any ansi or control chars when piping to the log file.
-         RevHippie++.
-       - Added 'thanks' language.
-       - Typo in Freshmeat.pl; Fixed.
-       - Added $rootwarnmode = passive || aggressive to satisfy lilo@OPN.
-         default is passive.
-       - Fixed mix up of fix in 'tell' code. I had the if statements the
-         wrong way around.
-       - Removed more debug code.
-       - FactStats/author fixed; now multiple authors with the same stats
-         are printed together.
-       - Added logfile cycling w/ approx maximum size.
-       - Changed infobot.config yet again. now it's much better than
-         before. Some variables removed.
-       - Added Unset support to Set.pl; Changed so anything can be set
-         or unset.
-       - Made use of &purifyNick() so regex doesn't break. $safeWho
-         now defined earlier.
-
-v0.16.0 (19991122):
-       - Applied bug fixes from infobot 0.44.3, added md5 password
-         support (*BSD?).
-       - Added &IsParam() to check existance of params the proper
-         (strict) way.
-       - Moved rootWarn stuff from Extras.pl to RootWarn.pl.
-       - filenames (rootwarn and uptime) now not statically set.
-       - Cleaned up config file and Setup.pl.
-       - Fixed up &parsectcp() in CTCP.pl.
-       - Changed ($ischan) to (\S+) in Irc.pl under PRIVMSG.
-       - Major reorganisation of Misc.pl -- removed unused functions.
-       - Moved some variables to 'infobot'.
-       - Fixed ANSI typo by some loser; Changed format of &status()'s in
-         Irc.pl, seems to look nice thus far.
-       - Added "author" command under &FactStats() in DBMExtra.pl.
-       - Added case insensitivity to &IsHostMatch() and search strings in
-         DBMExtra.pl. Any more of these?
-       - Removed disabled netsplit code.
-       - Changed 'defined' to 'exists' on all hash lists, 'cept hashes
-         created by opening db's.
-       - Modified repeat code on modified_time. If this time is small,
-         msgType is changed to 'private' for flooding reasons and
-         max_time is reduced by half. latter appears not to work???
-
-v0.15.0 (19991112):
-       - Quite funny that once the repeat code was moved to Question.pl
-         factoid extension leakage was found. maths leakage was also
-         happening but somehow is fixed when the repeat code was moved
-         back.
-       - Clean up of variable names in Reply.pl and Question.pl
-       - Changed 'length' to 'eq ""' or 'ne ""' where possible.
-         This should produce faster code but benchmarks prove this change
-         is neglible. Guess perl is slow :)
-       - Cleaned up and fixed 'tell <who> about <what>' code.
-       - Set.pl fixed; Added DEBUG to allowable set list.
-       - Volunteer code moved to top of Question.pl.
-
-v0.14.0 (19991110):
-       - Message overflow fix in &FactStats().
-       - Added 'factstats new' command to display new factoids in the
-         last 24 hours.
-       - Fixed up ping reply, requested by a few from #debian@OPN.
-       - Re-added debugging of DBMExtra due to leakage of orthaned
-         factoid extensions. Need to investigate and confirm the
-         lowercase fix of factoids.
-       - Two functions which used &mkRandom() now fixed due to poor
-         effort in implementation. Added missing srand(). now the maximum
-         length of 475 should not be exceeded, hopefully. it can be
-         beefed up to 490 if needed.
-
-v0.13.0 (19991108):
-       - Made use of &help() which uses infobot.help. This paves the way
-         for NLS as suggested by njs.
-       - Fixed up code on netjoin/netsplit in an effort to find
-         statistics leakage. Added debugging info to netjoin/netsplit.
-       - Fixed typo (three instances) in factinfo where time() was used
-         instead of the data in the factoid extension. Found by larne.
-       - Allow main thread to do a clean exit while the child does
-         nothing. Possible fix for weird uptime info.
-       - Removed sar of 'your|i|you|me' to prevent automated reverse
-         persona which is better done by the user. Suggested by njs.
-       - Cleaned up behaviour of &FixPlural(). Fixes a bug.
-       - Repeat prevention code now replaced (moved aswell) to use
-         factoid extensions
-       - Fixed 'factstats requested' error.
-
-v0.12.6 (19991103): bugfix on bugfix release ;)
-       - Fixed bug where you can't lock a factoid because the hostmatch
-         ($thisnuh = "") failed. Found by wolfie.
-       - Fixed up 512byte overflow in factstats[requested].
-       - hm... wonder how I broke Weather.pl.
-
-v0.12.5 (19991101): Bugfix release
-       - Fixed "bad" array in Freshmeat.pl. All appologies to scoop.
-         [update: use array[5] if it exists, otherwise do as before.]
-       - Removed some debugging info from DBMExtra.pl.
-       - Fixed inconsistent chanstats behaviour in SignOff.
-         [Update: forgot to delete the user info _after_ we do the stats]
-       - Moved factoid stats count and repeat checking code to
-         Question.pl. Now it works as planned :) :) :)
-
-v0.12.4 (19991028):
-       - Added factstat and listauth commands.
-       - 'topic add' now prepends subtopic not append.
-       - Fixed up minor problem with 'topic restore last'.
-       - Changed default of locking access to people who own their
-         factoid or to registered ops. This should please #debian.
-       - Reduced usage of @{$var} which cannot be really deleted cleanly.
-       - Moved DBMExtra-related stuff from myRoutines.pl to DBMExtra.pl.
-       - Added new functions &mkRandom() and &getRandom().
-       - Changed all code (Search.pl) which used random to the one
-         developed in DBMExtra.pl. => made code slightly smaller.
-       - Cleaned up Search.pl to look nice.
-       - Found yet another casing bug under TOPIC in Irc.pl.
-       - Fixed bug where dbmextra queries where made on non-factoids like
-         maths and probably karma.
-
-v0.12.3 (19991025):
-       - Added while loop around connect which should prevent the bot
-         from falling down (dying).
-       - Forgot 'main::' for &getURL in Freshmeat.pl. Changed
-         opening/closing code yet again. Removed checking on open
-         read-only.
-       - Changed Dict.pl to reply private only by default. '+' will allow
-         public responses without suggestions/synonyms.
-       - Added checking against pidfile. running two bots from the same
-         dir at the same time using the same db == disaster. Ask #debian
-         about it :)
-       - Implemented Weather.pl.
-
-v0.12.1 (19991022):
-       - Made distribution out of infobot -> blootbot.
-       - Irc.pl was prone to be fucking up -- swapped (.*) to (\S+) where
-         necessary. stab lenzo for this :) found more instances of this.
-               [update: appears to trap too many of something, check
-                 'chaninfo #chan' for info.]
-       - Minor fix for Freshmeat.pl when opening/closing db.
-       - Factoid extension code is ready for testing. possible in the
-         future to add "factstats" for like: top 3 requested factoids.
-         [update] added lock checking on sar and on updates ("no, "...)
-
-v0.12.0 (19991020): (v0.11.6 + bugfixes + trial)
-       - Major shake-up of how addressing is handled -- damn it took me a
-         long time to get this to work.
-       - Changed command names in Topic.pl to &topicBlah().
-       - Found and fixed (hopefully) all 7 channel casing bugs.
-       - Moved freshmeat to use berkeley db instead of raw appindex.txt
-         file. finally got it to work, seems 30% faster. Creating the db
-         takes a long time though.
-       - Added "set" command => Set.pl.
-       - Added support of talkMethod which behaves much like lobotomy.
-         In the future, talkMethod =~ /(lobotomy|none)/ may be used.
-       - Purged: METAR2.pl, NOAA.pl, UAFlight.pl.
-       - RootWarn only works if the bot is opped in the channel.
-       - Created performStrictReply() from performReply().
-       - Quote.pl and Internic.pl now work.
-       - Fixed a few typos in myRoutines.pl
-       - Removed bold on dictionary.
-
-v0.11.5 (19991012):
-       - Fixed $chan to lowercase where appropriate.
-       - Fixed volunteer reply code... I guess it worked before but now
-         it is somewhat cleaner and easy to understand.
-       - Added factoid owner database, requested by njs.
-       - If public message is addressed to someone else, we ignore it.
-       - Now support referer factoids ('blah is <REPLY> see erp'). if
-         'blah' is asked, the reply from 'erp' is given.
-       - OPN allows part messages -- fixed in /PART/ for $chan.
-
-v0.11.3 (19991008):
-       - Uptime.pl appears to be fixed after rewrite of getUptimeInfo.
-       - Fixed up Freshmeat.pl for updating the index. Proxy is now
-         optional.
-       - Moved rootWarn to RootWarn.pl. Added hall-of-fame of losers.
-       - Cleaned up bugs/typo here and there which may have caused the
-         bot to behave in a weird manner.
-
-v0.11.2 (19991006):
-       - ChanInfo now displays "statistics" just like our little friend
-         BitchX.
-       - Minor change in determining args on commands [myRoutines].
-       - Added "cmdstats".
-       - Added rootWarn checking on checks. Repeat offenders will be
-         punished. Requested by larne. [update: we aren't so harsh now]
-       - Added lc $chan where appropriate. damn uppercase channames.
-
-v0.11.1 (19991005):
-       - all instances of undef on hash lists changed to delete which
-         _now_ works. found minor bugs/typos related to DUI.
-       - Now skip internic whois intro (13 lines) to fix bad output.
-       - Forgot to subtract $i from $counter in chaninfo when full.
-               [update: whole function changed, see above]
-       - Now backup (and gzip) freshmeat index file.
-
-v0.11 (19991004): looks like a bug fix release :)
-       - Fixed typo in reply of Topic.pl/&NewTopic().
-       - Decreased max topic length allowed; now print it, too, for
-         debugging.
-       - Altered repeat code to only work on public. Flooders should be
-         taken care of by the (allowOutsiders == 0) code. if not, there's
-         'lobotomy' :)
-       - Added excess flood protection around &rawout();
-       - Don't bother about outsiders if we haven't joined any channels.
-       - Changed email address to one throughout modifications.
-         New files have neato headers.
-       - Uptime.pl fixed, didn't need to check against ($pid == $$)
-       - Repeat-prevention code kind-of looks what it was before but this
-         one, at least, works :). any problems, just bitch at me.
-       - Added debugging code for chaninfo to diagnose "problem".
-
-v0.10 (19991001):
-       - Added Uptime module.
-       - Added Freshmeat module.
-       - Dict now returns definition without suggestions (syn's) by
-         default. Also cleaned up.
-       - NickServ/ChanServ major clean up.
-       - Join upon reconnect fix: set $joinchans = 0.
-       - Fixed up Help.pl, added more help entries.
-
-v0.9b (19990925):
-       - Did repeat-prevention code from scratch -- now works.
-         [19991001 update]: multiplier is now 2 instead of 10.
-       - Made reaction to "hello" more strict. the same should be done to
-         "thanks", don't you think?
-       - Converted remaining modules to use forking. should be no more
-         bot lockups...
-       - Changed maxhits to 20 for Search.
-
-v0.9 (19990924): +16K added to patch size.
-       - More, more and more major changes.
-       - Fixed up inappropriate usage of performReply.
-       - Added lobotomy command to (un)silence the bot.
-       - Added allowOutsiders toggle to prevent usage of the bot
-         _outside_ the channels the bot is in.
-       - Added $fullyaddressed, enabled if $addressed == 1 and
-         $param{addressing} == REQUIRE.
-       - Readded auto-continuity code. it is disable if not fully
-         addressed. otherwise works as per normal.
-       - Moved join-on-start-of-motd code to end-of-motd. If nickserv &&
-         chanserv is enabled, IDENTIFY is done first. If okay, then we
-         proceed to join channels.
-       - When bot joins channel, summary of nicks (ops|voice|total) is
-         given instead of NAMES list.
-       - Chanserv support moved to "end of names".
-       - Detection of nickserv (no such nick).
-       - join channel if channel is on our joins list and if we're not on
-         it (hrm, providing their client prevents it).
-       - ...
-
-v0.8 (19990919): +50K patch from last version.
-       - Major changes, particularly cleanups and fixed a few bugs:
-               - Found 2 or so instances of $params{}. Either deleted or
-                 renamed to $param where appropriate.
-               - Shortened foreach statements where possible.
-       - Replaced duplicate code involving &say and &msg with
-         &performReply($text,[0=rand,1=strict]). -- major shortcut and
-         cleanup.
-       - Added tracking of all users on channel(s). Users are
-         deleted if they disappear for whatever reason with
-         &DeleteUserInfo.
-       - Tracking of channels now works; they are deleted if we disappear
-         from any channel for whatever reason (hopefully).
-       - 'forget' command _SHOULD_ be wrapped with $addressed.
-       - Moved 'modes' from User.pl to myRoutines.pl as 'chaninfo'.
-       - Added stock quote support by using mu's script. Thanks.
-       - Added param{*} around stuff in myRoutines.pl for flexibility.
-       - Added auto-join on invite if not on specific "join_channels"
-       - Renamed &Timetostring to &Time2String and made use of it not
-         only for status but for seen.
-       - If $param{*} == false, it is now not defined.
-       - Removed Auto-continuity code -- very evil for any bot commands
-         other than non-intentionally requesting a factoid.
-       - crypt command required "(" before passwd???
-       - Removed stupid commands which just generate URLs for you to cut
-         and paste.
-       - repeatIgnoreInterval code _NOW_ works unlike before.
-       - Added support for Topic.pl not to update topics if commands are
-         prepended by '-'. Topics can be "rehashed" when either a) the
-         next command is used without '-' or b) "rehash" is the next
-         command.
-       - &NewTopic takes two more args to prevent repetition and now does
-         topic checking. Check code for details.
-
-v0.7 (19990914):
-       - Major clean up: Search.pl now only uses the "is" dbm; final
-         pair of parens in commands removed for legibility; Removed
-         debugging for NickServ, ChanServ to go.
-       - Added multiple subtopic delete ability. requested by Mercury.
-       - Moved responses/replies to [files/infobot.lang]. Modified
-         related functions to conform, including mine.
-       - Fixed up Kernel.pl to use different type of sockets. Previous
-         code somehow broke itself.
-       - Added, but disabled, semi-working timer support. Need to ask
-         lenzo some questions on how to implement it the best way.
-       - Added channel (and offender's) notification if someone joins the
-         channel with root. requested by #debian.
-       - Added dict.org support. For now, it uses wordnet and returns a
-         random definition. Could change in the future.
-
-v0.6 (19990903):
-       - Added support for nickserv and chanserv, requested by is.
-       - Updated README to describe new features and modifications. Do we
-         need to elaborate on the modifications to the depth where it
-         would exceed the size of the patch?
-       - Minor clean up.
-       - Removed assumed-continuity of messages -- should be used if
-         addressing is in optional mode but would be bad in any situation
-         if more than one infobot existed in the channel.
-       - Added parsing of g flag to factoid sar.
-
-v0.5 (19990827):
-       - Better way to confirm if bot is on channel now for topic
-         management. Also added check for +o+t or -t. &DoModes() on
-         server stuff, too?
-       - Patch updated to work for infobot-0.44.2 only.
-       - Found a bug in Irc.pl under "NAMES" where $u was used initially
-         but trashed afterwards. => replaced $u w/ $_.
-       - Lost track of a bug found by Mercury. Seems to be fixed now,
-         somehow, heh.
-
-v0.4c (19990822):
-       - Worked on random-cookie -- random responses can now be added
-         (internally) with ease.
-       - Noticed joeyh changing his nick to/from '||' which reminded me
-         of something bad ;) hint: topic management.
-       - One line patch to allow '|' in factoids; delimiter is now '||'.
-
-v0.4b (19990818):
-       - Implemented patch from mu. Now it is possible to use the topic
-         command through private messages to the bot instead of the
-         channel.
-       - Replaced SAR of \| with \|\| so we can still use the single
-         pipes. Double pipes will be either removed or promote an error
-         message. Found by Robot101. Added el-cheapo work-around if the
-         last char of subtopic is |, kill it.
-
-v0.4a (19990816):
-       - Added cheap fix (sleep 1, heh) to excess floods of 'topic
-         history'. Is sleep 1 enough?
-       - Added 'random' for random value{key} from database.
-         Requested by jCommons.
-
-v0.4 (19990815):
-       - Fixed topic history by replacing push with unshift. Now the
-         history list is reversed and cycled properly.
-       - Reversed Changes list. request by mu.
-       - Totally fixed up topic history since it would break if
-         'topic add' was induced quickly. Now we only record topics set
-         by us (for reasons) and onjoin topics (set by anyone).
-       - Removed 'topic last/reset' because how do you know which topic
-         is last? Better control with 'topic restore'.
-
-v0.3c (19990813):
-       - Fixed 'topic mv 2 before 1' bug. Forgot to store 'move' topic
-         before doing the foreach loop.
-       - Touched up Kernel.pl in preparation for auto-notify feature.
-
-v0.3b (19990812):
-       - Added version string to new files so we know which version
-         of patch we're using (or used). There you go, Mercury ;)
-       - Fixed up DecipherTopic to reject null subtopics. This would, if
-         unchanged, (theoretically but not tried, luckily) produce a
-         domino-effect of problems if the topic was to be changed.
-               Update: check if the supposed null topic contains spaces
-                       within the nick component. If so, then it's not
-                       nick, therefore treat like ownerless subtopic.
-       - Worked on README.
-
-v0.3a (19990810):
-       - Changed back to use topic{chan} (now topicnow{chan}) since
-         @topiclist{chan} (now @topichist{chan}) does not deal with dupes
-         or blanks.
-       - Renamed 'topic last' in preference to 'topic reset'. Original
-         command can be used but is vague in meaning.
-       - Fixed several typos made in Irc.pl.
-       - Replaced 'defined' with 'length' in if statements.
-
-v0.3 (19990809):
-       - Applied patch from mu for Irc.pl | Topic.pl.
-       - Replaced %topic hash and $topiclast with @{$topiclist{chan}}.
-         Much cleaner implementation. Thanks to mu for this. Fully
-         implemented by xk.
-       - Reworked on topicbyme (was topiclast), should work now.
-
-v0.2 (19990808):
-       - Changed name of patch to funkystuph.
-       - Added history/last/restore to Topic.pl by request of mu and is.
-       - Reorganised help and order of commands in Topic.pl
-       - Bot must be addressed to use commands.
-               - Fixed bug if multiple infobots were in the channel.
-       - One occurrence where Cipher was called instead of CipherTopic.
-       - Fixed up Slashdot.pl. Problems: a) borked completely b) missed
-         first headline. el-cheapo fix but it works.
-
-v0.1c (19990729):
-       - Fixed long list{keys|values} bug, hopefully.
-       - Now randomize key results from search.
-       - If keys contain ',', underline to differentiate it.
-       - Fixed possible DoS against Kernel.pl.
-       - Bug fixed with Kernel.pl repeating itself.
-               - Typo of @results [one occurrance of @result]
-
-v0.1b (19990723):
-       - Fixed bug with &CipherTopic where, if no owner was found, it
-         would just use NULL. [like "Topic ()"]
-       - Added kernel feature.
-       - Moved error messages to public/private, depending on behaviour.
-         Help-related stuff is private(msg) only for convenience.
-
-v0.1a (19990721):
-       - Misc cleanup, removed repeated code.
-
-v0.1  (19990720):
-       - Initial release.
diff --git a/FAQ b/FAQ
new file mode 100644 (file)
index 0000000..f7a8dcc
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,36 @@
+# $Id$
+
+Q: The bot exits after I run 'factstats testing' or 'kernel' or anything
+   that uses fork(). Is this a bug in the bot?
+
+A: No, this is not a bug in the bot but rather Net::IRC.  A cheap hack is
+   to edit /usr/lib/perl5/Net/IRC/Connection.pm, search for DESTROY, and
+   comment out '$self->quit();'
+A: Apply the patches in the patches/ directory.
+
+
+Q: I notice that, in the bot logs, the bot attempts to close all current
+   DCC CHAT connections whenever a forked process ends. Why is this?
+
+A: Yet another bug in Net::IRC. Currently, DCC CHAT connections are not
+   closed because there is an endless-loop bug when it is done.
+
+
+Q: I executed 'scripts/setup_user.pl' but it said 'connection refused to
+   localhost'
+
+A: Looks like a bug in the installation of mysqld. You need to reload or
+   restart the daemon.
+       reload => 'mysqladmin -u root -p reload'
+       restart => '/etc/init.d/mysql stop; /etc/init.d/mysql start'
+
+Q: How do I get my bot to automatically ask for OP's from chanserv?
+
+A: By default, the "chanServCheck" option is off in _default. You can
+   set it on a per channel basis or as default. For example, the following
+   commands will enable asking for OP by default, except on #notmychannel
+
+       chanset _default chanServCheck 1
+       chanset #notmychannel chanServCheck 0
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/INSTALL b/INSTALL
index aed3621b75880b7faa382bd7c90381a7ddd1ab4c..12f1b3ea1acd5647f07a77d1dc64ac56435ffa99 100644 (file)
--- a/INSTALL
+++ b/INSTALL
-Method of installation.
------------------------
-
-- Copy files/sample/* to files/
-
-- Edit files/blootbot.config, modify to taste.
-- Edit files/blootbot.servers to modify list of IRC servers to connect.
-- Edit files/blootbot.chan to set which channels to join.
-
-- Install the following Perl modules:
-       - Net::IRC perl module
-           - Debian: (apt-get install libnet-irc-perl)
-       - WWW::Search
-           - Debian: (apt-get install libwww-search-perl)
-       - LWP
-           - Debian: (apt-get install libwww-perl)
-       - HTML::Parser
-           - Debian: (apt-get install libhtml-parser-perl)
-
-- Choose your database:
-       - MySQL, read INSTALL.mysql (supported)
-       - SQLite, read INSTALL.sqlite (supported)
-       - SQLite2, read INSTALL.sqlite (supported)
-       - PgSQL, read INSTALL.pgsql (unsupported, may work)
-
-- There are "bugs" in the perl modules.  Read INSTALL.patches on how to fix.
-
-- Finally, './blootbot'
+                           --------------------------
+                           -- General Installation --
+                           --------------------------
+
+This file contains some general guidelines for installing infobot on your
+system. At this point it is very basic, but should hopefully clear up some of
+your confusion.
+
+Configuration:
+
+    - Copy files/sample/* to files/
+
+    - Edit files/infobot.config, modify to taste.
+    - Edit files/infobot.servers to modify list of IRC servers to connect.
+    - Edit files/infobot.chan to set which channels to join.
+
+Required Perl modules:
+
+    - Net::IRC perl module
+        - Debian: (apt-get install libnet-irc-perl)
+    - WWW::Search
+        - Debian: (apt-get install libwww-search-perl)
+    - LWP
+        - Debian: (apt-get install libwww-perl)
+    - HTML::Parser
+        - Debian: (apt-get install libhtml-parser-perl)
+    - XML::Feed
+        - Debian: (apt-get install libxml-feed-perl)
+
+Choose your database:
+       - MySQL, read the section MySQL below
+       - SQLite or SQLite2, read the section SQLite below
+       - PgSQL, read the section PostgreSQL below
+
+NOTE: There are "bugs" in the perl modules.  Read the section "Patches" below, on how to fix.
+
+Finally, start your bot by changing to the base dir and type:
+
+    ./infobot
+
+
+
+                                 -------------
+                                 -- Patches --
+                                 -------------
+
+- apply *.patch patches inside patches/
+    - cd /usr/lib/perl5/WWW/Search
+    - patch -p0 < WWW::Search::Google.patch
+
+- alternatively, move the files from patches/
+    - mv patches/Google.pm /usr/lib/perl5/WWW/Search/
+
+
+Net::IRC DCC CHAT
+-----------------
+Unfortunately, Net::IRC 0.70 has buggy code that does not detect DCC CHAT
+properly. to patch:
+    - cd /usr/share/perl5/Net/IRC/
+    - cat ~bot/patches/Net_IRC_Connection_pm.patch | patch -p0
+
+
+
+
+                                ----------------
+                                -- PostgreSQL --
+                                ----------------
+
+- Debian: (apt-get install postgresql)
+- Debian: (apt-get install libpg-perl)
+
+
+As of now, infobot has full pgsql support. It seems to be working 100%, but it
+assumes that you have precreated the database and user for now. As long as you
+already created the database and user and stored this info in the
+infobot.config, then the tables will automatically be created on startup. Until
+I get setup.pl fixed, run the following commands as root (or postgres if root
+doesnt have permission to create users/db's):
+
+    > createuser --no-adduser --no-createdb --pwprompt --encrypted <user>
+    > createdb --owner=<user> <dbname> [<description>]
+
+Dont forget to replace <user> and so forth with actual values you intend to use,
+and dont include the <>'s ;) If you run these commands, you should get a user
+with an encrypted password that cannot create new db's or user's (as it should
+be!), and the user will own the newly created database <dbname>. Congrats!
+
+If everything went fine, you should have everything infobot needs to use pgsql.
+Next simply cd to the base directory you installed the bot to and type:
+
+    ./infobot
+
+
+Thats it! Everything the bot needs should be automatically created when it loads
+for the first time.
+
+In the future I will try to get around to editing the setup.pl file to ask the
+same questions it does for mysql (your root password etc) so that you can skip
+manually creating the database/user. But for now, this should be just fine for
+most of you techies out there.
+
+
+
+
+                                  -----------
+                                  -- MySQL --
+                                  -----------
+
+- Install a MySQL server and the DBI Perl modules.
+    - Debian: (apt-get install mysql-server libdbd-mysql-perl)
+
+- Run 'mysqladmin -u root -p create <DB NAME>'
+    Where <DB NAME> is the same as specified in infobot.config.
+
+- Run 'setup/setup.pl'
+    FIXME: This script is horribly broken! Do NOT use it! The bot will
+    automatically create the tables when it starts. You just need to ensure that
+    the database and the login information are correct, and start the bot.
+
+Possible problems
+-----------------
+    - if connection to localhost is (short) refused, run
+           '/etc/init.d/mysql stop'
+           '/etc/init.d/mysql start'
+    - if connection for user is refused, reload grant tables with
+           'mysqladmin -u root -p reload'
+
+* [OPTIONAL]
+    - run 'scripts/dbm2mysql.pl old-db' to convert dbm database file
+    to mysql.
+
+
+ADDITIONAL NOTES
+----------------
+You can add a new user manually by connecting to MySQL and performing these
+commands:
+
+  $ mysql -u root -p
+
+  mysql> CREATE DATABASE infobot;
+  mysql> GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'yourpassword';
+  mysql> GRANT ALL PRIVILEGES ON infobot.* TO 'user'@'localhost';
+
+FULL FACTOID DATABASE
+---------------------
+You can get the data from the MySQL database that the apt bot uses on
+#debian at freenode (irc.freenode.net), at:
+
+    http://lain.cheme.cmu.edu/~apt/infobot/apt.sql.bz2
+
+
+
+
+                                  ------------
+                                  -- SQLite --
+                                  ------------
+
+SQLite is a C library that implements an embeddable SQL database engine.
+Programs that link with the SQLite library can have SQL database access without
+running a separate RDBMS process. The distribution comes with a standalone
+command-line access program (sqlite) that can be used to administer an SQLite
+database and which serves as an example of how to use the SQLite library.
+
+infobot will create a file called <DBname>.sqlite and populate the tables for
+you if they do not already exist.
+
+- Install SQLite libraries and DBI Perl modules.
+    - Debian: (apt-get install libsqlite0 libdbd-sqlite-perl)
+
+other distros might need to build from sources.
+
+You may use either DBD::SQLite or DBD::SQLite2
+
+SQLite sources:
+
+    http://www.hwaci.com/sw/sqlite/
+
+DBD::SQLite sources:
+
+    http://search.cpan.org/author/MSERGEANT/DBD-SQLite/
+
+You will also need the normal Perl DBD stuff which should be included in your
+Perl distribution.
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/INSTALL.mysql b/INSTALL.mysql
deleted file mode 100644 (file)
index 5de7a16..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-INSTALL.mysql
-----------------
-
-- Install a MySQL server and the DBI Perl modules.
-    - Debian: (apt-get install mysql-server libdbd-mysql-perl)
-
-- Run 'mysqladmin -u root -p create <DB NAME>'
-    Where <DB NAME> is the same as specified in blootbot.config.
-
-- Run 'setup/setup.pl'
-
-= Possible problems
-    - if connection to localhost is (short) refused, run
-           '/etc/init.d/mysql stop'
-           '/etc/init.d/mysql start'
-    - if connection for user is refused, reload grant tables with
-           'mysqladmin -u root -p reload'
-
-* [OPTIONAL]
-    - run 'scripts/dbm2mysql.pl old-db' to convert dbm database file
-    to mysql.
-
-ADDITIONAL NOTES:
------------------
-You can add a new user manually by connecting to MySQL and performing these
-commands:
-
-  $ mysql -u root -p
-
-  mysql> CREATE DATABASE blootbot;
-  mysql> GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'yourpassword';
-  mysql> GRANT ALL PRIVILEGES ON blootbot.* TO 'user'@'localhost';
-
-FULL FACTOID DATABASE:
-----------------------
-You can get the data from the MySQL database that the apt bot uses on
-#debian at freenode (irc.freenode.net), at:
-
-    http://lain.cheme.cmu.edu/~apt/blootbot/apt.sql.bz2
diff --git a/INSTALL.patches b/INSTALL.patches
deleted file mode 100644 (file)
index c72294c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-INSTALL.patches
--------------------
-
-- apply *.patch patches inside patches/
-       - cd /usr/lib/perl5/WWW/Search
-         patch -p0 < WWW::Search::Google.patch
-
-- alternatively, move the files from patches/
-       - mv patches/Google.pm /usr/lib/perl5/WWW/Search/
-
-Net::IRC DCC CHAT
-----------------------
-Unfortunately, Net::IRC 0.70 has buggy code that does not detect DCC CHAT
-properly. to patch:
-       cd /usr/share/perl5/Net/IRC/
-       cat ~bot/patches/Net_IRC_Connection_pm.patch | patch -p0
diff --git a/INSTALL.pgsql b/INSTALL.pgsql
deleted file mode 100644 (file)
index 1810d5f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Method of installation.
------------------------
-
-- Debian: (apt-get install postgresql)
-- Debian: (apt-get install libpgperl)
-
-SUPPORT FOR PGSQL IS CURRENTLY BROKEN! You'll have to use one of the other
-databases instead.
diff --git a/INSTALL.sqlite b/INSTALL.sqlite
deleted file mode 100644 (file)
index 35c6b7b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-INSTALL.sqlite
-----------------
-
-SQLite is a C library that implements an embeddable SQL database engine.
-Programs that link with the SQLite library can have SQL database access without
-running a separate RDBMS process. The distribution comes with a standalone
-command-line access program (sqlite) that can be used to administer an SQLite
-database and which serves as an example of how to use the SQLite library.
-
-blootbot will create a file called <DBname>.sqlite and populate the tables for
-you if they do not already exist.
-
-- Install SQLite libraries and DBI Perl modules.
-       - Debian: (apt-get install libsqlite0 libdbd-sqlite-perl)
-
-other distros might need to build from sources.
-
-You may use either DBD::SQLite or DBD::SQLite2
-
-SQLite sources:
-
-http://www.hwaci.com/sw/sqlite/
-
-DBD::SQLite sources:
-
-http://search.cpan.org/author/MSERGEANT/DBD-SQLite/
-
-You will also need the normal Perl DBD stuff which should be included in your
-Perl distribution.
diff --git a/README b/README
index 92fc7e6d84e3d50292988f04264df866ca0ced6a..32197d3ccb47eda5e6bd496458fc6dcaadf6972f 100644 (file)
--- a/README
+++ b/README
@@ -1,20 +1,17 @@
-This is out of date.
+# $Id$
 
 
-
-
-
-
-
-blootbot v1.0.0 (20000729)
--------------------------
+                                 -------------
+                                 -- Infobot --
+                                 -------------
 
 INTRODUCTION
 
 INTRODUCTION
-       This bot is based upon infobot-0.44.2 by kevin lenzo
-<lenzo@cs.cmu.edu>. The basis of infobot is still there but _many_ wild
-features have been added. Along the way, a couple of typos were spotted
-in the original infobot source and fixed in this version. Without infobot,
-there would be no blootbot so all thanks to kevin for bringing infobot in
-the first place.
+       This bot is based upon blootbot, which was a fork of infobot-0.44.2 by
+Kevin Lenzo <lenzo@cs.cmu.edu>, which is now officially rebranded back to
+infobot!  The basis of infobot is still there but _many_ wild features have
+been added.  Along the way, many issues were spotted in the original
+infobot source and fixed in this version. Many new bugs have been added as well
+Thanks to kevin for bringing infobot in the first place.
+
 
 FEATURES
        * Additional information stored with factoids. (factinfo)
 
 FEATURES
        * Additional information stored with factoids. (factinfo)
@@ -29,17 +26,20 @@ FEATURES
        * Slashdot, Kernel and Freshmeat auto-update announcements.
        * Units conversion (provided by external module, Units-Module)
 
        * Slashdot, Kernel and Freshmeat auto-update announcements.
        * Units conversion (provided by external module, Units-Module)
 
-       DESIGN
-               - Modularity. Ability to disable IRC or Factoid support.
-               - Funky pseudo Module autoloader support
-               - Eleet Forker() function
 
 
-Improvements include:
+DESIGN
+       - Modularity. Ability to disable IRC or Factoid support.
+       - Funky pseudo Module autoloader support
+       - Eleet Forker() function
+
+
+IMPROVEMENTS
        * log file is not opened and closed for each line of data
                => unblocked logging is used.
        * seen data is not flushed for each public message on IRC
                => caching and flushing over an interval is used.
 
        * log file is not opened and closed for each line of data
                => unblocked logging is used.
        * seen data is not flushed for each public message on IRC
                => caching and flushing over an interval is used.
 
+
 HISTORY
        As of 0.99pre1, blootbot supports mysql database in the hope to
 increase performance and to avoid borked over dbm's which occurred when
 HISTORY
        As of 0.99pre1, blootbot supports mysql database in the hope to
 increase performance and to avoid borked over dbm's which occurred when
@@ -56,9 +56,13 @@ back. It should work in all but 3 specific (countdown, factstats unreq)
 cases. preliminary pgsql support has been added but someone with pgperl
 knowledge needs to fix it up or at least unify the module with mysql.
 
 cases. preliminary pgsql support has been added but someone with pgperl
 knowledge needs to fix it up or at least unify the module with mysql.
 
+       As of 1.5.0, blootbot was rebranded back to infobot.
+
+
 INSTALLATION
   - Read the included INSTALL file
 
 INSTALLATION
   - Read the included INSTALL file
 
+
 NOTICE
        Be warned that this bot consumes quite a lot of memory upon start
 up and during usage. Right now, 7.4megs is used for old'ish perl, 8.3megs
 NOTICE
        Be warned that this bot consumes quite a lot of memory upon start
 up and during usage. Right now, 7.4megs is used for old'ish perl, 8.3megs
@@ -77,6 +81,7 @@ welcomed.
 blootbot, not based on the above source base.  Core factoid code and
 mysql support works - but that is it.
 
 blootbot, not based on the above source base.  Core factoid code and
 mysql support works - but that is it.
 
+
 MODIFICATIONS
        All modifications are that of the blootbot author unless otherwise
 specified, like none.  See 'ChangeLog' for details.  A list of future
 MODIFICATIONS
        All modifications are that of the blootbot author unless otherwise
 specified, like none.  See 'ChangeLog' for details.  A list of future
@@ -119,7 +124,8 @@ NOTES
 through DCC CHAT. /chat <BOT NICK>.  All commands must be prepended by
 '.' otherwise it is sent to the bot chat net
 
 through DCC CHAT. /chat <BOT NICK>.  All commands must be prepended by
 '.' otherwise it is sent to the bot chat net
 
-### UNTESTED:
+
+UNTESTED:
        - user statistics shown by 'seen'. bug in this?
        - User Information Services.
        - new wingate caching/file-read code.
        - user statistics shown by 'seen'. bug in this?
        - User Information Services.
        - new wingate caching/file-read code.
@@ -145,7 +151,15 @@ hope to get that same guy to re-send me the patch...
 
 CONTACT
        Contributions of a patch, or anything, can be sent to
 
 CONTACT
        Contributions of a patch, or anything, can be sent to
-<dms@users.sourceforge.net>
+<infobot-devel@lists.sourceforge.net>
 
 Some Documentation is on the website. Please see it for details or
 
 Some Documentation is on the website. Please see it for details or
-visit: http://sourceforge.net/docman/?group_id=8794
+visit: http://infobot.sourceforge.net/
+
+
+IRC
+       If your looking to hang out on IRC, feel free. We can be found
+in the #infobot channel on irc.freenode.net. See you there!
+
+
+# vim:ts=4:sw=4:expandtab:tw=80
index c17c34de52bf433fc4c66fcc2ce757a61f47aef9..6ffa1a2817779f78897c6eddc6d926f111f542e5 100644 (file)
@@ -12,3 +12,6 @@ DCC CHAT:
 
 for list of configuration options, run:
        perl scripts/findparam.pl
 
 for list of configuration options, run:
        perl scripts/findparam.pl
+
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/THANKS b/THANKS
new file mode 100644 (file)
index 0000000..20cb949
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,32 @@
+# $Id$
+
+                                  ------------
+                                  -- THANKS --
+                                  ------------
+
+Over time, many people have helped us out with the project. Some have helped on
+IRC with suggestions, ideas, bug fixes. Some still with bug reports, complaints
+and feedback. Below is a list of those people that have contributed in one way
+other another, or people who we feel we owe thanks to in one way or another.
+
+If we missed you from this list, drop us a line and we will be sure to give
+credit where it is due.
+
+
+#perl@freenode.net
+------------------
+Somni
+apeiron
+sili
+f00li5h
+Caelum
+anno-
+mst
+dngor
+PerlJam
+Limbic_Region
+mmap__
+jagerman
+
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/TODO b/TODO
index b3ddccc00a3e4b710a005a3c1b91d84e1b816a39..579c6c34afc11436a09ed37547f5593f33076268 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,6 @@
 TODO:
 TODO:
-       - let's get a release out!
+       - Normalize the SQL tables a little better to reduce size and increase speed
+       - Keep the Changelog, TODO and BUGS files up to date. Clean things up a bit
        - rename ^[+-] commands
        - remind - like this and others: http://jibble.org/reminderbot/
        - kill SHM and and move to a pipe
        - rename ^[+-] commands
        - remind - like this and others: http://jibble.org/reminderbot/
        - kill SHM and and move to a pipe
@@ -8,8 +9,8 @@ TODO:
        - move nicks/server into sql table
        - make channel flags be server/channel flags
        - move channel flags to sql table, include initial state
        - move nicks/server into sql table
        - make channel flags be server/channel flags
        - move channel flags to sql table, include initial state
-       - move praise from blootbot.lang to "praise:<something>" in factoids?
-       - move lart from blootbot.lang to "lart:<something>" in factoids?
+       - move praise from infobot.lang to "praise:<something>" in factoids?
+       - move lart from infobot.lang to "lart:<something>" in factoids?
        - debian BTS frontend "bugs"
        - !country
        - !dinstall
        - debian BTS frontend "bugs"
        - !country
        - !dinstall
@@ -43,7 +44,7 @@ TODO:
 
 Other TODO items may be listed on sourceforge. Please access it from the
 website or this link:
 
 Other TODO items may be listed on sourceforge. Please access it from the
 website or this link:
-http://sourceforge.net/pm/task.php?group_id=8794&group_project_id=3207&func=browse&set=open
+http://sourceforge.net/pm/task.php?group_id=2241
 
 ----------------------------------------------------
 ------------ FUTURE, NON-IMPORTANT
 
 ----------------------------------------------------
 ------------ FUTURE, NON-IMPORTANT
@@ -72,26 +73,5 @@ http://sourceforge.net/pm/task.php?group_id=8794&group_project_id=3207&func=brow
                - do some test cases to confirm code actually works as
                  proposed.
 
                - do some test cases to confirm code actually works as
                  proposed.
 
--- useless statistics
-- 20010420:
-DEBUG:      373
-WARN:       129
-FIXME:       35
-status:     386
-TODO:       145
 
 
-20031111: scripts/output_stats.sh
-DEBUG:      384
-WARN:       167
-FIXME:       33
-status:     424
-ERROR:      123
-TODO:        91
-
-20050217: scripts/output_stats.sh
-DEBUG:  388
-WARN:   164
-FIXME:  43
-status: 436
-ERROR:  125
-TODO:   158
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/VERSION b/VERSION
new file mode 100644 (file)
index 0000000..bc80560
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.5.0
diff --git a/blootbot b/blootbot
deleted file mode 100755 (executable)
index a888ed2..0000000
--- a/blootbot
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/perl
-
-# infobot  -- copyright kevin lenzo (c) 1997-1999
-# blootbot -- copyright david sobon (c) 1999-infinity
-
-use strict;
-use vars qw($bot_base_dir $bot_src_dir $bot_misc_dir $bot_state_dir
-           $bot_data_dir $bot_config_dir $bot_log_dir $bot_run_dir
-           $bot_pid $memusage %param
-);
-
-BEGIN {
-    if (@ARGV and -f $ARGV[0]) {
-       # source passed config to allow $bot_*_dir to be set.
-       do $ARGV[0];
-    }
-
-    # set any $bot_*_dir var's that aren't already set
-    $bot_base_dir      ||= '.';
-    $bot_config_dir    ||= 'files/';
-    $bot_data_dir      ||= 'files/';
-    $bot_state_dir     ||= 'files/';
-    $bot_run_dir       ||= '.';
-    $bot_src_dir       ||= "$bot_base_dir/src";
-    $bot_log_dir       ||= "$bot_base_dir/log";
-    $bot_misc_dir      ||= "$bot_base_dir/files";
-
-    $bot_pid           = $$;
-
-    unshift @INC,"$bot_src_dir","$bot_src_dir/Modules";
-
-    require "$bot_src_dir/logger.pl";
-    require "$bot_src_dir/core.pl";
-    require "$bot_src_dir/modules.pl";
-
-    # load the configuration (params) file.
-    &setupConfig();
-
-    &showProc();       # to get the first value.
-    &status("Initial memory usage: $memusage kB");
-    &loadCoreModules();
-    &loadDBModules();
-    &loadFactoidsModules();
-    &loadIRCModules();
-
-    &status("Memory usage after loading modules: $memusage kB");
-}
-
-# prevent duplicate processes of the same bot
-&duperuncheck();
-
-# initialize everything
-&startup();    # first time initialization.
-&setup();
-
-if (!&IsParam("Interface") or $param{'Interface'} =~ /IRC/) {
-    # launch the irc event loop
-    &ircloop();
-} else {
-    &cliloop();
-}
-
-exit 0;  # just so you don't look farther down in this file :)
-
-# --- support routines
-
-# FIXME: add arguments, basically '-h' and '--help', heh.
-
-# added by the xk
-sub duperuncheck {
-    my $pid    = $$;
-    my $file   = $file{PID};
-
-    if ( -f $file) {
-       open(PIDFILE,$file) or die "error: cannot open $file.";
-       my $thispid = <PIDFILE> || "NULL\n";
-       close PIDFILE;
-       chop $thispid;
-
-       if ($thispid =~ /^\D$/) {
-           &staus("warning: pidfile is invalid; wiping out.");
-       } else {
-           if ( -d "/proc/$thispid/") {
-               &ERROR("bot is already running from this directory.");
-               &ERROR("if this is incorrect, erase '*.pid'.");
-               &ERROR("verify with 'ps -axu | grep $thispid'.");
-               exit 1;
-           } else {
-               &status("warning: stale $file found; wiping.");
-           }
-       }
-    }
-
-    open(PIDFILE,">$file") or die "error: cannot write to $file.";
-    print PIDFILE "$pid\n";
-    close PIDFILE;
-
-    return 0;
-}
-
-1;
diff --git a/doc/USAGE b/doc/USAGE
new file mode 100644 (file)
index 0000000..23786fe
--- /dev/null
+++ b/doc/USAGE
@@ -0,0 +1,782 @@
+# $Id$
+
+############
+# EXAMPLES #
+############
+
+DCC CHAT:
+.+chan #chan
+.chanset #chan +autojoin
+.chanset +autojoin
+.chanunset -autojoin
+.chanset -autojoin
+
+for list of configuration options, run:
+        ./scripts/findparam.pl
+
+
+=====
+<me> infobot: hex2ip aaBBcD12
+<infobot> me: AABBCD12 = 170.187.205.18 
+
+<me> infobot: test is testing
+<infobot> me: okay
+<me> infobot: testing?
+<infobot> testing is testing
+
+<me> infobot: tests is <REPLY> testing
+<infobot> me: okay
+<me> infobot: tests?
+<infobot> testing
+
+<me> infobot: cough is <ACTION> coughs
+<infobot> me: okay
+<me> infobot: cough
+* infobot/#infobot coughs
+
+<me> infobot: test is <REPLY> What's (one|two|three|four|five|six)
+       times (seven|eight|nine|ten|eleven|twelve)?
+<infobot> okay, me
+<me> infobot: test
+<infobot> What's four times nine?
+<me> infobot: test?
+<infobot> What's six times ten?
+
+<me> infobot: op me is <ACTION> Mode change "+o $nick" on channel
+       $channel by $ident
+<infobot> me: okay
+<me> infobot: op me
+* infobot/#debian-bots Mode change "+o me" on channel #infobot by
+       infobot
+
+<me> infobot: no who am i is <REPLY> You are $nick!$user@$host on
+       $channel.
+<infobot> okay, me
+<me> infobot: who am i
+<infobot> You are me!me@home.org on #infobot.
+
+<me> infobot: who last spoke is <REPLY> To my knowledge, $lastspeaker
+       was the last to say something worthwhile.
+<infobot> me: okay
+<me> infobot: who last spoke
+<infobot> To my knowledge, me was the last to say something worthwhile.
+
+<me> infobot: percentage is <REPLY> you are $randpercentage% lame
+<infobot> me: okay
+<me> infobot: percentage
+<infobot> you are 79% lame
+
+<me> infobot: slap $1 is <action> slaps $1
+<infobot> me: okay, me
+<me> infobot: slap Bob
+ * infobot slaps Bob
+<me> infobot: forget cmd: slap (.*?)
+<infobot> me: i forgot cmd: slap (.*?)
+
+
+#################
+# USER COMMANDS #
+#################
+
+Command: 4op
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       4op ...
+
+Example:
+       ...
+
+
+Command: dumpvars
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       dumpvars ...
+
+Example:
+       ...
+
+
+Command: kick
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       kick ...
+
+Example:
+       ...
+
+
+Command: ignore
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       ignore ...
+
+Example:
+       ...
+
+
+Command: ignorelist
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       ignorelist ...
+
+Example:
+       ...
+
+
+Command: unignore
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       unignore ...
+
+Example:
+       ...
+
+
+Command: clear ignorelist
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       clear ignorelist ...
+
+Example:
+       ...
+
+
+Command: lobotomy
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       lobotomy ...
+
+Example:
+       ...
+
+
+Command: unlobotomy
+=============
+Description:
+       ...
+
+Usage:
+       unlobotomy ...
+
+Example:
+       ...
+
+
+Command: op
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       op ...
+
+Example:
+       ...
+
+
+Command: say
+=============
+Description:
+       ...
+
+Usage: REQUIRES +o flag.
+       say ...
+
+Example:
+       ...
+
+
+Command: die
+=============
+Description:
+       ...
+
+Usage: REQUIRES +n flag.
+       die ...
+
+Example:
+       ...
+
+
+Command: jump
+=============
+Description:
+       ...
+
+Usage: REQUIRES +n flag.
+       jump ...
+
+Example:
+       ...
+
+
+Command: rehash
+=============
+Description:
+       ...
+
+Usage: REQUIRES +n flag.
+       rehash ...
+
+Example:
+       ...
+
+
+Command: set
+=============
+Description:
+       ...
+
+Usage: REQUIRES +n flag.
+       set ...
+
+Example:
+       ...
+
+
+Command: unset
+=============
+Description:
+       ...
+
+Usage: REQUIRES +n flag.
+       unset ...
+
+Example:
+       ...
+
+
+Command: chanstats
+=============
+Description:
+       Channel statistics is gathered while the bot is operation in those
+       channels it is located. They include: join, part, kick, ban, and
+       countless others.
+
+Usage:
+       chanstats [#channel]
+
+Example:
+       > infobot: chanstats
+       <infobot> i am on 2 channels: #infobot #debian
+       <infobot> i've cached 5 users distributed over 2 channels.      
+
+       > infobot: chanstats #infobot
+       <infobot> On #infobot, there have been 1 Join, 1 Op and 20
+               PublicMsgs.
+       <infobot> At the moment, 3 Opped and 3 Total.
+
+
+Command: cmdstats
+=============
+Description:
+       ...
+
+Usage:
+       cmdstats ...
+
+Example:
+       ...
+
+
+Command: crypt
+=============
+Description:
+       ...
+
+Usage:
+       crypt ...
+
+Example:
+       ...
+
+
+Command: factinfo
+=============
+Description:
+       ...
+
+Usage:
+       factinfo ...
+
+Example:
+       ...
+
+
+Command: factstats
+=============
+Description:
+       ...
+
+Usage:
+       factstats ...
+
+Example:
+       ...
+
+
+Command: karma
+=============
+Description:
+       ...
+
+Usage:
+       karma ...
+
+Example:
+       ...
+
+
+Command: spell
+=============
+Description:
+       ...
+
+Usage:
+       spell ...
+
+Example:
+       ...
+
+
+Command: nslookup
+=============
+Description:
+       ...
+
+Usage:
+       nslookup ...
+
+Example:
+       ...
+
+
+Command: part
+=============
+Description:
+       ...
+
+Usage:
+       part ...
+
+Example:
+       ...
+
+
+Command: rot13
+=============
+Description:
+       ...
+
+Usage:
+       rot13 ...
+
+Example:
+       ...
+
+
+Command: wantNick
+=============
+Description:
+       ...
+
+Usage:
+       wantNick ...
+
+Example:
+       ...
+
+
+Command: join
+=============
+Description:
+       The bot can be commanded to join a channel if it is not already on
+       there in the case of a kick/ban, invite only or invalid key to
+       name a few typical case scenarios.
+
+       The channels which the bot can join is governed by the
+       configuration parameter labelled 'join_channels'. However, this
+       is ignored for those users with the +o flag in the user table.
+
+Usage:
+       join <#channel>[,key]
+
+Example:
+       > infobot: join #infobot
+       [infobot] joining #infobot
+       *** join/#debian infobot (xk@router.home.org)
+       > infobot: join #infobot
+       [infobot] I'm already on #infobot...
+
+
+
+                    ======================================
+                               MODULE COMMANDS
+                    ======================================
+
+Command: babelfish
+=============
+Description:
+       ...
+
+Usage:
+       x from [language]: phrase
+
+Example:
+       ...
+
+
+Command: debian package
+=============
+Description:
+       ...
+
+Usage:
+       [] ...
+
+Example:
+       ...
+
+
+Command: dict
+=============
+Description:
+       ...
+
+Usage:
+       dict ...
+
+Example:
+       ...
+
+
+Command: freshmeat
+=============
+Description:
+       ...
+
+Usage:
+       freshmeat ...
+
+Example:
+       ...
+
+
+Command: google
+=============
+Description:
+       ...
+
+Usage:
+       google ...
+
+Example: DOES NOT WORK YET(??)
+       ...
+
+
+Command: insult
+=============
+Description:
+       ...
+
+Usage:
+       insult ...
+
+Example:
+       ...
+
+
+Command: kernel
+=============
+Description:
+       ...
+
+Usage:
+       kernel ...
+
+Example:
+       ...
+
+
+Command: lart
+=============
+Description:
+       ...
+
+Usage:
+       lart ...
+
+Example:
+       ...
+
+
+Command: list{keys|vals}
+=============
+Description:
+       ...
+
+Usage:
+       list{keys|vals} ...
+
+Example:
+       ...
+
+
+Command: nickometer
+=============
+Description:
+       ...
+
+Usage:
+       nickometer ...
+
+Example:
+       ...
+
+
+Command: quotes
+=============
+Description:
+       ...
+
+Usage:
+       quotes ...
+
+Example:
+       ...
+
+
+Command: rootwarn
+=============
+Description:
+       ...
+
+Usage:
+       rootwarn ...
+
+Example:
+       ...
+
+
+Command: seen
+=============
+Description:
+       ...
+
+Usage:
+       seen ...
+
+Example:
+       ...
+
+
+Command: listauth
+=============
+Description:
+       ...
+
+Usage:
+       listauth ...
+
+Example:
+       ...
+
+
+Command: slashdot
+=============
+Description:
+       ...
+
+Usage:
+       slashdot ...
+
+Example:
+       ...
+
+
+Command: debian contents
+=============
+Description:
+       ...
+
+Usage:
+       debian ...
+
+Example:
+       ...
+
+
+Command: topic
+=============
+Description:
+       ...
+
+Usage:
+       topic ...
+
+Example:
+       ...
+
+
+Command: countdown
+=============
+Description:
+       ...
+
+Usage:
+       countdown ...
+
+Example:
+       ...
+
+
+Command: uptime
+=============
+Description:
+       ...
+
+Usage:
+       uptime ...
+
+Example:
+       ...
+
+
+Command: weather
+=============
+Description:
+       ...
+
+Usage:
+       weather ...
+
+Example: DOES NOT WORK
+       ...
+
+
+Command: whatis
+=============
+Description:
+       ...
+
+Usage:
+       whatis ...
+
+Example: DOES NOT WORK
+       ...
+
+
+
+##################################
+# MISCELLANEOUS/FACTOID COMMANDS #
+##################################
+
+Command: forget
+=============
+Description:
+       ...
+
+Usage:
+       forget ...
+
+Example:
+       ...
+
+
+Command: {un|}lock
+=============
+Description:
+       ...
+
+Usage:
+       {un|}lock ...
+
+Example:
+       ...
+
+
+Command: rename
+=============
+Description:
+       ...
+
+Usage:
+       rename ...
+
+Example:
+       ...
+
+
+Command: substitution
+=============
+Description:
+       ...
+
+Usage:
+       $factoid =~ s/from/to/
+       $factoid =~ s#te/st/#test#g
+
+Example:
+       ...
+
+
+Command: karma set
+=============
+Description:
+       ...
+
+Usage:
+       $nick++
+       $nick--
+
+Example:
+       infobot++
+       infobot--
+
+
+Command: maths
+=============
+Description:
+       ...
+
+Usage:
+       2 + 2
+
+Example:
+       ...
+
+
+Command: tell
+=============
+Description:
+       ...
+
+Usage:
+       tell <nick> about <factoid>
+
+Example:
+       ...
diff --git a/doc/infobot.config.pod b/doc/infobot.config.pod
new file mode 100644 (file)
index 0000000..584bba7
--- /dev/null
@@ -0,0 +1,455 @@
+=pod
+
+=head1 NAME
+
+infobot.config - Main infobot configuration file
+
+=head1 SYNOPSIS
+
+B<set> E<lt>B<variable>E<gt> E<lt>B<value>E<gt>
+
+=head1 DESCRIPTION
+
+This file is the main configuration file for your bot. Empty lines are ignored
+as usual, and any lines which start with a C<#> are treated as comments.
+
+When you first setup your infobot, you should start by copying the sample file,
+found in S<F</path/to/bot/files/sample/infobot.config>> to the
+S<F</path/to/bot/files>> directory. Once this is done, start up your favorite
+editor and carefully go over the settings one by one, before you attempt to
+start your bot.
+
+Fields that are commented out by default, are typically not needed. Use your
+own judgement.
+
+=head1 OPTIONS
+
+Below is a list of the variables that infobot currently recognises, along with
+a short blurb about each.
+
+=head2 Basic IRC info
+
+=over
+
+=item B<set ircNick> E<lt>B<nick>E<gt>
+
+The name that you want your infobot to appear as on B<IRC>.
+
+=item B<set ircUser> E<lt>B<user>E<gt>
+
+The ident reply that you want your infobot to send if you don't already have a
+running ident daemon on your system.
+
+=item B<set ircName> E<lt>B<description of your bot>E<gt>
+
+This sets the name that appears as "Real Name" when someone does a C</WHOIS> on
+your infobot's nick on B<IRC>.
+
+=item B<set ircPasswd> E<lt>B<your_password>E<gt>
+
+If this variable is set, then the server will send it when connecting to the
+B<IRC> server. Most networks only use this for server administrators to gain
+their operator status. However, B<Freenode> (B<http://www.freenode.net/>) uses
+this server password to identify you automatically to nickserv on connect.
+
+=item B<set ircUMode> E<lt>B<+>|B<->E<gt>E<lt>B<modes>E<gt>[E<lt>B<+>|B<->E<gt>E<lt>B<modes>E<gt>...]
+
+This is a list of user modes that the infobot should attempt to set after it
+has established a connection with the B<IRC> server.
+
+=item B<set ircHost> E<lt>B<ip address>|B<dns name>E<gt>
+
+Typically this setting isn't used. However, if you have a muti-homed server
+(multiple network cards), and you don't want your bot to use the default route
+out of the network, you can set this to the B<IP Address> or B<hostname> of the
+interface that you want it to use when connecting to B<IRC>.
+
+=item B<set owner> E<lt>B<owners_user_name>E<gt>
+
+Set this to the nick that matches the name of the account that you set in the
+F<infobot.users> file for yourself.
+
+I<FIXME: Does this actually do anything yet?>
+
+=item B<set nickServ_pass> E<lt>B<password>E<gt>
+
+If the server your bot is connecting to supports nick services, you can set the
+password here that will be used to identify itself with.
+
+=item B<set quitMsg> E<lt>B<quit message>E<gt>
+
+When your bot intentionally disconnects from a server, it will display the
+following quit reason to users who see it quit.
+
+I<Note: some servers can optionally, or forcefully, hide this message>
+
+=item B<set tempDir> E<lt>B</path/to/directory>E<gt>
+
+This sets a path to a temporary directory which infobot can use. Most people
+find this best set to F</tmp>.
+
+=back
+
+=head2 Factoid database configuration
+
+=over
+
+=item B<set DBType> E<lt>B<none>|B<mysql>|B<SQLite>|B<SQLite2>|B<pgsql>E<gt>
+
+If you have enabled factoid support, this setting will control the backend
+database that you use to save factoids and other various information.
+
+If you choose SQLite or SQLite2, you will need to ensure that you have
+installed S<libdbd-sqlite-perl> on your system. Also, SQLite will support a
+version 2 or 3 of the library, where as SQLite2 will force the bot to use
+version 2 specifically.
+
+I<FIXME: Does C<none> type actually work without breaking non factoid related>
+I<db saves?>
+
+=item B<set DBName> E<lt>B<DB name>|B</path/to/store/sqlite>E<gt>
+
+If you have database support enabled, this setting will tell the bot what
+database it should use. If you are using SQLite, it should be set to the
+directory where you want to store the database files on disk.
+
+I<FIXME: Is this a file or a directory?>
+
+=item B<set SQLHost> E<lt>B<hostname>|B<IP address>E<gt>
+
+If you are using a database, this specifies the name of the host that the
+database resides on. If you are using SQLite, this value should be commented
+out.
+
+I<FIXME: If using SQLite, does it need to be commented out, or is it ignored?>
+
+=item B<set SQLUser> E<lt>B<username>E<gt>
+
+If you are using a database, this specifies the user name that the bot should
+use to login with. If you are using SQLite, this value should be commented out.
+
+I<FIXME: If using SQLite, does it need to be commented out, or is it ignored?>
+
+=item B<set SQLPass> E<lt>B<password>E<gt>
+
+If you are using a database, this specifies the password that the bot should
+use to login with. If you are using SQLite, this value should be commented out.
+
+I<FIXME: If using SQLite, does it need to be commented out, or is it ignored?>
+
+=item B<set SQLDebug> E<lt>B<filename>E<gt>
+
+If you are using a database, this specifies the filename that you wish to log
+all B<SQL> commands to. On some platforms, you may be able to use a "-" to
+specify B<stdout> so that it displays on the console instead.
+
+=back
+
+=head2 Logfile configuration
+
+These settings control the various aspects of how the bot logs the console.
+
+=over
+
+=item B<set logfile> E<lt>B<directory>|B<filename>E<gt>
+
+This setting tells the bot where to log everything you see on the console
+screen.  You can optionally use a variable such as B<$ircUser> in the filename
+if you want to name the logs after the name of the bot. If this setting is left
+out, logging is disabled.
+
+I<FIXME: What if it is a directory?>
+
+=item B<set logType> E<lt>B<DAILY>|B<DEFAULTE><gt>
+
+If you have enabled logging, this setting will determine if the log file should
+be rotated on a daily basis, or use on continuous file.
+
+I<FIXME: What happens if it is unset?>
+
+=item B<set maxLogSize> E<lt>B<max size in bytes>E<gt>
+
+If you have enabled logging, this setting will determine the maximum size of
+the log file. The size should be specified in bytes. A reasonable size is
+10000000 (10MB).
+
+I<FIXME: What happens when the maximum is reached? What if its unset?>
+
+=back
+
+=head2 Factoid-related configuration
+
+These settings govern how factoids are managed.
+
+=over
+
+=item B<set factoids> E<lt>B<true>|B<false>E<gt>
+
+This is a boolean value that decides if you want factoid support enabled for
+your bot. Typically you want you leave this enabled.
+
+=item B<set factoidDeleteDelay> E<lt>B<number of days>E<gt>
+
+When you delete a factoid, it isn't immediately removed. Instead, the factoid
+key is renamed with a "#DEL#" appended to it. This allows you to undelete
+factoids that were erased by accident.
+
+If you have factoid support enabled, this setting will determine how long
+deleted factoids stay in the database before they are automatically purged. A
+value of B<0> will disable auto purging of deleted factoids.
+
+=item B<set maxKeySize> E<lt>B<integer>E<gt>
+
+If you have factoid support enabled, this value determines the maximum length
+of the factoid key.
+
+=item B<set maxDataSize> E<lt>B<number of bytes>E<gt>
+
+If you have factoid support enabled, this value determines the maximum length
+of the value for a factoid key.
+
+=item B<set learn> E<lt>B<ADDRESSED>|B<HUNGRY>E<gt>
+
+If you have factoid support enabled, this value determines how the bot reacts
+to public chatter.
+
+In B<ADDRESSED> mode, the bot will only learn the factoid if you address it
+specifically by name S<(eg: Botname: ...)>, or by B<!trigger>. This is the
+recommended mode.
+
+In B<HUNGRY> mode, the bot will take assuming everything said is an attempt to
+talk with the bot. This includes things like welcoming you when you say thanks
+and other various spam. This will also tend to catch useless garbage in your
+database since the word "is" will be recognised as an attempt to teach it a new
+factoid. Use at your own risk. ;)
+
+=item B<set acceptUrl> E<lt>B<REQUIRE>|B<OPTIONAL>|B<REJECT>E<gt>
+
+The bot has the ability to recognize B<URL>'s. This setting will control what
+it accepts as a B<URL>.
+
+In B<REQUIRE> mode, the bot will need the protocol to be specifically mentioned
+for it to be considered (eg: file://, http://).
+
+In B<OPTIONAL> mode, the bot will accept just about anything.
+
+In B<REJECT> mode, the bot will not accept any B<URL>'s. This makes it easy to
+run with different nicks and styles.
+
+I<FIXME: What is the point of REJECT?>
+
+=item B<set profanityCheck> E<lt>B<true>|B<false>E<gt>
+
+This determines if the bot should accept or reject factoids which contain foul
+language.
+
+=item B<set allowTelling> E<lt>B<true>|B<false>E<gt>
+
+The the has the ability for people to ask the bot to tell someone else about
+one of its factoids. This setting controls if that is allowed or not.
+
+=item B<set friendlyBots> [B<botname> [B<bot2> ... B<botN>]]
+
+An infobot has a built in protocol which allows them to communicate with each
+other. If a user asks your bot for a factoid that doesnt exist, the bot will
+attempt to ask each bot in this space seperated list for it.  If one of the
+bots has an answer, your bot will save it to its database, and tell it to the
+person who requested it.
+
+I<NOTE: Many bots are set to require that your bot be in a channel with it>
+I<before they will allow your bot to talk to it.>
+
+=back
+
+=head2 Factoid related and unrelated features, mainly Extras.
+
+These settings are basically stuff that doesn't fit anywhere else.
+
+=over
+
+=item B<set addressing> E<lt>B<REQUIRE>|B<OPTIONAL>E<gt>
+
+This setting controls how your bot responds (not related to learning factoids)
+to people saying stuff in a channel. With B<REQUIRE>, the bot will only say
+something if it is addressed (via nick or trigger). With B<OPTIONAL>, the bot
+will respong (not learn) irrelevent of addressing.
+
+=item B<set talkMethod> E<lt>B<PRIVATE>|B<DEFAULT>E<gt>
+
+This setting controls how the bot should send messages. With B<PRIVATE>, the
+bot will reply to private messages only, rejecting public messags. With
+B<DEFAULT>, the bot will reply to publid and private queries.
+
+=item B<set minLengthBeforePrivate> E<lt>B<integer>E<gt>
+
+This will determine how long the output string of a reply should be before it
+is changed from public response, to a private message. A value of B<192> is
+recommended. You can disable this feature by commenting out the setting.
+
+=item B<set disallowOutsiders> E<lt>B<true>|B<false>E<gt>
+
+This setting, if enabled, will allow people outside and channels that your bot
+is on to use the bot.
+
+=item B<set ignoreAutoExpire> E<lt>B<minutes>E<gt>
+
+This setting controls the amount of time for auto-ignore (flooding) to expire.
+
+=item B<set ignoreTempExpire> E<lt>B<minutes>E<gt>
+
+This controls the amount of time for forced-online ignore to expire in minutes.
+
+=back
+
+=head2 Internal (simple) bot commands
+
+=over
+
+=item B<set forking> E<lt>B<true>|B<false>E<gt>
+
+The controls forking in the bot. This should be disabled for non-nix operating
+systems, or to reduce memory usage. Disabling should also make the bot work on
+Win32 and MacOS.
+
+=item B<set backlog> E<lt>B<number lines>E<gt>
+
+This controls the maximum number of lines to use for a backlog buffer on the
+console.  Fairly handy for looking back a page or two to see what the bot is
+doing. Typically not needed when used with screen sessions.
+
+=back
+
+=head2 Extra features
+
+=over
+
+=item B<set httpProxy> E<lt>B<http://HOSTNAME:PORT/>E<gt>
+
+This proxy is used for any module in the bot which requires LWP + http proxy.
+
+=item B<set countdown> E<lt>B<true>|B<false>E<gt>
+
+This determines if the bot should use the countdown file to remember and
+announce special dates.
+
+=item B<set Debian> E<lt>B<true>|B<false>E<gt>
+
+This setting controls the Debian module for file and package searching. If it
+is enabled, users of the bot will be allowed to search, otherwise it will be
+completly disabled.
+
+=item B<set freshmeat> E<lt>B<true>|B<false>E<gt>
+
+The bot has the ability to search B<freshmeat.net> for packages. This setting
+controls if that is enabled or not.
+
+=item B<set freshmeatRefreshInterval> E<lt>B<hours>E<gt>
+
+If the B<freshmeat.net> search is enabled, this setting will control how often
+the bot should update the index in hours.
+
+=item B<set freshmeatForFactoid> E<lt>B<true>|B<false>E<gt>
+
+If B<freshmeat.net> is enabled as well as this setting, the bot will search
+freshmeat for factoids which do not exist.
+
+=item B<set Uptime> E<lt>B<true>|B<false>E<gt>
+
+This controls if the bot should store uptime records or not.
+
+=item B<set rssFeedTime E<lt>minutesE<gt>>
+
+Should you decide to use the RSS Feed module, this setting controls how often
+the feeds for all channels will be polled.
+
+=back
+
+=head2 Miscellaneous configuration options
+
+=over
+
+=item B<set VERBOSITY> E<lt>B<0>|B<1>|B<2>E<gt>
+
+Controls how verbose the console output should be. A setting of B<0> will
+disable verbosity. A setting of B<1> will give standard information. And a
+setting of B<2> will give you extra information.
+
+=item B<set WARN> E<lt>B<true>|B<false>E<gt>
+
+This setting controls if the bot console will display warning messages or not.
+
+=item B<set DEBUG> E<lt>B<true>|B<false>E<gt>
+
+If the bot console should display debugging messages or not.
+
+=item B<set WIP> E<lt>B<true>|B<false>E<gt>
+
+If the bot should activate work in progress (experimental) features.
+
+I<FIXME: Likely to be removed.>
+
+=item B<set useStrict> E<lt>B<true>|B<false>E<gt>
+
+This setting controls if the bot should "use strict" in its code. Handy to have
+enabled for catching problems in the code. Best leave this enabled.
+
+=item B<set Interface> E<lt>B<IRC>|B<CLI>E<gt>
+
+This controls the interface that the bot should use. Most people will want to
+use B<IRC> which connects the bot to an IRC server. Optionally, you can setup a
+standalone bot by setting this to B<CLI>. In B<CLI> mode, the bot will not
+connect to a server, but instead allow you to use it on the console as if it
+were being used in a private message on IRC.
+
+=item B<set topicAuthor> E<lt>B<true>|B<false>E<gt>
+
+This setting controls how the bot adds topic's in a channel. If enabled, topics
+managed with !topic add foo, will show the nick of the person who set it with
+the format: "foobar (nick)" in ()'s. If it is disabled, only the topic will be
+added, not the creator.
+
+=back
+
+=head2 Debugging
+
+=over
+
+=item B<set DumpVars> E<lt>B<true>|B<false>E<gt>
+
+If the bot should dump its variables or not.
+
+=item B<set dumpvarsAtExit> E<lt>B<true>|B<false>E<gt>
+
+If the bot should dump its variables when it shuts down.
+
+=item B<set dumpvarsLogFile> E<lt>B<filename.log>E<gt>
+
+If the dumped variables should go to a sepcific log file.
+
+=item B<set DumpVars2> E<lt>B<true>|B<false>E<gt>
+
+If the bot should dump extra variables.
+
+=item B<set symdumpLogFile> E<lt>B<filename.log>E<gt>
+
+The file the extra variables should be dumped to.
+
+=back
+
+=head1 BUGS
+
+There is a lot of upper/lower case issues with some of the variables. It is not
+know if and or all of them are case sensitive. Also, Many of the original
+settings ask for "[0|1]", and depending on how the code is written, a B<TRUE>
+or B<FALSE> may not work for certain variables. This is considered a B<BUG>,
+and should be reported as such.
+
+=head1 CONTACT
+
+If you need to contact us to submit patches or whatever, please try out mailing
+list available at S<B<infobot-devel@lists.sourceforge.net>>. If you would
+rather a more realtime conversation with us, we can be found in the B<#infobot>
+channel on the B<Freenode> network (B<irc://irc.freenode.net>).
+
+=cut
+
diff --git a/doc/infobot.users.pod b/doc/infobot.users.pod
new file mode 100644 (file)
index 0000000..264196a
--- /dev/null
@@ -0,0 +1,158 @@
+=pod
+
+=head1 NAME
+
+infobot.users - User accounts database for infobot
+
+=head1 SYNOPSIS
+
+  # Please edit to your needs.
+  # "local" is used for CLI mode
+  # Passwords can be generated with mkpasswd in linux
+
+  _default
+  --FLAGS              amrt
+  --HOSTS              *!*@*
+
+  local
+  --FLAGS              Aemnorst
+  --HOSTS              local!local@local
+  --PASS               xxfxfIfoJHdYg
+
+  timriker
+  --FLAGS              Aemnorst
+  --HOSTS              *!~timr@TimRiker.active.supporter.pdpc
+  --PASS               xxfxfIfoJHdYg
+
+  xk
+  --FLAGS              emnorst
+  --HOSTS              *!xk@example.com
+  --HOSTS              *!xk@superbox.home.org
+  --PASS               5K/rmJPzwxJhU
+
+=head1 DESCRIPTION
+
+This file controls who has access to use your infobot.
+
+=head1 FIELDS
+
+There are various fields allowed in your file. Whitespace is ignored, and as
+usual, any line starting with a C<#> is treated as a comment.
+
+The first non whitespace/comment line in your file, is the user name for the
+account you are about to define. Take note that a special username called
+C<_default>, is meant to define what everyone who doesnt have an account in this
+file should use for permissions.
+
+Also, the special user name C<local>, is used when you run the bot in B<CLI>
+mode (console only, no B<IRC> connection). As well, the C<local> user requires a
+special hostmask of S<I<local!local@local>>.
+
+Below is a list of the valid options available for each user account.
+
+=over
+
+=item B<--FLAGS>
+
+This field is a list of possible flags that this account has. Think of them as
+similar to irc user modes (although, with different meanings).
+
+Here is a list of the current flags available, and their meanings:
+
+I<Note: Modes flags are case sensitive>
+
+=over
+
+=item *
+
+B<A> - bot administration over /msg (default is only via DCC CHAT)
+
+=item *
+
+B<O> - dynamic ops (as on channel). (automatic +o)
+
+=item *
+
+B<T> - add topics.
+
+=item *
+
+B<a> - ask/request factoid.
+
+=item *
+
+B<m> - modify factoid. (includes renaming)
+
+=item *
+
+B<n> - bot owner, can "reload"
+
+=item *
+
+B<o> - master of bot (automatic +amrt). 
+
+=over
+
+=item *
+
+Can search on factoid strings shorter than 2 chars
+
+=item *
+
+Can tell bot to join new channels
+
+=item *
+
+Can [un]lock factoids
+
+=back
+
+=item *
+
+B<r> - remove factoid.
+
+=item *
+
+B<t> - teach/add factoid.
+
+=item *
+
+B<s> - Bypass +silent on channels
+
+=back
+
+=item B<--HOSTS>
+
+This field is used to specify a hostmask that a user must appear from for the
+bot to consider them to be this specific account definition.
+
+This hostmask takes the form of: I<nick!user@hostname>
+
+I<Note: You can have this field multiple times>
+
+=item B<--PASS>
+
+This field used a C<crypt> formated password, that is used for B<DCC> chats to
+the bot, or if you need to identify yourself to the bot in the event that you
+come from a different host.
+
+You can generate one using the C<mkpasswd> command, available on most systems.
+
+For example:
+
+ infobot@myhost:~$ mkpasswd
+ Password: test
+ GVrl9PMBB0gpw
+
+You can also change your password at anytime by sending the bot a C<chpass>
+command on B<IRC>. 
+
+=back
+
+=head1 BUGS
+
+At some point, it is likely that the C<local> account will be removed and
+implied to have full access.
+
+=cut
+
diff --git a/files/.cvsignore b/files/.cvsignore
deleted file mode 100644 (file)
index cb7dd24..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-blootbot.chan
-blootbot.config
-blootbot.countdown
-blootbot.servers
-blootbot.uptime
-blootbot.users
-debian
diff --git a/files/blootbot.help b/files/blootbot.help
deleted file mode 100644 (file)
index 2044d08..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-# Revised: 20050224
-#  Author: Tim Riker <Tim@Rikers.org>
-###
-
-main: I learn mainly by observing declarative statements such as "x is at http://www.xxx.com", and then reply when people ask things like "where can i find x?"
-
-action: This is used to override the usual response. "x is <action> does the hokey-pokey". When asked about x, the bot does this "* blootbot does the hokey-pokey"
-
-alternation: The || symbol in an entry causes an blootbot to choose one of the replies at random. "X is Y||Z" will produce "X is Y" or "X is Z" randomly.
-
-author: oznoid (mailto:lenzo@ri.cmu.edu) is my original author.
-
-dollar variables: D: To be used in factoids
-dollar variables: $Fdunno      - ...
-dollar variables: $Fquestion   - ...
-dollar variables: $Fupdate     - ...
-dollar variables: $channel     - channel from which the factoid was requested
-dollar variables: $date        - current date (GMT)
-dollar variables: $day         - day of week (full name, locale)
-dollar variables: $factoids    - factoid count
-dollar variables: $host        - hostname of factoid requester
-dollar variables: $ident       - bot nick
-dollar variables: $lastspeaker - ...
-dollar variables: $memusage    - ...
-dollar variables: $rand        - random number, also $rand100.2
-dollar variables: $randnick    - random nick
-dollar variables: $startTime   - start time
-dollar variables: $time        - current time (GMT)
-dollar variables: $uptime      - ...
-dollar variables: $user        - username of factoid requester
-dollar variables: $who         - nick of factoid requester
-
-corrections: If I come back with "...but x is at http://xx.xx.xx" or something like that, and you want to change the entry, use "no, x is at http://sdfsdfsdf".  The "No," tells me to supercede the existing value.
-corrections: you can append stuff to a factoid with "also". "x is also at ..."
-
-math: D: math expresions can be evaluated. This uses Perl syntax.
-math: E: 1+1
-math: + - add
-math: - - subtract
-math: * - multiply
-math: / - division
-math: ** - to the power
-math: pi - pi
-math: & - and
-math: | = or
-math: ^ - xor
-
-redirection: If a factoid x contains simply "<reply> see y", then when asked for x, I will deliver factoidor command result y instead.
-
-reply: There is a special tag, <reply>, that is used to override the usual response.  Usually, a response is "X is Y", but it can be made "Y" by making the entry "X is <reply> Y".
-
-# now the commands...
-
-adduser: D: Administrative command to add new user to the .users file
-adduser: U: ## <user> <mask>
-adduser: E: ## bloot bloot!bloot@example.com
-
-addressing: It is a good idea if I stay in REQUIRE mode so that I won't yell out random crap if I listen in too hard.  Currently there is no way to turn this off on-the-fly. (REQUIRE mode requires me to be addressed by name if I am to respond)
-
-babelfish: D: Frontend to babelfish translating service provided by http://babelfish.altavista.com/ Note that utf8 is used for non-ascii characters.
-babelfish: U: x <fromLang> <toLang> <words>
-babelfish: U: translate <fromLang> <toLang> <words>
-babelfish: E: x en de your cars rock
-
--ban: D: FIXME:
--ban: U: ## <mask|user>
--ban: E: ## *!*@owns.org
--ban: E: ## MoronMan
-
-+ban: D: FIXME:
-+ban: U: ## <mask|user> [chan] [time] [reason]
-+ban: E: ## *!*@owns.org #bots 60 stop flooding.
-+ban: E: ## *!*@*microsoft.com STOOPID
-+ban: E: ## MoronMan
-
-botmail: D: Send someone botmail
-botmail: U: ## {for <who>[:] <message>}|stats|check|read
-botmail: E: ## for infobot: you rock!
-botmail: E: ## stats
-botmail: E: ## check
-botmail: E: ## read
-
--chan: D: Leave a channel permanently
--chan: U: ## -#channel
--chan: E: ## -#botpark
-
-+chan: D: Join a channel permanently
-+chan: U: ## #channel
-+chan: E: ## #botpark
-
-chaninfo: D: Display channel statistics on Op, Ban, Deop, Unban, Part, Join, SignOff, PublicMsg, Kick and Topic
-chaninfo: U: ## [#channel]
-chaninfo: E: ##
-chaninfo: E: ## #botpark
-
-chanset: D: set a variable for a channel
-chanset: U: ## [#chan] [what] [val]
-chanset: E: ## #c +test
-chanset: E: ## #c -test
-chanset: E: ## #c test
-chanset: E: ## #c test 0
-chanset: E: ## #c test testing123
-
-chanunset: D: remove a variable from a channel
-chanunset: U: ## <#chan> [what]
-chanunset: E: ## #c
-chanunset: E: ## #c test
-
-chattr: D: Change flags on a user (see @regFlagsUser in source)
-chattr: U: ## <user> [flags]
-chattr: E: ## bloot +nmo
-chattr: E: ## bloot -ot
-chattr: E: ## bloot
-
-chnick: D: rename a nick (user) entry
-chnick: U: ## [nick] <new-nick>
-chnick: E: ## moron
-chnick: E: ## owner eleet
-
-chpass: D: Change a user's password
-chpass: U: ## [user] <pass>
-chpass: E: ## testing
-chpass: E: ## testing test0R
-
-contents: D: Debian Contents search only (no Packages)
-contents: U: ## <string> [dist]
-contents: E: ## strings.h
-contents: E: ## x11amp potato
-
-cookie: I can feed your appetite with random factoids.
-
-cpustats: cpustats dumps the bot's cpu usage this session
-
-crypt: It's good that you thought about encryption. I can do it for you.
-crypt: U: ## <salt> <string>
-crypt: E: ## 69 changeme
-crypt: E: ## $1$abcde changeme
-
-cycle: D: Causes me to cycle in the channel it's said, or in the named channel
-cycle: U: ## [channel]
-cycle: E: ##
-cycle: E: ## #botpark
-
-dauthor: D: Find Debian package maintainers, and list the packages they maintain
-dauthor: U: ## <string> [dist]
-dauthor: E: ## Wichert
-dauthor: E: ## Wichert potato
-
-dbugs: D: Show the current count of release critical bugs (latest versions)
-dbugs: U: ##
-
-deluser: D: Administrative command to remove a user from the .users file
-deluser: U: ## <user>
-deluser: E: ## bloot
-
-ddesc: D: Search the Description: lines in Debian packages
-ddesc: U: ## <string> [dist]
-ddesc: E: ## mule
-ddesc: E: ## mule potato
-
-dfind: D: Debian Packages (fallback to Contents) search
-dfind: U: ## <string> [dist]
-dfind: E: ## strings.h
-dfind: E: ## x11amp potato
-
-dict: D: DICT Protocol Client - likely dicts: elements web1913 wn gazetteer jargon foldoc easton hitchcock devils world02 vera
-dict: U: ## [entry num] <query>[/dict]
-dict: E: ## linux
-dict: E: ## 33 set/wn
-
-dns: D: Query DNS
-dns: U: ## <host|ip>
-dns: E: ## debian.org
-dns: E: ## 3.1.33.7
-
-do: D: operator command to do things in a channel
-do: U: ## <chan> <what>
-
-dstats: D: Show basic stats on the current size of the Debian distros
-dstats: U: ## [dist]
-dstats: E: ##
-dstats: E: ## potato
-
-factinfo: D: View statistical information about a particular factoid.
-factinfo: U: ## <factoid>
-factinfo: E: ## test
-
-factstats: D: Display statistical data (max of 15) about factoids.
-factstats: U: ## <type>
-factstats: == author    -- top author of factoids.
-factstats: == deadredir -- ??
-factstats: == duplicate -- duplicate factoids.
-factstats: == listfix   -- ??
-factstats: == locked    -- locked factoids.
-factstats: == new       -- recent addition of factoids.
-factstats: == nullfactoids -- ??
-factstats: == partdupe  -- initial partial duplicate factoids.
-factstats: == profanity -- possibly offensive factoids.
-factstats: == redir     -- redirection in factoids.
-factstats: == reqrate   -- ??
-factstats: == requested -- most requested factoids.
-factstats: == requesters -- most requested factoids.
-factstats: == seefix    -- ??
-factstats: == toolong   -- factoid {key|value} exceeding specified length.
-factstats: == tooshort  -- factoid {key|value} shorter than specified length.
-factstats: == total     -- ??
-factstats: == unrequest -- unrequested factoids.
-factstats: == vandalism -- ??
-factstats: E: ## new
-
-forget: If I have an old/redundant factoid x, "forget x" will cause me to erase it.
-
-freshmeat: D: Frontend to www.freshmeat.net
-freshmeat: U: ## <query>
-freshmeat: E: ## blootbot
-
-hex: D: Convert ascii to hex
-hex: U: ## <string>
-hex: E: ## carrot
-
-httpdtype: D: Get httpd server software version / configuration
-httpdtype: U: ## <hostname>
-httpdtype: E: ## example.com
-
-ignore: D: ignore list management
-ignore: E: ## [mask chan expire comment]
-ignore: E: addignore guu!*@*
-
-ircstats: ircstats dumps some status information on the bot's IRC connection
-
-join: U: ## <#chan> [key]
-join: E: ## #botpark
-join: E: ## #botpark rules
-
-karma: Karma is a community rating system.  Use "X++" to increase the karma, or "X--" to decrease it.  Ask for ratings using "karma for X?"
-
-kernel: D: Frontend to linux.kernel.org's finger response.
-kernel: U: ##
-
-kick: U: ## <nick> [#chan] [message]
-kick: E: ## oznoid
-kick: E: ## larne #botpark
-kick: E: ## john #foo go away!
-
-lart: D: Luser Attitude Readjustment Tool
-lart: U: ## [#chan] <who>
-lart: E: ## lenzo infobot's bugginess
-lart: E: ## #perl everyone perl \=\= lamerville
-
-lc: D: lower case a given string
-lc: U: ## <string>
-lc: E: ## When will blootbot achieve world domination?
-
-listauth: D: Search the factoid extension db by creator
-listauth: U: ## <search>
-listauth: E: ## xk
-
-listkeys: D: Search the factoid database by key (factoid)
-listkeys: U: ## <regex>
-listkeys: E: ## blootbot
-
-listvalues: D: Search the factoid database by value (description)
-listvalues: U: ## <regex>
-listvalues: E: ## blootbot
-
-literal: used to get a raw factoid contents. Use _default to ignore factoidSearch path.
-literal: U: ## [_default|prefix] <factoid>
-literal: E: ## blootbot
-
-lobotomy: I can be given a lobotomy ([o] is required) if people start to abuse me.  To bring me back to life, give me an unlobotomy
-
-lock: D: Factoid locking to prevent removal by others
-lock: U: ## <factoid>
-lock: E: ## abuse
-lock: N: By default, only registered "ops" on the bots or factoids matching the user's nick are able to lock factoids.
-lock: N: Requires factoid extension (extra) support enabled.
-
-md5: D: calculates the md5sum of a given string
-md5: U: ## <string>
-md5: E: ## When will blootbot achieve world domination?
-
-mode: set modes for a channel
-mode: U: ## <#chan> <mode>
-mode: E: ## #botpark +t
-mode: E: ## #botpark -i
-
-news: D: News functions
-news: U: ## [chan] <add,del,mod,set,latest,read,help>
-
-news add: D: Add news items
-news add: U: news [chan] add <title>
-news add: E: news add This is a test
-news add: see _news set Text_ aswell
-
-news set: D: Set stuff for news item
-news set: U: news [chan] set <item> <what> [value]
-news set:    valid <what>: Expire, Text
-news set: E: news set 1 Text ok, this works
-news set: E: news set test Text and this is a test
-news set: E: news set test Text
-
-news set expire: D: Set expire for news item
-news set expire: U: news [chan] expire <what> <value>
-news set expire: value can be: Xd Xh Xm Xs
-news set expire: value can be: never
-news set expire: news expire 1 3days
-news set expire: news expire 2 +20d
-news set expire: news expire Test 30d 20h 10m 5s
-news set expire: news expire TEST never
-
-news del: D: Delete news item (requires +o or be author)
-news del: U: news [chan] del <item>
-news del: E: news del 1
-news del: E: news del test
-
-news mod: D: Modify a news item (todo: modify Text aswell)
-news mod: E: news [chan] mod <item> s/<from>/<to>/[g]
-news mod: E: news mod 1 s/test/Test/
-news mod: E: news mod test s/test/Test/g
-
-nickometer: D: Measures the lame-ness of a nick or channel
-nickometer: U: ## {nick,channel}
-nickometer: E: ## unknown_lamer
-nickometer: E: ## #botpark
-
-onjoin: D: get/set OnJoin message (needs chan option +OnJoin)
-onjoin: U: ## [#chan|_default] [-]<nick> [message]
-onjoin: E: ## blootbot Hey! It's another blootbot!
-
-ord: D: Convert ascii to decimal
-ord: U: ## <single character>
-ord: E: ## c
-
-page: D: Send someone a pager message
-page: U: ## <who> <message>
-page: E: ## infobot you rock!
-page: NOTE: this uses the "<who>'s pager" factoids for the From: and To: addresses of the format "example's pager" is "mailto:me@example.com"
-
-part: D: Leave a channel (DCC only)
-part: U: ## <#channel>
-part: E: ## #botpark
-part: NOTE: /kick is an alternative
-
-piglatin: D: translates english text into piglatin
-piglatin: U: ## <string>
-piglatin: E: ## When will blootbot achieve world domination?
-
-quote: D: Frontend to yahoo's online stock market share listing
-quote: U: ## <query...>
-quote: E: ## RHAT,MSFT
-
-rename: D: Factoid renaming
-rename: U: ## 'from' 'to'
-rename: E: ## 'infobot' 'blootbot'
-
-reverse: D: reverses a given string
-reverse: U: ## <string>
-reverse: E: ## When will blootbot achieve world domination?
-
-rot13: D: ROT13's a given string
-rot13: U: ## <string>
-rot13: E: ## guvf vf n ynzr rknzcyr
-
-say: D: operator command to say things in a channel
-say: U: ## <chan> <what>
-
-scramble: D: scrambles a given string
-scramble: U: ## <string>
-scramble: E: ## When will blootbot achieve world domination?
-
-search: U: ## <engine> for <string>
-search: E: ## google for blootbot
-
-seen: D: Report last seen time for somebody
-seen: U: ## <nick>
-seen: E: ## blootbot
-
-slashdot: D: News for nerds, Stuff that matters. [tm] (shows the headlines)
-slashdot: U: ##
-
-spell: You've guessed it right, I'm a spell checker. Give me any word and I can confirm whether it's good or bad.
-
-status: status dumps general status information
-
-tell: D: Tell someone about a factoid or command
-tell: U: ## <who> -?about <what>
-tell: E: ## me about blootbot
-tell: E: ## someone -about testing
-
-topic add: D: Add your own topic
-topic add: U: ## <topic>
-topic add: E: ## This is a test
-
-topic del: D: Delete one or two subtopics
-topic del: U: ## <#>
-topic del: E: ## 1
-topic del: E: ## 1-3,5
-topic del: E: ## last
-
-topic mod: D: Search and replace strings in the topic
-topic mod: U: ## <REGEX>
-topic mod: E: ## s/test/TEST/
-topic mod: E: ## s#msg test#/msg test#g
-
-topic mv: D: Move subtopics around.
-topic mv: U: ## <#> <before|after|swap> <#>
-topic mv: E: ## 1 after 2
-topic mv: E: ## first before last
-
-topic restore: D: Restores the topic to an earlier version
-topic restore: U: ## <#>
-topic restore: E: ## 3
-
-topic: Usage for 'topic [#chan] <params>':
-topic:   ---------------- __Subtopic__:
-topic:   add <TOPIC>    - Append <TOPIC> to topic.
-topic:   del <#>        - Remove subtopic <#> from topic.
-topic:   list           - Display subtopics.
-topic:   mod s/old/new/ - Search and replace topic.
-topic:   mv <ARGS>      - 'topic mv'.
-topic:   shuffle        - Randomly organize subtopics.
-topic:   ---------------- __Topic__
-topic:   history        - Show previous topics.
-topic:   restore <#>    - Restore topic to <#>.
-topic:   rehash         - Rehash changes to topic.
-topic:   info           - Who and time info.
-topic:   ---------------- __Misc__
-topic:   about          - Read the file :)
-topic:   help           - This screen.
-
-topic: NOTE: #chan arg is only required if command is sent over private message to nick, otherwise it is not needed if sent to the channel.
-topic: NOTE: commands can be preceeded? with '-' in order not to enforce changes to topic.
-topic: End of help.
-
-uc: D: upper case a given string
-uc: U: ## <string>
-uc: E: ## When will blootbot achieve world domination?
-
-unforget: If a factoid has been forgotten, "unforget x" will cause me to unerase it.
-
-unlobotomy: Not possible in real life, an unlobotomy will bring me back to life in the case of a lobotomy.
-
-unlock: D: Factoid unlocking to allow removal by others.
-unlock: U: ## <factoid>
-unlock: E: ## abuse
-
-uptime: D: Show the current uptime, and the top 3 uptimes recorded
-uptime: U: ##
-
-wantnick: If someone's taken my nick (I hope not) and I'm using some temporary nick, I can change back to my original nick if it's not taken (again).
-
-wikipedia: D: Frontend to the Wikipedia at http://www.wikipedia.org/wiki/ Note that utf8 is used for non-ascii characters.
-wikipedia: U: ## <topic>
-wikipedia: U: wiki <topic>
-wikipedia: E: wiki irc
-
-wtf: D: Interface to the BSD wtf command
-wtf: U: ## <abbreviation>
-wtf: E: ## iirc
-
--host: D: admin command to remove hostmask from a user account
--host: U: ## [user] <mask>
--host: E: ## *!*@owns.org
--host: E: ## owner leet!leet@*.heh.org
-
-+host: D: admin command to list or add hostmasks to a user account
-+host: U: ## [user] [<mask>]
-+host: E: ## owner
-+host: E: ## *!*@owns.org
-+host: E: ## owner leet!leet@*.heh.org
diff --git a/files/blootbot.lang b/files/blootbot.lang
deleted file mode 100644 (file)
index 527ea1f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-# blootbot.lang: configurable responses.
-# by the xk.
-###
-
-# Welcome reply: Things to say when people thank me.
-welcome
-  no problem
-  my pleasure
-  sure thing
-  no worries
-  de nada
-  de rien
-  bitte
-  pas de quoi
-  gern geschehen
-
-# Dunno reply (when i recognize a query but can't answer it):
-dunno
-  i don't know
-  i haven't a clue
-  no idea
-  wish i knew
-  bugger all, i dunno
-  I give up, what is it?
-  I don't know, could you explain it?
-  I'm not sure, is it larger than a breadbox?
-  parse error: dunno what the heck you're talking about
-  are you using Windows?
-  I wish you would RTFM.
-  have you tried http://www.tldp.org/ ?
-  KCI error, or a problem with the Keyboard-Chair Interface.
-
-# moron reply.
-moron
-  You think I'm human? Think again!
-  h0 h0 h0
-  Hi, how's life?
-  What do you want?
-  Are you on drugs?
-  Wassup G?
-
-# confuse/refuse learn.
-confused
-  I think you lost me on that one
-  what are you talking about?
-
-# Hello reply (ways to say hello):
-hello
-  hello
-  hi
-  hey
-  niihau
-  bonjour
-  hola
-  salut
-  que tal
-  privet
-  what's up
-  moin moin
-
-# Cookie reply: added by the xk.
-cookie
-  ACTION spins the wheel of knowledge and ponders... ##KEY... ##VALUE
-  ACTION pulls out the cookie jar and finds ##KEY... ##VALUE
-  Hey ##WHO, ##KEY is ##VALUE
-
-# Factoid reply:
-factoid
-  methinks ##KEY is ##VALUE
-  i heard ##KEY is ##VALUE
-  i guess ##KEY is ##VALUE
-  from memory, ##KEY is ##VALUE
-  hmm... ##KEY is ##VALUE
-  ##KEY is probably ##VALUE
-  ##KEY is, like, ##VALUE
-  rumour has it, ##KEY is ##VALUE
-  it has been said that ##KEY is ##VALUE
-  somebody said ##KEY was ##VALUE
-  well, ##KEY is ##VALUE
-  extra, extra, read all about it, ##KEY is ##VALUE
-  [##KEY] ##VALUE
-
-# HowAreYou reply:
-howareyou
-  eh, ok
-  peachy
-  just great
-  you know how it is...
-  pretty good. how about you?
-  mas o menos
-
-# Question word.
-qWord
-  who
-  who is
-  who are
-  what
-  what's
-  what is
-  what are
-  where
-  where's
-  where is
-  where are
-
-# botsnack etc praise
-# TODO add ACTION support
-praise
-  :)
-  thanks
-  aw, gee
diff --git a/files/blootbot.lart b/files/blootbot.lart
deleted file mode 100644 (file)
index 69e0478..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-
-#
-# lart info by ejb (larne) and cerb.
-#
-
---purges WHO
-accelerates a free AOL cd to 50,000 rpm and lets WHO feel it
-acting on orders from an unspecified client drags WHO into court suing for $200 million
-beats the living hamstercrap out of WHO
-beats WHO into protomatter with the andromeda galaxy
-beats WHO over the head with a microkernel
-beats WHO senseless with a 50lb Unix manual
-beats WHO severely about the head and shoulders with a rubber chicken
-beats WHO to within 2.54cm of his life
-blames WHO for all the evil in the world
-blasts WHO to oblivion with a kamehameha wave
-blasts WHO with a huge firehose then strangles WHO with it
-brandishes Excalibur! "With this sword, I vanquish thee, WHO!" and lops off WHO's head
-breaks out the Hoover and sucks up WHO
-burns WHO to a crisp with a laser
-calls WHO on the phone ... the lights are on but nobody's home
-cats /dev/urandom into WHO's ear
-changes WHO's permissions to 0777 and tells the world
-chops WHO in half with a free AOL CD
-chops WHO in half with a free Solaris 7 CD
-crushes WHO with a full height scsi disk
-cuts off WHO's head with a halberd that could have been a little bit sharper
-cuts WHO into thin stripes
-decapitates WHO conan the destroyer style
-declares WHO a moron
-does a little 'dpkg -P WHO' action
-does a little 'renice 20 -u WHO'
-DoSes WHO
-drops a baby grand on WHO
-drops a humongous exploding nuke on WHO
-drops a truckload of VAXen on WHO
-duct-tapes WHO to the floor and drools on him
-dumps 42 tons of dirt, manure, and fish heads on WHO
-eats WHO and falls over dead
-eats WHO's liver with some fava beans and a nice chianti
-executes killall -HUP WHO
-executes killall -KILL WHO
-executes killall -TERM WHO
-explains, ever so gently, that if WHO doesn't give the channel more information, they can't help
-farts in WHO's general direction
-flings poo at WHO
-follow's WHO with a gauntlet and ... scratch ... HUMILIATION
-forces WHO to use Outlook Express
-frags WHO with his BFG9000
-gets a hotmal account and SPAMs WHO
-gives WHO a "free" copy of Windows and then charges double for "Upgrades"
-gives WHO a good seeing to
-gives WHO an extra strength ACME sleeping pill, sending WHO to sleep for 150 years, and awakening to seven strange dwarfs and a large apple
-grabs a large, mis-shapened log, with squirrels, and beats WHO until only the nuts remain ... which the squirrels run off with
-hauls WHO up by the scruff of the neck and spanks him until he waddles
-hereby declares WHO a troll
-hits WHO with an anvil and laughs with a contralto voice ... Haha Ha HA Ha
-holds WHO to the floor and spanks him with a cat-o-nine-tails
-hooks into a hydrant and hoses WHO down
-hurls dozens of incontinent, insomniac, hungry kittens with tiny little razor-sharp claws and a wide variety of contagious intestinal parasites at WHO
-installs a bad bootloader on WHO and turns WHO into a brick
-installs PocketPC on WHO's PDA
-judo chops WHO
-keeps mailing WHO free America Online CDs until he drowns
-lowers WHO's priority
-makes a balloon animal out of WHO
-moos at WHO
-nabs the moon and broadsides WHO with the sea of tranquility
-nukes WHO with a single large nuke
-offers WHO some herring
-overclocks WHO until WHO burns out
-plops WHO into a giant vat of herring
-pours gasoline all over WHO, ignites the fire, and then enjoys some toasty marshmallows with the glorious blaze
-pours hot grits down the front of WHO's pants
-pries WHO's back open with a screwdriver and flashes a new bootldr to WHO
-pulls out a ClueBat (tm) and thwaps WHO
-pulls out his louisville slugger and uses WHO's head to break the homerun record
-pushes the wall down onto WHO whilst whistling innocently
-puts on a hockey mask and jumps out at WHO
-puts on some milking gloves.  "All right, now, WHO, this won't hurt a bit...."
-puts WHO into a headlock and administers a mighty noogie, rubbing half of WHO's hair of
-puts WHO through a wood chipper
-raises middle finger to WHO
-readies the nuke launcher and fires some rounds at WHO
-resizes WHO's terminal to 40x24
-rm -rf's WHO
-runs at WHO with an origami Swiss Army knife, and inflicts a nasty paper cut
-says "boot to the head" and knocks WHO over
-send killer squirrels to attack WHO
-sends a legion of lawyers after WHO's head
-shoots WHO in his sleep
-shoots WHO in the head
-shoves a crumpet down WHO's throat, happy now?! Huh? Want some JAM with that?
-slams WHO against a large cement Tux
-slaps a compatible dib on WHO's head
-slaps WHO around with a large trout
-slaps WHO upside and over the head with one freakishly huge killer whale named hugh
-slaps WHO upside the head with a wet fish
-smacks WHO up side the head with a clue-by-4
-squeezes WHO till WHO turns blue like papa smurf
-squishes WHO like a bug
-stabs WHO
-stamps WHO on the forehead with the official Troll marker
-steals WHO's mojo
-strangles WHO with a 9-pole serial cable
-strangles WHO with a doohicky mouse cord
-stuffs WHO into a shiny new tin can and vacuum seals it
-takes a big bite out of WHO's jugular vein
-takes a large goose feather pillow and swings it wildly in WHO's direction, hitting WHO and sending WHO flying into the closet
-takes a rusty axe and swings it violently, taking WHO's head off
-takes large quantities of Krispy Kream donuts and stuffs them one after another down WHO's throat until WHO puts on 150lbs
-takes out a cattle prod and gives WHO a good jolt
-takes out a seltzer bottle and sprays WHO in the face. You know, one of those old-school seltzer bottles clowns have? Yeah those. Anyway, consider yourself spritzed
-takes out WHO with the trash
-takes WHO to the vet for a "special" visit
-teaches WHO that M$ Access is a database. No, really, a database. A real live multi-user... well, ok, not multi-user, but a database. Yeah, that sounds right.
-teaches WHO the basics, including how to RTM
-throws a AN/M-8 smoke grenade at WHO
-throws WHO's poor little doggy off a cliff
-tries to shut WHO up
-turns WHO into a lifesized tux doll
-urinates on WHO
-wallops WHO with a main rotation server that needs rehubbing.  It won't take long
-whacks WHO upside the head
-whacks WHO with a giant beaver's tail
-whacks WHO with the cluebat
-whips out a hot clue gun and makes sure that WHO is stuck to the floor
-whips out a shotgun, trudges over to WHO, and goes postal
-whips out a sword and chops WHO in half
-whips out his power stapler and staples WHO's foot to the floor
-whips WHO with a wet and grimy noodle just because
diff --git a/files/blootbot.randtext b/files/blootbot.randtext
deleted file mode 100644 (file)
index 817a01e..0000000
+++ /dev/null
@@ -1,2104 +0,0 @@
-He who controls the source controls the universe!
-Want to see a listing of files installed by a package, type dpkg -L package
-Need to know the status of a package? type dpkg -s package
-Need help, but everyone is idle in the channel, try emailing to debian-user@lists.debian.org
-Need to see the list of packages matching a pattern, type dpkg -l pattern
-If you have a webserver and dww packages installed, try http://localhost/dwww for all kinds of documentation
-Need help setting up PPP? read /usr/doc/ppp/README.debian
-Want to know why Debian is best? type !why in the channel
-Want to upgrade to hamm (unstable)? type !libc6 to get the mini-HOWTO
-Want to check out Debian social contract? type !dfsg in the channel
-Warning: Dates in Calendar are closer than they appear.
-Daddy, why doesn't this magnet pick up this floppy disk?
-Give me ambiguity or give me something else.
-I.R.S.: We've got what it takes to take what you've got!
-We are born naked, wet and hungry.  Then things get worse.
-Pentiums melt in your PC, not in your hand.
-Suicidal twin kills sister by mistake!
-Did anyone see my lost carrier?
-Make it idiot proof and someone will make a better idiot.
-I'm not a complete idiot, some parts are missing!
-He who laughs last thinks slowest!
-Always remember you're unique, just like everyone else.
-'More hay, Trigger?'  'No thanks, Roy, I'm stuffed!'
-A flashlight is a case for holding dead batteries.
-Lottery: A tax on people who are bad at math.
-There's too much blood in my caffeine system.
-Artificial Intelligence usually beats real stupidity.
-Hard work has a future payoff.  Laziness pays off now.
-Friends help you move.  Real friends help you move bodies.
-I won't rise to the occaasion, but I'll slide over to it.
-Ever notice how fast Windows runs?  Neither did I.
-Double your drive space - delete Windows!
-What is a 'free' gift ?  Aren't all gifts free?
-If ignorance is bliss, you must be orgasmic.
-'Very funny, Scotty.  Now beam down my clothes.'
-Puritanism: The haunting fear that someone, somewhere may be happy.
-Consciousness: that annoying time between naps.
-Oops.  My brain just hit a bad sector.
-I used to have a handle on life, then it broke.
-Don't take life too seriously, you won't get out alive.
-I don't suffer from insanity.  I enjoy every minute of it.
-Better to understand a little than to misunderstand a lot.
-The gene pool could use a little chlorine.
-When there's a will, I want to be in it.
-Okay, who put a 'stop payment' on my reality check?
-Few women admit their age.  Few men act theirs.
-I'm as confused as a baby in a topless bar.
-We have enough youth, how about a fountain of SMART?
-All generalizations are false, including this one.
-Change is inevitable, except from a vending machine.
-C program run.  C program crash.  C programmer quit.
-'Criminal Lawyer' is a redundancy.
-Clap on! (clap, clap) Clap off! (clap@#&$NO CARRIER
-'640K ought to be enough for anybody.' Bill Gates '81
-'90% of all statistics are made up'
-'A fanatic is one who can't change his mind and won't change the subject.'
-'A little work, a little sleep, a little love and it is all over.' - R. Frost
-'A lot of people mistake a short memory for a clear conscience.' -Doug Larson
-'Apple' (c) 6024 b.c., Adam & Eve
-'Apple' (c) Copyright 1767, Sir Isaac Newton.
-'Bad knee, gotta run' - Pat Buchanan to his draft board
-'Beam me aboard, Scotty.' 'Sure. Will a 2x10 do?'
-'Beulah, peel me a grape.'
-'Bother,' said Pooh as the brakes went out!
-'Build a watch in 179 easy steps' by C. Forsberg.
-'C++' should have been called 'D'
-'COINCIDENCE' happens.
-'Calvin, we will not have an anatomically correct snowman!'
-'Careful.  We don't want to learn from this.' -- Calvin
-'Don't you hate it when your boogers freeze?' -- Calvin
-'Every time I've built character, I've regretted it.'
-'Freedom defined is freedom denied.' -The Illuminatus
-'Have you ever dated somebody because you were too lazy to commit suicide?'
-'Hi-ho, hi-ho, it's hand grenades I throw...'
-'Hmm... How *did* they finally kill Frosty?' -- Hobbes
-'Human equality is a contingent fact of history.' -Steven Jay Gould
-'I tried to think but nothing happened!' - Curly
-'I'm not an actor, but I play one on TV'
-'I'm not smart enough to lie' - Ronald Reagan
-'If I knew what I was doing...I'd be dangerous...'
-'If the shoe fits, buy it.'  Imelda Marcos
-'Instant gratification takes too long.' - Carrie Fisher
-'Is' is the verb for when you don't want a verb.
-'It is not the fall that kills you.  it's the sudden stop at the end.'-D. Adams
-'It's sad how whole families are torn apart by simple things, like wild dogs'
-'Keyboard?  How quaint!' - Scotty
-'Luke... Luke... Use the MOUSE, Luke' - Obi Wan Gates
-'Mr. Worf, blow the Windows-powered Borg ship out of this Universe!'
-'Off the keyboard, thru the router, over the bridge, nothing but net!'
-'Quotations are for people who are not saying things worth quoting.'
-'Remember when we said there was no future?  Well, this is it.' -- Blank Regk
-'Stupid' is a boundless concept.
-'Suicide Hotline...please hold.'
-'The faster you go, the shorter you are' - Einstein
-'The reports of my death have been greatly exaggerated.' - Mark Twain
-'The sun ain't yellow, its chicken.' -Bob Dylan
-'There are lies, damned lies, and statistics.' -Mark Twain
-'There's someone in my head, but its not me.' -Pink Floyd
-'This is a job for.. AACK! WAAUGHHH!! ...someone else.' -
-'To err is human, to forgive....$5.00'
-'Ummm, Trouble with grammar have I! Yes!' -Yoda-
-'Vote for Perot' - Bumper sticker attached with Velcro
-'You can't have everything.  Where would you put it?' -Steven Wright
-#1 OS/2 tip: Drag the Windows folder to the shreader!!!
-#include std/disclaimer.h
-$$$ not found --  (A)bort (R)efinance (B)ankrupt
-'Tis better to be thought a fool, then to open your mouth and remove all doubt
-(((((This tagline in Stereo where available)))))
-(A)bort (R)etry (C)ut  Your  Throat.....
-(A)bort (R)etry (F)ail (U)nplug & (S)ell.
-(A)bort (R)etry (P)ull leg (H)ot boot (S)wipe tagline!
-(A)bort, (R)etry, (I)nfluence with large hammer
-(A)bort, (R)etry, (P)retend this never happened...
-(D)inner not ready:  (A)bort (R)etry (P)izza
-(You can have your cake) XOR (You can eat your cake)
-(c) Copywight 1995 Elmer Fudd.  All wights wesewved.
-* OLX 3 * Windows is to OS/2 what Etch-a-Sketch is to art.
-*Four hours* to bury a cat?  Yes - it wouldn't keep still
-.. Bugs come in through open Windows.
-... 'I'll be Bach.' - Johann Sebastian Schwarzenegger
-... All the world's a stage, and I missed rehearsal.
-... Bill Clinton isn't slick.  He's just a liar.
-... Clinton Economics: If 1+2=3 then 4+5=6.
-... Clinton excuse #15: Hey - I just do what the wife says
-... Clinton excuse #18: You took that seriously?  Har har
-... Clinton sandwich:  $5 of baloney and $20 in taxes
-... Getting the truth from Clinton is like nailing Jello
-... It's tourist season in Florida, bag limit two.
-... KARAOKE is Japanese for 'Tone Deaf'
-... Some days you're the dog, some days you're the hydrant
-.....If it ain't broke, fix it anyway just to screw it up!
-...I'm sorry, Reality is not in service at this time.
-...On the other hand, you have different fingers.
-..Windows NT Performance', on the next 'In Search Of'
-/EARTH is 98% full. Please delete anybody you can
-1 + 1 = ?  Ask my calculator.
-10 out of 5 doctors feel it's OK to be schitzo!
-1200 bps used to seem so fast
-186,000 miles/sec: Not just a good idea, it's the LAW.
-1st rule of intelligent tinkering - save all the parts
-2 + 2 = 4 (for the time being).
-2 + 2 = 5 (for sufficiently large values of 2)
-3 out of 4 Americans make up 75% of the population.
-43% of all statistics are worthless.
-43rd Law of Computing: Anything that can go wr...
-5 schizophrenics agree!
-50 states, and I had to pick this one...
-668 - Neighbor of the Beast
-90% of being smart is knowing what you're dumb at.
-<<< Tagline deleted by Natl Endowment for the Arts >>>
-==/==/==/==Police tagline==/==/==Do not cross ==/==/==/==
-From my brain, an organ with a mind of it's own.
-From the Department of Redundancy Dept.
-A BBSer's telephone bill knows no bounds...
-A Bugless Program is an Abstract Theoretical Concept.
-A Metaphor is like a Simile.
-A Smith & Wesson *ALWAYS* beats 4 Aces.
-A big enough hammer fixes anything
-A bird in the hand can be messy.
-A camel is a horse planned by committee.
-A chicken is an egg's way of producing more eggs.
-A clean desk is a sign of a cluttered desk drawer.
-A closed mind gathers no intelligence
-A closed mouth gathers no feet.
-A committee has 6 or more legs and no brain.
-A conscience does not prevent sin. It only prevents you from enjoying it.
-A critic is a man who leaves no turn unstoned.
-A cynic smells flowers and looks for the casket.
-A day for firm decisions!  Or is it?
-A day not wasted is a day wasted!
-A day without radiation is a day without sunshine.
-A day without sunshine is like night.
-A diplomat thinks twice before saying nothing.
-A dirty book is rarely dusty.
-A fool and his money are soon SYSOP.
-A fool and his money rarely get together to start with.
-A fool must now and then be right by chance.
-A friend in need is a pest indeed...
-A friend: someone who likes you even after they know you.
-A good way to deal with predators is to taste terrible.
-A half moon is better than no moon at all.
-A harp is a nude piano.
-A hunch is creativity trying to tell you something.
-A library is an arsenal of liberty.
-A life lived in fear is half a life lived.
-A little greed can get you lots of stuff.
-A little inaccuracy sometimes saves tons of explanation.
-A living example of Artificial Intelligence.
-A man needs a good memory after he has lied.
-A man's best friend is his dogma.
-A man, a plan, a canal.  Suez!
-A mind is a terrible thing to taste.
-A mind is a terrible thing to ugg.. I forgot..
-A neat desk is a sign of a sick mind.
-A pedestrian hit me and went under my car.
-A penny saved is a Governmental oversight.
-A perversion of nature....how exciting!
-A pessimist is never disappointed.
-A phaser on stun is like a day without orange juice.
-A rolling stone gathers momentum.
-A seminar on Time Travel will be held two weeks ago.
-A single fact can spoil a good argument.
-A stitch in time would have confused Einstein.
-A truly wise man never plays leapfrog with a moose.
-A waist is a terrible thing to mind.
-A yer ago I kudnt spel progremr now I are won.
-ASCII and ye shall receive.
-ASCII stupid question... get a stupid ANSI!
-Abandon all hope ye who have entered cyberspace.
-Afraid of heights?   Not me, I'm afraid of widths!
-Agnodyslexic plea:  'why ME, dog?'
-Air conditioned environment - Do not open Windows.
-Alex, I'll take 'Things Only I Know' for $1000.
-All E-mail gladly received. Offensive reply ASAP.
-All I ask for is the opportunity to prove that money can't make me happy.
-All I need to know I learned from my cat.
-All I want is a warm bed, a kind word and unlimited power
-All generalizations are bad.
-All generalizations are false, including this one.
-All hope abandon, ye who enter messages here.
-All in a day's work for...'Confuse-a-Cat'!
-All in all it's just a... 'nother brick in the wall!
-All life's answers are on TV. - Bart Simpson
-All programers are optimists.
-All that glitters has a high refractive index.
-All the easy problems have been solved.
-All things are green unless they are not.
-All wiyht.  Rho sritched mg kegtops awound?
-All words are pegs on which to hang ideas.
-All work and no play, will make you a manager.
-All you need to be a fisherman is patience and bait.
-Almost went crazy.  Would have been a real short trip.
-Alone: In bad company.
-Always draw your curves, then plot the data.
-Always forgive your enemies, nothing annoys them so much.
-Always glad to share my ignorance - I've got plenty.
-Always proofread carefully to see if you any words out.
-Always remember no matter where you go, there you are.
-Alzheimers advantage: New friends every day.
-Ambition is the last refuge of the failure.
-America Good Place to Put Chinese Restaurant.
-Amusement is the happiness of those who cannot think.
-An Elephant;  A Mouse built to government specifications.
-An egotist thinks he's in the groove when he's really in a rut.
-An elephant is a mouse with an operating system.
-An idle mind is worth two in the bush.
-An ounce of application is worth a ton of abstraction.
-An ounce of emotion is equal to a ton of facts.
-An oyster is a fish built like a nut.
-An ulcer is what you get mountain climbing over molehills.
-An unbreakable toy is useful for breaking other toys.
-An unemployed court jester is no one's fool.
-And don't start a sentence with a conjunction.
-And he disappeared in a puff of logic.
-And if one bad cluster should accidentally fail...
-And it's only ones and zeros.
-And now for something completely different...
-And now for something completely the same...
-And tomorrow will be like today, only more so.
-And, the driver compresses EVERYTHING, not just EXE & COM
-Angels can fly because they take themselves so lightly.
-Anger blows out the lamp of the mind.
-Another case of Cherry Coke down the programming hatch!
-Answers: $1 * Correct answers: $5 * Dumb looks: Free! *
-Antidisestablishmentarianism!
-Any closet is a walk-in closet if you try hard enough.
-Any fool can criticize, condemn, & complain. And most do.
-Any philosophy that can be put in a nutshell belongs there
-Any wire cut to length will be too short.
-Anything worth doing, is worth doing for a profit.
-Are we having Fahrvergn\ 1ugen yet??
-Are ya feelin' lucky, punk?!! - Harry Callahan
-Are you really American if your ethnicity has to be hyphenated?
-Are you suggesting that coconuts migrate?
-Armageddon means never having to say you're sorry.
-Artificial Intelligence is no match for natural stupidity.
-As I said before, I never repeat myself.
-As a matter of fact, no, I don't have a life.
-As easy as 3.14159265358979323846264338327950288419716
-As long as I can remember, I've had amnesia.
-Ask not for whom the bell tolls; let the machine get it.
-Assumption is the mother of all screwups...
-Atheist = Deity Disadvantaged.
-Auntie Em: Hate you, hate Kansas, taking the dog.  -Dorothy
-B.Gates : quality software :: R.McDonald : gourmet cuisine
-BREAKFAST.COM Halted... Cereal Port Not Responding.
-Back Up My Hard Drive? I Can't Find The Reverse Switch!
-Backup not found: (A)bort (R)etry (P)anic
-Bad Command:(A)bort (R)etry (T)ake RAM hostage
-Bad breath is better than no breath.
-Bald: follicularly challenged.
-Barium:  what you do with dead chemists.
-Beautify Texas.  Put a Yankee on a bus.
-Been there, done that, got the T-shirt.
-Best file compressor around: DEL *.* (100% compression!)
-Best way to dispose of the Borg: Give them Windows 3.1.
-Better ... stronger ... faster!
-Beware of Geeks bearing gifs.
-Beware of barking dogs that bite.
-Beware of programmers carrying screwdrivers
-Bigamy : one wife too many. Monogamy : same thing
-Bill Clinton is the Lyin' King. ( Now playing nation wide )
-Bill Clinton thinks that Cheerios are donut seeds.
-Bill Clintoon: The prince of Dorkness, a caricature of a president
-Black Holes are Out of Sight
-Black holes really suck...
-Blessed are the pessimists, for they make backups!
-Blessed is the end-user who expects nothing, for ye shall not be dissapointed.
-Bliss *IS* ignorance
-Bo Knows Taglines!
-Bo Peep did it for the insurance.
-Bombs don't kill people, explosions kill people.
-Borderline psychotic with hermit-like tendencies.
-Bore: A person who talks when you wish him to listen.
-Bored? Drive the speed limit... in your garage.
-Borg spreadsheet: Locutus 1-2-3
-Borg?  Where?  I don't se*(#$#..NO CARRIER
-Both of his feet are firmly planted in the air.
-Boy: A noise with dirt on it.
-Brain dysfunction detected....
-Brain over - Insert coin
-Brain: The apparatus with which we think that we think.
-Break up a relationship - buy a computer!!
-Breathing may be hazardous to your health.
-Britannia waives the rules.
-Bug off, Banana Nose; Relieve mine eyes
-Bugs are Sons of Glitches!
-Bugs, like coathangers, breed if unobserved.
-Building Contractors, not to be confused with homemakers
-Bullets speak louder than reason.
-Bumper sticker on a hearse:  I'd rather be breathing
-Bungee Jumper? Catch you on the rebound.
-Bureaucrats cut red tape, lengthwise
-Bus error (Passengers dumped)
-Busier than a 1 legged man in an butt-kicking contest.
-But I forgot all about the Amnesia Conference!!
-But honey, we can afford it, I sold your car!
-But my little voice TOLD me to do it!
-But soft, what light through yonder tagline breaks?
-But then again, I like cold toilet seats.
-But what if I'm a figment of my OWN imagination?
-Buy American!
-Buy Land Now.  It's Not Being Made Any More.
-Buy a supscription to Playboy and send it to your boss' wife
-By all means, let's not confuse ourselves with the facts!
-C programmer run C programmer crash C programmer quit
-C:\DOS   C:\DOS\RUN   RUN DOS RUN
-CAUTION:  RIDER MAY BAIL AT ANY TIME
-CCITT: Can't Certify I Trust Telecom.
-CCITT: Can't Conceive Intelligent Thoughts Today
-CD-WOM, Wead Onwy Memowy.
-CEO of Dementia and Other Meaningless Entities.
-CHIP:  One California hi-way patrolman.
-CODING:  AN addictive Drug.
-COMMAND:  A suggestion made to a computer.
-CONgress (n) - Opposite of PROgress
-CRASH:  Normal termination.
-CRIME CONTROL: Fire a warning shot into his HEART!
-CURIOSITY?  Nah.  I got THAT cat with a lawnmower.
-CYCLIC REDUNDANCY CHECK: Stocktaking at a Bike shop
-California raisins murdered: Cereal Killer suspected
-Can I yell 'movie' in a crowded firehouse?
-Can you find the mispelled word in hear?
-Can you repeat the part after 'Listen very carefully'?
-Can you see the REAL ME, can ya?!?!  CAN YA??!?!!?!?!?!?!
-Can you tell me how to get to Sesame Street?
-Can't learn to do it well? Learn to enjoy doing it badly!
-Card-carrying member of the cultural elite.
-Carlsbad Caverns: 22% more cavities.
-Cause of crash: Inadvertent contact with the ground.
-Caution:  Breathing may be hazardous to your health.
-Caution:  Contents under pressure
-Caution:  Hungry Dieter   May bite if provoked
-Caveat emptor, no deposit no return, do not remove.
-Celibacy is not hereditary.
-Cheer up, the worst is yet to come.
-Chernobyl used Windows
-Chess players mate better.
-Chicago runs best on a VCR.
-Chicago, an operating system Pair-of-Dimes shift!
-Chicago...  The biggest thing since New Coke!
-Chicago: NT deja vu!
-Chicago?  Been there.  I'm ready to travel at WARP speed!
-Chicken heads are the chief food of captive alligators.
-Chipmunks roasting on an open fire.
-Choose heaven for climate, hell for society.
-Christmas comes, but once a year is enough.
-Circular Definition: see Definition, Circular.
-City Planners do it with their eyes shut.
-Civilization - biggest syntax error in history!
-Clark Kent is a transvestite.
-Clarvoiants meeting canceled due to unforseen events.
-Clean mind, clean body:  take your pick.
-Cleanliness is next to impossible.
-Climate is what you expect.  Weather is what you get.
-Clinton is one Bill, George Bush can't veto...
-Clinton/Gore is to the presidency as Beavis & Butthead are to television.
-Clones are people two.
-Close only counts in horseshoes and hand grenades!
-Close your eyes and press escape three times.
-Closed Hearing for the Caption Impaired...
-Cogito ergo spud I think therefore I yam.
-Cole's Law: Thinly sliced cabbage.
-Come in here, dear boy, have a cigar, you're gonna go far!
-Coming Soon!!  Mouse Support for Edlin!
-Coming soon: Netware for the Nintendo!
-Commence strategic maneuvers at audible command signal.  5, 4, 3...
-Committees keep minutes and lose hours.
-Common sense is the collection of prejudices acquired by age eighteen.
-Common sense isn't...
-Communism is like a mouth on a lollipop
-Competence always contains the seeds of incompetence.
-Computational Physicist and all around nice guy.
-Computer Lie #1: You'll never use all that disk space.
-Computer: a million morons working at the speed of light.
-Computers All Wait at the Same Speed!
-Computers Rule 01001111 01001011
-Computers are not intelligent. They only think they are.
-Computers are useless; they can only give answers.
-Computers run on faith, not electrons.
-Condense soup, not books!
-Conformity obstructs progress.
-Confucius say too much.
-Confucius say: I didn't say that!
-Confucius say: Man with no legs bums around.
-Confucius say: Those who quote me are fools.
-Confuse People:  Quote from the wrong message!
-Confused?  Call Counselor Troi 1-900-NCC-1701: $1.95/minute
-Confusion not only reigns, it pours.
-Consolations, Consultations, Conflagrations.
-Constant change is here to stay.
-Contentsoftaglinemaysettleduringshipping.
-Converse with any plankton lately?
-Copyright the Intergalactic Thought Association
-Corrupt REALITY.SYS: Reboot Universe (Y/n)?
-Could crop circles be the work of a cereal killer?
-Couldn't myself have better it said.
-Courage atrophies from lack of use.
-Crime does not pay...as well as politics.
-Crime doesn't pay... does that mean my job is a crime?
-Crime wouldn't pay if the government ran it.
-Crime, Sex, Alcohol, Drugs...Boy do I love Congress
-Cynicism is intellectual dandyism.
-Cynics are people who know the price of everything and the value of nothing.
-D.A.D.D. - Daddies Against Dirty Diapers
-D.A.M. - Mothers Against Dyslexia
-D.A.M.M - Drunks Against Mad Mothers
-DAM: Mothers Against Dyslexia.
-DANGER! Computer store ahead, hide wallet!
-DCE seeks DTE for mutual exchange of data.
-DEFINE: De ting you get for breaking de law.
-DEVICE=EXXON.SYS may mess up your environment
-DILATE: To live longer.
-DIODE: What happens to people who don't die young.
-DIVORCE =system('echo y| erase \wife\*.*' );
-DO NOT ADJUST YOUR MIND - the fault is with reality
-DO NOT REMOVE THIS TAGLINE (UNDER PENALTY OF LAW)!
-DOC files?  We don't need NO STINKIN' DOC FILES!
-DOS 5.0  Yesterday's operating system, today!
-DOS means never having to live hand-to-mouse.
-DOS never says 'EXCELLENT command or filename, Dude!'
-DOS-O-MANIA : Reboot is not kicking your computer again
-DOS-O-MANIA : Root is not the book Alex Haley wrote.
-DOWN WITH EXCLAMATION POINTS!!!!
-Daddy, what does 'Formatting Drive C:' mean?
-Dain Bramaged.
-Dang this hobby is expensive!
-Dangerous exercise: Jumping to conclusions.
-Darth Vader sleeps with a Teddywookie.
-Dawn: The time when men of reason go to bed.
-Dawson's First Law: You don't have enough outlets.
-Death benefits = oxymoron.
-Death is 99 per cent fatal to laboratory rats.
-Death is God's way of dropping carrier.
-Death is life's answer to the question 'Why?'
-Death is life's way of telling you you've been fired.
-Death sneaks up on you as a windshield sneaks up on a bug.
-Death: to stop sinning suddenly.
-Deflector shields just came on, Captain.
-Delivered by Electronic Sled-Dogs.....Woof!
-Democrats Call for Amnesty, Reduced Sentences Likely.
-Depart in pieces.... i.e., Split.
-Detour: The roughest distance between two points.
-Diagonally parked in a parallel universe.
-Did I just step on someone's toes again?
-Did ya hear? They took the word gullible out of the dictionary!
-Did you expect mere proof to sway my opinion?
-Die Yuppie Scum.
-Diets are for those who are thick and tired of it.
-Difference between Jane Fonda & Bill Clinton? Jane went to Vietnam
-Digression is education.
-Dime:  a dollar with all the taxes taken out.
-Dinner Not Ready...(A)bort (R)etry (P)izza
-Diplomacy is saying 'nice doggy' until you find a rock.
-Diplomacy is the ability to let someone else have your way.
-Diplomacy: The patriotic art of lying for one's country.
-Dirty deeds - DONE DIRT CHEAP!
-Disclaimer: All opinions are not really opinions.
-Disclaimer: Written by a highly caffeinated mammal.
-Discoveries are made by not following instructions.
-Disks travel in packs.
-Dyslexics of the world, UNTIE!
-Do Androids Dream of Electric Sheep?
-Do I mind if you smoke?  No.  Do you mind if I FART?
-Do fish get thirsty?
-Do not believe in miracles -- rely on them.
-Do not disturb. Already disturbed!
-Do not put statements in the negative form.
-Do radioactive cats have 18 half-lives?
-Do steam rollers really roll steam?
-Do the joke. Get the laugh. Move on.
-Do unto others BEFORE they do unto you!
-Do vegetarians eat animal crackers?
-Do you know the way to San Jose?
-Doctor Who for president
-Doctor, my brain hurts!
-Documentation is the castor oil of programming.
-Does Bill Clinton think Elvis is alive?
-Does killing time damage eternity?
-Does the Enterprise use DOS v2356.0?
-Does the name Pavlov ring a bell?
-Doesn't expecting the unexpected make the unexpected become the expected?
-Dogs come when you call. Cats have answering machines.
-Dogs crawl under Gates, software under Windows.
-Don't Take Life Seriously, It Is Not Permanent.
-Don't ask me, I have intermittent memory loss
-Don't ask me, I only work here.
-Don't ask me, I'm making this up as I go!
-Don't be a sexist, broads hate that.
-Don't be afraid to drive a nail in the wood!
-Don't believe everything you hear or anything you say.
-Don't blame me, I voted for Mickey Mouse.
-Don't buy furs, it takes trees to make protest signs.
-Don't byte off more than you can multiplex.
-Don't confuse me with facts, my mind's already made up!
-Don't crush that dwarf, hand me the pliers.
-Don't diet, download a virus to remove the FAT.
-Don't do what I SAY, do what I mean!
-Don't get stuck in a closet -- wear yourself out.
-Don't just do something !!! Stand there !!!
-Don't let school interfere with your education.
-Don't look at me in that tone of voice!
-Don't look back, the lemmings are gaining on you.
-Don't mess with Murphy.
-Don't panic.  Don't panic.  Don't panic. ... ALL RIGHT, NOW PANIC
-Don't play stupid with me! I'm better at it.
-Don't press the keys so hard!
-Don't read everything you believe.
-Don't rush me.  I get paid by the hour.
-Don't speak now, and forever hold your peace.
-Don't start with me.  You know how I get.
-Don't steal.  The government hates competition.
-Don't stop posting, a good laugh breaks up my day nicely
-Don't sweat it -- it's only ones and zeros.
-Don't talk unless you can improve the silence.
-Don't thank me for insulting you. It was my pleasure...
-Don't try to saw sawdust.
-Don't use a big word where a diminutive one will suffice.
-Don't use no double negatives.
-Don't worry, I'm fluent in weirdo.
-Down with categorical imperative!
-Down with ignurance!
-Downgrade your system for only 89 dollars!   Install Windows!
-Dragons love you. You're crunchy and good with ketchup.
-Drama is life with the dull bits cut out.
-Drawing on my fine command of language, I said nothing
-Drilling for oil is boring.
-Drink wet cement, and get completely stoned.
-Drive A: format failure, formatting C: instead...
-Drive C: Error, (A)bort (R)etry (I)gnore (K)ick (S)cream
-Dropped from my peeling lips like lousy fruit.
-Drugs have taught an entire generation of American kids the metric system.
-Dumb luck beats sound planning every time.  Trust me.
-Dying is no excuse. Nixon in 96.
-Dyslexics are persona au gratin.
-Dyslexics have more fnu.
-Dyslexics of the world, UNTIE!
-EMS: Enhanced Money Scam
-ERROR 103: Dead mouse in hard drive.
-EXPANSION SLOTS: The extra holes in your belt buckle.
-Eagles may soar but weasels aren't sucked into jet engines!
-Easter is canceled this year.  They've found the body.
-Eat Healthy, Exercise, and Die Anyway ...
-Eat the rich, the poor are tough and stringy
-Efficiency takes time!  Frugality: who can afford it?
-Eggheads unite!  You have nothing to lose but your yolks.
-Ego Gratification through Violence
-Either this man is dead or my watch has stopped.
-Email me the rules, please!
-Energizer Bunny Arrested! Charged with battery.
-Enjoy me, I may never pass this way again.
-Enough research will tend to support your theory.
-Ensign Pillsbury:  He's bread Jim!
-Enter that again, just a little slower.
-Error 15 - Unable to exit Windows. Try the door.
-Eschew obfuscation!
-Even in this corner of the galaxy, Captain, 2+2=4 ... Spock
-Even snakes are afraid of snakes.
-Even the greatest of whales is helpless in the middle of the desert
-Ever notice how fast Windows runs? Neither did I...
-Ever stop to think, and forget to start again?
-Ever wonder why Oprah spelled backwards is Harpo?
-Every man's work is a portrait of himself.
-Every purchase has its price.
-Every why hath a wherefore.
-Everybody is ignorant, only on different subjects.
-Everybody wants to go to heaven, but nobody wants to die.
-Everyone has photographic memory...some don't have film!
-Everyone hates me because I'm paranoid
-Everyone is entitled to my opinion.
-Everyone is gifted. Some open the package sooner.
-Everyone's expendable...and no one has a real friend
-Everything bows to success, even grammar.
-Everything in our favor was against us.
-Everything that is not mandatory is forbidden.
-Everywhere is walking distance if you have the time.
-Evil always triumphs over good, because good is STUPID!
-Exceeding the legal fun limit on a regular basis
-Excellent time to become a missing person.
-Excuse me while I dance a little jig of despair
-Excuse me while I sharpen my tongue.
-Experience is a good teacher but her fees are high...
-Experience: a name everyone gives to his mistakes.
-Exploding piglets!!!  My gosh, it's raining bacon!
-Exxon Suxx.
-F.A.R.T....Fathers Against Radical Teenagers
-FATAL SYSTEM ERROR:  Press F13 to continue...
-FIGHT BACK!  Fill out your tax forms with Roman numerals.
-FILE COPIED.                       I THINK?
-FLOPPY DISK: Serious curvature of the spine.
-FOR SALE: 1 set of morals, never used, will sell cheap.
-FORD: The Heartbreak of today's Chevrolet!
-Fact is solidified opinion
-Facts Just Get In The Way And Impede Progress.
-Facts are stubborn things.
-Fad: In one era and out the other
-Familiarity breeds attempt
-Familiarity breeds children.
-Famous last words - Don't worry, I can handle it.
-Famous last words - Icarus: Aaaahhhhhhhhh.
-Famous last words - You and what army?
-Faster than a speeding ticket!
-Fat Wars: May the Sauce Be With You.
-Fat person: Nutritional Overachiever
-Fatal Error Using Mouse. Replace and Bury Operator.
-Features should be discovered, not documented.
-Feel lucky????  Update your software!
-Felines... nothing more than felines...
-Fer sell cheep:  IBM spel chekker.  Wurks grate.
-Fife. n. Small shrill instrument that rhymes with wife.
-Figures won't lie, but liars will figure.
-File not found. Should I fake it? (Y/N)
-Find your aim in life, before you run out of ammunition
-First thing you do is shoot all the lawyers
-Fish and visitors stink in three days.
-Flames to /dev/null/here/is/a/quarter/now/go/buy/a/clue.
-Flaming nuclear death to Smurfs
-Flirt: A woman who thinks it's every man for herself.
-Floggings will continue until morale improves.
-Flying saucers are real, the Air Force doesn't exist.
-Folks who think they know it all bug those of us who do
-Follow-ups to alt.nobody.really.cares
-Food is an important part of a balanced diet.
-Fools rush in where Fools have been before!
-Fools rush in wherever lottery tickets are sold
-For Sale: Slightly used message. Enquire within.
-For at the end of history lies the undiscovered country.
-For discussion only. Not to be relied upon.
-For every vision there is an equal and opposite revision.
-For people who like peace and quiet: A phoneless cord!
-For sale, Toilet-seat cover.  Barely used.
-For the finest in brain candy.
-Forget the Joneses...I can't keep up with the SIMPSONS!
-Forget the computer!  Where's my abacus??
-Forget the diet center; send yourself a candygram.
-Forgive your enemies...but REMEMBER THEIR NAMES!
-Four minus two is one and the same.
-Fraud(n): A telephone number starting with '1-900'
-Free Nelson Mandela, while stocks last!
-Free advice is worth what you pay for it
-Free your mind ... the rest will follow!
-Freedom is just chaos with better lighting.
-Friction can be a drag sometimes.
-Friendly fire - ISN'T !
-Friends are Friends, regardless of their baud rate!
-Friends come and go, enemies accumulate.
-Friends don't let friends drive naked.
-Friends encourage friends to use Windows - under Linux!
-Friendship is one soul in two bodies.
-Frost
-Funny, only sensible people agree with me.
-GURU: One who knows more jargon than you.
-Gambling: The sure way of getting nothing for something.
-Gargle twice daily - see if your neck leaks.
-Geez if you belive in honkus.
-Genealogy = A DNA square-dance in the Thighlight Zone
-General Failure reading John Dvorak
-General stupidity error reading drive C:
-Geoff, Brett and Todd...the BO-DYNASTY!!!
-George Orwell was an optimist.
-Get behind early so you have plenty of time to catch up.
-Get the facts first - you can distort them later!
-Get your filthy hands off my dessert!
-Gimme back my face! You're getting it ugly.
-Give a woman an inch  and she'll park a car in it.
-Give a woman an inch and she thinks she's a ruler.
-Give your child mental blocks for Christmas.
-Go Lemmings, Go!!!
-Go shopping. Buy Stuff. Sweat in it. Return it the next day.
-God created cats so that men could learn to understand women
-God does not play dice.
-God heals and the doctor takes the fee.
-Going out of my mind, back in 5 minutes.
-Going the speed of light is bad for your age.
-Good day to let down old friends who need help.
-Good girls go to heaven...but bad girls go EVERYWHERE!!
-Goodness has NOTHING to do with it.....
-Gotta love me!
-Grab your helmet, get your bike, it's SHOWTIME!
-Graduate Of The Uncle Fester & Keith Moon School of hair styling
-Gravity brings me down
-Gravity doesn't exist.  The Earth sucks.
-Great minds travel in the same sewers.
-Greed is good!  Greed is right!  Greed works!
-Grow your own dope...   plant a man
-Growing old is mandatory; growing up is optional!!
-Grub first, then ethics.
-Gun control is being able to hit your target!
-Guns don't kill people... death does.
-Guns don't kill people..., I kill people!
-H lp!  S m b d  st l  ll th  v w ls fr m m  k yb  rd!
-HAL 9000: Dave.  Put down those Windows disks, Dave.  DAVE!
-Hackito ergo sum.
-Hailing frequencies open, Captain.
-Hand me that crowbar... I must pry out this bullet.
-Happiness is Earth in your rear view mirror.
-Happiness is a warm gun.
-Happiness is a warm modem
-Happiness is finding special characters \ 1\ 2\ 1\ 2
-Happiness is not a destination.  It's the trip.
-Happiness is seeing your mother-in-law's face on the back of a milk carton.
-Happiness is...receiving YOUR posts!!!!
-Hard work has a future payoff.  Laziness pays off now.
-Hard work must have killed someone!
-Has it ever rained cats and dogs?
-Hasta la vista, Baby!
-Have Tardis, will travel.
-Have an adequate day.
-Have cursor, will curse.
-Have it OUR way.  Yours is IRRELEVANT.  At BORGerKing.
-Have you ever talked into an acoustic modem?
-Have you seen Quasimoto? I have a hunch he's back!
-Having Windows problems?  Dial 1-800-3-IBM-OS2 for fast relief!
-Having two bathrooms ruins the capacity to co-operate.
-He does the work of 3 Men...Moe, Larry & Curly
-He has Van Gogh's ear for music.
-He who Laughs, Lasts.
-He who always plows a straight furrow is in a rut.
-He who asks timidly makes denial easy.
-He who dies with the most access, wins.
-He who dies with the most toys... is *still* DEAD!
-He who eats too many prunes, sits on toilet many moons.
-He who hesitates is constipated.
-He who laughs last is S-L-O-W.
-He who laughs last probably made a backup.
-He who lives by the sword laughs last.
-He who places head in sand, will get kicked in the end!
-He who shouts the loudest has the floor.
-He who sitteth on an upturned tack shall surely rise.
-He's dead Jim. Grab his tricorder. I'll get his wallet.
-He's dim, Jed
-He's not dead, Jim, he's just metabolically challenged.
-Heads I win... DITTO tails
-Health food makes me sick.
-Heisenberg slept here, I think.
-Help endangered species - adopt a KGB operative.
-Help fight continental drift.
-Help stamp out mental illness, or I'll kill you!
-Help stamp out, eliminate and abolish redundancy!
-Help!  I'm lost somewhere in the Generation Gap.
-Help!  I've been stuck in here for years and years...
-Help! Police! That guy stole my .sig! STOP!!! THIEF!!!
-Help!!!  I'm falling and I can't click out!!!
-Help, I'm slipping into the Twilight Zone!
-Here today, gaunt tomorrow.
-Hey!  Hacker!  Leave those lists alone!
-Hey!  This is a morgue, not an amusement park!
-Hey!  Who took the cork off my lunch??!
-Hey, CServe/Unisys! Stick it where the sun don't shine!
-Hey, Worf...I hooked Data up to a Modem...Wanna see?
-Hi!  I can't remember your name either.
-Hi, I'm from Corporate.  I'm here to help you.
-Hi. I'll be your tagline for this evening.
-High message: 9434567.  Message last read: 9.
-Hills weed out the weak.  Darwin would argue this is good.
-Hindsight is always 20:20.
-Hindsight is an exact science.
-Hm..what's this red button fo:=/07<NO CARRIER
-Hmm...Nice tagline. <SWIPE!> SUCKER!!! AH, HAHAHAHAHAHAHAHA!
-Hollow chocolate has no calories
-Hollywood is like Picasso's bathroom.
-Honey, PLEASE don't pick up the PH$@#*&$^(#@&$^%(*NO CARRIER
-Honeymoon Salad: Lettuce alone, with no dressing.
-Honeymoon: time between 'I do' and 'you'd better'
-Honk if you love cheeses.
-Honk if you love peace and quiet.
-Honk, if you have slept with Clinton.
-Hors d'oeuvres--a ham sandwich cut into forty pieces.
-Housework done properly, can kill you
-Houston! do you read.
-How come the AT&T logo looks like the Death Star?
-How come there's only one Monopolies Commission?
-How come wrong numbers are never busy?
-How do I set my laser printer for stun?
-How do you know it's summer in Seattle?  Rain's warm!
-How do you make Windows faster ?  Throw it harder
-How do you pronounce my name?   With reverence.
-How do you write zero in Roman numerals?
-How does Michael Jackson pick his nose? From a catalog!
-How does one expect the unexpected?
-How long is a short story?
-How long will a floating point operation float?
-How many consultants will fit onto the head of a pin?
-How many of you believe in telekinesis?  Raise MY hand!
-How many weeks are there in a light year?
-How much can I get away with and still go to heaven?
-How much deeper would the ocean be without sponges?
-Humpty dumpty was pushed.
-Hydrate or Die.
-Hypochondria is the only disease I haven't got.
-I *LOVE* it when a plan comes together!
-I BBS because no one can read my handwriting.
-I Cayman went.
-I Have To Stop Now, My Fingers Are Getting Hoarse!
-I M a tru beleever in hour edukashun sistum.
-I Still miss my ex-wife.....BUT, My aim is improving!
-I Think....therefore I'm OVER QUALIFIED!!!!!!!!!
-I love it when a plan comes together!
-I admit it's offbeat, but lets not get hysterical.
-I always lie.  In fact, I'm lying to you right now!
-I always like to try the one I've never tried before.
-I am Clinton of Borg.  Your income will be assimilated.
-I am Homer of Borg!  Prepare to be...OOooooo!  Donuts!!!
-I am Lancelot of Borg. Resistance is feudal.
-I am both of us & so are you.
-I am built for comfort, not speed!
-I am free of all prejudice. I hate everyone equally.
-I am functioning within established parameters.
-I am in total control, but don't tell my wife.
-I am not an animal!  I am ... well, not an animal.
-I am serious.  And don't call me Shirley.
-I am sweet and lovable at all times.
-I am the girl-next-door's imaginary boyfriend.
-I am what I am and that's all that I am.
-I am. Therefore, I think.  I think.
-I apologize to the deaf for the loss of subtitles.
-I bet you I could stop gambling.
-I bought a cordless extension cord.
-I came, I saw, I did a little shopping.
-I came, I saw, I took LOTS of PICTURES!
-I came... I saw... I stole your tagline.
-I can do without essentials but I must have my luxuries
-I can quit anytime I want; I just don't want to!
-I can resist anything but temptation.
-I can tell you are lying. Your lips are moving.
-I can walk on water, but I stagger on alcohol.
-I can't be overdrawn, I still have checks left!
-I can't believe my computer's on fire.
-I can't hear you. There's a banana republic in my ear.
-I cna ytpe 300 wrods pre mniuet!!!
-I could be arguing in my spare time.
-I could have stuck with DOS, but NO.
-I couldn't care less about apathy.
-I didn't cheat, I just changed the Rules!
-I didn't know it was impossible when I did it.
-I distinctly remember forgetting that.
-I do not fear computers.  I fear the lack of them.
-I do this kind of stuff to him all through the picture.
-I don't care if I'm apathetic.
-I don't care who you are, Fatso. Get the reindeer off my roof!
-I don't care who you are, what you are driving, or where you would rather be.
-I don't eat snails... I prefer FAST food!
-I don't hate Windows - it runs great under Linux!
-I don't have a solution but I admire the problem.
-I don't lie, cheat or steal unnecessarily.
-I don't need a disclaimer. I OWN the company.
-I don't think, therefore I am not.
-I don't want the world, I just want your half.
-I drink to make other people interesting.
-I eat Swiss cheese from the inside out.
-I feel like a fugitive from the law of averages.
-I feel so inar-inar-inar tic-u-late
-I feel the need......the need for speed!
-I finally washed the mud off of mud.
-I find myself beside a stream of empty thought
-I float like an anchor and sting like a moth.
-I get mail........ I exist.
-I give advice worth the price....free!
-I got arrested in LA and boy am I beat!
-I guess a cynic smells different.
-I had a life once... now I have a computer and a modem.
-I had amnesia once or twice.
-I had my coat hangers spayed.
-I hate quotations. Tell me what you know.
-I hate to repeat gossip, so I'll only say this once.
-I have a 9600bps modem and 1.5bps fingers
-I have a rock garden.  3 of them died last week.
-I have a speech impediment... my foot.
-I have already not made that point
-I have seen the evidence.  I want DIFFERENT evidence!
-I have seen the truth and it makes no sense.
-I have the mars observer and I'm not returning it until I get an 'A' in astronomy
-I haven't lost my mind -- it's backed up on tape somewhere.
-I haven't lost my mind, I know exactly where I left it.
-I hear what you're saying but I just don't care.
-I is a college student.
-I is knot dain bramaged!
-I just bought a cured ham.  Wonder what it had?
-I keep my .BAT files in D:\BELFRY
-I know Karate, Kung Fu, and 47 other dangerous words
-I know everything about everything, except that.
-I know it all. I just can't remember it all at once.
-I like candy, especially the gooey kind with nougat!
-I like kids, but I don't think I could eat a whole one.
-I like to leave messages *before* the beep.
-I like to reminisce with people I don't know.
-I like to think of myself as a divide overflow.
-I like your approach, now let's see your departure.
-I lost a button hole today.
-I lost my knickers at Niagara.
-I made it foolproof. They are making better fools!
-I may be fat but you're ugly, and I can lose weight.
-I may be getting older, but I refuse to grow up
-I may not always be perfect, but I'm always me.
-I may not be perfect, but parts of me are excellent.
-I mustanottagottalotta sleep last night.
-I need someone really bad.  Are you really bad?
-I never deny, I never contradict. I sometimes forget.
-I never met a chocolate I didn't like!
-I only counted 100 dalmatians...!!!
-I owe, I owe, it's off to work I go.
-I parked my hard disk and now I can't find it!
-I planted some bird seed.  A bird came up.
-I post.......... I am
-I promise results, not promises.
-I refuse a battle of wits with an unarmed person!
-I remember when Saturns were rockets, not cars.
-I saw, I came, I cleaned it up.
-I smashed a Window and saw... Linux!
-I spilled spot remover on my dog, and now he's gone.
-I think I strained a muscle I didn't know I had!
-I think, therefore I am.  I think.
-I think. Therefore I am DANGEROUS.
-I thought I was wrong but I was mistaken.
-I tried being reasonable once.  I didn't like it.
-I tried switching to gum but I couldn't keep it lit.
-I tried to daydream, but my mind kept wandering.
-I tried to drown my problems but they can swim!
-I try to make everyone's day a little more surreal.
-I used to be disgusted, but now I'm just amused.
-I used to be indecisive, now I'm not so sure.
-I used to be schizophrenic, but we're all right now.
-I used to have a handle on life, then it broke.
-I used to spell badlie, but now I got worser.
-I used to watch TV, then I bought a modem.
-I wake near the end of the day.
-I want .50 cal machine guns as a factory option.
-I warn you not to underestimate my powers.
-I was arrested for selling illegal sized paper.
-I was arrested for walking in someone else's sleep.
-I was going to procrastinate, but I put it off....
-I went on a 30-day diet - and lost 30 days!
-I will defend to your death my right to my opinion.
-I wish life had a scroll-back buffer.
-I wouldn't touch the Metric System with a 3.048m pole!
-I wrote a few children's books, but not on purpose.
-I xeroxed my watch. Now I have time to spare.
-I'd give my left arm to be ambidextrous
-I'd like to live like a poor person with lots of money.
-I'd like to, but last time I went I never came back..
-I'd love to, but I have to fulfill my potential.
-I'd love to, but I have to rotate my crops.
-I'd love to, but I have to stay home and see if I snore
-I'd love to, but I prefer to remain an enigma.
-I'd love to, but I think you want the OTHER Phillip.
-I'd love to, but I'm trying to be less popular.
-I'd love to, but I've dedicated my life to linguini.
-I'd love to, but my crayons all melted together.
-I'd love to, but my favorite commercial is on TV.
-I'd love to, but my patent is pending.
-I'd love to, but none of my socks match.
-I'd love to, but there's a disturbance in the Force.
-I'd love to, but you know how we psychos are.
-I'd rather be bicycling!
-I'll eat anything that's BRIGHT BLUE!!
-I'll get you my pretty, and your little dog too!
-I'll get you yet, you kwazy wabbit!
-I'll jump off that bridge when I come to it.
-I'll tell you what's the matter!  This parrot is dead!
-I'm Not Schizophrenic, And Neither Am I.
-I'm Serfectly Pober.
-I'm a Bum...a BEACH Bum!
-I'm a cowboy ... on a steel horse I ride!
-I'm a lumberjack, and I'm okay!
-I'm a nobody, nobody is perfect, therefore I'm perfect.
-I'm an Debian developer...I don't NEED a life!
-I'm an absolute, off-the-wall fanatical moderate.
-I'm an incorrigible punster, so don't corrige me!
-I'm an influential person, gravitationally speaking.
-I'm as bored as a pacifist's pistol.
-I'm at the corner of Walk and Don't Walk.
-I'm dangerous when I know what I'm doing.
-I'm easy to please as long as I get my way.
-I'm fallin' down a spiral, destination unknown!
-I'm fascinated by the way memory diffuses fact.
-I'm in shape ... Rounds a shape isn't it?
-I'm leaving my body to science fiction.
-I'm moving to Mars next week, so if you have any boxes.
-I'm new and what's all this then?
-I'm no stranger, just a friend you haven't met...
-I'm not a complete idiot - several parts are missing.
-I'm not as dumb as you look.
-I'm not broke, I'm just badly bent.
-I'm not dead. I'm electroencephelographically challenged.
-I'm not even going to ignore that.
-I'm not fat just horizontally disproportionate.
-I'm not loafing. I work so fast I'm always finished
-I'm not lost, I'm 'locationally challenged.'
-I'm not nearly as think as you confused I am.
-I'm not opinionated, I'm just always right!
-I'm not paranoid! Which of my enemies told you this?
-I'm not real smart, but I can lift heavy things.
-I'm not rude, I'm 'attitudinally challenged'.
-I'm not schizophrenic.  It's this guy beside me!
-I'm not tense, just terribly alert.
-I'm on the crest of a slump.
-I'm out of sick days, so I'm calling in dead!
-I'm pink, therefore I'm Spam.
-I'm schizophrenic, What are you?
-I'm so broke, I can't even pay attention.
-I'm spending a year dead for tax purposes.
-I'm sure it's clearly explained in the Zmodem DOC's
-I'm sure it's in the manual somewhere...
-I'm the person your mother warned you about.
-I'm too smart to let my intelligence go to my head.
-I'm turning you in to the SPCA!
-I've been seduced by the chocolate side of the force.
-I've got Parkinson's disease.  And he's got mine.
-I've got a mind like a.. a.. what's that thing called?
-I've got to sit down and work out where I stand.
-I've had fun before.  This isn't it.
-I've run out of sick leave so I'm calling in dead.
-I've seen the future.  I can't afford it.
-IBM: I've Been Misled
-IBM: It may be slow, but at least it's expensive.
-IBM: you can buy better, but you can't pay more
-IF numcooks > .maxcooks THEN;SET V broth = 'spoiled';END
-INTERLACE: To tie two boots together.
-Ideas are not responsible for their followers!
-If At First You Don't Succeed Ignore The Docs...
-If Clinton's the answer, it must have been a really stupid question.
-If I can't fix it, it's probably dead.
-If I can't win, I don't wanna play!
-If I had anything witty to say, I wouldn't put it here.
-If I had been using Windoze, I'd still be writing this.
-If I save the whales, where do I keep them?
-If I save time, when do I get it back ?
-If I want your stupid opinion, I'll beat it out of you.
-If I were here more often, I wouldn't be gone so much.
-If I were two faced, would I wear this one?
-If I were you, who'd be me?
-If Murphy's Law can go wrong, it will.
-If The Shoe Fits - The Sock Fits !
-If a fly has no wings would you call him a walk?
-If a tree falls on a florist, would he make a sound?
-If all goes well, you've overlooked something!
-If all you have is a hammer, everything looks like a nail
-If at first we don't succeed, we run the risk of failure.
-If at first you don't succeed, call it v1.0!
-If at first you don't succeed, hide your astonishment.
-If at first you don't succeed, put it out for beta test.
-If at first you don't succeed, redefine success.
-If at first you don't succeed, skydiving isn't for you.
-If at first you don't succeed, work for Microsoft.
-If at first you don't succeed, you must be using Windows.
-If brains were dynamite you couldn't blow your nose!
-If cows could fly, everyone would carry an umbrella.
-If evolution is outlawed, only outlaws will evolve.
-If idiots could fly, this would be an airport.
-If in doubt, make it sound convincing.
-If it glows don't touch it!
-If it has feelings, its not cooked enough!
-If it isn't broken, don't fix it.
-If it jams, force it. If it breaks, it needed replacing
-If it walks out of your refrigerator, LET IT GO !!
-If it works, tear it apart and find out why!
-If it's not broke, let me take a crack at it.
-If it's not going to plan, maybe there never was a plan.
-If it's not on fire, it's a software problem.
-If it's not worth doing well, it's not worth doing.
-If it's stupid and works, then it ain't stupid
-If it's too loud, you're too old.
-If life gives you lemons, make lemonade.
-If little else, the brain is an educational toy.
-If marriage is outlawed, only outlaws will have inlaws.
-If money could talk, it would say goodbye.
-If nobody measures up, check your yardstick.
-If rabbits feet are so lucky, what happened to the rabbit?
-If speed scares you, try Windows...
-If the shoe fits, put it in your mouth.
-If there are epigrams, there must be meta-epigrams.
-If there's one thing I can't stand, it's intolerance.
-If this were an actual tagline, it would be funny.
-If truth is stranger than fiction, you must be truth!
-If voting changed anything, they'd make it illegal.
-If winning isn't important then why keep score?
-If you associate with the wise, you will become wise.
-If you believe in telekinesis, raise my hand.
-If you can't run with the big dogs, stay on the porch.
-If you cannot convince them, confuse them.
-If you choke a smurf, what color does it turn?
-If you didn't get caught, did you really do it?
-If you don't care where you are, then you ain't lost.
-If you don't like my opinion of you - improve yourself!
-If you don't like the news, go out and make some of your own.
-If you have nothing to do, don't do it here.
-If you have to ask what jazz is, you'll never know.
-If you hear an onion ring please answer it.
-If you mess with something long enough it'll break.
-If you must drink and drive, drive a Yugo!
-If you saw a heat wave, would you wave back?
-If you say nothing, no one will repeat it.
-If you see an onion ring, ANSWER IT!
-If you think education is expensive, try ignorance.
-If you try to fail, and succeed, which have you done?
-If you want your name spelt wrong, die.
-If you wish work poorly done, pay in advance.
-If you're not confused, you're not paying attention.
-If you're not the solution, you're the precipitate.
-If your attack is going well, then it's an ambush..
-If your ship doesn't come in, swim out to it!
-Ifyoucanreadthis,youspendtoomuchtimefiguringouttaglines!
-Ignorance is temporary; stupid is forever.
-Illiterate? Write for free help.
-Imagery is All In The Mind.
-Imagination is the only weapon in the war against reality
-Impropriety is the soul of wit.
-In God we trust, all others pay cash.
-In a fight between you and the world, back the world.
-In case of emergency, break glass. Scream. Bleed to death
-In case of fire, yell 'FIRE!'
-In politics stupidity is not a handicap.
-In the land of the witless, the halfwit is king.
-In war there is no substitute for victory.
-Include this in your CONFIG.SYS File: BUGS=OFF
-Incompetence plus incompetence equals incompetence.
-Individualists of the world, UNITE!
-Inertia makes the world go round.
-Inferiority complex: conviction by a jury of your fears.
-Innovate or Die.
-Insanity is hereditary.  You get it from your kids.
-Insanity is just a state of mind.
-Insert New Disk for Drive C: Press ENTER when ready.
-Insert inevitable trivial witticism of your choice.
-Interchangeable parts won't.
-Internal combustion engines are the dinosaurs' revenge
-International Brotherhood of Tagline Thieves.
-Interstellar Matter is a Gas
-Invisible Systems, Inc. If you don't see it, we made it.
-Iron Law of Distribution: Them that has, gets.
-Is 'tired old cliche' one?
-Is it OK to yell 'MOVIE' in a crowded firehouse?
-Is it in my head...or in my heart?
-Is it ok to use my AM radio after NOON?
-Is it possible to feel gruntled?
-Is that a flying saucer or a pie in the sky?
-Is there life before coffee?
-Is this a machine?  I don't talk to machines!  [Click]
-Is this the right room for an argument?
-It all looks the same if you're not the lead dog.
-It can't be full...I STILL HAVE SUBDIRECTORIES!
-It compiled, first screen came up??  Ship it! --Bill Gates
-It did what?  Well, it's not supposed to do that.
-It doesn't work, but it looks pretty.
-It has many other uses as well.  Allow me. - Worf
-It is always better to sacrifice your opponent's men
-It is bad luck to be superstitious.
-It is better to be brief than boring.
-It is better to wear out than to rust out.
-It is broke.  It will not work.  It does not go.
-It is fatal to live too long.
-It is incumbent on us to avoid archaisms.
-It is morally wrong to allow suckers to keep their money.
-It is much easier to be critical than to be correct
-It is not enough to succeed.  Others must fail.
-It is, after all,  only a moment in the infinity of time.
-It really bothers me when people cut me o...
-It said 'Insert disk #3', but only two will fit!
-It works better if you plug it in.
-It's 10:00 PM...do YOU know where YOUR tagline is?
-It's Ensign Flintstone - he's Fred, Jim.
-It's a Tough Job! ..... So I'd Rather YOU do it.
-It's a fine line between fishing & standing still
-It's a fine night to have an evening.
-It's a good thing we don't get all the government we pay for.
-It's a tough job! ..... So I'd Rather YOU do it.
-It's an ill wind that gathers no moss.
-It's as bad as you think and they are out to get you.
-It's bad luck to be superstitious.
-It's been a business doing pleasure with you.
-It's been lovely, but I have to scream now.
-It's best to leave quickly when you make noises like that...
-It's better to burn out than to fade away.
-It's clever, but is it art?
-It's de\ 2ja\ 5 vu all over again.
-It's easier to get older than it is to get wiser.
-It's easier to obtain forgiveness than permission.
-It's easy to apply yourself, just use crazy glue!
-It's easy to be brave from a safe distance.
-It's hard to RTFM when you can't find the FM..
-It's hard to be serious when you're naked.
-It's life Jim, but not as we know it.
-It's like Deja Vu all over again...
-It's lonely at the top, but you eat better.
-It's more than a reader.  It's a message base manager!
-It's never too late to have a happy childhood
-It's not easy having an overbearing parent! - Troi
-It's not hard to meet expenses, they're everywhere!
-It's not in the manual!
-It's not just a hobby, it's an obsession!
-It's not pretty being easy.
-It's not the bullet that kills you, it's the hole.
-It's not the money I want, it's the stuff.
-It's not the principle of the thing, it's the money
-It's okay to be ugly...but aren't you overdoing it?
-It's only a hobby ... only a hobby ... only a hobby ... only
-It's only ones and zeros.
-It's raining, it's pouring, the old man is...dead, Jim.
-It's smart to pick your friends, but not your nose.
-It's starting to rain, .SQZ the animals into the .ARC !
-It's true, forgiveness IS easier to get than permission
-Its a JOKE, like the funny kind but different.
-Itsdifficulttobeverycreativewithonlyfiftysevencharacters!
-JFK: I need this motorcade like a hole in my head!
-James Bond rules.  00K.
-Jealousy is all the fun you think they have.
-Jet Engine Theory -Suck, Squeeze, Bang, Blow!
-Join the Group Mind - become a Borg
-Joseph Stalin's grave was a Communist Plot.
-Jumbo shrimp = oxymoron.
-Junk: stuff we throw away.  Stuff: junk we keep.
-Just because you're STUPID ain't no excuse.
-Just because I'm paranoid doesn't mean they aren't out to get me!
-Just do it.
-Just don't tell the asylum you saw me here
-Just how much leg have I got
-Just my 78,000 lira worth.
-Just what part of 'NO' didn't you understand...?
-Just when you think you've won the rat race along come faster rats.
-Justice is incidental to law and order.
-Justice: A decision in your favor.
-Kamikaze Pilot Wanted: Experienced only need apply.
-Keep America beautiful.. properly dispose of your lawyer.
-Keep a clear head and always carry a lightbulb.
-Keep emotionally active. Cater to your favorite neurosis.
-Keyboard Not Found - Press [F1] to Continue
-Kicked wide of the goal with such precision.
-Kids-They're not sleeping, they're recharging!
-Kill them all!  .... Let God sort them out.
-Killer Rabbit's Motto:  'Lettuce Prey.'
-Kilroy occupied these coordinates.
-Kleptomania: take something for it
-Know what I hate?  I hate rhetorical questions!
-Knowing Murphy's Law won't help either.
-LISP:  To call a spade a thpade.
-LISTEN HERE!  I HAVE FIRST AMENDENT RIGH(@#$!9*&^ NO CARRIER
-LOTUS - Let Only The Users Suffer
-Laddie, ya think ya might like ta ... rephrase that?
-Land of the Single Entendre...
-Last week I forgot how to ride a bicycle.
-Laugh and the world thinks you're an idiot.
-Laughter: The shortest distance between two people.
-Lead me not into temptation, I can find it myself.
-Lesser artists borrow. Great artists steal.
-Let he who takes the plunge remember to return it!
-Let's organize this thing and take all the fun out of it.
-Let's split up, we can do more damage that way.
-Liberal - a power worshiper without power.
-Libraries: There are no answers, only cross references.
-Life - brief interlude between nothingness and eternity.
-Life can be great if you live it to the fullest!
-Life is a sandwich, and it's always lunchtime
-Life is a series of very rude awakenings.
-Life is like a Car-wash and I'm on a bicycle.
-Life is only as long as you live it.
-Life is serious, but ART is fun!
-Life is tough. It's tougher when you're stupid.
-Life is uncertain...eat dessert first!
-Life sucks, but Death swallows!
-Life would be easier if I had the source code.
-Life's too short to dance with ugly men.
-Life's too short to dance with ugly women.
-Life, loathe it or ignore it, you can't like it.
-Likelihoods, however, are 90% against you.
-Likes and dislikes are among my favorites
-Linux, the choice of a GNU generation.
-Liposuction will destroy your FAT
-Lisp programmers have to stop and collect garbage.
-Live before you die.
-Living poor is best left to those with no money.
-Locked coathanger in car. Good thing I had a key.
-Looks like I picked the wrong week to stop sniffing glue.
-Love is blind, marriage is the eye-opener.
-Luxuriantly hand-crafted from only the finest ASCII.
-M.A.D.D.:  Midgets Against Desk Drawers.
-MOPAR  =  Move Over Plymouth Approaching Rapidly!
-MS Windows -- From the people who brought you EDLIN!
-MS-DOS: celebrating ten years of obsolescence
-Macho does not prove Mucho.
-Madness takes its toll; please have exact change.
-Make Headlines..use a corduroy pillow....
-Make it as simple as possible, but no simpler.
-Make it do ... Or do without.
-Make like a Tom and Cruise.
-Make like a baby and head out.
-Make like a banana and split.
-Make like a drum and beat it!
-Make like a tree and leave.
-Make somebody happy. Mind your own business.
-Make up a language and ask people for directions.
-Man has his will.  Woman has her won't!
-Man invented language to satisfy his need to complain.
-Man who get hit by car, get that run down feeling
-Man who jumps through screen door likely to strain himself
-Man who put head on railroad track get splitting headache
-Man who run behind car get exhausted.
-Man who speaks with forked tongue should not kiss balloon
-Marching to a different kettle of fish.
-Mary had a little RAM -- only about a MEG or so.
-Math is the language God used to write the universe.
-May I please be excused?  My Brain is full.
-May the Porsche be with you.
-May you live in interesting times.
-May your life be filled with experiences.
-Me know gammar.  Me cood use it gud.
-Mediocrity requires aloofness to preserve it's dignity
-Meditation is not what you Think.
-Meet the new Boss--same as the old Boss...
-Megabyte: A nine course dinner.
-Member: International Brotherhood of Tagline Thieves!
-Memory is a thing we forget with.
-Mental Floss prevents Moral Decay.
-Mercifully free of the ravages of intelligence
-Microfiche: Sardines.
-Microsoft Windows... a virus with mouse support.
-Microsoft gives you Windows... Linux gives you the whole house.
-Migratory lifeform with a tropism for parties
-Minds are like parachutes, they only work when open.
-Misfortune: The kind of fortune that never misses.
-Misspelled? Impossible. My modem is error correcting!
-Mistakes are often the stepping stones to utter failure.
-Modem: What landscapers do to dem lawns.
-Money is the root of all wealth.
-Monogamy leaves a lot to be desired.
-Monopoly? No, we just don't want competition.
-Most of us have been at work for several hours now.
-Mother is the invention of necessity.
-Multitasking = 3 PCs and a chair with wheels!
-Multitasking causes schizophrenia..
-Murphy is out there... waiting...
-Murphy was an optimist.
-Murphy's law needs to be repealed.
-Must Go - My Rotweiler needs its teeth sharpened.
-My *taglines* are original.  *I* am a copy.
-My RAM's not what it used to be, so don't quote me.
-My attention isn't hard to get. It IS hard to keep...
-My best friend is a social worker.
-My computer has a terminal illness
-My computer's sick, I think my modem's a carrier
-My couch potato routine honed to perfection
-My fallacies are more logical than your fallacies.
-My foolish parents taught me to read and write.
-My hat covers my head... Just like hair used to!
-My haystack had no needle!
-My head is sore, and there's a hole in the brick wall!
-My inferiority complexes aren't as good as yours.
-My karma ran over your dogma.
-My life may be strange, but at least it's not boring
-My message above.  Your response here ____________.
-My other computer is a Cray Y/MP-4!
-My other computer is a HAL 9000.
-My other computer is an abacus.
-My other vehicle is a Galaxy Class Starship ...
-My reality check just bounced.
-My tagline can beat up your tagline!
-My weight is perfect for my height... which varies.
-NAVY: Never Again Volunteer Yourself
-NETWORK: What fishermen do when not fishing.
-NEWS! Drunk gets nine months in violin case
-NEWS! Enraged cow injures farmer with ax
-NEWS! Iraqi head seeks arms
-NEWS! Police begin campaign to run down jaywalkers
-NEWS! Stolen painting found by tree
-NEWS! Survivor of siamese twins joins parents
-NO!  Taco Bell is NOT the Mexican Phone Company!
-NUMBER CRUNCHING:  Jumping on a Computer.
-Naaah, real men don't read docs.
-Nanosecond: Mork's stunt man.
-Neil Armstrong tripped.
-Neither rain, nor snow, nor l?ne n*oi*se
-Neurotic: Self-taut person.
-Never argue with a woman when she's tired, or rested.
-Never assume.  It makes an 'ass' out of 'u' and 'me'.
-Never count your chickens before they rip your lips off.
-Never draw fire, it irritates everyone around you
-Never eat anything bigger than your head.
-Never eat more than you can lift.
-Never enter a battle of wits unarmed.
-Never go with the odds
-Never hit a man with glasses.  Use your fist!
-Never judge a man by his taglines.
-Never let your feet run faster than your shoes.
-Never mind the facts - I know what I know.
-Never park your hard disk in a tow-away zone.
-Never say, 'Oops!'; always say, 'Ah, interesting!'
-Never test for an error you don't know how to handle.
-Never trust a man who can count to 1,023 on his fingers
-Never trust a skinny cook.
-Never underestimate the power of human stupidity.
-Never use a preposition to end a sentence with.
-New Highway gets Railroaded.
-Newsbytes - Microsoft announce EDLIN for Windows.
-Nihilism should commence with oneself.
-Ninety per cent of everything is crap.
-Nitpicking:  Not just a hobby, it's a way of life!
-Nitrate:  Lower than the day rate.
-No .sig is a good .sig
-No free lunch in an ecosystem.
-No one EXPECTS the Spanish Inquisition!!!
-No one ever said 'if I'd only spent more time in the office'
-No radio.  Already stolen.
-No sense being pessimistic.  It wouldn't work anyway.
-No wanna work.  Wanna bang on keyboard.
-No, I'm from Iowa. I only work in Outer Space.
-Nobody roots for Goliath.
-Nobody shoots at Santa Claus.
-Nodding the head does not row the boat.
-None of you exist, my Sysop types all this in.
-Nostalgia isn't what it used to be.
-Not a computer nerd; merely a techno-weenie.
-Not a real tagline, but an incredible soy substitute.
-Not many people realize just how well known I am.
-Not now, John, we gotta get on with the game show...
-Not quite human any longer.
-Nothing is 100% certain, bug free or IBM compatible.
-Nothing is as inevitable as a mistake whose time has come
-Nothing is ever so bad that it can't get worse.
-Nothing is foolproof because fools are so ingenious
-Nothing is impossible for anyone impervious to reason
-Nothing recedes like success.
-Nothing succeeds like excess.
-Now entering Iowa.  Please set your clocks back 20 years.
-Now go away or I shall taunt you a second time.
-Now is not a good time to annoy me
-Now is the time for all good men to come to.
-Now that I've given up hope I feel much better...
-Nudge, nudge, wink, wink, know what I mean?
-O Oysters come and walk with us, the Walrus did beseech.
-OK Scotty, detonate and energize NOW!  No, wait, I mean.......
-OK, I'm weird! But I'm saving up to become eccentric.
-OPERATOR! Trace this call and tell me where I am.
-OUT TO LUNCH - If not back at five, OUT TO DINNER!
-Obe Wan Kenobi at the dinner table: 'Use the FORKS, Luke!'
-Objection, your Honor! My client is an idiot!
-Objectivity is in the eye of the beholder
-Objects in taglines are closer than they appear.
-Of all the people I've met you're certainly one of them
-Of all the things I've lost, I miss my mind the most.
-Of course I'm running Windows[kVxB NO CARRIER
-Oh goody! Another Muranium Explosive Space Modulator!
-Oh no you don't!  You're not stealing this one!
-Oh no, not another learning experience!
-Oh, Bullwinkle, that trick NEVER works!
-Ok, I pulled the pin.  Now what?  Where are you going?
-Okay - right after this one we're BACK to the TOPIC
-Old MacDonald had a computer with an EIE I/O
-Old age is better than the alternative.
-On a clear disk you can seek forever.
-On a scale of 1 to 10, 4 is about 7.
-On an electrician's truck: Let Us Remove Your Shorts
-One atom bomb can really ruin your day.
-One good turn gets most of the blanket.
-One is never as happy or unhappy as one imagines.
-One man's Windows are another man's walls...
-One man's upload is another man's download
-One night I came home very late. It was the next night
-One tactical thermonuclear weapon can ruin your whole day.
-One way to better your lot is to do a lot better...
-One way to stop a run away horse is to bet on him.
-Only 19,999 lines of C++ to my next ski trip...
-Only cosmetologists give make-up exams.
-Only the winners decide what were war crimes.
-Open Mouth. Insert Foot. Chew Carefully.
-Optimization hinders evolution.
-Originality is the art of concealing your sources.
-Our houseplants have a good sense of humous.
-Our necessities are few but our wants are endless...
-Out here in the fields...I fight for my meals...!
-Out of Memory!?  But I fed you 6 Megs this morning!
-Out of the mouths of babes does often come cereal.
-Outlaw junk mail, and save the trees!
-Overload--core meltdown sequence initiated.
-Oxymoron - Definite possibility
-Oxymoron - Military Intelligence
-Oxymoron: Bosnian Cease-Fire
-Oxymoron: Soviet Union.
-PC!  Politically Correct (or) Pure Crap!
-PCBackup: 1 of 1362 disks.
-PI seconds is a nanocentury. - Tom Duff, Bell Labs
-PKZip - it's not just for downloads anymore
-Pain is inevitable, suffering is optional.
-Palindrome isn't one.
-Pandemonium doesn't reign here... It pours!
-Paranoia is heightened awareness.
-Paranoia is simply an optimistic outlook on life.
-Pardon my driving, I'm trying to reload.
-Pascal:  What's it Wirth?
-Passwords are implemented as a result of insecurity.
-Patience is a virtue that carries a lot of WAIT!
-Pay your electric bill in pennies.
-Peace through superior firepower.
-People are always available for work in the past tense.
-People say I'm apathetic, but I don't care.
-People who live in glass houses shouldn't!
-People who live in stone houses shouldn't throw glasses.
-Perot/Bush/Quayle: The Millionaire, Skipper & Gilligan.
-Pet Store: 'Buy one, get one flea.'
-Petroleum and coffee had no value a few centuries ago.
-Pi R squared.  Nooo!  Pie R round, cornbread R square!
-Pizza IS the four food groups!
-Plagiarism is the sincerest form of flattery.
-Plagiarism prohibited, derive carefully.
-Plankton lobbyist:  'NUKE THE WHALES!'
-Plasma is another matter.
-Please Tell Me if you Don't Get This Message
-Please call the windows police.  I've caught another gpf.
-Please don't drink and post.
-Please don't take my sunshine away.
-Please recycle this tagline.  Once is not enough.
-Pobody's Nerfect!
-Poets go from bad to verse
-Point not found. A)bort, R)eread, I)gnore.
-Politeness, n: The most acceptable hypocrisy.
-Political panjandrums prologize pedantic paronomasia.
-Political power grows out of the barrel of a gun.
-Politics is the entertainment branch of industry.
-Positive: Mistaken at the top of one's voice.
-Pound forehead on keyboard to continue.
-Power corrupts, but we need electricity.
-Power corrupts. Absolute power is kind of neat.
-Predestination was doomed from the start.
-Predicting the future of technology is fraud with peril!
-Prejudice is the reason of fools. - Voltaire.
-Preserve wildlife... pickle a rat.
-Press <CTRL>-<ALT>-<DEL> to continue...
-Press any key to continue or any other key to quit
-Press any key...NO, NO, NO, NOT THAT ONE!!!!!!
-Procrastination means never having to say you're sorry.
-Procrastination:  The art of keeping up with yesterday.
-Program too small to fit into memory.
-Programming is an art form that fights back.
-Progress is made on alternate Fridays.
-Prosecutors will be violated
-Psychiatrists stay on your mind.
-Psychoceramics: The study of crackpots.
-Push the limit, and the limit will move away!
-Put on your seatbelt. I wanna try something.
-Put people on hold when possible.
-Quantum mechanics do it in leaps.
-Quasimodo is a dead ringer.
-Question Authority, ask me anything
-RAID Antivirus - Kills Virus's DEAD!!!
-Racial prejudice is a pigment of the imagination.
-Radioactive halibut will make fission chips.
-Random order = oxymoron
-Rap music = oxymoron
-Read the dictionary backwards and look for secret messages.
-Real Programmers aren't afraid to use GOTO's.
-Real Trekkers work out at the He's Dead Gym.
-Real men don't set for stun.
-Real men write self-modifying code.
-Reality is a crutch for people who can't handle buttons
-Reality is an obstacle to hallucination.
-Reality is for people who can't handle Star Trek.
-Reality is nothing but a collective hunch.
-Really ??  What a coincidence, I'm shallow too!!
-Recursive, adj.; see Recursive
-Red ship crashes into blue ship - sailors marooned.
-Reduce Carbon Dioxide emmissions - STOP Breathing
-Redundancy: A Politician with an airbag in his car.
-Refuse Novocain...Transcend Dental Medication!
-Remember that you are unique.  Just like everyone else.
-Remember, If you're not in bed by 10:30..... go home!
-Remember, Subaru spelled backwards is U-R-A-BUS.
-Reputation:  what others are not thinking about you.
-Resistance Is Useless!   (If < 1 ohm)
-Return((usBirdInHand = 2 * InTheBush()));
-Reverse the polarity of the neutron flow.
-Revolution is the opiate of the intellectuals.
-Road Kill Cafe:  You kill 'em, we grill 'em.
-Roses are red, Violet's are blue, And mine are white.
-Rotisserie: a ferris wheel for chickens
-Round up the usual suspects!
-Rubber bands have snappy endings!
-Russian Express Card motto: Don't leave home!
-S met ing's hap ening t  my k ybo rd . .
-SCUD : Sure Could Use Directions
-STICK: A boomerang that doesn't work.
-STUPIDITY is NOT a HANDICAP!  Park elsewhere!
-SYNTAX?  Why not--they tax everything else!
-SYSTEM ERROR:  press F13 to continue...
-Santa's elves are just a bunch of subordinate Clauses.
-Sarcasm: barbed ire.
-Save California; when you leave take someone with you.
-Save energy: be apathetic.
-Save the whales!  Trade them for valuable prizes!
-Save the whales.  Collect the whole set.
-Save your money for a rainy day, or a new computer!
-Say yer prayers, y' flea-bitten' varmint.
-Schizophrenia beats being alone.
-Science asks why.  I ask why not.
-Science: preconception meeting verification.
-Scientists discover life causes cancer.
-Scotty! Hurry! Beam me uragg^*z~% NO CARRIER
-Scrute the inscrutable, eff the ineffable.
-See how you can be?
-Seeing is deceiving. It's eating that's believing.
-Send lawyers, guns, & money...
-Send more tourists..... the last ones were delicious!
-Sentient plasmoids are a gas.
-Serving the scum of Paris for over 300 years
-Set mode=Extremely verbose
-Shareware author dies:  .GIF at eleven!
-Shareware: forget the manual...phone the author at home!
-ShelfDoze is a registered Trademark of M$.
-Shell to DOS... come in DOS... Do you copy?
-Shh! Be vewy quiet, I'm hunting wuntime errors!
-Shin - a device for finding furniture in the dark..
-Shoot your program and put it out of its memory!
-Shoplifters with the runs take Clepto Bismol
-Short people are vertically challenged.
-Should I or shouldn't I?... Too late, I did!
-Should I weed the lawn or say it's a garden?
-Show me a sane man.  I'll cure him for you.
-Sign here please:_______________________Thanks
-Sign on Closed Nuclear Power Plant... 'Gone Fission'
-Sign on a clothing store - Come inside and have a fit.
-Signito ergo sum - I sign therefore I am.
-Simon says: don't be so suggestible.
-Sit down, you're rocking the boat!
-Six of one, 110 (base 2) of another.
-Skating away on the thin ice of a new day.
-Slower Traffic Keep Right  -  Is that so difficult?
-Slug Sautee: a hors of a different d'oeuvre.
-Small changes pick up the reins from nowhere.
-Smash forehead on keyboard to continue...
-Smile.  It's the second best thing you can do with your lips.
-Smile... people will wonder what you've been up to.
-Smiley faces were meant to be annoying.
-Smokey the Bear says, 'Strip mining prevents forest fires!'
-Smoking cures weight problems...eventually.
-Smoking is a leading cause of statistics.
-Smurf exterminator.
-So many bytes, so few cps.
-So many lawyers, so few bullets.
-So many pedestrians, so little time.
-So many toys, so little time...
-So much time, and so little to do.
-Socialism is the equal distribution of poverty.
-Software Independent: Won't work with ANY software.
-Software means never having to say you're finished
-Some Do, Some Don't, Some Will and Some Won't.
-Some People....
-Some days you're a bug, other days a windshield.
-Some days, nothing goes left.
-Some little dipstick stole all my good taglines...
-Some minds should be cultivated, others plowed under...
-Some people are so nice to be nasty to.
-Some people are, through no fault of their own, sane.
-Some things have got to be believed to be seen.
-Someone is unenthusiastic about your work.
-Something is rotten in the state of confusion.
-Sometimes a cigar is just a cigar.
-Sorry about your Rectal-Cranial Inversion.
-Sorry, I don't date outside my species.
-Sorry... my mind has a few bad sectors.
-Southern DOS:  Y'all reckon? (yep/Nope)
-Space is an illusion, disk space doubly so.
-Space is big.  Really big.
-Spaceman Spiff, Interplanetary Explorer!
-Speaking only for myself, one of my many tricks.
-Spell chequers dew knot work write.
-Spice is the variety of life.
-Stamp out philately!
-Standing there making a sitting target of himself.
-Stay Alert.  Stay Awake.  Stay Alive.
-Steal my cash, car and TV - but leave the computer!
-Sterility is hereditary.
-Stop tagline theft! Copyright your tagline &copy;
-Strike any user when ready.
-Stupidity got us into this mess, why can't it get us out?
-Subvert the dominant paradigm!
-Suicide is the most sincere form of self criticism.
-Sumo Wrestling: survival of the fattest.
-Supercalifragilisticexpialidocius
-Supernovae are a Blast
-Support bacteria - it's the only culture some people have!
-Support the helpless victims of computers.
-Surprise your boss.  Get to work on time.
-Swish, two, three, four!  Swish, two, three, four!
-Sylvester Stallone: father of the RISC concept.
-THE GOLDEN RULE: He who has the gold makes the rules
-TV is chewing gum for the eyes.
-Tact: knowing how far to go too far.
-Tact: making a point without making an enemy.
-Tagline Lotto: 2222222222<- Scratch here for prize.
-Tagline theft is a compliment.
-Taglines  \'tag-l\ 4inz \  The bumperstickers of the internet
-Take a bite out of crime .. Abolish the IRS!
-Take my advice, I don't use it anyway.
-Take two crows and caw me in the morning
-Talk is cheap because Supply exceeds Demand.
-Taxes are not levied for the benefit of the taxed.
-Teamwork is essential. It gives them another target.
-Ten weeks from Friday will be a pretty good day.
-Thank you very little.
-That ain't so good English!
-That must be wonderful! I don't understand it at all.
-That that is is not that that is not.
-That was ZEN -- this is TAO
-That'll be $67.50  CCCHHHHHIIIIINNNNGGGG!!!!
-That's inches away from being millimeter perfect.
-The Borg assimilated me & all I got was this stupid T-Shirt!
-The Czech's in the mail. Sending Frenchman by FAX.
-The French defense isn't...
-The Hubbell works fine; all that stuff IS blurry!
-The Lab called,..... Your brain is ready!
-The Magic of Windows:  Turns a 486 back into a PC/XT.
-The Microsoft Motto:  'We're the leaders, wait for us!'
-The PARITY CHECK is in the E-MAIL...
-The Tour de France!
-The UARTs won't take this speed, Captain
-The Universe is a big place... perhaps the biggest
-The Vatican Express Card. Don't leave Rome without it.
-The backup's not over 'til the FAT table sings!
-The ballot is stronger than the bullet.
-The best cure for insomnia is to get a lot of sleep.
-The best defense against logic is stupidity.
-The best defense is to stay out of range.
-The best substitute for experience is being sixteen.
-The best way to keep friends is not to give them away.
-The best way to win an argument is to be right.
-The buck doesn't even slow down here!
-The cause of problems are solutions!
-The cost of feathers has risen... Now even DOWN is up!
-The cost of living hasn't affected its popularity.
-The cream rises to the top.  So does the scum...
-The days of the digital watch are numbered
-The dentist said my wisdom teeth were retarded.
-The dreadful burden of having nothing to do.
-The evidence before the court is...INCONTROVERTIBLE!
-The eyes are the mirror of the soul.
-The first duty of a revolutionary is to get away with it
-The first myth of management is that it exists.
-The first rule of intelligent tinkering is save all parts!
-The fish that escaped is the big one.
-The further I go, the behinder I get.
-The future isn't what it used to be.
-The game's a little bit wide open again.
-The gene pool has no lifeguard.
-The hand that turneth the knob, opens the door.
-The hangman let us down.
-The hardest thing about time travel is the grammar.
-The heart is wiser than the intellect...
-The irony of life is that no one gets out alive...
-The large print giveth and the small print taketh away.
-The little engineer that could
-The longer the title, the less important the job.
-The man who begins many things finishes few.
-The margin is very marginal.
-The meek shall inherit the earth, if that's OK with you
-The mind is like a parachute - it works only when open.
-The moving cat sheds, and having shed, moves on...
-The next thing to do is hang all the consultants.
-The only thing shorter than a weekend is a vacation.
-The option to override self-destruct expir@^%i@&$#NO CARRIER
-The pen is mightier than the pencil.
-The penalty for bigamy is having two mothers-in-law.
-The pendulum has gone full circle.
-The purpose of computing is insight, not numbers.
-The rich get richer; the poor get babies.
-The road to success is always under construction.
-The score didn't really reflect the outcome.
-The secret of the universe is~~*#~** FF * NO CARRIER
-The shortest distance between two points is off the wall
-The simple explanation always follows the complex solution
-The sixth sheikh's sixth sheep's sick.
-The soul would have no heart had the eyes no tears...
-The superfluous is very necessary.
-The thrill is gone, the thrill is gone baby
-The universe is a spheroid region 705 meters in diameter...
-The unnatural, that too is natural.
-The way to a man's heart is through the left ventricle.
-The weather is here, wish you were beautiful.
-The whole world is about three drinks behind
-The world is coming to an end.  Please log off.
-The worst thing about censorship is **************************.
-The young know the rules, the old know the exceptions.
-Then somebody spoke, and I went into a dream....
-There are 2 ways to handle women and I know neither.
-There are many things I could say...
-There are no atheists in the foxholes.
-There is always a way, and it usually doesn't work.
-There is an exception to every rule, except this one.
-There is much Obiwan did not tell you.
-There is no dark side of the moon.  Really.
-There is no finish line.
-There is no remedy for fun but more fun!
-There is no vaccine against stupidity.
-There is something to be said about me: 'Wow!!'
-There will be no last bus tonight.
-There's a hot place with pitchforks waiting.
-There's no future in time travel
-There's no such thing as a free lunch, but you can always find someone willing to treat.
-There's one in every car... You'll see.
-There's one in every crowd and they always find me.
-There's safety in numbers/When you learn to divide.
-Thesaurus: ancient reptile with an excellent vocabulary.
-They told me I was gullible ... and I believed them!
-Things are not what they seem.
-Think 'HONK' if you're a telepath.
-Think hard now!  Which one is Shinola?
-This Charlie Brown must have been a very wise man.
-This Country Needs Group Therapy.
-This ain't no party...this ain't no disco...
-This door is baroque; please call Bach later.
-This is a Tagline mirror ][ rorrim enilgaT a si sihT
-This is abuse.  Arguments are down the hall.
-This is just a hobby. Perfection is not required. Fun is.
-This is not a fairing, it's a force field.
-This is only a test.
-This is our only tag line.
-This isn't right.  This isn't even wrong.
-This line intentionally left unjustified.
-This login session: $13.99, but for you $11.88
-This message has been UNIXized for your protection.
-This message is SHAREWARE!  To Register, send $5.
-This message was typed on recycled phosphorous.
-This mind intentionally left blank.
-This program makes me look like a genius.
-This sentence is false.
-This tagline does not require Micro$oft Windows.
-This tagline intentionally left blank.
-This tagline is umop apisdn
-This tagline only to be removed by the consumer.
-This tagline was created from many little letters.
-This tagline was reclaimed and is not yet stolen.
-This tagline was written before a live studio audience.
-Those who can't write, write manuals.
-Those who can, do.  Those who can't, simulate.
-Those who can, do.  Those who can't, supervise!
-Those who live by the nit, die by the nit
-Those without heads do not need hats.
-Three can keep a secret, if two are dead.
-Tilt your chair back, your breath is effecting my RAM!
-Tilting at windmills hurts you more than the windmills.
-Time flies like an arrow - Fruit flies like a banana
-Time flies when you don't know what you're doing.
-Time is an illusion, lunchtime doubly so.
-Tis better to be hunter than hunted.
-Tis better to have loved a short than to never have loved a tall.
-Tis better to have loved and lost than just to have lost.
-To be, or not to be, those are the parameters.
-To boldly go and watch Star Trek re-runs.
-To do nothing is also a good remedy.
-To eat is human, to digest, divine.
-To err is human, to eat Jello, is messy.
-To err is human, to forgive is against company policy.
-To err is human.  To really screw up it takes a computer.
-To err is human. To blame someone else is politics.
-To err is human. To moo bovine
-To every rule there is an exception, and vice versa.
-To iterate is human, to recurse, divine.
-To live in the hearts we leave behind, is not to die.
-To live well, know the difference between good and evil.
-To me personally, it's nothing personal to me.
-To shoot a mime, do you use a silencer?
-Today is Monday, cleverly disguised as Tuesday.
-Today is National Existential Ennui Awareness Day.
-Today is the first day of the rest of this mess.
-Today is the tomorrow you worried about yesterday
-Todays subliminal message is ' '
-Tolkien is hobbit-forming.
-Tongue tied & twisted, just an earthbound misfit I.
-Too bad stupidity isn't painful.
-Too much is never enough.
-Too much month at the end of the money.
-Too much of a good thing is WONDERFUL.
-Toto, I don't think we're in DOS anymore...
-Touch if you must, Pay up if you bust.
-Toys are made in heaven, batteries are made in hell.
-Trees hit cars only in self-defence.
-Trespassers will be shot, survivors will be shot again!
-Tried to play my shoehorn... all I got was footnotes!
-Trig..a..name...o...tree!!!
-Truck Pulls: for people who cannot understand the WWF
-Trust me -- I'm a Lawyer.
-Truth is just another misconception.
-Truthful: Dumb and illiterate.
-Try to get back on topic, he said moderately.
-Try to look unimportant, they may be low on ammo
-Try?  Try not.  Do, or do not.  There is no try.
-Trying to think of a good tagline...
-Tubby or not tubby, fat is the question!
-Turn right here. No! NO! The OTHER right!
-Turning floppies into hard drives.
-Two Wrongs Don't Make A Right, But Three Lefts Do.
-Two heads are more numerous than one.
-Two most common elements: hydrogen, stupidity.
-Tyre Shop sign - We Skid You Not.
-UART what UEAT!
-UNNAMED LAW: If it happens, it must be possible.
-Uh, yeah...I MEANT to do that!
-Ultimate Question Research Team
-Unable to locate Coffee -- Operator Halted!
-Unburdened by the rigors of coherent thought.
-Unix and the world Unix with you; VAX and you VAX alone.
-Unless you're the lead dog, the view never changes.
-Unqualified superlatives are the worst of all.
-Until people grow up, they have no idea what's cool
-Use your MasterCard to pay your Visa bill.
-Users, losers -- what's the difference?
-Using yesterday's technology to solve today's problems, tomorrow
-VLSI:  'Getting High On Low Voltage'
-Vampires Against Mundane Poetry.
-Variables won't; constants aren't.
-Veni Vidi Visa: I came, I saw, I did a little shopping.
-Verbosity leads to unclear, inarticulate things.
-Volcano -- a mountain with hiccups.
-Vote Democratic... It's easier than getting a job.
-Vuja De - The Feeling You've Never Been Here
-Vulcans have less fun.
-Vultures only fly with carrion luggage.
-W.A.R.P.: We Are Real Programmers.
-WAITER! there's soup in my fly!
-WARNING ... drinking tap water can kill your thirst!
-WARNING: my messages are offensive to morons!
-WINDOWS ERROR #004: Operator fell asleep while waiting.
-WWhhaatt   ddooeess   dduupplleexx    mmeeaann??
-WYGIWYD -What you got is what you deserved.
-WYTYSYDG-What you thought you saw, you didn't get.
-Waiter, there's no fly in my soup! - Kermit
-Walk softly and carry a megawatt laser.
-Walls impede my progress
-Wanna flirt with disaster? Become a SysOp!
-Want a LAUGH run a spell check on DSZ docs.
-Want a jelly baby?
-Want a stupid answer? Ask me anything!
-Wanted: Volcano.  Average size.  Must be active.
-War News: Saddam's army blown away by Thai hookers.
-Warning:  Whimsical when bored
-Warning: Politicians can damage your wealth.
-Warranty void if tagline removed.
-Was today really Necessary?
-Wash your face in the morning, neck at night.
-Wasting time is an important part of living.
-We all live in a yellow subroutine.
-We are not a clone.
-We are the people our parents warned us about
-We don't care. We don't have to. We're Telecom...
-We have here the latest in primitive technology.
-We seem to have juxtaposed an impasse here
-We should limit congressmen to two terms: one in Congress, one in prison
-We take drugs very seriously at my house...
-We were unanimous - in fact everyone was unanimous.
-We'll give you piece de resistance and a tour de force
-We're as similar as two dissimilar things in a pod.
-We're lost, but we're making good time.
-We're staying together for the sake of the cats.
-Weeping, I wake; waking, I weep, I weep.
-Welcome to Texas, now go home.
-Welcome to the Church of the Holy Cabbage. Lettuce pray
-Well cover me in egg & flour and bake me for 14 minutes
-What are you doing?!? The message is over,GO AWAY!
-What can you do for me?
-What color is a chameleon on a mirror?
-What could possibly go wrong.
-What do batteries run on?
-What do you mean that 2 years have passed??
-What do you think?
-What does Santa do at a house with no chimney?
-What does ignorant mean?
-What does this red button do?
-What else can you do at 3:00 am?
-What garlic is to salad, insanity is to art.
-What goes around usually gets dizzy and falls over.
-What goes up has probably been doused with petrol.
-What has four legs and an arm? A happy pitbull.
-What's Irish and stays out all night? Paddy O'Furniture.
-What's another word for 'thesaurus?'
-What's brown and sticky? A stick!
-When 911 won't work .357 will!
-When in doubt, think.
-When their numbers dwindled from 50 to 8, the dwarfs began to suspect 'Hungry'
-When your opponent is down, kick him.
-Where does weight go when you lose it?
-Where in the world is Carmen San Diego?
-Who cares how it plays in Peoria?
-Who cares who's on board?
-Who glued the cup to the table?
-Who is 'they' anyway?
-Whosoever diggeth a pit shall falleth therein.
-Why am I asking all these things?
-Why are Chinese fortune cookies written in English?
-Why are you looking down here? The joke is above!
-Why are you wasting time reading taglines?
-Why aren't there many Hannukah specials on tv?
-Why can't we just spell it orderves?
-Why did you read this?
-Why do people cry when they're sad?
-Why do they tell us to watch 'The Today Show' tomorrow?
-Why do we elect people and then become afraid of them?
-Why do we read left to right yet turn pages right to left?
-Why do you think they call it 'find'?
-Why does it matter if we all put our pants on one leg at a time?
-Why does the beginning of your sentence end up in the middle of mine?
-Why don't ease, lease, and please sound alike?
-Why don't tomb, comb, and bomb sound alike?
-Why get even, when you can get odd?
-Why is 'abbreviated' such a long word?
-Why isn't 'palindrome' spelled 'palindromeemordnilap'?
-Will Rogers never met a lawyer.
-Will the sound of one hand clapping still turn off my TV?
-Win if you can, lose if you must, but always cheat
-Windows Error #F99 - CPU too tired to continue...
-Windows N'T:  as in Wouldn't, Couldn't, and Didn't.
-Windows NT: Only 16 megs needed to play Minesweeper!
-Windows NT: The world's only 80 megabyte Solitaire game!
-Windows NT: Vapourware of the desperate and scared.
-Windows error 000 : No errors found! [CLOSE]
-Windows is *NOT* a virus. Viruses *DO* something!
-Windows is for fun, Linux is for getting things done.
-Windows is the best GUI - It always sticks!
-Windows isn't CrippleWare -- it's 'Functionally Challenged'.
-Windows only crashes itself under Linux.  Not the whole machine.
-Windows would look better with curtains.
-Windows: The answer to a question nobody has ever asked.
-Windows: an Unrecoverable Acquisition Error!
-WindowsNT: From the makers of Doublespace
-Wisdom is knowing what to do with what you know.
-Wit is cultured insolence.
-Without Time, everything would happen at once.
-Without music, life would be a mistake.
-Women - can't live with 'em and no resale value...
-Women do come with instructions; ask them.
-Women get minks the same way minks get minks.
-Women who seek to be equal to men lack ambition.
-Women! Can't live with 'em and no resale value.
-Work off excess energy. Steal something heavy
-World ends today at 9:30 pm!  Film at 11:00...
-Worry : The interest paid on trouble before it's due
-Worst-dressed sentient being in the known universe
-Would I ask you a rhetorical question?
-Yes my son, long ago mail was read 1 packet at a time.
-You buttered your bread, now lie in it.
-You can name your salary here. I call mine Fred.
-You can tune a guitar, but you cant tuna fish.
-You can't have everything...where would you put it?
-You hit the nail right between the eyes.
-You're it.
-You've got to be trusted by the people that you lie to.
-Young gorillas are friendly, but they soon learn.
-Your E-Mail has been returned due to insufficient voltage!
-Youth is a gift of nature. Age is a work of art.
-Yuk, what kind of dumb menu system is that?  Oh, so that is Windows!
-Zen T-Shirt: Enlightenment Available - Enquire Within
-[DISCLAIMER:  my fingers are epileptic]
-[If you can't hear me, it's because I'm in parentheses]
-hAS ANYONE SEEN MY cAPSLOCK KEY?
-Serenity through viciousness.
-FUN is never having to say you're SUSHI!!
-Include me out.
-YOW!!  I'm in a very clever and adorable INSANE ASYLUM!!
-'That boy's about as sharp as a pound of wet liver' -- Foghorn Leghorn
-Pardon me while I laugh.
-Vegeterians beware!  You are what you eat.
-Marriage is the sole cause of divorce.
-'From there to here, from here to there, funny things are everywhere.' -- Dr. Seuss
-You'll be sorry...
-The world is coming to an end.  Please log off.
-UH-OH!!  We're out of AUTOMOBILE PARTS and RUBBER GOODS!
-I used to get high on life but lately I've built up a resistance.
-Paranoia is heightened awareness.
-The things that interest people most are usually none of their business.
diff --git a/files/infobot.help b/files/infobot.help
new file mode 100644 (file)
index 0000000..c0370ee
--- /dev/null
@@ -0,0 +1,497 @@
+# Revised: 20071016
+#  Author: Tim Riker <Tim@Rikers.org>
+###
+
+main: I learn mainly by observing declarative statements such as "x is at http://www.xxx.com", and then reply when people ask things like "where can i find x?"
+
+action: This is used to override the usual response. "x is <action> does the hokey-pokey". When asked about x, the bot does this "* infobot does the hokey-pokey"
+
+alternation: The || symbol in an entry causes an infobot to choose one of the replies at random. "X is Y||Z" will produce "X is Y" or "X is Z" randomly.
+
+author: oznoid (mailto:lenzo@ri.cmu.edu) is my original author.
+
+dollar variables: D: To be used in factoids
+dollar variables: $Fdunno      - ...
+dollar variables: $Fquestion   - ...
+dollar variables: $Fupdate     - ...
+dollar variables: $channel     - channel from which the factoid was requested
+dollar variables: $date        - current date (GMT)
+dollar variables: $day         - day of week (full name, locale)
+dollar variables: $factoids    - factoid count
+dollar variables: $host        - hostname of factoid requester
+dollar variables: $ident       - bot nick
+dollar variables: $lastspeaker - ...
+dollar variables: $memusage    - ...
+dollar variables: $rand        - random number, also $rand100.2
+dollar variables: $randnick    - random nick
+dollar variables: $startTime   - start time
+dollar variables: $time        - current time (GMT)
+dollar variables: $uptime      - ...
+dollar variables: $user        - username of factoid requester
+dollar variables: $who         - nick of factoid requester
+
+corrections: If I come back with "...but x is at http://xx.xx.xx" or something like that, and you want to change the entry, use "no, x is at http://sdfsdfsdf".  The "No," tells me to supercede the existing value.
+corrections: you can append stuff to a factoid with "also". "x is also at ..."
+
+math: D: math expresions can be evaluated. This uses Perl syntax.
+math: E: 1+1
+math: + - add
+math: - - subtract
+math: * - multiply
+math: / - division
+math: ** - to the power
+math: pi - pi
+math: & - and
+math: | = or
+math: ^ - xor
+
+redirection: If a factoid x contains simply "<reply> see y", then when asked for x, I will deliver factoidor command result y instead.
+
+reply: There is a special tag, <reply>, that is used to override the usual response.  Usually, a response is "X is Y", but it can be made "Y" by making the entry "X is <reply> Y".
+
+# now the commands...
+
+adduser: D: Administrative command to add new user to the .users file
+adduser: U: ## <user> <mask>
+adduser: E: ## bloot bloot!bloot@example.com
+
+addressing: It is a good idea if I stay in REQUIRE mode so that I won't yell out random crap if I listen in too hard.  Currently there is no way to turn this off on-the-fly. (REQUIRE mode requires me to be addressed by name if I am to respond)
+
+babelfish: D: Frontend to babelfish translating service provided by http://babelfish.altavista.com/ Note that utf8 is used for non-ascii characters.
+babelfish: U: x <fromLang> <toLang> <words>
+babelfish: U: translate <fromLang> <toLang> <words>
+babelfish: E: x en de your cars rock
+
+-ban: D: FIXME:
+-ban: U: ## <mask|user>
+-ban: E: ## *!*@owns.org
+-ban: E: ## MoronMan
+
++ban: D: FIXME:
++ban: U: ## <mask|user> [chan] [time] [reason]
++ban: E: ## *!*@owns.org #bots 60 stop flooding.
++ban: E: ## *!*@*microsoft.com STOOPID
++ban: E: ## MoronMan
+
+botmail: D: Send someone botmail
+botmail: U: ## {for <who>[:] <message>}|stats|check|read
+botmail: E: ## for infobot: you rock!
+botmail: E: ## stats
+botmail: E: ## check
+botmail: E: ## read
+
+-chan: D: Leave a channel permanently
+-chan: U: ## -#channel
+-chan: E: ## -#botpark
+
++chan: D: Join a channel permanently
++chan: U: ## #channel
++chan: E: ## #botpark
+
+chaninfo: D: Display channel statistics on Op, Ban, Deop, Unban, Part, Join, SignOff, PublicMsg, Kick and Topic
+chaninfo: U: ## [#channel]
+chaninfo: E: ##
+chaninfo: E: ## #botpark
+
+chanset: D: set a variable for a channel
+chanset: U: ## [#chan] [what] [val]
+chanset: E: ## #c +test
+chanset: E: ## #c -test
+chanset: E: ## #c test
+chanset: E: ## #c test 0
+chanset: E: ## #c test testing123
+
+chanunset: D: remove a variable from a channel
+chanunset: U: ## <#chan> [what]
+chanunset: E: ## #c
+chanunset: E: ## #c test
+
+chattr: D: Change flags on a user (see "help flags")
+chattr: U: ## <user> [flags]
+chattr: E: ## bloot +nmo
+chattr: E: ## bloot -ot
+chattr: E: ## bloot
+
+chnick: D: rename a nick (user) entry
+chnick: U: ## [nick] <new-nick>
+chnick: E: ## moron
+chnick: E: ## owner eleet
+
+chpass: D: Change a user's password
+chpass: U: ## [user] <pass>
+chpass: E: ## testing
+chpass: E: ## testing test0R
+
+contents: D: Debian Contents search only (no Packages)
+contents: U: ## <string> [dist]
+contents: E: ## strings.h
+contents: E: ## x11amp potato
+
+cookie: I can feed your appetite with random factoids.
+
+cpustats: cpustats dumps the bot's cpu usage this session
+
+crypt: It's good that you thought about encryption. I can do it for you.
+crypt: U: ## <salt> <string>
+crypt: E: ## 69 changeme
+crypt: E: ## $1$abcde changeme
+
+cycle: D: Causes me to cycle in the channel it's said, or in the named channel
+cycle: U: ## [channel]
+cycle: E: ##
+cycle: E: ## #botpark
+
+dauthor: D: Find Debian package maintainers, and list the packages they maintain
+dauthor: U: ## <string> [dist]
+dauthor: E: ## Wichert
+dauthor: E: ## Wichert potato
+
+dbugs: D: Show the current count of release critical bugs (latest versions)
+dbugs: U: ##
+
+deluser: D: Administrative command to remove a user from the .users file
+deluser: U: ## <user>
+deluser: E: ## bloot
+
+ddesc: D: Search the Description: lines in Debian packages
+ddesc: U: ## <string> [dist]
+ddesc: E: ## mule
+ddesc: E: ## mule potato
+
+dfind: D: Debian Packages (fallback to Contents) search
+dfind: U: ## <string> [dist]
+dfind: E: ## strings.h
+dfind: E: ## x11amp potato
+
+dict: D: DICT Protocol Client - likely dicts: elements web1913 wn gazetteer jargon foldoc easton hitchcock devils world02 vera
+dict: U: ## [entry num] <query>[/dict]
+dict: E: ## linux
+dict: E: ## 33 set/wn
+
+dns: D: Query DNS
+dns: U: ## <host|ip>
+dns: E: ## debian.org
+dns: E: ## 3.1.33.7
+
+do: D: operator command to do things in a channel
+do: U: ## <chan> <what>
+
+dstats: D: Show basic stats on the current size of the Debian distros
+dstats: U: ## [dist]
+dstats: E: ##
+dstats: E: ## potato
+
+factinfo: D: View statistical information about a particular factoid.
+factinfo: U: ## <factoid>
+factinfo: E: ## test
+
+factstats: D: Display statistical data (max of 15) about factoids.
+factstats: U: ## <type>
+factstats: == author    -- top author of factoids.
+factstats: == deadredir -- ??
+factstats: == duplicate -- duplicate factoids.
+factstats: == listfix   -- ??
+factstats: == locked    -- locked factoids.
+factstats: == new       -- recent addition of factoids.
+factstats: == nullfactoids -- ??
+factstats: == partdupe  -- initial partial duplicate factoids.
+factstats: == profanity -- possibly offensive factoids.
+factstats: == redir     -- redirection in factoids.
+factstats: == reqrate   -- ??
+factstats: == requested -- most requested factoids.
+factstats: == requesters -- most requested factoids.
+factstats: == seefix    -- ??
+factstats: == toolong   -- factoid {key|value} exceeding specified length.
+factstats: == tooshort  -- factoid {key|value} shorter than specified length.
+factstats: == total     -- ??
+factstats: == unrequest -- unrequested factoids.
+factstats: == vandalism -- ??
+factstats: E: ## new
+
+forget: If I have an old/redundant factoid x, "forget x" will cause me to erase it.
+
+freshmeat: D: Frontend to www.freshmeat.net
+freshmeat: U: ## <query>
+freshmeat: E: ## infobot
+
+hex: D: Convert ascii to hex
+hex: U: ## <string>
+hex: E: ## carrot
+
+httpdtype: D: Get httpd server software version / configuration
+httpdtype: U: ## <hostname>
+httpdtype: E: ## example.com
+
+ignore: D: ignore list management
+ignore: E: ## [mask chan expire comment]
+ignore: E: addignore guu!*@*
+
+ircstats: ircstats dumps some status information on the bot's IRC connection
+
+join: U: ## <#chan> [key]
+join: E: ## #botpark
+join: E: ## #botpark rules
+
+karma: Karma is a community rating system.  Use "X++" to increase the karma, or "X--" to decrease it.  Ask for ratings using "karma for X?"
+
+kernel: D: Frontend to linux.kernel.org's finger response.
+kernel: U: ##
+
+kick: U: ## <nick> [#chan] [message]
+kick: E: ## oznoid
+kick: E: ## larne #botpark
+kick: E: ## john #foo go away!
+
+lart: D: Luser Attitude Readjustment Tool
+lart: U: ## [#chan] <who>
+lart: E: ## lenzo infobot's bugginess
+lart: E: ## #perl everyone perl \=\= lamerville
+
+lc: D: lower case a given string
+lc: U: ## <string>
+lc: E: ## When will infobot achieve world domination?
+
+listauth: D: Search the factoid extension db by creator
+listauth: U: ## <search>
+listauth: E: ## xk
+
+listkeys: D: Search the factoid database by key (factoid)
+listkeys: U: ## <regex>
+listkeys: E: ## infobot
+
+listvalues: D: Search the factoid database by value (description)
+listvalues: U: ## <regex>
+listvalues: E: ## infobot
+
+literal: used to get a raw factoid contents. Use _default to ignore factoidSearch path.
+literal: U: ## [_default|prefix] <factoid>
+literal: E: ## infobot
+
+lobotomy: I can be given a lobotomy ([o] is required) if people start to abuse me.  To bring me back to life, give me an unlobotomy
+
+lock: D: Factoid locking to prevent removal by others
+lock: U: ## <factoid>
+lock: E: ## abuse
+lock: N: By default, only registered "ops" on the bots or factoids matching the user's nick are able to lock factoids.
+lock: N: Requires factoid extension (extra) support enabled.
+
+md5: D: calculates the md5sum of a given string
+md5: U: ## <string>
+md5: E: ## When will infobot achieve world domination?
+
+mode: set modes for a channel
+mode: U: ## <#chan> <mode>
+mode: E: ## #botpark +t
+mode: E: ## #botpark -i
+
+news: D: News functions
+news: U: ## [chan] <add,del,mod,set,latest,read,help>
+
+news add: D: Add news items
+news add: U: news [chan] add <title>
+news add: E: news add This is a test
+news add: see _news set Text_ aswell
+
+news set: D: Set stuff for news item
+news set: U: news [chan] set <item> <what> [value]
+news set:    valid <what>: Expire, Text
+news set: E: news set 1 Text ok, this works
+news set: E: news set test Text and this is a test
+news set: E: news set test Text
+
+news set expire: D: Set expire for news item
+news set expire: U: news [chan] expire <what> <value>
+news set expire: value can be: Xd Xh Xm Xs
+news set expire: value can be: never
+news set expire: news expire 1 3days
+news set expire: news expire 2 +20d
+news set expire: news expire Test 30d 20h 10m 5s
+news set expire: news expire TEST never
+
+news del: D: Delete news item (requires +o or be author)
+news del: U: news [chan] del <item>
+news del: E: news del 1
+news del: E: news del test
+
+news mod: D: Modify a news item (todo: modify Text aswell)
+news mod: E: news [chan] mod <item> s/<from>/<to>/[g]
+news mod: E: news mod 1 s/test/Test/
+news mod: E: news mod test s/test/Test/g
+
+nickometer: D: Measures the lame-ness of a nick or channel
+nickometer: U: ## {nick,channel}
+nickometer: E: ## unknown_lamer
+nickometer: E: ## #botpark
+
+onjoin: D: get/set OnJoin message (needs chan option +OnJoin)
+onjoin: U: ## [#chan|_default] [-]<nick> [message]
+onjoin: E: ## infobot Hey! It's another infobot!
+
+ord: D: Convert ascii to decimal
+ord: U: ## <single character>
+ord: E: ## c
+
+page: D: Send someone a pager message
+page: U: ## <who> <message>
+page: E: ## infobot you rock!
+page: NOTE: this uses the "<who>'s pager" factoids for the From: and To: addresses of the format "example's pager" is "mailto:me@example.com"
+
+part: D: Leave a channel (DCC only)
+part: U: ## <#channel>
+part: E: ## #botpark
+part: NOTE: /kick is an alternative
+
+piglatin: D: translates english text into piglatin
+piglatin: U: ## <string>
+piglatin: E: ## When will infobot achieve world domination?
+
+quote: D: Frontend to yahoo's online stock market share listing
+quote: U: ## <query...>
+quote: E: ## RHAT,MSFT
+
+rename: D: Factoid renaming
+rename: U: ## 'from' 'to'
+rename: E: ## 'infobot' 'infobot'
+
+reverse: D: reverses a given string
+reverse: U: ## <string>
+reverse: E: ## When will infobot achieve world domination?
+
+rot13: D: ROT13's a given string
+rot13: U: ## <string>
+rot13: E: ## guvf vf n ynzr rknzcyr
+
+say: D: operator command to say things in a channel
+say: U: ## <chan> <what>
+
+scramble: D: scrambles a given string
+scramble: U: ## <string>
+scramble: E: ## When will infobot achieve world domination?
+
+search: U: ## <engine> for <string>
+search: E: ## google for infobot
+
+seen: D: Report last seen time for somebody
+seen: U: ## <nick>
+seen: E: ## infobot
+
+slashdot: D: News for nerds, Stuff that matters. [tm] (shows the headlines)
+slashdot: U: ##
+
+spell: You've guessed it right, I'm a spell checker. Give me any word and I can confirm whether it's good or bad.
+
+status: status dumps general status information
+
+tell: D: Tell someone about a factoid or command
+tell: U: ## <who> -?about <what>
+tell: E: ## me about infobot
+tell: E: ## someone -about testing
+
+topic add: D: Add your own topic
+topic add: U: ## <topic>
+topic add: E: ## This is a test
+
+topic del: D: Delete one or two subtopics
+topic del: U: ## <#>
+topic del: E: ## 1
+topic del: E: ## 1-3,5
+topic del: E: ## last
+
+topic mod: D: Search and replace strings in the topic
+topic mod: U: ## <REGEX>
+topic mod: E: ## s/test/TEST/
+topic mod: E: ## s#msg test#/msg test#g
+
+topic mv: D: Move subtopics around.
+topic mv: U: ## <#> <before|after|swap> <#>
+topic mv: E: ## 1 after 2
+topic mv: E: ## first before last
+
+topic restore: D: Restores the topic to an earlier version
+topic restore: U: ## <#>
+topic restore: E: ## 3
+
+topic: Usage for 'topic [#chan] <params>':
+topic:   ---------------- __Subtopic__:
+topic:   add <TOPIC>    - Append <TOPIC> to topic.
+topic:   del <#>        - Remove subtopic <#> from topic.
+topic:   list           - Display subtopics.
+topic:   mod s/old/new/ - Search and replace topic.
+topic:   mv <ARGS>      - 'topic mv'.
+topic:   shuffle        - Randomly organize subtopics.
+topic:   ---------------- __Topic__
+topic:   history        - Show previous topics.
+topic:   restore <#>    - Restore topic to <#>.
+topic:   rehash         - Rehash changes to topic.
+topic:   info           - Who and time info.
+topic:   ---------------- __Misc__
+topic:   about          - Read the file :)
+topic:   help           - This screen.
+
+topic: NOTE: #chan arg is only required if command is sent over private message to nick, otherwise it is not needed if sent to the channel.
+topic: NOTE: commands can be preceeded? with '-' in order not to enforce changes to topic.
+topic: End of help.
+
+uc: D: upper case a given string
+uc: U: ## <string>
+uc: E: ## When will infobot achieve world domination?
+
+unforget: If a factoid has been forgotten, "unforget x" will cause me to unerase it.
+
+unlobotomy: Not possible in real life, an unlobotomy will bring me back to life in the case of a lobotomy.
+
+unlock: D: Factoid unlocking to allow removal by others.
+unlock: U: ## <factoid>
+unlock: E: ## abuse
+
+uptime: D: Show the current uptime, and the top 3 uptimes recorded
+uptime: U: ##
+
+wantnick: If someone's taken my nick (I hope not) and I'm using some temporary nick, I can change back to my original nick if it's not taken (again).
+
+wikipedia: D: Frontend to the Wikipedia at http://www.wikipedia.org/wiki/ Note that utf8 is used for non-ascii characters.
+wikipedia: U: ## <topic>
+wikipedia: U: wiki <topic>
+wikipedia: E: wiki irc
+
+wtf: D: Interface to the BSD wtf command
+wtf: U: ## <abbreviation>
+wtf: E: ## iirc
+
+-host: D: admin command to remove hostmask from a user account
+-host: U: ## [user] <mask>
+-host: E: ## *!*@owns.org
+-host: E: ## owner leet!leet@*.heh.org
+
++host: D: admin command to list or add hostmasks to a user account
++host: U: ## [user] [<mask>]
++host: E: ## owner
++host: E: ## *!*@owns.org
++host: E: ## owner leet!leet@*.heh.org
+
+flags: D: Flags for chattr command
+flags: D: "A" - bot administration over /msg (default is only via DCC CHAT)
+flags: D: "O" - dynamic ops (as on channel). (automatic +o)
+flags: D: "T" - add topics.
+flags: D: "a" - ask/request factoid.
+flags: D: "m" - modify factoid. (includes renaming)
+flags: D: "n" - bot owner, can "reload"
+flags: D: "o" - master of bot (automatic +amrt)
+flags: D:        - can search on factoid strings shorter than 2 chars
+flags: D:        - can tell bot to join new channels
+flags: D:        - can [un]lock factoids
+flags: D: "r" - remove factoid.
+flags: D: "t" - teach/add factoid.
+flags: D: "s" - Bypass +silent on channels
+
+rssfeeds: D: rssfeeds is used to control the RSS Feed tracking module
+rssfeeds: U: rssfeeds [command]
+rssfeeds: E: rssfeeds flush
+rssfeeds: D: flush - Will erase the cache file. (Must be chattr +o)
+rssfeeds: D: update - Force a manual update of the feeds. (Must be chattr +o)
+
+hex2ip: D: Convert Hex idents for some gateways to an IP address
+hex2ip: U: ## <8 char hex value>
+hex2ip: E: ## AabBcC12
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/files/infobot.lang b/files/infobot.lang
new file mode 100644 (file)
index 0000000..242378b
--- /dev/null
@@ -0,0 +1,111 @@
+# infobot.lang: configurable responses.
+# by the xk.
+###
+
+# Welcome reply: Things to say when people thank me.
+welcome
+  no problem
+  my pleasure
+  sure thing
+  no worries
+  de nada
+  de rien
+  bitte
+  pas de quoi
+  gern geschehen
+
+# Dunno reply (when i recognize a query but can't answer it):
+dunno
+  i don't know
+  i haven't a clue
+  no idea
+  wish i knew
+  bugger all, i dunno
+  I give up, what is it?
+  I don't know, could you explain it?
+  I'm not sure, is it larger than a breadbox?
+  parse error: dunno what the heck you're talking about
+  are you using Windows?
+  I wish you would RTFM.
+  have you tried http://www.tldp.org/ ?
+  KCI error, or a problem with the Keyboard-Chair Interface.
+
+# moron reply.
+moron
+  You think I'm human? Think again!
+  h0 h0 h0
+  Hi, how's life?
+  What do you want?
+  Are you on drugs?
+  Wassup G?
+
+# confuse/refuse learn.
+confused
+  I think you lost me on that one
+  what are you talking about?
+
+# Hello reply (ways to say hello):
+hello
+  hello
+  hi
+  hey
+  niihau
+  bonjour
+  hola
+  salut
+  que tal
+  privet
+  what's up
+  moin moin
+
+# Cookie reply: added by the xk.
+cookie
+  ACTION spins the wheel of knowledge and ponders... ##KEY... ##VALUE
+  ACTION pulls out the cookie jar and finds ##KEY... ##VALUE
+  Hey ##WHO, ##KEY is ##VALUE
+
+# Factoid reply:
+factoid
+  methinks ##KEY is ##VALUE
+  i heard ##KEY is ##VALUE
+  i guess ##KEY is ##VALUE
+  from memory, ##KEY is ##VALUE
+  hmm... ##KEY is ##VALUE
+  ##KEY is probably ##VALUE
+  ##KEY is, like, ##VALUE
+  rumour has it, ##KEY is ##VALUE
+  it has been said that ##KEY is ##VALUE
+  somebody said ##KEY was ##VALUE
+  well, ##KEY is ##VALUE
+  extra, extra, read all about it, ##KEY is ##VALUE
+  [##KEY] ##VALUE
+
+# HowAreYou reply:
+howareyou
+  eh, ok
+  peachy
+  just great
+  you know how it is...
+  pretty good. how about you?
+  mas o menos
+
+# Question word.
+qWord
+  who
+  who is
+  who are
+  what
+  what's
+  what is
+  what are
+  where
+  where's
+  where is
+  where are
+
+# botsnack etc praise
+# TODO add ACTION support
+praise
+  :)
+  thanks
+  aw, gee
diff --git a/files/infobot.lart b/files/infobot.lart
new file mode 100644 (file)
index 0000000..69e0478
--- /dev/null
@@ -0,0 +1,131 @@
+
+#
+# lart info by ejb (larne) and cerb.
+#
+
+--purges WHO
+accelerates a free AOL cd to 50,000 rpm and lets WHO feel it
+acting on orders from an unspecified client drags WHO into court suing for $200 million
+beats the living hamstercrap out of WHO
+beats WHO into protomatter with the andromeda galaxy
+beats WHO over the head with a microkernel
+beats WHO senseless with a 50lb Unix manual
+beats WHO severely about the head and shoulders with a rubber chicken
+beats WHO to within 2.54cm of his life
+blames WHO for all the evil in the world
+blasts WHO to oblivion with a kamehameha wave
+blasts WHO with a huge firehose then strangles WHO with it
+brandishes Excalibur! "With this sword, I vanquish thee, WHO!" and lops off WHO's head
+breaks out the Hoover and sucks up WHO
+burns WHO to a crisp with a laser
+calls WHO on the phone ... the lights are on but nobody's home
+cats /dev/urandom into WHO's ear
+changes WHO's permissions to 0777 and tells the world
+chops WHO in half with a free AOL CD
+chops WHO in half with a free Solaris 7 CD
+crushes WHO with a full height scsi disk
+cuts off WHO's head with a halberd that could have been a little bit sharper
+cuts WHO into thin stripes
+decapitates WHO conan the destroyer style
+declares WHO a moron
+does a little 'dpkg -P WHO' action
+does a little 'renice 20 -u WHO'
+DoSes WHO
+drops a baby grand on WHO
+drops a humongous exploding nuke on WHO
+drops a truckload of VAXen on WHO
+duct-tapes WHO to the floor and drools on him
+dumps 42 tons of dirt, manure, and fish heads on WHO
+eats WHO and falls over dead
+eats WHO's liver with some fava beans and a nice chianti
+executes killall -HUP WHO
+executes killall -KILL WHO
+executes killall -TERM WHO
+explains, ever so gently, that if WHO doesn't give the channel more information, they can't help
+farts in WHO's general direction
+flings poo at WHO
+follow's WHO with a gauntlet and ... scratch ... HUMILIATION
+forces WHO to use Outlook Express
+frags WHO with his BFG9000
+gets a hotmal account and SPAMs WHO
+gives WHO a "free" copy of Windows and then charges double for "Upgrades"
+gives WHO a good seeing to
+gives WHO an extra strength ACME sleeping pill, sending WHO to sleep for 150 years, and awakening to seven strange dwarfs and a large apple
+grabs a large, mis-shapened log, with squirrels, and beats WHO until only the nuts remain ... which the squirrels run off with
+hauls WHO up by the scruff of the neck and spanks him until he waddles
+hereby declares WHO a troll
+hits WHO with an anvil and laughs with a contralto voice ... Haha Ha HA Ha
+holds WHO to the floor and spanks him with a cat-o-nine-tails
+hooks into a hydrant and hoses WHO down
+hurls dozens of incontinent, insomniac, hungry kittens with tiny little razor-sharp claws and a wide variety of contagious intestinal parasites at WHO
+installs a bad bootloader on WHO and turns WHO into a brick
+installs PocketPC on WHO's PDA
+judo chops WHO
+keeps mailing WHO free America Online CDs until he drowns
+lowers WHO's priority
+makes a balloon animal out of WHO
+moos at WHO
+nabs the moon and broadsides WHO with the sea of tranquility
+nukes WHO with a single large nuke
+offers WHO some herring
+overclocks WHO until WHO burns out
+plops WHO into a giant vat of herring
+pours gasoline all over WHO, ignites the fire, and then enjoys some toasty marshmallows with the glorious blaze
+pours hot grits down the front of WHO's pants
+pries WHO's back open with a screwdriver and flashes a new bootldr to WHO
+pulls out a ClueBat (tm) and thwaps WHO
+pulls out his louisville slugger and uses WHO's head to break the homerun record
+pushes the wall down onto WHO whilst whistling innocently
+puts on a hockey mask and jumps out at WHO
+puts on some milking gloves.  "All right, now, WHO, this won't hurt a bit...."
+puts WHO into a headlock and administers a mighty noogie, rubbing half of WHO's hair of
+puts WHO through a wood chipper
+raises middle finger to WHO
+readies the nuke launcher and fires some rounds at WHO
+resizes WHO's terminal to 40x24
+rm -rf's WHO
+runs at WHO with an origami Swiss Army knife, and inflicts a nasty paper cut
+says "boot to the head" and knocks WHO over
+send killer squirrels to attack WHO
+sends a legion of lawyers after WHO's head
+shoots WHO in his sleep
+shoots WHO in the head
+shoves a crumpet down WHO's throat, happy now?! Huh? Want some JAM with that?
+slams WHO against a large cement Tux
+slaps a compatible dib on WHO's head
+slaps WHO around with a large trout
+slaps WHO upside and over the head with one freakishly huge killer whale named hugh
+slaps WHO upside the head with a wet fish
+smacks WHO up side the head with a clue-by-4
+squeezes WHO till WHO turns blue like papa smurf
+squishes WHO like a bug
+stabs WHO
+stamps WHO on the forehead with the official Troll marker
+steals WHO's mojo
+strangles WHO with a 9-pole serial cable
+strangles WHO with a doohicky mouse cord
+stuffs WHO into a shiny new tin can and vacuum seals it
+takes a big bite out of WHO's jugular vein
+takes a large goose feather pillow and swings it wildly in WHO's direction, hitting WHO and sending WHO flying into the closet
+takes a rusty axe and swings it violently, taking WHO's head off
+takes large quantities of Krispy Kream donuts and stuffs them one after another down WHO's throat until WHO puts on 150lbs
+takes out a cattle prod and gives WHO a good jolt
+takes out a seltzer bottle and sprays WHO in the face. You know, one of those old-school seltzer bottles clowns have? Yeah those. Anyway, consider yourself spritzed
+takes out WHO with the trash
+takes WHO to the vet for a "special" visit
+teaches WHO that M$ Access is a database. No, really, a database. A real live multi-user... well, ok, not multi-user, but a database. Yeah, that sounds right.
+teaches WHO the basics, including how to RTM
+throws a AN/M-8 smoke grenade at WHO
+throws WHO's poor little doggy off a cliff
+tries to shut WHO up
+turns WHO into a lifesized tux doll
+urinates on WHO
+wallops WHO with a main rotation server that needs rehubbing.  It won't take long
+whacks WHO upside the head
+whacks WHO with a giant beaver's tail
+whacks WHO with the cluebat
+whips out a hot clue gun and makes sure that WHO is stuck to the floor
+whips out a shotgun, trudges over to WHO, and goes postal
+whips out a sword and chops WHO in half
+whips out his power stapler and staples WHO's foot to the floor
+whips WHO with a wet and grimy noodle just because
diff --git a/files/infobot.randtext b/files/infobot.randtext
new file mode 100644 (file)
index 0000000..817a01e
--- /dev/null
@@ -0,0 +1,2104 @@
+He who controls the source controls the universe!
+Want to see a listing of files installed by a package, type dpkg -L package
+Need to know the status of a package? type dpkg -s package
+Need help, but everyone is idle in the channel, try emailing to debian-user@lists.debian.org
+Need to see the list of packages matching a pattern, type dpkg -l pattern
+If you have a webserver and dww packages installed, try http://localhost/dwww for all kinds of documentation
+Need help setting up PPP? read /usr/doc/ppp/README.debian
+Want to know why Debian is best? type !why in the channel
+Want to upgrade to hamm (unstable)? type !libc6 to get the mini-HOWTO
+Want to check out Debian social contract? type !dfsg in the channel
+Warning: Dates in Calendar are closer than they appear.
+Daddy, why doesn't this magnet pick up this floppy disk?
+Give me ambiguity or give me something else.
+I.R.S.: We've got what it takes to take what you've got!
+We are born naked, wet and hungry.  Then things get worse.
+Pentiums melt in your PC, not in your hand.
+Suicidal twin kills sister by mistake!
+Did anyone see my lost carrier?
+Make it idiot proof and someone will make a better idiot.
+I'm not a complete idiot, some parts are missing!
+He who laughs last thinks slowest!
+Always remember you're unique, just like everyone else.
+'More hay, Trigger?'  'No thanks, Roy, I'm stuffed!'
+A flashlight is a case for holding dead batteries.
+Lottery: A tax on people who are bad at math.
+There's too much blood in my caffeine system.
+Artificial Intelligence usually beats real stupidity.
+Hard work has a future payoff.  Laziness pays off now.
+Friends help you move.  Real friends help you move bodies.
+I won't rise to the occaasion, but I'll slide over to it.
+Ever notice how fast Windows runs?  Neither did I.
+Double your drive space - delete Windows!
+What is a 'free' gift ?  Aren't all gifts free?
+If ignorance is bliss, you must be orgasmic.
+'Very funny, Scotty.  Now beam down my clothes.'
+Puritanism: The haunting fear that someone, somewhere may be happy.
+Consciousness: that annoying time between naps.
+Oops.  My brain just hit a bad sector.
+I used to have a handle on life, then it broke.
+Don't take life too seriously, you won't get out alive.
+I don't suffer from insanity.  I enjoy every minute of it.
+Better to understand a little than to misunderstand a lot.
+The gene pool could use a little chlorine.
+When there's a will, I want to be in it.
+Okay, who put a 'stop payment' on my reality check?
+Few women admit their age.  Few men act theirs.
+I'm as confused as a baby in a topless bar.
+We have enough youth, how about a fountain of SMART?
+All generalizations are false, including this one.
+Change is inevitable, except from a vending machine.
+C program run.  C program crash.  C programmer quit.
+'Criminal Lawyer' is a redundancy.
+Clap on! (clap, clap) Clap off! (clap@#&$NO CARRIER
+'640K ought to be enough for anybody.' Bill Gates '81
+'90% of all statistics are made up'
+'A fanatic is one who can't change his mind and won't change the subject.'
+'A little work, a little sleep, a little love and it is all over.' - R. Frost
+'A lot of people mistake a short memory for a clear conscience.' -Doug Larson
+'Apple' (c) 6024 b.c., Adam & Eve
+'Apple' (c) Copyright 1767, Sir Isaac Newton.
+'Bad knee, gotta run' - Pat Buchanan to his draft board
+'Beam me aboard, Scotty.' 'Sure. Will a 2x10 do?'
+'Beulah, peel me a grape.'
+'Bother,' said Pooh as the brakes went out!
+'Build a watch in 179 easy steps' by C. Forsberg.
+'C++' should have been called 'D'
+'COINCIDENCE' happens.
+'Calvin, we will not have an anatomically correct snowman!'
+'Careful.  We don't want to learn from this.' -- Calvin
+'Don't you hate it when your boogers freeze?' -- Calvin
+'Every time I've built character, I've regretted it.'
+'Freedom defined is freedom denied.' -The Illuminatus
+'Have you ever dated somebody because you were too lazy to commit suicide?'
+'Hi-ho, hi-ho, it's hand grenades I throw...'
+'Hmm... How *did* they finally kill Frosty?' -- Hobbes
+'Human equality is a contingent fact of history.' -Steven Jay Gould
+'I tried to think but nothing happened!' - Curly
+'I'm not an actor, but I play one on TV'
+'I'm not smart enough to lie' - Ronald Reagan
+'If I knew what I was doing...I'd be dangerous...'
+'If the shoe fits, buy it.'  Imelda Marcos
+'Instant gratification takes too long.' - Carrie Fisher
+'Is' is the verb for when you don't want a verb.
+'It is not the fall that kills you.  it's the sudden stop at the end.'-D. Adams
+'It's sad how whole families are torn apart by simple things, like wild dogs'
+'Keyboard?  How quaint!' - Scotty
+'Luke... Luke... Use the MOUSE, Luke' - Obi Wan Gates
+'Mr. Worf, blow the Windows-powered Borg ship out of this Universe!'
+'Off the keyboard, thru the router, over the bridge, nothing but net!'
+'Quotations are for people who are not saying things worth quoting.'
+'Remember when we said there was no future?  Well, this is it.' -- Blank Regk
+'Stupid' is a boundless concept.
+'Suicide Hotline...please hold.'
+'The faster you go, the shorter you are' - Einstein
+'The reports of my death have been greatly exaggerated.' - Mark Twain
+'The sun ain't yellow, its chicken.' -Bob Dylan
+'There are lies, damned lies, and statistics.' -Mark Twain
+'There's someone in my head, but its not me.' -Pink Floyd
+'This is a job for.. AACK! WAAUGHHH!! ...someone else.' -
+'To err is human, to forgive....$5.00'
+'Ummm, Trouble with grammar have I! Yes!' -Yoda-
+'Vote for Perot' - Bumper sticker attached with Velcro
+'You can't have everything.  Where would you put it?' -Steven Wright
+#1 OS/2 tip: Drag the Windows folder to the shreader!!!
+#include std/disclaimer.h
+$$$ not found --  (A)bort (R)efinance (B)ankrupt
+'Tis better to be thought a fool, then to open your mouth and remove all doubt
+(((((This tagline in Stereo where available)))))
+(A)bort (R)etry (C)ut  Your  Throat.....
+(A)bort (R)etry (F)ail (U)nplug & (S)ell.
+(A)bort (R)etry (P)ull leg (H)ot boot (S)wipe tagline!
+(A)bort, (R)etry, (I)nfluence with large hammer
+(A)bort, (R)etry, (P)retend this never happened...
+(D)inner not ready:  (A)bort (R)etry (P)izza
+(You can have your cake) XOR (You can eat your cake)
+(c) Copywight 1995 Elmer Fudd.  All wights wesewved.
+* OLX 3 * Windows is to OS/2 what Etch-a-Sketch is to art.
+*Four hours* to bury a cat?  Yes - it wouldn't keep still
+.. Bugs come in through open Windows.
+... 'I'll be Bach.' - Johann Sebastian Schwarzenegger
+... All the world's a stage, and I missed rehearsal.
+... Bill Clinton isn't slick.  He's just a liar.
+... Clinton Economics: If 1+2=3 then 4+5=6.
+... Clinton excuse #15: Hey - I just do what the wife says
+... Clinton excuse #18: You took that seriously?  Har har
+... Clinton sandwich:  $5 of baloney and $20 in taxes
+... Getting the truth from Clinton is like nailing Jello
+... It's tourist season in Florida, bag limit two.
+... KARAOKE is Japanese for 'Tone Deaf'
+... Some days you're the dog, some days you're the hydrant
+.....If it ain't broke, fix it anyway just to screw it up!
+...I'm sorry, Reality is not in service at this time.
+...On the other hand, you have different fingers.
+..Windows NT Performance', on the next 'In Search Of'
+/EARTH is 98% full. Please delete anybody you can
+1 + 1 = ?  Ask my calculator.
+10 out of 5 doctors feel it's OK to be schitzo!
+1200 bps used to seem so fast
+186,000 miles/sec: Not just a good idea, it's the LAW.
+1st rule of intelligent tinkering - save all the parts
+2 + 2 = 4 (for the time being).
+2 + 2 = 5 (for sufficiently large values of 2)
+3 out of 4 Americans make up 75% of the population.
+43% of all statistics are worthless.
+43rd Law of Computing: Anything that can go wr...
+5 schizophrenics agree!
+50 states, and I had to pick this one...
+668 - Neighbor of the Beast
+90% of being smart is knowing what you're dumb at.
+<<< Tagline deleted by Natl Endowment for the Arts >>>
+==/==/==/==Police tagline==/==/==Do not cross ==/==/==/==
+From my brain, an organ with a mind of it's own.
+From the Department of Redundancy Dept.
+A BBSer's telephone bill knows no bounds...
+A Bugless Program is an Abstract Theoretical Concept.
+A Metaphor is like a Simile.
+A Smith & Wesson *ALWAYS* beats 4 Aces.
+A big enough hammer fixes anything
+A bird in the hand can be messy.
+A camel is a horse planned by committee.
+A chicken is an egg's way of producing more eggs.
+A clean desk is a sign of a cluttered desk drawer.
+A closed mind gathers no intelligence
+A closed mouth gathers no feet.
+A committee has 6 or more legs and no brain.
+A conscience does not prevent sin. It only prevents you from enjoying it.
+A critic is a man who leaves no turn unstoned.
+A cynic smells flowers and looks for the casket.
+A day for firm decisions!  Or is it?
+A day not wasted is a day wasted!
+A day without radiation is a day without sunshine.
+A day without sunshine is like night.
+A diplomat thinks twice before saying nothing.
+A dirty book is rarely dusty.
+A fool and his money are soon SYSOP.
+A fool and his money rarely get together to start with.
+A fool must now and then be right by chance.
+A friend in need is a pest indeed...
+A friend: someone who likes you even after they know you.
+A good way to deal with predators is to taste terrible.
+A half moon is better than no moon at all.
+A harp is a nude piano.
+A hunch is creativity trying to tell you something.
+A library is an arsenal of liberty.
+A life lived in fear is half a life lived.
+A little greed can get you lots of stuff.
+A little inaccuracy sometimes saves tons of explanation.
+A living example of Artificial Intelligence.
+A man needs a good memory after he has lied.
+A man's best friend is his dogma.
+A man, a plan, a canal.  Suez!
+A mind is a terrible thing to taste.
+A mind is a terrible thing to ugg.. I forgot..
+A neat desk is a sign of a sick mind.
+A pedestrian hit me and went under my car.
+A penny saved is a Governmental oversight.
+A perversion of nature....how exciting!
+A pessimist is never disappointed.
+A phaser on stun is like a day without orange juice.
+A rolling stone gathers momentum.
+A seminar on Time Travel will be held two weeks ago.
+A single fact can spoil a good argument.
+A stitch in time would have confused Einstein.
+A truly wise man never plays leapfrog with a moose.
+A waist is a terrible thing to mind.
+A yer ago I kudnt spel progremr now I are won.
+ASCII and ye shall receive.
+ASCII stupid question... get a stupid ANSI!
+Abandon all hope ye who have entered cyberspace.
+Afraid of heights?   Not me, I'm afraid of widths!
+Agnodyslexic plea:  'why ME, dog?'
+Air conditioned environment - Do not open Windows.
+Alex, I'll take 'Things Only I Know' for $1000.
+All E-mail gladly received. Offensive reply ASAP.
+All I ask for is the opportunity to prove that money can't make me happy.
+All I need to know I learned from my cat.
+All I want is a warm bed, a kind word and unlimited power
+All generalizations are bad.
+All generalizations are false, including this one.
+All hope abandon, ye who enter messages here.
+All in a day's work for...'Confuse-a-Cat'!
+All in all it's just a... 'nother brick in the wall!
+All life's answers are on TV. - Bart Simpson
+All programers are optimists.
+All that glitters has a high refractive index.
+All the easy problems have been solved.
+All things are green unless they are not.
+All wiyht.  Rho sritched mg kegtops awound?
+All words are pegs on which to hang ideas.
+All work and no play, will make you a manager.
+All you need to be a fisherman is patience and bait.
+Almost went crazy.  Would have been a real short trip.
+Alone: In bad company.
+Always draw your curves, then plot the data.
+Always forgive your enemies, nothing annoys them so much.
+Always glad to share my ignorance - I've got plenty.
+Always proofread carefully to see if you any words out.
+Always remember no matter where you go, there you are.
+Alzheimers advantage: New friends every day.
+Ambition is the last refuge of the failure.
+America Good Place to Put Chinese Restaurant.
+Amusement is the happiness of those who cannot think.
+An Elephant;  A Mouse built to government specifications.
+An egotist thinks he's in the groove when he's really in a rut.
+An elephant is a mouse with an operating system.
+An idle mind is worth two in the bush.
+An ounce of application is worth a ton of abstraction.
+An ounce of emotion is equal to a ton of facts.
+An oyster is a fish built like a nut.
+An ulcer is what you get mountain climbing over molehills.
+An unbreakable toy is useful for breaking other toys.
+An unemployed court jester is no one's fool.
+And don't start a sentence with a conjunction.
+And he disappeared in a puff of logic.
+And if one bad cluster should accidentally fail...
+And it's only ones and zeros.
+And now for something completely different...
+And now for something completely the same...
+And tomorrow will be like today, only more so.
+And, the driver compresses EVERYTHING, not just EXE & COM
+Angels can fly because they take themselves so lightly.
+Anger blows out the lamp of the mind.
+Another case of Cherry Coke down the programming hatch!
+Answers: $1 * Correct answers: $5 * Dumb looks: Free! *
+Antidisestablishmentarianism!
+Any closet is a walk-in closet if you try hard enough.
+Any fool can criticize, condemn, & complain. And most do.
+Any philosophy that can be put in a nutshell belongs there
+Any wire cut to length will be too short.
+Anything worth doing, is worth doing for a profit.
+Are we having Fahrvergn\ 1ugen yet??
+Are ya feelin' lucky, punk?!! - Harry Callahan
+Are you really American if your ethnicity has to be hyphenated?
+Are you suggesting that coconuts migrate?
+Armageddon means never having to say you're sorry.
+Artificial Intelligence is no match for natural stupidity.
+As I said before, I never repeat myself.
+As a matter of fact, no, I don't have a life.
+As easy as 3.14159265358979323846264338327950288419716
+As long as I can remember, I've had amnesia.
+Ask not for whom the bell tolls; let the machine get it.
+Assumption is the mother of all screwups...
+Atheist = Deity Disadvantaged.
+Auntie Em: Hate you, hate Kansas, taking the dog.  -Dorothy
+B.Gates : quality software :: R.McDonald : gourmet cuisine
+BREAKFAST.COM Halted... Cereal Port Not Responding.
+Back Up My Hard Drive? I Can't Find The Reverse Switch!
+Backup not found: (A)bort (R)etry (P)anic
+Bad Command:(A)bort (R)etry (T)ake RAM hostage
+Bad breath is better than no breath.
+Bald: follicularly challenged.
+Barium:  what you do with dead chemists.
+Beautify Texas.  Put a Yankee on a bus.
+Been there, done that, got the T-shirt.
+Best file compressor around: DEL *.* (100% compression!)
+Best way to dispose of the Borg: Give them Windows 3.1.
+Better ... stronger ... faster!
+Beware of Geeks bearing gifs.
+Beware of barking dogs that bite.
+Beware of programmers carrying screwdrivers
+Bigamy : one wife too many. Monogamy : same thing
+Bill Clinton is the Lyin' King. ( Now playing nation wide )
+Bill Clinton thinks that Cheerios are donut seeds.
+Bill Clintoon: The prince of Dorkness, a caricature of a president
+Black Holes are Out of Sight
+Black holes really suck...
+Blessed are the pessimists, for they make backups!
+Blessed is the end-user who expects nothing, for ye shall not be dissapointed.
+Bliss *IS* ignorance
+Bo Knows Taglines!
+Bo Peep did it for the insurance.
+Bombs don't kill people, explosions kill people.
+Borderline psychotic with hermit-like tendencies.
+Bore: A person who talks when you wish him to listen.
+Bored? Drive the speed limit... in your garage.
+Borg spreadsheet: Locutus 1-2-3
+Borg?  Where?  I don't se*(#$#..NO CARRIER
+Both of his feet are firmly planted in the air.
+Boy: A noise with dirt on it.
+Brain dysfunction detected....
+Brain over - Insert coin
+Brain: The apparatus with which we think that we think.
+Break up a relationship - buy a computer!!
+Breathing may be hazardous to your health.
+Britannia waives the rules.
+Bug off, Banana Nose; Relieve mine eyes
+Bugs are Sons of Glitches!
+Bugs, like coathangers, breed if unobserved.
+Building Contractors, not to be confused with homemakers
+Bullets speak louder than reason.
+Bumper sticker on a hearse:  I'd rather be breathing
+Bungee Jumper? Catch you on the rebound.
+Bureaucrats cut red tape, lengthwise
+Bus error (Passengers dumped)
+Busier than a 1 legged man in an butt-kicking contest.
+But I forgot all about the Amnesia Conference!!
+But honey, we can afford it, I sold your car!
+But my little voice TOLD me to do it!
+But soft, what light through yonder tagline breaks?
+But then again, I like cold toilet seats.
+But what if I'm a figment of my OWN imagination?
+Buy American!
+Buy Land Now.  It's Not Being Made Any More.
+Buy a supscription to Playboy and send it to your boss' wife
+By all means, let's not confuse ourselves with the facts!
+C programmer run C programmer crash C programmer quit
+C:\DOS   C:\DOS\RUN   RUN DOS RUN
+CAUTION:  RIDER MAY BAIL AT ANY TIME
+CCITT: Can't Certify I Trust Telecom.
+CCITT: Can't Conceive Intelligent Thoughts Today
+CD-WOM, Wead Onwy Memowy.
+CEO of Dementia and Other Meaningless Entities.
+CHIP:  One California hi-way patrolman.
+CODING:  AN addictive Drug.
+COMMAND:  A suggestion made to a computer.
+CONgress (n) - Opposite of PROgress
+CRASH:  Normal termination.
+CRIME CONTROL: Fire a warning shot into his HEART!
+CURIOSITY?  Nah.  I got THAT cat with a lawnmower.
+CYCLIC REDUNDANCY CHECK: Stocktaking at a Bike shop
+California raisins murdered: Cereal Killer suspected
+Can I yell 'movie' in a crowded firehouse?
+Can you find the mispelled word in hear?
+Can you repeat the part after 'Listen very carefully'?
+Can you see the REAL ME, can ya?!?!  CAN YA??!?!!?!?!?!?!
+Can you tell me how to get to Sesame Street?
+Can't learn to do it well? Learn to enjoy doing it badly!
+Card-carrying member of the cultural elite.
+Carlsbad Caverns: 22% more cavities.
+Cause of crash: Inadvertent contact with the ground.
+Caution:  Breathing may be hazardous to your health.
+Caution:  Contents under pressure
+Caution:  Hungry Dieter   May bite if provoked
+Caveat emptor, no deposit no return, do not remove.
+Celibacy is not hereditary.
+Cheer up, the worst is yet to come.
+Chernobyl used Windows
+Chess players mate better.
+Chicago runs best on a VCR.
+Chicago, an operating system Pair-of-Dimes shift!
+Chicago...  The biggest thing since New Coke!
+Chicago: NT deja vu!
+Chicago?  Been there.  I'm ready to travel at WARP speed!
+Chicken heads are the chief food of captive alligators.
+Chipmunks roasting on an open fire.
+Choose heaven for climate, hell for society.
+Christmas comes, but once a year is enough.
+Circular Definition: see Definition, Circular.
+City Planners do it with their eyes shut.
+Civilization - biggest syntax error in history!
+Clark Kent is a transvestite.
+Clarvoiants meeting canceled due to unforseen events.
+Clean mind, clean body:  take your pick.
+Cleanliness is next to impossible.
+Climate is what you expect.  Weather is what you get.
+Clinton is one Bill, George Bush can't veto...
+Clinton/Gore is to the presidency as Beavis & Butthead are to television.
+Clones are people two.
+Close only counts in horseshoes and hand grenades!
+Close your eyes and press escape three times.
+Closed Hearing for the Caption Impaired...
+Cogito ergo spud I think therefore I yam.
+Cole's Law: Thinly sliced cabbage.
+Come in here, dear boy, have a cigar, you're gonna go far!
+Coming Soon!!  Mouse Support for Edlin!
+Coming soon: Netware for the Nintendo!
+Commence strategic maneuvers at audible command signal.  5, 4, 3...
+Committees keep minutes and lose hours.
+Common sense is the collection of prejudices acquired by age eighteen.
+Common sense isn't...
+Communism is like a mouth on a lollipop
+Competence always contains the seeds of incompetence.
+Computational Physicist and all around nice guy.
+Computer Lie #1: You'll never use all that disk space.
+Computer: a million morons working at the speed of light.
+Computers All Wait at the Same Speed!
+Computers Rule 01001111 01001011
+Computers are not intelligent. They only think they are.
+Computers are useless; they can only give answers.
+Computers run on faith, not electrons.
+Condense soup, not books!
+Conformity obstructs progress.
+Confucius say too much.
+Confucius say: I didn't say that!
+Confucius say: Man with no legs bums around.
+Confucius say: Those who quote me are fools.
+Confuse People:  Quote from the wrong message!
+Confused?  Call Counselor Troi 1-900-NCC-1701: $1.95/minute
+Confusion not only reigns, it pours.
+Consolations, Consultations, Conflagrations.
+Constant change is here to stay.
+Contentsoftaglinemaysettleduringshipping.
+Converse with any plankton lately?
+Copyright the Intergalactic Thought Association
+Corrupt REALITY.SYS: Reboot Universe (Y/n)?
+Could crop circles be the work of a cereal killer?
+Couldn't myself have better it said.
+Courage atrophies from lack of use.
+Crime does not pay...as well as politics.
+Crime doesn't pay... does that mean my job is a crime?
+Crime wouldn't pay if the government ran it.
+Crime, Sex, Alcohol, Drugs...Boy do I love Congress
+Cynicism is intellectual dandyism.
+Cynics are people who know the price of everything and the value of nothing.
+D.A.D.D. - Daddies Against Dirty Diapers
+D.A.M. - Mothers Against Dyslexia
+D.A.M.M - Drunks Against Mad Mothers
+DAM: Mothers Against Dyslexia.
+DANGER! Computer store ahead, hide wallet!
+DCE seeks DTE for mutual exchange of data.
+DEFINE: De ting you get for breaking de law.
+DEVICE=EXXON.SYS may mess up your environment
+DILATE: To live longer.
+DIODE: What happens to people who don't die young.
+DIVORCE =system('echo y| erase \wife\*.*' );
+DO NOT ADJUST YOUR MIND - the fault is with reality
+DO NOT REMOVE THIS TAGLINE (UNDER PENALTY OF LAW)!
+DOC files?  We don't need NO STINKIN' DOC FILES!
+DOS 5.0  Yesterday's operating system, today!
+DOS means never having to live hand-to-mouse.
+DOS never says 'EXCELLENT command or filename, Dude!'
+DOS-O-MANIA : Reboot is not kicking your computer again
+DOS-O-MANIA : Root is not the book Alex Haley wrote.
+DOWN WITH EXCLAMATION POINTS!!!!
+Daddy, what does 'Formatting Drive C:' mean?
+Dain Bramaged.
+Dang this hobby is expensive!
+Dangerous exercise: Jumping to conclusions.
+Darth Vader sleeps with a Teddywookie.
+Dawn: The time when men of reason go to bed.
+Dawson's First Law: You don't have enough outlets.
+Death benefits = oxymoron.
+Death is 99 per cent fatal to laboratory rats.
+Death is God's way of dropping carrier.
+Death is life's answer to the question 'Why?'
+Death is life's way of telling you you've been fired.
+Death sneaks up on you as a windshield sneaks up on a bug.
+Death: to stop sinning suddenly.
+Deflector shields just came on, Captain.
+Delivered by Electronic Sled-Dogs.....Woof!
+Democrats Call for Amnesty, Reduced Sentences Likely.
+Depart in pieces.... i.e., Split.
+Detour: The roughest distance between two points.
+Diagonally parked in a parallel universe.
+Did I just step on someone's toes again?
+Did ya hear? They took the word gullible out of the dictionary!
+Did you expect mere proof to sway my opinion?
+Die Yuppie Scum.
+Diets are for those who are thick and tired of it.
+Difference between Jane Fonda & Bill Clinton? Jane went to Vietnam
+Digression is education.
+Dime:  a dollar with all the taxes taken out.
+Dinner Not Ready...(A)bort (R)etry (P)izza
+Diplomacy is saying 'nice doggy' until you find a rock.
+Diplomacy is the ability to let someone else have your way.
+Diplomacy: The patriotic art of lying for one's country.
+Dirty deeds - DONE DIRT CHEAP!
+Disclaimer: All opinions are not really opinions.
+Disclaimer: Written by a highly caffeinated mammal.
+Discoveries are made by not following instructions.
+Disks travel in packs.
+Dyslexics of the world, UNTIE!
+Do Androids Dream of Electric Sheep?
+Do I mind if you smoke?  No.  Do you mind if I FART?
+Do fish get thirsty?
+Do not believe in miracles -- rely on them.
+Do not disturb. Already disturbed!
+Do not put statements in the negative form.
+Do radioactive cats have 18 half-lives?
+Do steam rollers really roll steam?
+Do the joke. Get the laugh. Move on.
+Do unto others BEFORE they do unto you!
+Do vegetarians eat animal crackers?
+Do you know the way to San Jose?
+Doctor Who for president
+Doctor, my brain hurts!
+Documentation is the castor oil of programming.
+Does Bill Clinton think Elvis is alive?
+Does killing time damage eternity?
+Does the Enterprise use DOS v2356.0?
+Does the name Pavlov ring a bell?
+Doesn't expecting the unexpected make the unexpected become the expected?
+Dogs come when you call. Cats have answering machines.
+Dogs crawl under Gates, software under Windows.
+Don't Take Life Seriously, It Is Not Permanent.
+Don't ask me, I have intermittent memory loss
+Don't ask me, I only work here.
+Don't ask me, I'm making this up as I go!
+Don't be a sexist, broads hate that.
+Don't be afraid to drive a nail in the wood!
+Don't believe everything you hear or anything you say.
+Don't blame me, I voted for Mickey Mouse.
+Don't buy furs, it takes trees to make protest signs.
+Don't byte off more than you can multiplex.
+Don't confuse me with facts, my mind's already made up!
+Don't crush that dwarf, hand me the pliers.
+Don't diet, download a virus to remove the FAT.
+Don't do what I SAY, do what I mean!
+Don't get stuck in a closet -- wear yourself out.
+Don't just do something !!! Stand there !!!
+Don't let school interfere with your education.
+Don't look at me in that tone of voice!
+Don't look back, the lemmings are gaining on you.
+Don't mess with Murphy.
+Don't panic.  Don't panic.  Don't panic. ... ALL RIGHT, NOW PANIC
+Don't play stupid with me! I'm better at it.
+Don't press the keys so hard!
+Don't read everything you believe.
+Don't rush me.  I get paid by the hour.
+Don't speak now, and forever hold your peace.
+Don't start with me.  You know how I get.
+Don't steal.  The government hates competition.
+Don't stop posting, a good laugh breaks up my day nicely
+Don't sweat it -- it's only ones and zeros.
+Don't talk unless you can improve the silence.
+Don't thank me for insulting you. It was my pleasure...
+Don't try to saw sawdust.
+Don't use a big word where a diminutive one will suffice.
+Don't use no double negatives.
+Don't worry, I'm fluent in weirdo.
+Down with categorical imperative!
+Down with ignurance!
+Downgrade your system for only 89 dollars!   Install Windows!
+Dragons love you. You're crunchy and good with ketchup.
+Drama is life with the dull bits cut out.
+Drawing on my fine command of language, I said nothing
+Drilling for oil is boring.
+Drink wet cement, and get completely stoned.
+Drive A: format failure, formatting C: instead...
+Drive C: Error, (A)bort (R)etry (I)gnore (K)ick (S)cream
+Dropped from my peeling lips like lousy fruit.
+Drugs have taught an entire generation of American kids the metric system.
+Dumb luck beats sound planning every time.  Trust me.
+Dying is no excuse. Nixon in 96.
+Dyslexics are persona au gratin.
+Dyslexics have more fnu.
+Dyslexics of the world, UNTIE!
+EMS: Enhanced Money Scam
+ERROR 103: Dead mouse in hard drive.
+EXPANSION SLOTS: The extra holes in your belt buckle.
+Eagles may soar but weasels aren't sucked into jet engines!
+Easter is canceled this year.  They've found the body.
+Eat Healthy, Exercise, and Die Anyway ...
+Eat the rich, the poor are tough and stringy
+Efficiency takes time!  Frugality: who can afford it?
+Eggheads unite!  You have nothing to lose but your yolks.
+Ego Gratification through Violence
+Either this man is dead or my watch has stopped.
+Email me the rules, please!
+Energizer Bunny Arrested! Charged with battery.
+Enjoy me, I may never pass this way again.
+Enough research will tend to support your theory.
+Ensign Pillsbury:  He's bread Jim!
+Enter that again, just a little slower.
+Error 15 - Unable to exit Windows. Try the door.
+Eschew obfuscation!
+Even in this corner of the galaxy, Captain, 2+2=4 ... Spock
+Even snakes are afraid of snakes.
+Even the greatest of whales is helpless in the middle of the desert
+Ever notice how fast Windows runs? Neither did I...
+Ever stop to think, and forget to start again?
+Ever wonder why Oprah spelled backwards is Harpo?
+Every man's work is a portrait of himself.
+Every purchase has its price.
+Every why hath a wherefore.
+Everybody is ignorant, only on different subjects.
+Everybody wants to go to heaven, but nobody wants to die.
+Everyone has photographic memory...some don't have film!
+Everyone hates me because I'm paranoid
+Everyone is entitled to my opinion.
+Everyone is gifted. Some open the package sooner.
+Everyone's expendable...and no one has a real friend
+Everything bows to success, even grammar.
+Everything in our favor was against us.
+Everything that is not mandatory is forbidden.
+Everywhere is walking distance if you have the time.
+Evil always triumphs over good, because good is STUPID!
+Exceeding the legal fun limit on a regular basis
+Excellent time to become a missing person.
+Excuse me while I dance a little jig of despair
+Excuse me while I sharpen my tongue.
+Experience is a good teacher but her fees are high...
+Experience: a name everyone gives to his mistakes.
+Exploding piglets!!!  My gosh, it's raining bacon!
+Exxon Suxx.
+F.A.R.T....Fathers Against Radical Teenagers
+FATAL SYSTEM ERROR:  Press F13 to continue...
+FIGHT BACK!  Fill out your tax forms with Roman numerals.
+FILE COPIED.                       I THINK?
+FLOPPY DISK: Serious curvature of the spine.
+FOR SALE: 1 set of morals, never used, will sell cheap.
+FORD: The Heartbreak of today's Chevrolet!
+Fact is solidified opinion
+Facts Just Get In The Way And Impede Progress.
+Facts are stubborn things.
+Fad: In one era and out the other
+Familiarity breeds attempt
+Familiarity breeds children.
+Famous last words - Don't worry, I can handle it.
+Famous last words - Icarus: Aaaahhhhhhhhh.
+Famous last words - You and what army?
+Faster than a speeding ticket!
+Fat Wars: May the Sauce Be With You.
+Fat person: Nutritional Overachiever
+Fatal Error Using Mouse. Replace and Bury Operator.
+Features should be discovered, not documented.
+Feel lucky????  Update your software!
+Felines... nothing more than felines...
+Fer sell cheep:  IBM spel chekker.  Wurks grate.
+Fife. n. Small shrill instrument that rhymes with wife.
+Figures won't lie, but liars will figure.
+File not found. Should I fake it? (Y/N)
+Find your aim in life, before you run out of ammunition
+First thing you do is shoot all the lawyers
+Fish and visitors stink in three days.
+Flames to /dev/null/here/is/a/quarter/now/go/buy/a/clue.
+Flaming nuclear death to Smurfs
+Flirt: A woman who thinks it's every man for herself.
+Floggings will continue until morale improves.
+Flying saucers are real, the Air Force doesn't exist.
+Folks who think they know it all bug those of us who do
+Follow-ups to alt.nobody.really.cares
+Food is an important part of a balanced diet.
+Fools rush in where Fools have been before!
+Fools rush in wherever lottery tickets are sold
+For Sale: Slightly used message. Enquire within.
+For at the end of history lies the undiscovered country.
+For discussion only. Not to be relied upon.
+For every vision there is an equal and opposite revision.
+For people who like peace and quiet: A phoneless cord!
+For sale, Toilet-seat cover.  Barely used.
+For the finest in brain candy.
+Forget the Joneses...I can't keep up with the SIMPSONS!
+Forget the computer!  Where's my abacus??
+Forget the diet center; send yourself a candygram.
+Forgive your enemies...but REMEMBER THEIR NAMES!
+Four minus two is one and the same.
+Fraud(n): A telephone number starting with '1-900'
+Free Nelson Mandela, while stocks last!
+Free advice is worth what you pay for it
+Free your mind ... the rest will follow!
+Freedom is just chaos with better lighting.
+Friction can be a drag sometimes.
+Friendly fire - ISN'T !
+Friends are Friends, regardless of their baud rate!
+Friends come and go, enemies accumulate.
+Friends don't let friends drive naked.
+Friends encourage friends to use Windows - under Linux!
+Friendship is one soul in two bodies.
+Frost
+Funny, only sensible people agree with me.
+GURU: One who knows more jargon than you.
+Gambling: The sure way of getting nothing for something.
+Gargle twice daily - see if your neck leaks.
+Geez if you belive in honkus.
+Genealogy = A DNA square-dance in the Thighlight Zone
+General Failure reading John Dvorak
+General stupidity error reading drive C:
+Geoff, Brett and Todd...the BO-DYNASTY!!!
+George Orwell was an optimist.
+Get behind early so you have plenty of time to catch up.
+Get the facts first - you can distort them later!
+Get your filthy hands off my dessert!
+Gimme back my face! You're getting it ugly.
+Give a woman an inch  and she'll park a car in it.
+Give a woman an inch and she thinks she's a ruler.
+Give your child mental blocks for Christmas.
+Go Lemmings, Go!!!
+Go shopping. Buy Stuff. Sweat in it. Return it the next day.
+God created cats so that men could learn to understand women
+God does not play dice.
+God heals and the doctor takes the fee.
+Going out of my mind, back in 5 minutes.
+Going the speed of light is bad for your age.
+Good day to let down old friends who need help.
+Good girls go to heaven...but bad girls go EVERYWHERE!!
+Goodness has NOTHING to do with it.....
+Gotta love me!
+Grab your helmet, get your bike, it's SHOWTIME!
+Graduate Of The Uncle Fester & Keith Moon School of hair styling
+Gravity brings me down
+Gravity doesn't exist.  The Earth sucks.
+Great minds travel in the same sewers.
+Greed is good!  Greed is right!  Greed works!
+Grow your own dope...   plant a man
+Growing old is mandatory; growing up is optional!!
+Grub first, then ethics.
+Gun control is being able to hit your target!
+Guns don't kill people... death does.
+Guns don't kill people..., I kill people!
+H lp!  S m b d  st l  ll th  v w ls fr m m  k yb  rd!
+HAL 9000: Dave.  Put down those Windows disks, Dave.  DAVE!
+Hackito ergo sum.
+Hailing frequencies open, Captain.
+Hand me that crowbar... I must pry out this bullet.
+Happiness is Earth in your rear view mirror.
+Happiness is a warm gun.
+Happiness is a warm modem
+Happiness is finding special characters \ 1\ 2\ 1\ 2
+Happiness is not a destination.  It's the trip.
+Happiness is seeing your mother-in-law's face on the back of a milk carton.
+Happiness is...receiving YOUR posts!!!!
+Hard work has a future payoff.  Laziness pays off now.
+Hard work must have killed someone!
+Has it ever rained cats and dogs?
+Hasta la vista, Baby!
+Have Tardis, will travel.
+Have an adequate day.
+Have cursor, will curse.
+Have it OUR way.  Yours is IRRELEVANT.  At BORGerKing.
+Have you ever talked into an acoustic modem?
+Have you seen Quasimoto? I have a hunch he's back!
+Having Windows problems?  Dial 1-800-3-IBM-OS2 for fast relief!
+Having two bathrooms ruins the capacity to co-operate.
+He does the work of 3 Men...Moe, Larry & Curly
+He has Van Gogh's ear for music.
+He who Laughs, Lasts.
+He who always plows a straight furrow is in a rut.
+He who asks timidly makes denial easy.
+He who dies with the most access, wins.
+He who dies with the most toys... is *still* DEAD!
+He who eats too many prunes, sits on toilet many moons.
+He who hesitates is constipated.
+He who laughs last is S-L-O-W.
+He who laughs last probably made a backup.
+He who lives by the sword laughs last.
+He who places head in sand, will get kicked in the end!
+He who shouts the loudest has the floor.
+He who sitteth on an upturned tack shall surely rise.
+He's dead Jim. Grab his tricorder. I'll get his wallet.
+He's dim, Jed
+He's not dead, Jim, he's just metabolically challenged.
+Heads I win... DITTO tails
+Health food makes me sick.
+Heisenberg slept here, I think.
+Help endangered species - adopt a KGB operative.
+Help fight continental drift.
+Help stamp out mental illness, or I'll kill you!
+Help stamp out, eliminate and abolish redundancy!
+Help!  I'm lost somewhere in the Generation Gap.
+Help!  I've been stuck in here for years and years...
+Help! Police! That guy stole my .sig! STOP!!! THIEF!!!
+Help!!!  I'm falling and I can't click out!!!
+Help, I'm slipping into the Twilight Zone!
+Here today, gaunt tomorrow.
+Hey!  Hacker!  Leave those lists alone!
+Hey!  This is a morgue, not an amusement park!
+Hey!  Who took the cork off my lunch??!
+Hey, CServe/Unisys! Stick it where the sun don't shine!
+Hey, Worf...I hooked Data up to a Modem...Wanna see?
+Hi!  I can't remember your name either.
+Hi, I'm from Corporate.  I'm here to help you.
+Hi. I'll be your tagline for this evening.
+High message: 9434567.  Message last read: 9.
+Hills weed out the weak.  Darwin would argue this is good.
+Hindsight is always 20:20.
+Hindsight is an exact science.
+Hm..what's this red button fo:=/07<NO CARRIER
+Hmm...Nice tagline. <SWIPE!> SUCKER!!! AH, HAHAHAHAHAHAHAHA!
+Hollow chocolate has no calories
+Hollywood is like Picasso's bathroom.
+Honey, PLEASE don't pick up the PH$@#*&$^(#@&$^%(*NO CARRIER
+Honeymoon Salad: Lettuce alone, with no dressing.
+Honeymoon: time between 'I do' and 'you'd better'
+Honk if you love cheeses.
+Honk if you love peace and quiet.
+Honk, if you have slept with Clinton.
+Hors d'oeuvres--a ham sandwich cut into forty pieces.
+Housework done properly, can kill you
+Houston! do you read.
+How come the AT&T logo looks like the Death Star?
+How come there's only one Monopolies Commission?
+How come wrong numbers are never busy?
+How do I set my laser printer for stun?
+How do you know it's summer in Seattle?  Rain's warm!
+How do you make Windows faster ?  Throw it harder
+How do you pronounce my name?   With reverence.
+How do you write zero in Roman numerals?
+How does Michael Jackson pick his nose? From a catalog!
+How does one expect the unexpected?
+How long is a short story?
+How long will a floating point operation float?
+How many consultants will fit onto the head of a pin?
+How many of you believe in telekinesis?  Raise MY hand!
+How many weeks are there in a light year?
+How much can I get away with and still go to heaven?
+How much deeper would the ocean be without sponges?
+Humpty dumpty was pushed.
+Hydrate or Die.
+Hypochondria is the only disease I haven't got.
+I *LOVE* it when a plan comes together!
+I BBS because no one can read my handwriting.
+I Cayman went.
+I Have To Stop Now, My Fingers Are Getting Hoarse!
+I M a tru beleever in hour edukashun sistum.
+I Still miss my ex-wife.....BUT, My aim is improving!
+I Think....therefore I'm OVER QUALIFIED!!!!!!!!!
+I love it when a plan comes together!
+I admit it's offbeat, but lets not get hysterical.
+I always lie.  In fact, I'm lying to you right now!
+I always like to try the one I've never tried before.
+I am Clinton of Borg.  Your income will be assimilated.
+I am Homer of Borg!  Prepare to be...OOooooo!  Donuts!!!
+I am Lancelot of Borg. Resistance is feudal.
+I am both of us & so are you.
+I am built for comfort, not speed!
+I am free of all prejudice. I hate everyone equally.
+I am functioning within established parameters.
+I am in total control, but don't tell my wife.
+I am not an animal!  I am ... well, not an animal.
+I am serious.  And don't call me Shirley.
+I am sweet and lovable at all times.
+I am the girl-next-door's imaginary boyfriend.
+I am what I am and that's all that I am.
+I am. Therefore, I think.  I think.
+I apologize to the deaf for the loss of subtitles.
+I bet you I could stop gambling.
+I bought a cordless extension cord.
+I came, I saw, I did a little shopping.
+I came, I saw, I took LOTS of PICTURES!
+I came... I saw... I stole your tagline.
+I can do without essentials but I must have my luxuries
+I can quit anytime I want; I just don't want to!
+I can resist anything but temptation.
+I can tell you are lying. Your lips are moving.
+I can walk on water, but I stagger on alcohol.
+I can't be overdrawn, I still have checks left!
+I can't believe my computer's on fire.
+I can't hear you. There's a banana republic in my ear.
+I cna ytpe 300 wrods pre mniuet!!!
+I could be arguing in my spare time.
+I could have stuck with DOS, but NO.
+I couldn't care less about apathy.
+I didn't cheat, I just changed the Rules!
+I didn't know it was impossible when I did it.
+I distinctly remember forgetting that.
+I do not fear computers.  I fear the lack of them.
+I do this kind of stuff to him all through the picture.
+I don't care if I'm apathetic.
+I don't care who you are, Fatso. Get the reindeer off my roof!
+I don't care who you are, what you are driving, or where you would rather be.
+I don't eat snails... I prefer FAST food!
+I don't hate Windows - it runs great under Linux!
+I don't have a solution but I admire the problem.
+I don't lie, cheat or steal unnecessarily.
+I don't need a disclaimer. I OWN the company.
+I don't think, therefore I am not.
+I don't want the world, I just want your half.
+I drink to make other people interesting.
+I eat Swiss cheese from the inside out.
+I feel like a fugitive from the law of averages.
+I feel so inar-inar-inar tic-u-late
+I feel the need......the need for speed!
+I finally washed the mud off of mud.
+I find myself beside a stream of empty thought
+I float like an anchor and sting like a moth.
+I get mail........ I exist.
+I give advice worth the price....free!
+I got arrested in LA and boy am I beat!
+I guess a cynic smells different.
+I had a life once... now I have a computer and a modem.
+I had amnesia once or twice.
+I had my coat hangers spayed.
+I hate quotations. Tell me what you know.
+I hate to repeat gossip, so I'll only say this once.
+I have a 9600bps modem and 1.5bps fingers
+I have a rock garden.  3 of them died last week.
+I have a speech impediment... my foot.
+I have already not made that point
+I have seen the evidence.  I want DIFFERENT evidence!
+I have seen the truth and it makes no sense.
+I have the mars observer and I'm not returning it until I get an 'A' in astronomy
+I haven't lost my mind -- it's backed up on tape somewhere.
+I haven't lost my mind, I know exactly where I left it.
+I hear what you're saying but I just don't care.
+I is a college student.
+I is knot dain bramaged!
+I just bought a cured ham.  Wonder what it had?
+I keep my .BAT files in D:\BELFRY
+I know Karate, Kung Fu, and 47 other dangerous words
+I know everything about everything, except that.
+I know it all. I just can't remember it all at once.
+I like candy, especially the gooey kind with nougat!
+I like kids, but I don't think I could eat a whole one.
+I like to leave messages *before* the beep.
+I like to reminisce with people I don't know.
+I like to think of myself as a divide overflow.
+I like your approach, now let's see your departure.
+I lost a button hole today.
+I lost my knickers at Niagara.
+I made it foolproof. They are making better fools!
+I may be fat but you're ugly, and I can lose weight.
+I may be getting older, but I refuse to grow up
+I may not always be perfect, but I'm always me.
+I may not be perfect, but parts of me are excellent.
+I mustanottagottalotta sleep last night.
+I need someone really bad.  Are you really bad?
+I never deny, I never contradict. I sometimes forget.
+I never met a chocolate I didn't like!
+I only counted 100 dalmatians...!!!
+I owe, I owe, it's off to work I go.
+I parked my hard disk and now I can't find it!
+I planted some bird seed.  A bird came up.
+I post.......... I am
+I promise results, not promises.
+I refuse a battle of wits with an unarmed person!
+I remember when Saturns were rockets, not cars.
+I saw, I came, I cleaned it up.
+I smashed a Window and saw... Linux!
+I spilled spot remover on my dog, and now he's gone.
+I think I strained a muscle I didn't know I had!
+I think, therefore I am.  I think.
+I think. Therefore I am DANGEROUS.
+I thought I was wrong but I was mistaken.
+I tried being reasonable once.  I didn't like it.
+I tried switching to gum but I couldn't keep it lit.
+I tried to daydream, but my mind kept wandering.
+I tried to drown my problems but they can swim!
+I try to make everyone's day a little more surreal.
+I used to be disgusted, but now I'm just amused.
+I used to be indecisive, now I'm not so sure.
+I used to be schizophrenic, but we're all right now.
+I used to have a handle on life, then it broke.
+I used to spell badlie, but now I got worser.
+I used to watch TV, then I bought a modem.
+I wake near the end of the day.
+I want .50 cal machine guns as a factory option.
+I warn you not to underestimate my powers.
+I was arrested for selling illegal sized paper.
+I was arrested for walking in someone else's sleep.
+I was going to procrastinate, but I put it off....
+I went on a 30-day diet - and lost 30 days!
+I will defend to your death my right to my opinion.
+I wish life had a scroll-back buffer.
+I wouldn't touch the Metric System with a 3.048m pole!
+I wrote a few children's books, but not on purpose.
+I xeroxed my watch. Now I have time to spare.
+I'd give my left arm to be ambidextrous
+I'd like to live like a poor person with lots of money.
+I'd like to, but last time I went I never came back..
+I'd love to, but I have to fulfill my potential.
+I'd love to, but I have to rotate my crops.
+I'd love to, but I have to stay home and see if I snore
+I'd love to, but I prefer to remain an enigma.
+I'd love to, but I think you want the OTHER Phillip.
+I'd love to, but I'm trying to be less popular.
+I'd love to, but I've dedicated my life to linguini.
+I'd love to, but my crayons all melted together.
+I'd love to, but my favorite commercial is on TV.
+I'd love to, but my patent is pending.
+I'd love to, but none of my socks match.
+I'd love to, but there's a disturbance in the Force.
+I'd love to, but you know how we psychos are.
+I'd rather be bicycling!
+I'll eat anything that's BRIGHT BLUE!!
+I'll get you my pretty, and your little dog too!
+I'll get you yet, you kwazy wabbit!
+I'll jump off that bridge when I come to it.
+I'll tell you what's the matter!  This parrot is dead!
+I'm Not Schizophrenic, And Neither Am I.
+I'm Serfectly Pober.
+I'm a Bum...a BEACH Bum!
+I'm a cowboy ... on a steel horse I ride!
+I'm a lumberjack, and I'm okay!
+I'm a nobody, nobody is perfect, therefore I'm perfect.
+I'm an Debian developer...I don't NEED a life!
+I'm an absolute, off-the-wall fanatical moderate.
+I'm an incorrigible punster, so don't corrige me!
+I'm an influential person, gravitationally speaking.
+I'm as bored as a pacifist's pistol.
+I'm at the corner of Walk and Don't Walk.
+I'm dangerous when I know what I'm doing.
+I'm easy to please as long as I get my way.
+I'm fallin' down a spiral, destination unknown!
+I'm fascinated by the way memory diffuses fact.
+I'm in shape ... Rounds a shape isn't it?
+I'm leaving my body to science fiction.
+I'm moving to Mars next week, so if you have any boxes.
+I'm new and what's all this then?
+I'm no stranger, just a friend you haven't met...
+I'm not a complete idiot - several parts are missing.
+I'm not as dumb as you look.
+I'm not broke, I'm just badly bent.
+I'm not dead. I'm electroencephelographically challenged.
+I'm not even going to ignore that.
+I'm not fat just horizontally disproportionate.
+I'm not loafing. I work so fast I'm always finished
+I'm not lost, I'm 'locationally challenged.'
+I'm not nearly as think as you confused I am.
+I'm not opinionated, I'm just always right!
+I'm not paranoid! Which of my enemies told you this?
+I'm not real smart, but I can lift heavy things.
+I'm not rude, I'm 'attitudinally challenged'.
+I'm not schizophrenic.  It's this guy beside me!
+I'm not tense, just terribly alert.
+I'm on the crest of a slump.
+I'm out of sick days, so I'm calling in dead!
+I'm pink, therefore I'm Spam.
+I'm schizophrenic, What are you?
+I'm so broke, I can't even pay attention.
+I'm spending a year dead for tax purposes.
+I'm sure it's clearly explained in the Zmodem DOC's
+I'm sure it's in the manual somewhere...
+I'm the person your mother warned you about.
+I'm too smart to let my intelligence go to my head.
+I'm turning you in to the SPCA!
+I've been seduced by the chocolate side of the force.
+I've got Parkinson's disease.  And he's got mine.
+I've got a mind like a.. a.. what's that thing called?
+I've got to sit down and work out where I stand.
+I've had fun before.  This isn't it.
+I've run out of sick leave so I'm calling in dead.
+I've seen the future.  I can't afford it.
+IBM: I've Been Misled
+IBM: It may be slow, but at least it's expensive.
+IBM: you can buy better, but you can't pay more
+IF numcooks > .maxcooks THEN;SET V broth = 'spoiled';END
+INTERLACE: To tie two boots together.
+Ideas are not responsible for their followers!
+If At First You Don't Succeed Ignore The Docs...
+If Clinton's the answer, it must have been a really stupid question.
+If I can't fix it, it's probably dead.
+If I can't win, I don't wanna play!
+If I had anything witty to say, I wouldn't put it here.
+If I had been using Windoze, I'd still be writing this.
+If I save the whales, where do I keep them?
+If I save time, when do I get it back ?
+If I want your stupid opinion, I'll beat it out of you.
+If I were here more often, I wouldn't be gone so much.
+If I were two faced, would I wear this one?
+If I were you, who'd be me?
+If Murphy's Law can go wrong, it will.
+If The Shoe Fits - The Sock Fits !
+If a fly has no wings would you call him a walk?
+If a tree falls on a florist, would he make a sound?
+If all goes well, you've overlooked something!
+If all you have is a hammer, everything looks like a nail
+If at first we don't succeed, we run the risk of failure.
+If at first you don't succeed, call it v1.0!
+If at first you don't succeed, hide your astonishment.
+If at first you don't succeed, put it out for beta test.
+If at first you don't succeed, redefine success.
+If at first you don't succeed, skydiving isn't for you.
+If at first you don't succeed, work for Microsoft.
+If at first you don't succeed, you must be using Windows.
+If brains were dynamite you couldn't blow your nose!
+If cows could fly, everyone would carry an umbrella.
+If evolution is outlawed, only outlaws will evolve.
+If idiots could fly, this would be an airport.
+If in doubt, make it sound convincing.
+If it glows don't touch it!
+If it has feelings, its not cooked enough!
+If it isn't broken, don't fix it.
+If it jams, force it. If it breaks, it needed replacing
+If it walks out of your refrigerator, LET IT GO !!
+If it works, tear it apart and find out why!
+If it's not broke, let me take a crack at it.
+If it's not going to plan, maybe there never was a plan.
+If it's not on fire, it's a software problem.
+If it's not worth doing well, it's not worth doing.
+If it's stupid and works, then it ain't stupid
+If it's too loud, you're too old.
+If life gives you lemons, make lemonade.
+If little else, the brain is an educational toy.
+If marriage is outlawed, only outlaws will have inlaws.
+If money could talk, it would say goodbye.
+If nobody measures up, check your yardstick.
+If rabbits feet are so lucky, what happened to the rabbit?
+If speed scares you, try Windows...
+If the shoe fits, put it in your mouth.
+If there are epigrams, there must be meta-epigrams.
+If there's one thing I can't stand, it's intolerance.
+If this were an actual tagline, it would be funny.
+If truth is stranger than fiction, you must be truth!
+If voting changed anything, they'd make it illegal.
+If winning isn't important then why keep score?
+If you associate with the wise, you will become wise.
+If you believe in telekinesis, raise my hand.
+If you can't run with the big dogs, stay on the porch.
+If you cannot convince them, confuse them.
+If you choke a smurf, what color does it turn?
+If you didn't get caught, did you really do it?
+If you don't care where you are, then you ain't lost.
+If you don't like my opinion of you - improve yourself!
+If you don't like the news, go out and make some of your own.
+If you have nothing to do, don't do it here.
+If you have to ask what jazz is, you'll never know.
+If you hear an onion ring please answer it.
+If you mess with something long enough it'll break.
+If you must drink and drive, drive a Yugo!
+If you saw a heat wave, would you wave back?
+If you say nothing, no one will repeat it.
+If you see an onion ring, ANSWER IT!
+If you think education is expensive, try ignorance.
+If you try to fail, and succeed, which have you done?
+If you want your name spelt wrong, die.
+If you wish work poorly done, pay in advance.
+If you're not confused, you're not paying attention.
+If you're not the solution, you're the precipitate.
+If your attack is going well, then it's an ambush..
+If your ship doesn't come in, swim out to it!
+Ifyoucanreadthis,youspendtoomuchtimefiguringouttaglines!
+Ignorance is temporary; stupid is forever.
+Illiterate? Write for free help.
+Imagery is All In The Mind.
+Imagination is the only weapon in the war against reality
+Impropriety is the soul of wit.
+In God we trust, all others pay cash.
+In a fight between you and the world, back the world.
+In case of emergency, break glass. Scream. Bleed to death
+In case of fire, yell 'FIRE!'
+In politics stupidity is not a handicap.
+In the land of the witless, the halfwit is king.
+In war there is no substitute for victory.
+Include this in your CONFIG.SYS File: BUGS=OFF
+Incompetence plus incompetence equals incompetence.
+Individualists of the world, UNITE!
+Inertia makes the world go round.
+Inferiority complex: conviction by a jury of your fears.
+Innovate or Die.
+Insanity is hereditary.  You get it from your kids.
+Insanity is just a state of mind.
+Insert New Disk for Drive C: Press ENTER when ready.
+Insert inevitable trivial witticism of your choice.
+Interchangeable parts won't.
+Internal combustion engines are the dinosaurs' revenge
+International Brotherhood of Tagline Thieves.
+Interstellar Matter is a Gas
+Invisible Systems, Inc. If you don't see it, we made it.
+Iron Law of Distribution: Them that has, gets.
+Is 'tired old cliche' one?
+Is it OK to yell 'MOVIE' in a crowded firehouse?
+Is it in my head...or in my heart?
+Is it ok to use my AM radio after NOON?
+Is it possible to feel gruntled?
+Is that a flying saucer or a pie in the sky?
+Is there life before coffee?
+Is this a machine?  I don't talk to machines!  [Click]
+Is this the right room for an argument?
+It all looks the same if you're not the lead dog.
+It can't be full...I STILL HAVE SUBDIRECTORIES!
+It compiled, first screen came up??  Ship it! --Bill Gates
+It did what?  Well, it's not supposed to do that.
+It doesn't work, but it looks pretty.
+It has many other uses as well.  Allow me. - Worf
+It is always better to sacrifice your opponent's men
+It is bad luck to be superstitious.
+It is better to be brief than boring.
+It is better to wear out than to rust out.
+It is broke.  It will not work.  It does not go.
+It is fatal to live too long.
+It is incumbent on us to avoid archaisms.
+It is morally wrong to allow suckers to keep their money.
+It is much easier to be critical than to be correct
+It is not enough to succeed.  Others must fail.
+It is, after all,  only a moment in the infinity of time.
+It really bothers me when people cut me o...
+It said 'Insert disk #3', but only two will fit!
+It works better if you plug it in.
+It's 10:00 PM...do YOU know where YOUR tagline is?
+It's Ensign Flintstone - he's Fred, Jim.
+It's a Tough Job! ..... So I'd Rather YOU do it.
+It's a fine line between fishing & standing still
+It's a fine night to have an evening.
+It's a good thing we don't get all the government we pay for.
+It's a tough job! ..... So I'd Rather YOU do it.
+It's an ill wind that gathers no moss.
+It's as bad as you think and they are out to get you.
+It's bad luck to be superstitious.
+It's been a business doing pleasure with you.
+It's been lovely, but I have to scream now.
+It's best to leave quickly when you make noises like that...
+It's better to burn out than to fade away.
+It's clever, but is it art?
+It's de\ 2ja\ 5 vu all over again.
+It's easier to get older than it is to get wiser.
+It's easier to obtain forgiveness than permission.
+It's easy to apply yourself, just use crazy glue!
+It's easy to be brave from a safe distance.
+It's hard to RTFM when you can't find the FM..
+It's hard to be serious when you're naked.
+It's life Jim, but not as we know it.
+It's like Deja Vu all over again...
+It's lonely at the top, but you eat better.
+It's more than a reader.  It's a message base manager!
+It's never too late to have a happy childhood
+It's not easy having an overbearing parent! - Troi
+It's not hard to meet expenses, they're everywhere!
+It's not in the manual!
+It's not just a hobby, it's an obsession!
+It's not pretty being easy.
+It's not the bullet that kills you, it's the hole.
+It's not the money I want, it's the stuff.
+It's not the principle of the thing, it's the money
+It's okay to be ugly...but aren't you overdoing it?
+It's only a hobby ... only a hobby ... only a hobby ... only
+It's only ones and zeros.
+It's raining, it's pouring, the old man is...dead, Jim.
+It's smart to pick your friends, but not your nose.
+It's starting to rain, .SQZ the animals into the .ARC !
+It's true, forgiveness IS easier to get than permission
+Its a JOKE, like the funny kind but different.
+Itsdifficulttobeverycreativewithonlyfiftysevencharacters!
+JFK: I need this motorcade like a hole in my head!
+James Bond rules.  00K.
+Jealousy is all the fun you think they have.
+Jet Engine Theory -Suck, Squeeze, Bang, Blow!
+Join the Group Mind - become a Borg
+Joseph Stalin's grave was a Communist Plot.
+Jumbo shrimp = oxymoron.
+Junk: stuff we throw away.  Stuff: junk we keep.
+Just because you're STUPID ain't no excuse.
+Just because I'm paranoid doesn't mean they aren't out to get me!
+Just do it.
+Just don't tell the asylum you saw me here
+Just how much leg have I got
+Just my 78,000 lira worth.
+Just what part of 'NO' didn't you understand...?
+Just when you think you've won the rat race along come faster rats.
+Justice is incidental to law and order.
+Justice: A decision in your favor.
+Kamikaze Pilot Wanted: Experienced only need apply.
+Keep America beautiful.. properly dispose of your lawyer.
+Keep a clear head and always carry a lightbulb.
+Keep emotionally active. Cater to your favorite neurosis.
+Keyboard Not Found - Press [F1] to Continue
+Kicked wide of the goal with such precision.
+Kids-They're not sleeping, they're recharging!
+Kill them all!  .... Let God sort them out.
+Killer Rabbit's Motto:  'Lettuce Prey.'
+Kilroy occupied these coordinates.
+Kleptomania: take something for it
+Know what I hate?  I hate rhetorical questions!
+Knowing Murphy's Law won't help either.
+LISP:  To call a spade a thpade.
+LISTEN HERE!  I HAVE FIRST AMENDENT RIGH(@#$!9*&^ NO CARRIER
+LOTUS - Let Only The Users Suffer
+Laddie, ya think ya might like ta ... rephrase that?
+Land of the Single Entendre...
+Last week I forgot how to ride a bicycle.
+Laugh and the world thinks you're an idiot.
+Laughter: The shortest distance between two people.
+Lead me not into temptation, I can find it myself.
+Lesser artists borrow. Great artists steal.
+Let he who takes the plunge remember to return it!
+Let's organize this thing and take all the fun out of it.
+Let's split up, we can do more damage that way.
+Liberal - a power worshiper without power.
+Libraries: There are no answers, only cross references.
+Life - brief interlude between nothingness and eternity.
+Life can be great if you live it to the fullest!
+Life is a sandwich, and it's always lunchtime
+Life is a series of very rude awakenings.
+Life is like a Car-wash and I'm on a bicycle.
+Life is only as long as you live it.
+Life is serious, but ART is fun!
+Life is tough. It's tougher when you're stupid.
+Life is uncertain...eat dessert first!
+Life sucks, but Death swallows!
+Life would be easier if I had the source code.
+Life's too short to dance with ugly men.
+Life's too short to dance with ugly women.
+Life, loathe it or ignore it, you can't like it.
+Likelihoods, however, are 90% against you.
+Likes and dislikes are among my favorites
+Linux, the choice of a GNU generation.
+Liposuction will destroy your FAT
+Lisp programmers have to stop and collect garbage.
+Live before you die.
+Living poor is best left to those with no money.
+Locked coathanger in car. Good thing I had a key.
+Looks like I picked the wrong week to stop sniffing glue.
+Love is blind, marriage is the eye-opener.
+Luxuriantly hand-crafted from only the finest ASCII.
+M.A.D.D.:  Midgets Against Desk Drawers.
+MOPAR  =  Move Over Plymouth Approaching Rapidly!
+MS Windows -- From the people who brought you EDLIN!
+MS-DOS: celebrating ten years of obsolescence
+Macho does not prove Mucho.
+Madness takes its toll; please have exact change.
+Make Headlines..use a corduroy pillow....
+Make it as simple as possible, but no simpler.
+Make it do ... Or do without.
+Make like a Tom and Cruise.
+Make like a baby and head out.
+Make like a banana and split.
+Make like a drum and beat it!
+Make like a tree and leave.
+Make somebody happy. Mind your own business.
+Make up a language and ask people for directions.
+Man has his will.  Woman has her won't!
+Man invented language to satisfy his need to complain.
+Man who get hit by car, get that run down feeling
+Man who jumps through screen door likely to strain himself
+Man who put head on railroad track get splitting headache
+Man who run behind car get exhausted.
+Man who speaks with forked tongue should not kiss balloon
+Marching to a different kettle of fish.
+Mary had a little RAM -- only about a MEG or so.
+Math is the language God used to write the universe.
+May I please be excused?  My Brain is full.
+May the Porsche be with you.
+May you live in interesting times.
+May your life be filled with experiences.
+Me know gammar.  Me cood use it gud.
+Mediocrity requires aloofness to preserve it's dignity
+Meditation is not what you Think.
+Meet the new Boss--same as the old Boss...
+Megabyte: A nine course dinner.
+Member: International Brotherhood of Tagline Thieves!
+Memory is a thing we forget with.
+Mental Floss prevents Moral Decay.
+Mercifully free of the ravages of intelligence
+Microfiche: Sardines.
+Microsoft Windows... a virus with mouse support.
+Microsoft gives you Windows... Linux gives you the whole house.
+Migratory lifeform with a tropism for parties
+Minds are like parachutes, they only work when open.
+Misfortune: The kind of fortune that never misses.
+Misspelled? Impossible. My modem is error correcting!
+Mistakes are often the stepping stones to utter failure.
+Modem: What landscapers do to dem lawns.
+Money is the root of all wealth.
+Monogamy leaves a lot to be desired.
+Monopoly? No, we just don't want competition.
+Most of us have been at work for several hours now.
+Mother is the invention of necessity.
+Multitasking = 3 PCs and a chair with wheels!
+Multitasking causes schizophrenia..
+Murphy is out there... waiting...
+Murphy was an optimist.
+Murphy's law needs to be repealed.
+Must Go - My Rotweiler needs its teeth sharpened.
+My *taglines* are original.  *I* am a copy.
+My RAM's not what it used to be, so don't quote me.
+My attention isn't hard to get. It IS hard to keep...
+My best friend is a social worker.
+My computer has a terminal illness
+My computer's sick, I think my modem's a carrier
+My couch potato routine honed to perfection
+My fallacies are more logical than your fallacies.
+My foolish parents taught me to read and write.
+My hat covers my head... Just like hair used to!
+My haystack had no needle!
+My head is sore, and there's a hole in the brick wall!
+My inferiority complexes aren't as good as yours.
+My karma ran over your dogma.
+My life may be strange, but at least it's not boring
+My message above.  Your response here ____________.
+My other computer is a Cray Y/MP-4!
+My other computer is a HAL 9000.
+My other computer is an abacus.
+My other vehicle is a Galaxy Class Starship ...
+My reality check just bounced.
+My tagline can beat up your tagline!
+My weight is perfect for my height... which varies.
+NAVY: Never Again Volunteer Yourself
+NETWORK: What fishermen do when not fishing.
+NEWS! Drunk gets nine months in violin case
+NEWS! Enraged cow injures farmer with ax
+NEWS! Iraqi head seeks arms
+NEWS! Police begin campaign to run down jaywalkers
+NEWS! Stolen painting found by tree
+NEWS! Survivor of siamese twins joins parents
+NO!  Taco Bell is NOT the Mexican Phone Company!
+NUMBER CRUNCHING:  Jumping on a Computer.
+Naaah, real men don't read docs.
+Nanosecond: Mork's stunt man.
+Neil Armstrong tripped.
+Neither rain, nor snow, nor l?ne n*oi*se
+Neurotic: Self-taut person.
+Never argue with a woman when she's tired, or rested.
+Never assume.  It makes an 'ass' out of 'u' and 'me'.
+Never count your chickens before they rip your lips off.
+Never draw fire, it irritates everyone around you
+Never eat anything bigger than your head.
+Never eat more than you can lift.
+Never enter a battle of wits unarmed.
+Never go with the odds
+Never hit a man with glasses.  Use your fist!
+Never judge a man by his taglines.
+Never let your feet run faster than your shoes.
+Never mind the facts - I know what I know.
+Never park your hard disk in a tow-away zone.
+Never say, 'Oops!'; always say, 'Ah, interesting!'
+Never test for an error you don't know how to handle.
+Never trust a man who can count to 1,023 on his fingers
+Never trust a skinny cook.
+Never underestimate the power of human stupidity.
+Never use a preposition to end a sentence with.
+New Highway gets Railroaded.
+Newsbytes - Microsoft announce EDLIN for Windows.
+Nihilism should commence with oneself.
+Ninety per cent of everything is crap.
+Nitpicking:  Not just a hobby, it's a way of life!
+Nitrate:  Lower than the day rate.
+No .sig is a good .sig
+No free lunch in an ecosystem.
+No one EXPECTS the Spanish Inquisition!!!
+No one ever said 'if I'd only spent more time in the office'
+No radio.  Already stolen.
+No sense being pessimistic.  It wouldn't work anyway.
+No wanna work.  Wanna bang on keyboard.
+No, I'm from Iowa. I only work in Outer Space.
+Nobody roots for Goliath.
+Nobody shoots at Santa Claus.
+Nodding the head does not row the boat.
+None of you exist, my Sysop types all this in.
+Nostalgia isn't what it used to be.
+Not a computer nerd; merely a techno-weenie.
+Not a real tagline, but an incredible soy substitute.
+Not many people realize just how well known I am.
+Not now, John, we gotta get on with the game show...
+Not quite human any longer.
+Nothing is 100% certain, bug free or IBM compatible.
+Nothing is as inevitable as a mistake whose time has come
+Nothing is ever so bad that it can't get worse.
+Nothing is foolproof because fools are so ingenious
+Nothing is impossible for anyone impervious to reason
+Nothing recedes like success.
+Nothing succeeds like excess.
+Now entering Iowa.  Please set your clocks back 20 years.
+Now go away or I shall taunt you a second time.
+Now is not a good time to annoy me
+Now is the time for all good men to come to.
+Now that I've given up hope I feel much better...
+Nudge, nudge, wink, wink, know what I mean?
+O Oysters come and walk with us, the Walrus did beseech.
+OK Scotty, detonate and energize NOW!  No, wait, I mean.......
+OK, I'm weird! But I'm saving up to become eccentric.
+OPERATOR! Trace this call and tell me where I am.
+OUT TO LUNCH - If not back at five, OUT TO DINNER!
+Obe Wan Kenobi at the dinner table: 'Use the FORKS, Luke!'
+Objection, your Honor! My client is an idiot!
+Objectivity is in the eye of the beholder
+Objects in taglines are closer than they appear.
+Of all the people I've met you're certainly one of them
+Of all the things I've lost, I miss my mind the most.
+Of course I'm running Windows[kVxB NO CARRIER
+Oh goody! Another Muranium Explosive Space Modulator!
+Oh no you don't!  You're not stealing this one!
+Oh no, not another learning experience!
+Oh, Bullwinkle, that trick NEVER works!
+Ok, I pulled the pin.  Now what?  Where are you going?
+Okay - right after this one we're BACK to the TOPIC
+Old MacDonald had a computer with an EIE I/O
+Old age is better than the alternative.
+On a clear disk you can seek forever.
+On a scale of 1 to 10, 4 is about 7.
+On an electrician's truck: Let Us Remove Your Shorts
+One atom bomb can really ruin your day.
+One good turn gets most of the blanket.
+One is never as happy or unhappy as one imagines.
+One man's Windows are another man's walls...
+One man's upload is another man's download
+One night I came home very late. It was the next night
+One tactical thermonuclear weapon can ruin your whole day.
+One way to better your lot is to do a lot better...
+One way to stop a run away horse is to bet on him.
+Only 19,999 lines of C++ to my next ski trip...
+Only cosmetologists give make-up exams.
+Only the winners decide what were war crimes.
+Open Mouth. Insert Foot. Chew Carefully.
+Optimization hinders evolution.
+Originality is the art of concealing your sources.
+Our houseplants have a good sense of humous.
+Our necessities are few but our wants are endless...
+Out here in the fields...I fight for my meals...!
+Out of Memory!?  But I fed you 6 Megs this morning!
+Out of the mouths of babes does often come cereal.
+Outlaw junk mail, and save the trees!
+Overload--core meltdown sequence initiated.
+Oxymoron - Definite possibility
+Oxymoron - Military Intelligence
+Oxymoron: Bosnian Cease-Fire
+Oxymoron: Soviet Union.
+PC!  Politically Correct (or) Pure Crap!
+PCBackup: 1 of 1362 disks.
+PI seconds is a nanocentury. - Tom Duff, Bell Labs
+PKZip - it's not just for downloads anymore
+Pain is inevitable, suffering is optional.
+Palindrome isn't one.
+Pandemonium doesn't reign here... It pours!
+Paranoia is heightened awareness.
+Paranoia is simply an optimistic outlook on life.
+Pardon my driving, I'm trying to reload.
+Pascal:  What's it Wirth?
+Passwords are implemented as a result of insecurity.
+Patience is a virtue that carries a lot of WAIT!
+Pay your electric bill in pennies.
+Peace through superior firepower.
+People are always available for work in the past tense.
+People say I'm apathetic, but I don't care.
+People who live in glass houses shouldn't!
+People who live in stone houses shouldn't throw glasses.
+Perot/Bush/Quayle: The Millionaire, Skipper & Gilligan.
+Pet Store: 'Buy one, get one flea.'
+Petroleum and coffee had no value a few centuries ago.
+Pi R squared.  Nooo!  Pie R round, cornbread R square!
+Pizza IS the four food groups!
+Plagiarism is the sincerest form of flattery.
+Plagiarism prohibited, derive carefully.
+Plankton lobbyist:  'NUKE THE WHALES!'
+Plasma is another matter.
+Please Tell Me if you Don't Get This Message
+Please call the windows police.  I've caught another gpf.
+Please don't drink and post.
+Please don't take my sunshine away.
+Please recycle this tagline.  Once is not enough.
+Pobody's Nerfect!
+Poets go from bad to verse
+Point not found. A)bort, R)eread, I)gnore.
+Politeness, n: The most acceptable hypocrisy.
+Political panjandrums prologize pedantic paronomasia.
+Political power grows out of the barrel of a gun.
+Politics is the entertainment branch of industry.
+Positive: Mistaken at the top of one's voice.
+Pound forehead on keyboard to continue.
+Power corrupts, but we need electricity.
+Power corrupts. Absolute power is kind of neat.
+Predestination was doomed from the start.
+Predicting the future of technology is fraud with peril!
+Prejudice is the reason of fools. - Voltaire.
+Preserve wildlife... pickle a rat.
+Press <CTRL>-<ALT>-<DEL> to continue...
+Press any key to continue or any other key to quit
+Press any key...NO, NO, NO, NOT THAT ONE!!!!!!
+Procrastination means never having to say you're sorry.
+Procrastination:  The art of keeping up with yesterday.
+Program too small to fit into memory.
+Programming is an art form that fights back.
+Progress is made on alternate Fridays.
+Prosecutors will be violated
+Psychiatrists stay on your mind.
+Psychoceramics: The study of crackpots.
+Push the limit, and the limit will move away!
+Put on your seatbelt. I wanna try something.
+Put people on hold when possible.
+Quantum mechanics do it in leaps.
+Quasimodo is a dead ringer.
+Question Authority, ask me anything
+RAID Antivirus - Kills Virus's DEAD!!!
+Racial prejudice is a pigment of the imagination.
+Radioactive halibut will make fission chips.
+Random order = oxymoron
+Rap music = oxymoron
+Read the dictionary backwards and look for secret messages.
+Real Programmers aren't afraid to use GOTO's.
+Real Trekkers work out at the He's Dead Gym.
+Real men don't set for stun.
+Real men write self-modifying code.
+Reality is a crutch for people who can't handle buttons
+Reality is an obstacle to hallucination.
+Reality is for people who can't handle Star Trek.
+Reality is nothing but a collective hunch.
+Really ??  What a coincidence, I'm shallow too!!
+Recursive, adj.; see Recursive
+Red ship crashes into blue ship - sailors marooned.
+Reduce Carbon Dioxide emmissions - STOP Breathing
+Redundancy: A Politician with an airbag in his car.
+Refuse Novocain...Transcend Dental Medication!
+Remember that you are unique.  Just like everyone else.
+Remember, If you're not in bed by 10:30..... go home!
+Remember, Subaru spelled backwards is U-R-A-BUS.
+Reputation:  what others are not thinking about you.
+Resistance Is Useless!   (If < 1 ohm)
+Return((usBirdInHand = 2 * InTheBush()));
+Reverse the polarity of the neutron flow.
+Revolution is the opiate of the intellectuals.
+Road Kill Cafe:  You kill 'em, we grill 'em.
+Roses are red, Violet's are blue, And mine are white.
+Rotisserie: a ferris wheel for chickens
+Round up the usual suspects!
+Rubber bands have snappy endings!
+Russian Express Card motto: Don't leave home!
+S met ing's hap ening t  my k ybo rd . .
+SCUD : Sure Could Use Directions
+STICK: A boomerang that doesn't work.
+STUPIDITY is NOT a HANDICAP!  Park elsewhere!
+SYNTAX?  Why not--they tax everything else!
+SYSTEM ERROR:  press F13 to continue...
+Santa's elves are just a bunch of subordinate Clauses.
+Sarcasm: barbed ire.
+Save California; when you leave take someone with you.
+Save energy: be apathetic.
+Save the whales!  Trade them for valuable prizes!
+Save the whales.  Collect the whole set.
+Save your money for a rainy day, or a new computer!
+Say yer prayers, y' flea-bitten' varmint.
+Schizophrenia beats being alone.
+Science asks why.  I ask why not.
+Science: preconception meeting verification.
+Scientists discover life causes cancer.
+Scotty! Hurry! Beam me uragg^*z~% NO CARRIER
+Scrute the inscrutable, eff the ineffable.
+See how you can be?
+Seeing is deceiving. It's eating that's believing.
+Send lawyers, guns, & money...
+Send more tourists..... the last ones were delicious!
+Sentient plasmoids are a gas.
+Serving the scum of Paris for over 300 years
+Set mode=Extremely verbose
+Shareware author dies:  .GIF at eleven!
+Shareware: forget the manual...phone the author at home!
+ShelfDoze is a registered Trademark of M$.
+Shell to DOS... come in DOS... Do you copy?
+Shh! Be vewy quiet, I'm hunting wuntime errors!
+Shin - a device for finding furniture in the dark..
+Shoot your program and put it out of its memory!
+Shoplifters with the runs take Clepto Bismol
+Short people are vertically challenged.
+Should I or shouldn't I?... Too late, I did!
+Should I weed the lawn or say it's a garden?
+Show me a sane man.  I'll cure him for you.
+Sign here please:_______________________Thanks
+Sign on Closed Nuclear Power Plant... 'Gone Fission'
+Sign on a clothing store - Come inside and have a fit.
+Signito ergo sum - I sign therefore I am.
+Simon says: don't be so suggestible.
+Sit down, you're rocking the boat!
+Six of one, 110 (base 2) of another.
+Skating away on the thin ice of a new day.
+Slower Traffic Keep Right  -  Is that so difficult?
+Slug Sautee: a hors of a different d'oeuvre.
+Small changes pick up the reins from nowhere.
+Smash forehead on keyboard to continue...
+Smile.  It's the second best thing you can do with your lips.
+Smile... people will wonder what you've been up to.
+Smiley faces were meant to be annoying.
+Smokey the Bear says, 'Strip mining prevents forest fires!'
+Smoking cures weight problems...eventually.
+Smoking is a leading cause of statistics.
+Smurf exterminator.
+So many bytes, so few cps.
+So many lawyers, so few bullets.
+So many pedestrians, so little time.
+So many toys, so little time...
+So much time, and so little to do.
+Socialism is the equal distribution of poverty.
+Software Independent: Won't work with ANY software.
+Software means never having to say you're finished
+Some Do, Some Don't, Some Will and Some Won't.
+Some People....
+Some days you're a bug, other days a windshield.
+Some days, nothing goes left.
+Some little dipstick stole all my good taglines...
+Some minds should be cultivated, others plowed under...
+Some people are so nice to be nasty to.
+Some people are, through no fault of their own, sane.
+Some things have got to be believed to be seen.
+Someone is unenthusiastic about your work.
+Something is rotten in the state of confusion.
+Sometimes a cigar is just a cigar.
+Sorry about your Rectal-Cranial Inversion.
+Sorry, I don't date outside my species.
+Sorry... my mind has a few bad sectors.
+Southern DOS:  Y'all reckon? (yep/Nope)
+Space is an illusion, disk space doubly so.
+Space is big.  Really big.
+Spaceman Spiff, Interplanetary Explorer!
+Speaking only for myself, one of my many tricks.
+Spell chequers dew knot work write.
+Spice is the variety of life.
+Stamp out philately!
+Standing there making a sitting target of himself.
+Stay Alert.  Stay Awake.  Stay Alive.
+Steal my cash, car and TV - but leave the computer!
+Sterility is hereditary.
+Stop tagline theft! Copyright your tagline &copy;
+Strike any user when ready.
+Stupidity got us into this mess, why can't it get us out?
+Subvert the dominant paradigm!
+Suicide is the most sincere form of self criticism.
+Sumo Wrestling: survival of the fattest.
+Supercalifragilisticexpialidocius
+Supernovae are a Blast
+Support bacteria - it's the only culture some people have!
+Support the helpless victims of computers.
+Surprise your boss.  Get to work on time.
+Swish, two, three, four!  Swish, two, three, four!
+Sylvester Stallone: father of the RISC concept.
+THE GOLDEN RULE: He who has the gold makes the rules
+TV is chewing gum for the eyes.
+Tact: knowing how far to go too far.
+Tact: making a point without making an enemy.
+Tagline Lotto: 2222222222<- Scratch here for prize.
+Tagline theft is a compliment.
+Taglines  \'tag-l\ 4inz \  The bumperstickers of the internet
+Take a bite out of crime .. Abolish the IRS!
+Take my advice, I don't use it anyway.
+Take two crows and caw me in the morning
+Talk is cheap because Supply exceeds Demand.
+Taxes are not levied for the benefit of the taxed.
+Teamwork is essential. It gives them another target.
+Ten weeks from Friday will be a pretty good day.
+Thank you very little.
+That ain't so good English!
+That must be wonderful! I don't understand it at all.
+That that is is not that that is not.
+That was ZEN -- this is TAO
+That'll be $67.50  CCCHHHHHIIIIINNNNGGGG!!!!
+That's inches away from being millimeter perfect.
+The Borg assimilated me & all I got was this stupid T-Shirt!
+The Czech's in the mail. Sending Frenchman by FAX.
+The French defense isn't...
+The Hubbell works fine; all that stuff IS blurry!
+The Lab called,..... Your brain is ready!
+The Magic of Windows:  Turns a 486 back into a PC/XT.
+The Microsoft Motto:  'We're the leaders, wait for us!'
+The PARITY CHECK is in the E-MAIL...
+The Tour de France!
+The UARTs won't take this speed, Captain
+The Universe is a big place... perhaps the biggest
+The Vatican Express Card. Don't leave Rome without it.
+The backup's not over 'til the FAT table sings!
+The ballot is stronger than the bullet.
+The best cure for insomnia is to get a lot of sleep.
+The best defense against logic is stupidity.
+The best defense is to stay out of range.
+The best substitute for experience is being sixteen.
+The best way to keep friends is not to give them away.
+The best way to win an argument is to be right.
+The buck doesn't even slow down here!
+The cause of problems are solutions!
+The cost of feathers has risen... Now even DOWN is up!
+The cost of living hasn't affected its popularity.
+The cream rises to the top.  So does the scum...
+The days of the digital watch are numbered
+The dentist said my wisdom teeth were retarded.
+The dreadful burden of having nothing to do.
+The evidence before the court is...INCONTROVERTIBLE!
+The eyes are the mirror of the soul.
+The first duty of a revolutionary is to get away with it
+The first myth of management is that it exists.
+The first rule of intelligent tinkering is save all parts!
+The fish that escaped is the big one.
+The further I go, the behinder I get.
+The future isn't what it used to be.
+The game's a little bit wide open again.
+The gene pool has no lifeguard.
+The hand that turneth the knob, opens the door.
+The hangman let us down.
+The hardest thing about time travel is the grammar.
+The heart is wiser than the intellect...
+The irony of life is that no one gets out alive...
+The large print giveth and the small print taketh away.
+The little engineer that could
+The longer the title, the less important the job.
+The man who begins many things finishes few.
+The margin is very marginal.
+The meek shall inherit the earth, if that's OK with you
+The mind is like a parachute - it works only when open.
+The moving cat sheds, and having shed, moves on...
+The next thing to do is hang all the consultants.
+The only thing shorter than a weekend is a vacation.
+The option to override self-destruct expir@^%i@&$#NO CARRIER
+The pen is mightier than the pencil.
+The penalty for bigamy is having two mothers-in-law.
+The pendulum has gone full circle.
+The purpose of computing is insight, not numbers.
+The rich get richer; the poor get babies.
+The road to success is always under construction.
+The score didn't really reflect the outcome.
+The secret of the universe is~~*#~** FF * NO CARRIER
+The shortest distance between two points is off the wall
+The simple explanation always follows the complex solution
+The sixth sheikh's sixth sheep's sick.
+The soul would have no heart had the eyes no tears...
+The superfluous is very necessary.
+The thrill is gone, the thrill is gone baby
+The universe is a spheroid region 705 meters in diameter...
+The unnatural, that too is natural.
+The way to a man's heart is through the left ventricle.
+The weather is here, wish you were beautiful.
+The whole world is about three drinks behind
+The world is coming to an end.  Please log off.
+The worst thing about censorship is **************************.
+The young know the rules, the old know the exceptions.
+Then somebody spoke, and I went into a dream....
+There are 2 ways to handle women and I know neither.
+There are many things I could say...
+There are no atheists in the foxholes.
+There is always a way, and it usually doesn't work.
+There is an exception to every rule, except this one.
+There is much Obiwan did not tell you.
+There is no dark side of the moon.  Really.
+There is no finish line.
+There is no remedy for fun but more fun!
+There is no vaccine against stupidity.
+There is something to be said about me: 'Wow!!'
+There will be no last bus tonight.
+There's a hot place with pitchforks waiting.
+There's no future in time travel
+There's no such thing as a free lunch, but you can always find someone willing to treat.
+There's one in every car... You'll see.
+There's one in every crowd and they always find me.
+There's safety in numbers/When you learn to divide.
+Thesaurus: ancient reptile with an excellent vocabulary.
+They told me I was gullible ... and I believed them!
+Things are not what they seem.
+Think 'HONK' if you're a telepath.
+Think hard now!  Which one is Shinola?
+This Charlie Brown must have been a very wise man.
+This Country Needs Group Therapy.
+This ain't no party...this ain't no disco...
+This door is baroque; please call Bach later.
+This is a Tagline mirror ][ rorrim enilgaT a si sihT
+This is abuse.  Arguments are down the hall.
+This is just a hobby. Perfection is not required. Fun is.
+This is not a fairing, it's a force field.
+This is only a test.
+This is our only tag line.
+This isn't right.  This isn't even wrong.
+This line intentionally left unjustified.
+This login session: $13.99, but for you $11.88
+This message has been UNIXized for your protection.
+This message is SHAREWARE!  To Register, send $5.
+This message was typed on recycled phosphorous.
+This mind intentionally left blank.
+This program makes me look like a genius.
+This sentence is false.
+This tagline does not require Micro$oft Windows.
+This tagline intentionally left blank.
+This tagline is umop apisdn
+This tagline only to be removed by the consumer.
+This tagline was created from many little letters.
+This tagline was reclaimed and is not yet stolen.
+This tagline was written before a live studio audience.
+Those who can't write, write manuals.
+Those who can, do.  Those who can't, simulate.
+Those who can, do.  Those who can't, supervise!
+Those who live by the nit, die by the nit
+Those without heads do not need hats.
+Three can keep a secret, if two are dead.
+Tilt your chair back, your breath is effecting my RAM!
+Tilting at windmills hurts you more than the windmills.
+Time flies like an arrow - Fruit flies like a banana
+Time flies when you don't know what you're doing.
+Time is an illusion, lunchtime doubly so.
+Tis better to be hunter than hunted.
+Tis better to have loved a short than to never have loved a tall.
+Tis better to have loved and lost than just to have lost.
+To be, or not to be, those are the parameters.
+To boldly go and watch Star Trek re-runs.
+To do nothing is also a good remedy.
+To eat is human, to digest, divine.
+To err is human, to eat Jello, is messy.
+To err is human, to forgive is against company policy.
+To err is human.  To really screw up it takes a computer.
+To err is human. To blame someone else is politics.
+To err is human. To moo bovine
+To every rule there is an exception, and vice versa.
+To iterate is human, to recurse, divine.
+To live in the hearts we leave behind, is not to die.
+To live well, know the difference between good and evil.
+To me personally, it's nothing personal to me.
+To shoot a mime, do you use a silencer?
+Today is Monday, cleverly disguised as Tuesday.
+Today is National Existential Ennui Awareness Day.
+Today is the first day of the rest of this mess.
+Today is the tomorrow you worried about yesterday
+Todays subliminal message is ' '
+Tolkien is hobbit-forming.
+Tongue tied & twisted, just an earthbound misfit I.
+Too bad stupidity isn't painful.
+Too much is never enough.
+Too much month at the end of the money.
+Too much of a good thing is WONDERFUL.
+Toto, I don't think we're in DOS anymore...
+Touch if you must, Pay up if you bust.
+Toys are made in heaven, batteries are made in hell.
+Trees hit cars only in self-defence.
+Trespassers will be shot, survivors will be shot again!
+Tried to play my shoehorn... all I got was footnotes!
+Trig..a..name...o...tree!!!
+Truck Pulls: for people who cannot understand the WWF
+Trust me -- I'm a Lawyer.
+Truth is just another misconception.
+Truthful: Dumb and illiterate.
+Try to get back on topic, he said moderately.
+Try to look unimportant, they may be low on ammo
+Try?  Try not.  Do, or do not.  There is no try.
+Trying to think of a good tagline...
+Tubby or not tubby, fat is the question!
+Turn right here. No! NO! The OTHER right!
+Turning floppies into hard drives.
+Two Wrongs Don't Make A Right, But Three Lefts Do.
+Two heads are more numerous than one.
+Two most common elements: hydrogen, stupidity.
+Tyre Shop sign - We Skid You Not.
+UART what UEAT!
+UNNAMED LAW: If it happens, it must be possible.
+Uh, yeah...I MEANT to do that!
+Ultimate Question Research Team
+Unable to locate Coffee -- Operator Halted!
+Unburdened by the rigors of coherent thought.
+Unix and the world Unix with you; VAX and you VAX alone.
+Unless you're the lead dog, the view never changes.
+Unqualified superlatives are the worst of all.
+Until people grow up, they have no idea what's cool
+Use your MasterCard to pay your Visa bill.
+Users, losers -- what's the difference?
+Using yesterday's technology to solve today's problems, tomorrow
+VLSI:  'Getting High On Low Voltage'
+Vampires Against Mundane Poetry.
+Variables won't; constants aren't.
+Veni Vidi Visa: I came, I saw, I did a little shopping.
+Verbosity leads to unclear, inarticulate things.
+Volcano -- a mountain with hiccups.
+Vote Democratic... It's easier than getting a job.
+Vuja De - The Feeling You've Never Been Here
+Vulcans have less fun.
+Vultures only fly with carrion luggage.
+W.A.R.P.: We Are Real Programmers.
+WAITER! there's soup in my fly!
+WARNING ... drinking tap water can kill your thirst!
+WARNING: my messages are offensive to morons!
+WINDOWS ERROR #004: Operator fell asleep while waiting.
+WWhhaatt   ddooeess   dduupplleexx    mmeeaann??
+WYGIWYD -What you got is what you deserved.
+WYTYSYDG-What you thought you saw, you didn't get.
+Waiter, there's no fly in my soup! - Kermit
+Walk softly and carry a megawatt laser.
+Walls impede my progress
+Wanna flirt with disaster? Become a SysOp!
+Want a LAUGH run a spell check on DSZ docs.
+Want a jelly baby?
+Want a stupid answer? Ask me anything!
+Wanted: Volcano.  Average size.  Must be active.
+War News: Saddam's army blown away by Thai hookers.
+Warning:  Whimsical when bored
+Warning: Politicians can damage your wealth.
+Warranty void if tagline removed.
+Was today really Necessary?
+Wash your face in the morning, neck at night.
+Wasting time is an important part of living.
+We all live in a yellow subroutine.
+We are not a clone.
+We are the people our parents warned us about
+We don't care. We don't have to. We're Telecom...
+We have here the latest in primitive technology.
+We seem to have juxtaposed an impasse here
+We should limit congressmen to two terms: one in Congress, one in prison
+We take drugs very seriously at my house...
+We were unanimous - in fact everyone was unanimous.
+We'll give you piece de resistance and a tour de force
+We're as similar as two dissimilar things in a pod.
+We're lost, but we're making good time.
+We're staying together for the sake of the cats.
+Weeping, I wake; waking, I weep, I weep.
+Welcome to Texas, now go home.
+Welcome to the Church of the Holy Cabbage. Lettuce pray
+Well cover me in egg & flour and bake me for 14 minutes
+What are you doing?!? The message is over,GO AWAY!
+What can you do for me?
+What color is a chameleon on a mirror?
+What could possibly go wrong.
+What do batteries run on?
+What do you mean that 2 years have passed??
+What do you think?
+What does Santa do at a house with no chimney?
+What does ignorant mean?
+What does this red button do?
+What else can you do at 3:00 am?
+What garlic is to salad, insanity is to art.
+What goes around usually gets dizzy and falls over.
+What goes up has probably been doused with petrol.
+What has four legs and an arm? A happy pitbull.
+What's Irish and stays out all night? Paddy O'Furniture.
+What's another word for 'thesaurus?'
+What's brown and sticky? A stick!
+When 911 won't work .357 will!
+When in doubt, think.
+When their numbers dwindled from 50 to 8, the dwarfs began to suspect 'Hungry'
+When your opponent is down, kick him.
+Where does weight go when you lose it?
+Where in the world is Carmen San Diego?
+Who cares how it plays in Peoria?
+Who cares who's on board?
+Who glued the cup to the table?
+Who is 'they' anyway?
+Whosoever diggeth a pit shall falleth therein.
+Why am I asking all these things?
+Why are Chinese fortune cookies written in English?
+Why are you looking down here? The joke is above!
+Why are you wasting time reading taglines?
+Why aren't there many Hannukah specials on tv?
+Why can't we just spell it orderves?
+Why did you read this?
+Why do people cry when they're sad?
+Why do they tell us to watch 'The Today Show' tomorrow?
+Why do we elect people and then become afraid of them?
+Why do we read left to right yet turn pages right to left?
+Why do you think they call it 'find'?
+Why does it matter if we all put our pants on one leg at a time?
+Why does the beginning of your sentence end up in the middle of mine?
+Why don't ease, lease, and please sound alike?
+Why don't tomb, comb, and bomb sound alike?
+Why get even, when you can get odd?
+Why is 'abbreviated' such a long word?
+Why isn't 'palindrome' spelled 'palindromeemordnilap'?
+Will Rogers never met a lawyer.
+Will the sound of one hand clapping still turn off my TV?
+Win if you can, lose if you must, but always cheat
+Windows Error #F99 - CPU too tired to continue...
+Windows N'T:  as in Wouldn't, Couldn't, and Didn't.
+Windows NT: Only 16 megs needed to play Minesweeper!
+Windows NT: The world's only 80 megabyte Solitaire game!
+Windows NT: Vapourware of the desperate and scared.
+Windows error 000 : No errors found! [CLOSE]
+Windows is *NOT* a virus. Viruses *DO* something!
+Windows is for fun, Linux is for getting things done.
+Windows is the best GUI - It always sticks!
+Windows isn't CrippleWare -- it's 'Functionally Challenged'.
+Windows only crashes itself under Linux.  Not the whole machine.
+Windows would look better with curtains.
+Windows: The answer to a question nobody has ever asked.
+Windows: an Unrecoverable Acquisition Error!
+WindowsNT: From the makers of Doublespace
+Wisdom is knowing what to do with what you know.
+Wit is cultured insolence.
+Without Time, everything would happen at once.
+Without music, life would be a mistake.
+Women - can't live with 'em and no resale value...
+Women do come with instructions; ask them.
+Women get minks the same way minks get minks.
+Women who seek to be equal to men lack ambition.
+Women! Can't live with 'em and no resale value.
+Work off excess energy. Steal something heavy
+World ends today at 9:30 pm!  Film at 11:00...
+Worry : The interest paid on trouble before it's due
+Worst-dressed sentient being in the known universe
+Would I ask you a rhetorical question?
+Yes my son, long ago mail was read 1 packet at a time.
+You buttered your bread, now lie in it.
+You can name your salary here. I call mine Fred.
+You can tune a guitar, but you cant tuna fish.
+You can't have everything...where would you put it?
+You hit the nail right between the eyes.
+You're it.
+You've got to be trusted by the people that you lie to.
+Young gorillas are friendly, but they soon learn.
+Your E-Mail has been returned due to insufficient voltage!
+Youth is a gift of nature. Age is a work of art.
+Yuk, what kind of dumb menu system is that?  Oh, so that is Windows!
+Zen T-Shirt: Enlightenment Available - Enquire Within
+[DISCLAIMER:  my fingers are epileptic]
+[If you can't hear me, it's because I'm in parentheses]
+hAS ANYONE SEEN MY cAPSLOCK KEY?
+Serenity through viciousness.
+FUN is never having to say you're SUSHI!!
+Include me out.
+YOW!!  I'm in a very clever and adorable INSANE ASYLUM!!
+'That boy's about as sharp as a pound of wet liver' -- Foghorn Leghorn
+Pardon me while I laugh.
+Vegeterians beware!  You are what you eat.
+Marriage is the sole cause of divorce.
+'From there to here, from here to there, funny things are everywhere.' -- Dr. Seuss
+You'll be sorry...
+The world is coming to an end.  Please log off.
+UH-OH!!  We're out of AUTOMOBILE PARTS and RUBBER GOODS!
+I used to get high on life but lately I've built up a resistance.
+Paranoia is heightened awareness.
+The things that interest people most are usually none of their business.
diff --git a/files/sample/blootbot.chan b/files/sample/blootbot.chan
deleted file mode 100644 (file)
index b0fe8b6..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#v1: blootbot -- infobot -- written Sat Jan 21 06:17:24 2006
-
-#botpark
-    -OnJoin
-    +RootWarn
-    +autojoin
-
-#debian-bots
-    +News
-    +RootWarn
-    +chanlimitcheck
-    chanlimitcheckInterval 10
-    chanlimitcheckPlus 10
-    factoidDeleteDelay 7
-    ircTextCounters heh hah :) ? hi lol
-    +joinfloodCheck
-    limitcheckInterval 10
-    limitcheckPlus 10
-    newsDefaultExpire 7
-    +newsKeepRead
-    +newsNotifyAll
-    rootWarnMode aggressive
-
-_default
-    +BZFlag
-    +Debian
-    +DebianExtra
-    +Dict
-    +Exchange
-    +Factoids
-    +HTTPDtype
-    +Kernel
-    +Math
-    +OnJoin
-    +Plug
-    +Quote
-    +Rss
-    +Search
-    +Topic
-    +Units
-    +UserInfo
-    +W3Search
-    +Weather
-    +Zippy
-    addressCharacter ~
-    +allowConv
-    +allowTelling
-    +babelfish
-    +botmail
-    +case
-    +cookie
-    +countdown
-    debianRefreshInterval 7
-    +dice
-    +dns
-    +factoidArguments
-    factoidSearch $chan _default
-    floodMessages 10:30
-    floodRepeat 2:10
-    +freshmeat
-    freshmeatRefreshInterval 24
-    +insult
-    +karma
-    +lart
-    +limitcheck
-    +log
-    maxListReplyCount 15
-    maxListReplyLength 400
-    +md5
-    minVolunteerLength 50
-    +nickometer
-    +pager
-    +piglatin
-    randomFactoidInterval 60
-    randomQuoteInterval 60
-    +reverse
-    +scramble
-    +sed
-    +seen
-    seenFlushInterval 60
-    seenMaxDays 90
-    +seenStats
-    +seenStoreAll
-    sendNoticeLimitBytes 1000
-    sendNoticeLimitLines 3
-    sendPrivateLimitBytes 1000
-    sendPrivateLimitLines 3
-    sendPublicLimitBytes 1000
-    sendPublicLimitLines 3
-    +slashdot
-    +spell
-    +tell
-    +wtf
-    +zfi
-    +zsi
-
diff --git a/files/sample/blootbot.config b/files/sample/blootbot.config
deleted file mode 100644 (file)
index 246ed2e..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-# blootbot configuration file, modify it to your own taste.  blootbot reads
-# this file from files/blootbot.config so it should be moved there.
-
-#####
-# Basic IRC info
-#####
-set ircNick            blootbot
-set ircUser            blootbot
-set ircName            blootbot experimental bot
-# if your irc network requires a password to get on the servers
-#set ircPasswd         SomePassword
-set ircUMode           +iw
-
-# if not using a virtualhost set to 0.0.0.0
-# otherwise IRC::Connection might try localhost which will NOT work
-###set ircHost         vh.virtualhost.org
-set ircHost            0.0.0.0
-
-set owner              OWNER
-
-# nickserv/chanserv support.
-###set nickServ_pass   PASSWORD
-###set chanServ_ops    #chan1 #chan2
-
-# default quit message.
-set quitMsg            adios amigos
-
-# path to a temporary directory which blootbot can use.
-set tempDir            temp
-
-#####
-# Factoid database configuration
-#####
-
-# [str] Ability to remember/tell factoids
-#      none    -- disable.
-#      mysql   -- ...
-#      SQLite  -- SQLite (libdbd-sqlite-perl) (might be version 2 or 3)
-#      SQLite2 -- SQLite (libdbd-sqlite-perl) (force version 2)
-#      pgsql   -- postgresql (NOT SUPPORTED)
-### REQUIRED by factoids,freshmeat,karma,seen,...
-set DBType             mysql
-
-# [str] SQLite filename prefix // MYSQL/PGSQL database.
-#      eg: blootbot-factoids, blootbot-seen
-#      eg: /var/db/mysql/blootbot/factoids.*
-set DBName             blootbot
-
-# [str] Hostname of database server (unset for SQLite)
-set SQLHost            localhost
-
-# [str] SQL user allowed to insert,update,delete stuff from tables. (unset for SQLite)
-set SQLUser            blootbot
-
-# [str] SQL password. (unset for SQLite)
-set SQLPass            PASSWORD
-
-# [str] SQL debug file. "-" for stdout may work on some platforms
-###set SQLDebug                SQL_debug.log
-
-#####
-# Logfile configuration
-#####
-
-# [file] where to put logging info. comment out to disable.
-#set logfile           log/$ircUser.log
-set logfile            log/
-
-# [str] Type of logging.
-#   DAILY      -- Create a new log each day.
-#   DEFAULT    -- One continuous log file.
-set logType            DAILY
-
-# [int] Maximum log size, if logfile is defined, in bytes.
-set maxLogSize         10000000
-
-#####
-# Factoid-related configuration
-#####
-
-# [bool] Factoid support.
-set factoids           true
-
-# [days] if not 0, number of days until factoid is deleted for good.
-set factoidDeleteDelay 0
-
-# [int] maximum length of factoid key.
-set maxKeySize         32
-
-# [int] maximum length of factoid value.
-set maxDataSize                450
-
-# [str] when should the bot bother learning new factoids.
-#   ADDRESSED  -- only learn when addressed.
-#   HUNGRY     -- learn irrelevent of addressing. this will catch
-#                 _everything_, use at your own risk.
-set learn              ADDRESSED
-
-# [str] different behaviour with URLs.
-#   REQUIRE    -- means it will need to be a url type (e.g. file:, http:)
-#   OPTIONAL   -- will take anything
-#   REJECT     -- will not accept any urls.  this makes it easy to
-#                 run 2 with different nicks and styles.
-#                 ^^^ what's the point of this???
-set acceptUrl          OPTIONAL
-
-# [bool] profanity checking.
-set profanityCheck     false
-
-# [0/1] tell so-and-so about such-and-such of a factoid.
-set allowTelling       1
-
-# [str] other bots to ask for factoids which they may have.
-#set friendlyBots      url purl script mrapi
-
-#####
-# Factoid related and unrelated features, mainly Extras.
-#####
-
-# [str] addressing is when you name the bot. FIXME:
-#   REQUIRE    -- the bot only does something if addressed.
-#   OPTIONAL   -- the bot responds (does not learn) irrelevent of
-#                 addressing.
-set addressing         REQUIRE
-
-# [str] how the bot should send messages.
-#   PRIVATE    -- reply to private messages only, rejecting public msgs.
-#   DEFAULT    -- reply to public _and_ private queries.
-set talkMethod         DEFAULT
-
-# [str] how long the output string should be before it is changed from
-#      public to private.
-#      "+" before bot commands overrides this option temporarily.
-###set minLengthBeforePrivate 192
-
-# [0/1] allow people outside any channels the bot is on to use the bot
-#      for factoids and commands.
-set disallowOutsiders  1
-
-# [int] Amount of time for auto-ignore (flooding) to expire.
-set ignoreAutoExpire   5
-
-# [int] Amount of time for forced-online ignore to expire. minutes.
-set ignoreTempExpire   60
-
-#####
-# Internal (simple) bot commands
-#####
-
-# [0/1] Forking... disable for non-nix OS or to reduce mem usage.
-#      Disabling should make the bot work on Win32 and MacOS.
-set forking            1
-
-# [int] Backlog... ideal to see what happened to the bot on console.
-#      maximum number of lines to backlog.
-set backlog            24
-
-#####
-# Extra features
-#####
-
-# [str] anything which requires LWP + http proxy.
-###set httpProxy               http://HOSTNAME:PORT/
-
-# [0/1] countdown to specific dates
-set countdown          true
-
-# [0/1] Debian file and package search.
-# FIXME: should be a channel option
-set Debian             true
-
-# [0/1] Freshmeat
-set freshmeat          false
-# [int] how often to update the freshmeat table, in hours.
-set freshmeatRefreshInterval 24
-
-# [bool] if factoid does not exist, check freshmeat for it.
-set freshmeatForFactoid                false
-
-# [0/1] Uptime logs
-set Uptime             true
-
-#####
-# Miscellaneous configuration options
-#####
-
-# [int] Display a bit too much info about stuff.
-#   0  -- disable.
-#   1  -- standard.
-#   2  -- extra.
-set VERBOSITY          1
-
-# [0/1] Warn messages.
-set WARN               1
-
-# [0/1] Debugging messages.
-set DEBUG              0
-
-# [0/1] Work In Progress...
-set WIP                        0
-
-# strict perl?
-set useStrict          1
-
-# debugging...
-###set DumpVars                1
-###set dumpvarsAtExit  1
-# log to specific file or global log file.
-###set dumpvarsLogFile dumpvars.log
-# more debugging
-###set DumpVars2               1
-###set symdumpLogFile  log/dumpvars2.log
-
-# [str] Interface: [IRC/CLI]
-#   IRC                -- Internet Relay Chat
-#   CLI                -- Command Line Interface
-set Interface          IRC
-
-####
-# Now modify blootbot.chan for per-channel specific configuration see
-# sample.chans for info.
-####
diff --git a/files/sample/blootbot.countdown b/files/sample/blootbot.countdown
deleted file mode 100644 (file)
index f127682..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# countdown file.
-20001225 christmas     Christmas
-20000914 olympics      Opening ceremony of Olympics in Sydney, Australia
-20000704 america       Independence Day
-20000501 potato                Proposed release of Debian GNU/Linux Potato 2.2
-20000420 2.4           Hopeful debut of 2.4.0 kernel
-20000315 xfree4.0      XFree86 4.0 core release
-20000217 win2k         Evil Empire's Release of deadly OS
-20000126 australia     Australia Day
-20000119 crusoe                Transmeta comes out of hiding
-20000115 freeze                Debian (GNU/Linux) Potato version 2.2 stabilization begins
-20000101 y2k           Year 2000
diff --git a/files/sample/blootbot.servers b/files/sample/blootbot.servers
deleted file mode 100644 (file)
index 648b010..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-###
-# blootbot.servers: line separated list of servers to connect to
-###
-
-irc.freenode.net
-irc.home.org
-irc.linux.com
diff --git a/files/sample/blootbot.users b/files/sample/blootbot.users
deleted file mode 100644 (file)
index 59f7b1e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#v1: blootbot -- blootbot -- written Mon Feb 28 23:46:48 2005
-
-_default
---FLAGS                amrt
---HOSTS                *!*@*
-
-local
---FLAGS                Aemnorst
---HOSTS                local!local@local
---PASS         xxfxfIfoJHdYg
-
-timriker
---FLAGS                Aemnorst
---HOSTS                *!~timr@TimRiker.active.supporter.pdpc
---PASS         xxfxfIfoJHdYg
-
-xk
---FLAGS                emnorst
---HOSTS                *!xk@example.com
---HOSTS                *!xk@superbox.home.org
---PASS         5K/rmJPzwxJhU
-
diff --git a/files/sample/infobot.chan b/files/sample/infobot.chan
new file mode 100644 (file)
index 0000000..c721138
--- /dev/null
@@ -0,0 +1,104 @@
+#v1.5.0: infobot
+
+#botpark
+    -OnJoin
+    +RootWarn
+    +autojoin
+
+#debian-bots
+    +News
+    -OnJoin
+    +RootWarn
+    +chanlimitcheck
+    chanlimitcheckInterval 10
+    chanlimitcheckPlus 10
+    factoidDeleteDelay 7
+    ircTextCounters heh hah :) ? hi lol
+    +joinfloodCheck
+    limitcheckInterval 10
+    limitcheckPlus 10
+    newsDefaultExpire 7
+    +newsKeepRead
+    +newsNotifyAll
+    rootWarnMode aggressive
+
+#infobot
+    -OnJoin
+    +RootWarn
+    +autojoin
+
+_default
+    +hex2ip
+    +News
+    +BZFlag
+    +chanServCheck
+    +Debian
+    +DebianExtra
+    +Dict
+    +Exchange
+    +Factoids
+    +HTTPDtype
+    +Kernel
+    +Math
+    +OnJoin
+    +Plug
+    +Quote
+    +Rss
+    +Search
+    +Topic
+    +Units
+    +UserInfo
+    +W3Search
+    +Weather
+    +Zippy
+    addressCharacter ~
+    +allowConv
+    +allowTelling
+    +babelfish
+    +botmail
+    +case
+    +cookie
+    +countdown
+    debianRefreshInterval 7
+    +dice
+    +dns
+    +factoidArguments
+    factoidSearch $chan _default
+    floodMessages 10:30
+    floodRepeat 2:10
+    +freshmeat
+    freshmeatRefreshInterval 24
+    +insult
+    +karma
+    +lart
+    +limitcheck
+    +log
+    maxListReplyCount 15
+    maxListReplyLength 400
+    +md5
+    minVolunteerLength 50
+    +nickometer
+    +pager
+    +piglatin
+    randomFactoidInterval 60
+    randomQuoteInterval 60
+    +reverse
+    +scramble
+    +sed
+    +seen
+    seenFlushInterval 60
+    seenMaxDays 90
+    +seenStats
+    +seenStoreAll
+    sendNoticeLimitBytes 1000
+    sendNoticeLimitLines 3
+    sendPrivateLimitBytes 1000
+    sendPrivateLimitLines 3
+    sendPublicLimitBytes 1000
+    sendPublicLimitLines 3
+    +slashdot
+    +spell
+    +tell
+    +wtf
+    +zfi
+    +zsi
diff --git a/files/sample/infobot.config b/files/sample/infobot.config
new file mode 100644 (file)
index 0000000..073a81e
--- /dev/null
@@ -0,0 +1,229 @@
+# infobot configuration file, modify it to your own taste.  infobot reads
+# this file from files/infobot.config so it should be moved there.
+
+#####
+# Basic IRC info
+#####
+set ircNick            infobot
+set ircUser            infobot
+set ircName            infobot experimental bot
+# if your irc network requires a password to get on the servers
+#set ircPasswd         SomePassword
+set ircUMode           +iw
+
+# if not using a virtualhost set to 0.0.0.0
+# otherwise IRC::Connection might try localhost which will NOT work
+###set ircHost         vh.virtualhost.org
+set ircHost            0.0.0.0
+
+set owner              OWNER
+
+# nickserv support.
+###set nickServ_pass   PASSWORD
+
+# default quit message.
+set quitMsg            adios amigos
+
+# path to a temporary directory which infobot can use.
+set tempDir            /tmp
+
+#####
+# Factoid database configuration
+#####
+
+# [str] Ability to remember/tell factoids
+#      none    -- disable.
+#      mysql   -- ...
+#      SQLite  -- SQLite (libdbd-sqlite-perl) (might be version 2 or 3)
+#      SQLite2 -- SQLite (libdbd-sqlite-perl) (force version 2)
+#      pgsql   -- postgresql (SUPPORTED and TESTED!!!)
+### REQUIRED by factoids,freshmeat,karma,seen,...
+set DBType             mysql
+
+# [str] SQLite filename prefix // MYSQL/PGSQL database.
+#      eg: infobot-factoids, infobot-seen
+#      eg: /var/db/mysql/infobot/factoids.*
+set DBName             infobot
+
+# [str] Hostname of database server (unset for SQLite)
+set SQLHost            localhost
+
+# [str] SQL user allowed to insert,update,delete stuff from tables. (unset for SQLite)
+set SQLUser            infobot
+
+# [str] SQL password. (unset for SQLite)
+set SQLPass            PASSWORD
+
+# [str] SQL debug file. "-" for stdout may work on some platforms
+###set SQLDebug                SQL_debug.log
+
+#####
+# Logfile configuration
+#####
+
+# [file] where to put logging info. comment out to disable.
+#set logfile           log/$ircUser.log
+set logfile            log/
+
+# [str] Type of logging.
+#   DAILY      -- Create a new log each day.
+#   DEFAULT    -- One continuous log file.
+set logType            DAILY
+
+# [int] Maximum log size, if logfile is defined, in bytes.
+set maxLogSize         10000000
+
+#####
+# Factoid-related configuration
+#####
+
+# [bool] Factoid support.
+set factoids           true
+
+# [days] if not 0, number of days until factoid is deleted for good.
+set factoidDeleteDelay 0
+
+# [int] maximum length of factoid key.
+set maxKeySize         32
+
+# [int] maximum length of factoid value.
+set maxDataSize                450
+
+# [str] when should the bot bother learning new factoids.
+#   ADDRESSED  -- only learn when addressed.
+#   HUNGRY     -- learn irrelevent of addressing. this will catch
+#                 _everything_, use at your own risk.
+set learn              ADDRESSED
+
+# [str] different behaviour with URLs.
+#   REQUIRE    -- means it will need to be a url type (e.g. file:, http:)
+#   OPTIONAL   -- will take anything
+#   REJECT     -- will not accept any urls.  this makes it easy to
+#                 run 2 with different nicks and styles.
+#                 ^^^ what's the point of this???
+set acceptUrl          OPTIONAL
+
+# [bool] profanity checking.
+set profanityCheck     false
+
+# [0/1] tell so-and-so about such-and-such of a factoid.
+set allowTelling       1
+
+# [str] other bots to ask for factoids which they may have.
+#set friendlyBots      url purl script mrapi
+
+#####
+# Factoid related and unrelated features, mainly Extras.
+#####
+
+# [str] addressing is when you name the bot. FIXME:
+#   REQUIRE    -- the bot only does something if addressed.
+#   OPTIONAL   -- the bot responds (does not learn) irrelevent of
+#                 addressing.
+set addressing         REQUIRE
+
+# [str] how the bot should send messages.
+#   PRIVATE    -- reply to private messages only, rejecting public msgs.
+#   DEFAULT    -- reply to public _and_ private queries.
+set talkMethod         DEFAULT
+
+# [str] how long the output string should be before it is changed from
+#      public to private.
+#      "+" before bot commands overrides this option temporarily.
+###set minLengthBeforePrivate 192
+
+# [0/1] allow people outside any channels the bot is on to use the bot
+#      for factoids and commands.
+set disallowOutsiders  1
+
+# [int] Amount of time for auto-ignore (flooding) to expire.
+set ignoreAutoExpire   5
+
+# [int] Amount of time for forced-online ignore to expire. minutes.
+set ignoreTempExpire   60
+
+#####
+# Internal (simple) bot commands
+#####
+
+# [0/1] Forking... disable for non-nix OS or to reduce mem usage.
+#      Disabling should make the bot work on Win32 and MacOS.
+set forking            1
+
+# [int] Backlog... ideal to see what happened to the bot on console.
+#      maximum number of lines to backlog.
+set backlog            24
+
+#####
+# Extra features
+#####
+
+# [str] anything which requires LWP + http proxy.
+###set httpProxy               http://HOSTNAME:PORT/
+
+# [0/1] countdown to specific dates
+set countdown          true
+
+# [0/1] Debian file and package search.
+# FIXME: should be a channel option
+set Debian             true
+
+# [0/1] Freshmeat
+set freshmeat          false
+# [int] how often to update the freshmeat table, in hours.
+set freshmeatRefreshInterval 24
+
+# [bool] if factoid does not exist, check freshmeat for it.
+set freshmeatForFactoid                false
+
+# [0/1] Uptime logs
+set Uptime             true
+
+# [minutes] RSS Feeds refresh interval
+set rssFeedTime         30
+
+#####
+# Miscellaneous configuration options
+#####
+
+# [int] Display a bit too much info about stuff.
+#   0  -- disable.
+#   1  -- standard.
+#   2  -- extra.
+set VERBOSITY          1
+
+# [0/1] Warn messages.
+set WARN               1
+
+# [0/1] Debugging messages.
+set DEBUG              0
+
+# [0/1] Work In Progress...
+set WIP                        0
+
+# strict perl?
+set useStrict          1
+
+# debugging...
+###set DumpVars                1
+###set dumpvarsAtExit  1
+# log to specific file or global log file.
+###set dumpvarsLogFile dumpvars.log
+# more debugging
+###set DumpVars2               1
+###set symdumpLogFile  log/dumpvars2.log
+
+# [str] Interface: [IRC/CLI]
+#   IRC                -- Internet Relay Chat
+#   CLI                -- Command Line Interface
+set Interface          IRC
+
+# [0/1] Show topic author (troubled)
+# If 1, topics managed with !topic add foo will show the nick in ()'s
+# If 0, the nick of the creator will be recorded for !topic list, but not shown in the topic itself
+set topicAuthor 1
+
+####
+# Now modify infobot.chan for per-channel specific configuration see
+# sample.chans for info.
+####
diff --git a/files/sample/infobot.countdown b/files/sample/infobot.countdown
new file mode 100644 (file)
index 0000000..f127682
--- /dev/null
@@ -0,0 +1,12 @@
+# countdown file.
+20001225 christmas     Christmas
+20000914 olympics      Opening ceremony of Olympics in Sydney, Australia
+20000704 america       Independence Day
+20000501 potato                Proposed release of Debian GNU/Linux Potato 2.2
+20000420 2.4           Hopeful debut of 2.4.0 kernel
+20000315 xfree4.0      XFree86 4.0 core release
+20000217 win2k         Evil Empire's Release of deadly OS
+20000126 australia     Australia Day
+20000119 crusoe                Transmeta comes out of hiding
+20000115 freeze                Debian (GNU/Linux) Potato version 2.2 stabilization begins
+20000101 y2k           Year 2000
diff --git a/files/sample/infobot.servers b/files/sample/infobot.servers
new file mode 100644 (file)
index 0000000..93767ca
--- /dev/null
@@ -0,0 +1,7 @@
+###
+# infobot.servers: line separated list of servers to connect to
+###
+
+irc.freenode.net
+irc.home.org
+irc.linux.com
diff --git a/files/sample/infobot.users b/files/sample/infobot.users
new file mode 100644 (file)
index 0000000..9f30e78
--- /dev/null
@@ -0,0 +1,25 @@
+#v1.5.0: infobot -- written Mon Feb 28 23:46:48 2005
+# Please edit to your needs.
+# "local" is used for CLI mode
+# Passwords can be generated with mkpasswd in linux
+
+_default
+--FLAGS                amrt
+--HOSTS                *!*@*
+
+local
+--FLAGS                Aemnorst
+--HOSTS                local!local@local
+--PASS         xxfxfIfoJHdYg
+
+timriker
+--FLAGS                Aemnorst
+--HOSTS                *!~timr@TimRiker.active.supporter.pdpc
+--PASS         xxfxfIfoJHdYg
+
+xk
+--FLAGS                emnorst
+--HOSTS                *!xk@example.com
+--HOSTS                *!xk@superbox.home.org
+--PASS         5K/rmJPzwxJhU
+
diff --git a/files/unittab b/files/unittab
deleted file mode 100644 (file)
index d4f7a0e..0000000
+++ /dev/null
@@ -1,668 +0,0 @@
-#
-# Unit defintions
-# 18 May 2001  M-J. Dominus <mjd-perl-units+@plover.com>.
-# This file is in the PUBLIC DOMAIN.
-# All rights abandoned.
-#
-# If you discover definitions of units that do not appear in this
-# file, you are invited to mail them to mjd-perl-units+@plover.com, so
-# that I can include them in a future version.  Please include the
-# date of this file, 18 May 2001, with all such submissions.
-
-# If a unit is defined as `***', that means
-# it has no definition because it is a fundamental unit.
-
-# http://perl.plover.com/units/unittab
-
-# Fundamental units:
-# Seven instrinsic SI units:
-gram       ***
-meter     ***
-# Tim Riker <Tim@Rikers.org> adds metre alias
-metre     meter
-second     ***
-ampere     ***
-candela    ***
-Kelvin     ***
-mole       ***
-# Two supplementary units
-radian     ***
-steradian  ***
-# Some miscellany
-dollar     ***
-bit        ***
-sheet      ***      # Of paper
-turn       ***      # Of coiled wire
-
-# DIMENSIONLESS
-pi         3.1415926535897932386
-two        2
-half       1|2
-e         2.718281828459045 # Why did I put this in?  Oh, I don't know.
-Neper     1         # Unit of logarithmic ratio
-Np         Neper
-# Would it be better to make this a fundamental unit?
-bel       .868588963 Np   # 2/ln(10) actually
-B          bel
-dB         decibel
-
-# LENGTH
-m       meter
-km      kilometer
-cm      centimeter
-mm      millimeter
-micron  micrometer
-inch    2.54 cm        # This is the official definition and is exact
-mil    milliinch
-in      inch
-barleycorn     1/3 inch        # Tim Riker <Tim@Rikers.org
-inches  inch           # plural
-foot    12 inch
-ft      foot
-feet    foot
-yard    3 feet
-yd      yard
-mile    5280 feet
-mi      mile
-#nautical 1.151         # For `nautical mile'
-nautical       1.150779447892
-statute 1
-# pilots need this :)
-nm      1 nautical mile
-sm      1 statute mile
-parsec  1.91615e13 mi
-#parsec 3.08568025e16 m        # better?
-# light year will be implied by `year' and `light' below
-fathom  6 ft
-cable   120 fathoms
-league  3 mi
-bolt    25 yd          # Of cloth; bolt length varies from bolt to bolt
-                       # 25 yd is typical
-cubit   18 in
-ell     45 in          # More or less standard, although other ells
-                       # have also been used.
-hand    4 in
-palm    3 in
-span    9 in
-pace    2.5ft
-astronomicalunit 92.9 megamiles  # Is this exact?
-au      astronomicalunit
-rope    20 ft
-skein   360 feet
-
-# Surveyor's
-furlong 1|8 mi
-chain   1|10 furlong
-rod     1|4 chain
-link    1|100 chain
-
-# Typographic
-point    .013837 in
-pt       point
-bigpoint 1|72 in
-pica     12 pt
-didot    1238|1157 pt
-dd       didot
-cicero   12dd  # TeX likes to abbreviate this to cc, but cc is cubic centimeter
-scaledpoint 1|65536 pt # Internal to TeX
-sp       scaledpoint
-
-
-
-# AREA
-are     (10 m)2        # Implies `hectare'
-acre    chain furlong  # Now you know why an acre is the size it is
-rood    1|4 acre
-township 36 mi2        # Who uses these?
-barn    (1.0E-12 centimeter)2 # Particle physics
-board   144 in3/ft     # Implies `board feet'
-
-# VOLUME
-cc      cm3
-liter   (decimeter)3
-ml      milliliter
-stere   m3
-floz    29.573 ml      # `floz' means `fluid ounce', which is different
-                       # from `ounce', which is a measurement of mass.
-                       # See `pound' below for more details.
-fldram  1|8 floz
-minim   1|60 fldram
-cup     8 floz
-cu      cup
-gill    1|2 cup
-pint    two cups
-quart   two pints
-pottle  two quarts     # Yup!
-gallon  two pottles
-qt      quart
-gal     gallon
-tablespoon 1|2 floz
-tbsp       tablespoon
-teaspoon   1|3 tbsp
-tsp        teaspoon
-cordfoot   16 ft2      # NOT the same as `cord foot'.
-cordfeet   cordfoot
-cord       8 cordfeet
-# Barrels are complicated.  `Barrel' here means `U.S. liquid barrel'.
-barrel     31.5 gal
-bbl        barrel
-hogshead   two barrels
-butt       two hogsheads
-tun        two butts
-firkin     9 gal        # American firkin, not British firkin
-perch      24.75 ft3    # Masonry
-puncheon   84 gal
-# Following units contributed 20011217 Thomas R Wyant III
-fifth 1|5 gallon
-magnum 2.5 fifth
-jeroboam 4 fifth
-rehoboam 7.5 fifth
-methuselah 10 fifth
-shalmanazar 14 fifth
-balthazar 20 fifth
-nebuchadnezzar 25 fifth
-
-# Delightful British liquid volumes; they all begin with `brit'.
-britfloz   28.41225 ml
-britminim  1|480 britfloz
-britdrachm 1|8 britfloz
-drachm     britdrachm     # U.S. drachm is spelled `dram'.
-britgill   5 britfloz     # five, NOT four.
-britnoggin britgill
-noggin     britnoggin     # Yeah, as though anyone else would have a `noggin.'
-britpint   4 britgill
-britpt     britpint
-britquart  2 britpint
-britqt     britquart
-britgallon 4 britquart
-britgal    britgallon
-britpeck   2 britgal
-britfirkin 9 britgal
-britkilderkin  two britfirkins
-kilderkin britkilderkin  # kilderkin is British only
-britbucket 4 britgal     # That's `britbucket,' not `bit bucket'.
-bucket     britbucket    # Buckets are brit only.
-britlast   2909.414 liters
-last       britlast
-
-# Dry volume
-dry     1.164904862579 # For `dry pint,' `dry quart,' etc.
-peck    8 dry quarts
-bushel  4 pecks
-bu      bushel
-seam    8bu
-bag     3bu
-
-imperial 1.201          # For `imperial pint,' etc.
-
-# MASS (also WEIGHT)
-#
-# To avoid confusing the end user, we will pretend that `pound' is
-# a unit of mass, interconvertible with `grams'.  If you want
-# pounds of force, see `lbf,' below.  In this section, `pound'
-# really means `mass of an object that weighs one-pound at the surface
-# of the Earth.'  That is, in this program, `slug' has its usual
-# meaning, and `pound' is synonymous aith `slug'.
-g             gram
-kg            kilogram
-metricton     kilokilogram
-tonne         metricton
-mg            milligram
-grain         64.79891 mg
-ounce         437.5 grains
-oz            ounce
-pound         16 oz
-lb            pound
-slug          lb
-hundredweight 112 lb  # This is the `long' hundredweight, analagous to
-                      # the long ton.  There is also a `short' hundredwight,
-                      # but it's just a hectlb, so I put this one in instead.
-cwt           hundredweight
-quarter       5 cwts
-longton       20 cwt
-#ton           longton # use shortton my default Tim Riker <Tim@Rikers.org>
-short         100|112   # Convert long tons, cwts, and quarters to short.
-shortton      short longton
-ton           short longton # the american ton, see metriton and longton
-stone         14 lb
-cental        100 lb
-wey           252 lb
-# Obscure apothecaries' measures
-scruple       20 grains
-dram          3 scruples
-apothounce    480 grains
-apothoz       apothounce
-apothpound    12 apothoz
-apothlb       apothpound
-# Troy measures (for gold and precious stones)
-pennyweight   24 grains
-troyoz        480 grains # We can't define `troy' as a constant,
-                         # because there are 16 oz in a lb, but only
-                         # 12 troyoz in a troylb, so at least one of
-                         # `troy oz' or `troy lb' would be wrong.
-troylb        12 troyoz
-carat         3.08647 grain # Metric version.  Is this useful?
-atomicmassunit 1.6605402e-27 kg # NIST 19990301 (+/- 0.10e-33 kg)
-amu           atomicmassunit
-quintal       100kg      # Metric quintal.  Wasn't there another quintal?
-elvis         255lb      # At the time of his death, the King weighed 255 lb.
-
-# TIME
-sec            second
-s               second
-minute         60 sec
-min            minute
-hour           60 min
-hr             hour
-day            24 hrs
-dy             day                  # This will denote mean solar days
-siderealday     0.99726957 dys
-week           7 days
-wk             week
-month          30 days
-lunarmonth      29.530588 days       # Mean solar days
-meanmonth       730 hours
-mo             month
-tropicalyear   365.24219 dys        # Mean solar days
-siderealyear    365.25636 dys        # Mean solar days
-leapyear        366       dys        # Mean solar days
-calendaryear    365       dys        # Mean solar days
-gregorianyear  365.2425  dys
-year            tropicalyear         # Correct on average for most calculations
-yr             years
-fortnight      two weeks
-decade          10 years
-century         100 years
-millennium      1000 years
-millennia       millennium
-centuries       century
-beat           1|1000 day           # Swatch Internet Time (``Fuck the Sun'')
-# Velocity
-knot            1 nautical mi/hour
-mph             1 mi/hr
-
-# SCIENTIFIC
-#
-# Electromagnetic items, work, force, energy.
-#
-# Velocity
-c             299792458 m/s  # NIST 19990301 EXACT
-light         c   # Implies `light year'
-
-
-# Absolute temperature
-kelvin        Kelvin
-K             Kelvin
-Rankine       5|9 K     # This is a very funny unit
-Ra            Rankine
-
-# Amount of substance
-mol           mole
-Avogadro      6.0221367e23
-avogadro      Avogadro
-molecule      1 mole per Avogadro # 1 mole is an Avogagro-number of molecules
-
-# Current
-# The Ampere is fundamental here, defined as the constant current
-# which, if maintained in two straight parallel conductors of infinite
-# length, of negligible circular cross-section, and placed 1m apart in
-# vacuum, would produce between these conductors a force equal to 2e-7
-# newtons per meter of length.
-Ampere        ampere
-amp           ampere
-abampere      10 amps
-abamp         abampere
-statampere    3.335635e-11 abamperes
-statamp       statampere
-
-# What is this called?  Is it capitalized?  Is there an abbreviation?
-gilbert       0.79577472 ampere turns
-
-# Electrostatic charge
-Coulomb       ampere sec
-coulomb       Coulomb
-coul          Coulomb
-C             Coulomb
-electron      1.60217733e-19 C  # Charge on the electron; implies electron-volts
-e             electron
-abcoulomb     10C
-statcoulomb   3.335635e-11 abcoulomb
-
-
-# Force
-Newton        kg m/s2
-newton        Newton
-N             newton
-dyne          g cm/s2
-grav          9.8 m/s2  # Acceleration due to gravity
-gee           grav
-# Actually the accleration varies with altitude and latitude,
-# from 9.78039 m/s2 at the equator to 9.83217 m/s2 at the poles.
-# This mean value corresponds to a latitude of about 38 degrees.
-lbf           lb grav
-
-# Pressure
-Pascal        N/m2
-pascal        Pascal
-Pa            pascal
-atmosphere    101325 N/m2  # NIST 20010518 EXACT
-atm           atmosphere
-bar           megadyne/cm2  # Implies `millibars'
-mercury       1|760 atm/mm # Implies `mm mercury' and `inches mercury'
-hg            mercury
-torricelli    mm hg
-torr          torricelli
-water         .0295 atm/ft # Implies `feet water'
-barye         dyne/cm2
-air           6.6083e-5 atm/foot  # At 60 deg.F; Implies `feet air'
-
-# Work and energy
-Joule         newton-meter
-joule         Joule
-J             joule
-footpound     ft-lbf   # foot-pound won't work, because `pound' is a mass
-calorie       4.186 J
-cal           calorie
-kcal          kilocalorie
-britishthermalunit  1054.8 J
-btu           britishthermalunit
-erg           dyne-cm
-# Kilowatt-hour (kWh) will be implied by `Watt'.
-
-
-# Power
-Watt          J/sec
-watt          Watt
-W             Watt
-horsepower    550 ft-lbf/s
-
-# Electric potential
-Volt          W/amp
-volt         Volt
-V             Volt
-abvolt        1|100 microvolt
-statvolt      2.997930e10 V
-
-# Frequency
-cycle        1           # For `cycles per second'
-Hertz        cycles per second
-Hz            Hertz
-hz            Hz
-
-# Inductance
-Henry         volt s/amp
-henry         Henry
-H             Henry
-abhenry       1.0e-9 henry
-Henries       Henry       # For plural
-henries       Henry
-stathenry     8.987584e11 henries
-stathenries   stathenry
-
-# Etc.
-Weber         volt s
-weber         Weber
-Wb            weber
-Tesla         Wb/m2
-tesla         Tesla
-T             tesla
-Oersted       1|4 pi kiloamp/m
-oersted       Oersted
-Oe            oersted
-Maxwell       1.0e-8 Wb
-maxwell       Maxwell
-Mx            Maxwell
-Gauss         1.0e-4 T
-gauss         Gauss
-# We won't use G for Gauss because it is more important to
-# use it for the universal gravitational constant
-
-# Capacitance
-# `farad' is *not* an abbreviation for `Faraday' as far as I can tell.
-farad         amp sec / volt
-F             farad
-abfarad       1.0e9 farad
-statfarad     1.112646e-13 farad
-
-# Resistance
-Ohm           volt/amp
-ohm           Ohm
-abohm         1.0e-9 ohm
-statohm       8.987584e11 Ohms
-
-# Conductance
-mho           1/ohm
-abmho         1/abohm
-Siemens       mho
-siemens       Siemens
-
-# Misc
-Angstrom      1.0e-10 m
-angstrom      Angstrom
-G             6.67259e-11 N m2/kg2 # Newton gravitational constant NIST19990301
-lightyear     light year    # Common abbreviation
-eV            e V           # Electron volts
-ev            eV
-kev           kiloeV
-Mev           megaeV
-Gev           gigaeV
-Tev           teraeV
-energy        c2 # You can ask for `1 gram energy' and get
-                 # the amount of energy equivalent to
-                 # 1 gram according to e=mc2.
-                 # Check: 1amu energy == 931.16 Mev?
-Franklin      (10/c) C cm/sec
-Fr            Franklin
-franklin      Franklin
-Biot          10 amp
-Bi            Biot
-biot          Biot
-
-# Viscosity - Maybe someone who understands this better can check.
-poise         g/(cm s) # Named after M. Poiseuille
-rhe           1/poise
-reyn          (lbf s)/in2
-# Kinematic viscosity = viscosity per unit density
-stoke         cm2/s
-
-# Refrigeration - Maybe someone who understands this better can check.
-refrigeration 288000 btu/ton
-ice           tons refrigeration / 2009.1 lb
-
-# Light
-# The candela is fundamental here.  Prior to 1979, it was defined as
-# the luminous intensity of a black body at the temperature of
-# solidification of platinum, whose radiating surface is 1/60 cm2.  It
-# is now the luminous intensity, in a given direction, of a source
-# that emits monochromatic radiation of frequency 540e12 Hz and that
-# has a radiant intensity in that direction of 1|683 W/sr
-cd            candela
-sr           steradian
-lumen         candela sr
-lm           lumen
-lux           lm/m2
-lx            lux
-candlepower   12.566370 lumens
-candle        candela # ``International standard candle''
-Hefner        0.90 candles # This was the German standard in early C20.
-hefner        Hefner
-Lambert       lm/cm2
-lambert       Lambert
-footcandle    lm/ft2  # NOT the same as foot-candle.
-phot          1.0e4 lx
-stilb         candle/m2   # Same as a pi lambert
-
-# Various important physical constants
-# I got this stuff from physics.nist.gov on 19990301.
-h             6.6260755e-27 erg-sec   # Planck's constant
-hbar          h/(2 pi)
-plancklength  1.61605e-35 m
-planckmass    2.17671e-8 kg
-plancktime    5.39056e-44 sec
-# Let's reserve `Planck' for a while longer until I can decide if
-# they'd be useful in `planck time' etc.
-permeability  4*pi*1.0e-7 H/m     # Magnetic permeability of vacuum constant
-permittivity  8.854187817e-12 F/m # Electric permittivity of vacuum constant
-protonmass    1.6726231e-27 kg
-neutronmass   1.6749286e-27 kg
-electronmass  9.1093897e-31 kg
-finestructure 7.29735308e-3 # Rl
-# Electron charge is up above under `electrostatic'.
-# There's no reason to get too obscure here because if someone wants
-# they can make up an `obscure physical constants' file that
-# physiscists could load in if they wanted to.  So I've omitted stuff
-# like the magnetic moment of the muon.
-
-# ANGULAR
-rad            radian
-circle         2 pi radians
-revolution      circle       # For revolutions / sec
-rev             revolution
-rpm            revolutions per minute
-quadrant        1|4 circle
-degree         1|360 circle
-arcminute       1|60 degree
-arcsecond       1|60 arcminute
-arcmin          arcminute
-arcsec          arcsecond
-sphere          4 pi steradians
-grade           1|100 quadrant
-grad            grade
-
-# PAPER
-quire           50 sheets
-ream            10 quires
-
-# INFORMATION
-byte           8 bits
-nybble          half byte
-kbyte           1024 bytes   # `kilobyte' means 1000    bytes
-# Don't use `K'; that's for Kelvins.
-kb              kbyte
-Kb              kbyte
-KB              kbyte
-mbyte           1024 kbytes  # `megabyte' means 1000000 bytes
-meg             mbyte
-kbit           1024 bits
-Kbit           kbit
-mbit           1024 kbits
-Mbit           mbit
-baud            bit/sec      # Not strictly correct
-
-# MONEY
-#
-# Conversions accurate only as of 25 November 1996.
-#
-$              dollar
-usdollar        $
-usd             $
-us$             $
-$us             $
-US$             $
-$US             $
-cent            1|100 $
-Australia.dollar               0.8123$
-AUS$                   Australia.dollar
-Austria.schilling              0.09438$
-Belgium.franc          0.03223$
-Brazil.real            0.9709$
-British.pound          1.681$
-pound.sterling         British.pound
-sterling               British.pound
-Canada.dollar          0.7468$
-Can$                   Canada.dollar
-Cayman.currency                1.22$
-Denmark.krone          0.173$
-krone                  Denmark.krone
-EuropeanCommunityUnit.ECU      1.278$
-ECU                    EuropeanCommunityUnit.ECU
-ecu                    ECU
-Finland.markka         0.2203$
-markka                 Finland.markka
-France.franc           0.1963$
-franc                  France.franc
-Germany.mark           0.6647$
-DM                     Germany.mark
-Deutschmark            DM
-mark                   DM
-Greece.drachma         0.004216$
-drachma                        Greece.drachma
-HongKong.dollar                0.1294$
-HK$                    HongKong.dollar
-India.rupee            0.02797$
-rupee                  India.rupee
-Ireland.punt           1.684$
-punt                   Ireland.punt
-Israel.shekel          0.3623$
-shekel                 Israel.shekel
-Italy.lira             0.0006655$
-Japan.yen              0.008976$
-yen                    Japan.yen
-Kenya.shilling         0.02376$
-Malaysia.dollar                0.397$
-Mexico.peso            0.1269$
-peso                   Mexico.peso
-Morocco.dirham         0.1248$
-dirham                 Morocco.dirham
-Netherlands.guilder    0.5924$
-guilder                        Netherlands.guilder
-NewZealand.dollar      0.7153$
-NZ$                    NewZealand.dollar
-Norway.krone           0.1576$
-krone                  Norway.krone
-Portugal.escudo                0.006577$
-escudo                 Portugal.escudo
-Senegal.CFAfranc       0.002019$
-SouthAfrica.rand       0.2169$
-rand                   SouthAfrica.rand
-Spain.peseta           0.007896$
-peseta                 Spain.peseta
-Sweden.krona           0.1513$
-krona                  Sweden.krona
-Switzerland.franc      0.788$
-swissfranc             Switzerland.franc
-Swissfranc             Switzerland.franc
-Turkey.lira            1.3e-05$
-# Old-style Brit money.  Did I omit anything interesting?
-sovereign               sterling
-shilling             1|20 sterling
-penny                1|12 shilling
-pence                penny
-farthing             1|4 penny
-hapenny              half penny
-twopence             two pence
-tuppence             two pence
-thruppence           3 pence
-threepence           3 pence
-sixpence             6 pence
-crown                5 shillings  # Implies `half crown'
-guinea               21 shillings
-florin               2 shillings
-
-
-# 18th century French coinage. References:
-# http://home.nordnet.fr/~jlmorel/mesures.html and reverse-engineered
-# from The Three Musketeers
-# 20011227 Thomas R Wyant III
-livre franc ### 3 Musketeers has francs!
-            ### Now, you too can convert Louis d'Or to U.S. Dollars!
-sou 1|20 livre
-crown 3 livres # It's ecu in French, not to be confused with ECU.
-pistole 10 livres
-double 2    # 3 Musketeers refers to double pistoles, so ...
-louis 24 livres
-### Now if only I had good definitions for reals and doubloons ...
-
-
-# For `register tons'
-register        100 ft3/ton
-registerton     register ton
-
-# What's missing?
-# bequerel (nucleotide radioactivity): Bq = k/s                k=1??
-# gray (absorbed dose): Gy = k J/kg                    k=1??
-# sievert (dose equivalent): Sv = k J/kg                       k=1??
-# curie: Ci = 3.3e10 Bq
-# roentgen: R = 2.58e-4 C/kg
-# rad: rad = centigray
-# rem: rem = centisievert
diff --git a/infobot b/infobot
new file mode 100755 (executable)
index 0000000..f20af53
--- /dev/null
+++ b/infobot
@@ -0,0 +1,103 @@
+#!/usr/bin/perl
+
+# infobot
+# copyright kevin lenzo (c) 1997-1999
+# copyright david sobon (c) 1999-infinity
+# Copyright (c) 2001-2008 Tim Riker <Tim@Rikers.org>
+
+use strict;
+use vars qw($bot_base_dir $bot_src_dir $bot_misc_dir $bot_state_dir
+           $bot_data_dir $bot_config_dir $bot_log_dir $bot_run_dir
+           $bot_pid $memusage %param
+);
+
+BEGIN {
+    if (@ARGV and -f $ARGV[0]) {
+       # source passed config to allow $bot_*_dir to be set.
+       do $ARGV[0];
+    }
+
+    # set any $bot_*_dir var's that aren't already set
+    $bot_base_dir      ||= '.';
+    $bot_config_dir    ||= 'files/';
+    $bot_data_dir      ||= 'files/';
+    $bot_state_dir     ||= 'files/';
+    $bot_run_dir       ||= '.';
+    $bot_src_dir       ||= "$bot_base_dir/src";
+    $bot_log_dir       ||= "$bot_base_dir/log";
+    $bot_misc_dir      ||= "$bot_base_dir/files";
+
+    $bot_pid           = $$;
+
+    require "$bot_src_dir/logger.pl";
+    require "$bot_src_dir/core.pl";
+    require "$bot_src_dir/modules.pl";
+
+    # load the configuration (params) file.
+    &setupConfig();
+
+    &showProc();       # to get the first value.
+    &status("Initial memory usage: $memusage kB");
+    &loadCoreModules();
+    &loadDBModules();
+    &loadFactoidsModules();
+    &loadIRCModules();
+
+    &status("Memory usage after loading modules: $memusage kB");
+}
+
+# prevent duplicate processes of the same bot
+&duperuncheck();
+
+# initialize everything
+&startup();    # first time initialization.
+&setup();
+
+if (!&IsParam("Interface") or $param{'Interface'} =~ /IRC/) {
+    # launch the irc event loop
+    &ircloop();
+} else {
+    &cliloop();
+}
+
+exit 0;  # just so you don't look farther down in this file :)
+
+# --- support routines
+
+# FIXME: add arguments, basically '-h' and '--help', heh.
+
+# added by the xk
+sub duperuncheck {
+    my $pid    = $$;
+    my $file   = $file{PID};
+
+    if ( -f $file) {
+       open(PIDFILE,$file) or die "error: cannot open $file.";
+       my $thispid = <PIDFILE> || "NULL\n";
+       close PIDFILE;
+       chop $thispid;
+
+       if ($thispid =~ /^\D$/) {
+           &staus("warning: pidfile is invalid; wiping out.");
+       } else {
+           if ( -d "/proc/$thispid/") {
+               &ERROR("bot is already running from this directory.");
+               &ERROR("if this is incorrect, erase '*.pid'.");
+               &ERROR("verify with 'ps -axu | grep $thispid'.");
+               exit 1;
+           } else {
+               &status("warning: stale $file found; wiping.");
+           }
+       }
+    }
+
+    open(PIDFILE,">$file") or die "error: cannot write to $file.";
+    print PIDFILE "$pid\n";
+    close PIDFILE;
+
+    return 0;
+}
+
+1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/log/.cvsignore b/log/.cvsignore
deleted file mode 100644 (file)
index 72e8ffc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*
diff --git a/patches/WWW_Search.patch b/patches/WWW_Search.patch
new file mode 100644 (file)
index 0000000..a276101
--- /dev/null
@@ -0,0 +1,444 @@
+--- Google.pm.orig     Wed May 24 16:55:47 2000
++++ Google.pm  Wed Jan 16 22:02:53 2002
+@@ -2,7 +2,7 @@
+ # Google.pm
+ # by Jim Smyser
+ # Copyright (C) 1996-1999 by Jim Smyser & USC/ISI
+-# $Id$
++# $Id$
+ ##########################################################
+@@ -30,8 +30,6 @@
+ It handles making and interpreting Google searches.
+ F<http://www.google.com>.
+-Googles returns 100 Hits per page. Custom Linux Only search capable.
+-
+ This class exports no public interface; all interaction should
+ be done through L<WWW::Search> objects.
+@@ -70,33 +68,41 @@
+ This module adheres to the C<WWW::Search> test suite mechanism. 
+-=head1 BUGS
+-
+-2.07 now parses for most of what Google produces, but not all.
+-Because Google does not produce universial formatting for all
+-results it produces, there are undoublty a few line formats yet 
+-uncovered by the author. Different search terms creates various
+-differing format out puts for each line of results. Example,
+-searching for "visual basic" will create whacky url links,
+-whereas searching for "Visual C++" does not. It is a parsing
+-nitemare really! If you think you uncovered a BUG just remember
+-the above comments!  
+-
+-With the above said, this back-end will produce proper formated
+-results for 96+% of what it is asked to produce. Your milage
+-will vary.
+-
+ =head1 AUTHOR
+-This backend is maintained and supported by Jim Smyser.
++This backend is written and maintained/supported by Jim Smyser.
+ <jsmyser@bigfoot.com>
+ =head1 BUGS
+-2.09 seems now to parse all hits with the new format change so there really shouldn't be
+-any like there were with 2.08. 
++Google is not an easy search engine to parse in that it is capable 
++of altering it's output ever so slightly on different search terms.
++There may be new slight results output the author has not yet seen that
++will pop at any given time for certain searches. So, if you think you see
++a bug keep the above in mind and send me the search words you used so I
++may code for any new variations.
++
++=head1 CHANGES
++
++2.22
++Fixed up changed format from google
++reformatted code
++
++2.21
++Minor code correction for empty returned titles
++
++2.20
++Forgot to add new next url regex in 2.19!
++
++2.19
++Regex work on some search results url's that has changed. Number found 
++return should be right now.
++
++2.17
++Insert url as a title when no title is found. 
+-=head1 VERSION HISTORY
++2.13
++New regexp to parse newly found results format with certain search terms.
+ 2.10
+ removed warning on absence of description; new test case
+@@ -131,15 +137,18 @@
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++
+ =cut
+ #'
+-
++          
++          
+ #####################################################################
++          
+ require Exporter;
+ @EXPORT = qw();
+ @EXPORT_OK = qw();
+ @ISA = qw(WWW::Search Exporter);
+-$VERSION = '2.10';
++$VERSION = '2.22';
+ $MAINTAINER = 'Jim Smyser <jsmyser@bigfoot.com>';
+ $TEST_CASES = <<"ENDTESTCASES";
+@@ -148,160 +157,187 @@
+ &test('Google', '$MAINTAINER', 'one_page', '+LS'.'AM +rep'.'lication', \$TEST_RANGE, 2,99);
+ &test('Google', '$MAINTAINER', 'multi', 'dir'.'ty ha'.'rr'.'y bimbo', \$TEST_GREATER_THAN, 101);
+ ENDTESTCASES
+-
++          
+ use Carp ();
+-use WWW::Search(generic_option);
++use WWW::Search(qw(generic_option strip_tags));
+ require WWW::SearchResult;
+-
++          
++          
++sub undef_to_emptystring {
++return defined($_[0]) ? $_[0] : "";
++}
++# private
+ sub native_setup_search {
+-   my($self, $native_query, $native_options_ref) = @_;
+-   $self->{_debug} = $native_options_ref->{'search_debug'};
+-   $self->{_debug} = 2 if ($native_options_ref->{'search_parse_debug'});
+-   $self->{_debug} = 0 if (!defined($self->{_debug}));
+-   $self->{agent_e_mail} = 'jsmyser@bigfoot.com';
+-   $self->user_agent('user');
+-   $self->{_next_to_retrieve} = 1;
+-   $self->{'_num_hits'} = 0;
+-   if (!defined($self->{_options})) {
+-     $self->{'search_base_url'} = 'http://www.google.com';
+-     $self->{_options} = {
+-         'search_url' => 'http://www.google.com/search',
+-         'num' => '100',
+-         'q' => $native_query,
+-         };
+-         }
+-   my $options_ref = $self->{_options};
+-   if (defined($native_options_ref)) 
+-     {
+-     # Copy in new options.
+-     foreach (keys %$native_options_ref) 
+-     {
+-     $options_ref->{$_} = $native_options_ref->{$_};
+-     } # foreach
+-     } # if
+-   # Process the options.
+-   my($options) = '';
+-   foreach (sort keys %$options_ref) 
+-     {
+-     # printf STDERR "option: $_ is " . $options_ref->{$_} . "\n";
+-     next if (generic_option($_));
+-     $options .= $_ . '=' . $options_ref->{$_} . '&';
+-     }
+-   chop $options;
+-   # Finally figure out the url.
+-   $self->{_next_url} = $self->{_options}{'search_url'} .'?'. $self->hash_to_cgi_string($self->{_options});
+-   } # native_setup_search
+- 
++    my($self, $native_query, $native_options_ref) = @_;
++    $self->user_agent('user');
++    $self->{_next_to_retrieve}                = 0;
++    $self->{'_num_hits'}              = 100;
++
++    if (!defined $self->{_options}) {
++      $self->{_options} = {
++              'search_url' => 'http://www.google.com/search',
++              'num' => $self->{'_num_hits'},
++      };
++    }
++
++    my($options_ref) = $self->{_options};
++
++    if (defined $native_options_ref) {
++      # Copy in new options.
++      foreach (keys %$native_options_ref) {
++          $options_ref->{$_} = $native_options_ref->{$_};
++      }
++    }
++
++    # Process the options.
++    my($options) = '';
++    foreach (keys %$options_ref) {
++      # printf STDERR "option: $_ is " . $options_ref->{$_} . "\n";
++      next if (generic_option($_));
++      $options .= $_ . '=' . $options_ref->{$_} . '&';
++    }
++
++    $self->{_debug} = $options_ref->{'search_debug'};
++    $self->{_debug} = 2 if ($options_ref->{'search_parse_debug'});
++    $self->{_debug} = 0 if (!defined $self->{_debug});
++
++    # Finally figure out the url.
++    $self->{_base_url} =
++    $self->{_next_url} =
++    $self->{_options}{'search_url'} .
++    "?" . $options .
++    "q=" . $native_query;
++}
++          
+ # private
+-sub native_retrieve_some
+-   {
+-   my ($self) = @_;
+-   print STDERR "**Google::native_retrieve_some()**\n" if $self->{_debug};
+-   # Fast exit if already done:
+-   return undef if (!defined($self->{_next_url}));
+-   
+-   # If this is not the first page of results, sleep so as to not
+-   # overload the server:
+-   $self->user_agent_delay if 1 < $self->{'_next_to_retrieve'};
+-   
+-   # Get some if were not already scoring somewhere else:
+-   print STDERR "*Sending request (",$self->{_next_url},")\n" if $self->{_debug};
+-   my($response) = $self->http_request('GET', $self->{_next_url});
+-   $self->{response} = $response;
+-   if (!$response->is_success) 
+-     {
+-     return undef;
+-     }
+-   $self->{'_next_url'} = undef;
+-   print STDERR "**Response\n" if $self->{_debug};
+-
+-   # parse the output
+-   my ($HEADER, $START, $HITS, $NEXT) = qw(HE HI ST NX);
+-   my $hits_found = 0;
+-   my $state = $HEADER;
+-   my $hit = ();
+-   foreach ($self->split_lines($response->content()))
+-      {
+-      next if m@^$@; # short circuit for blank lines
+-      print STDERR " $state ===$_=== " if 2 <= $self->{'_debug'};
+-  if (m|<b>(\d+)</b></font> matches|i) {
+-      print STDERR "**Found Header Count**\n" if ($self->{_debug});
+-      $self->approximate_result_count($1);
+-      $state = $START;
+-      # set-up attempting the tricky task of 
+-      # fetching the very first HIT line
+-      } 
+-  elsif ($state eq $START && m|Search took|i) 
+-      {
+-      print STDERR "**Found Start Line**\n" if ($self->{_debug});
+-      $state = $HITS;
+-      # Attempt to pull the very first hit line
+-      } 
+-  if ($state eq $HITS) {
+-      print "\n**state == HITS**\n" if 2 <= $self->{_debug};
+-  }
+-  if ($state eq $HITS && m@^<p><a href=([^<]+)>(.*)</a>$@i)      
+-      {
+-      print "**Found HIT**\n" if 2 <= $self->{_debug};
+-      my ($url, $title) = ($1,$2);
+-      if (defined($hit)) 
+-      {
+-      push(@{$self->{cache}}, $hit);
+-      };
+-      $hit = new WWW::SearchResult;
+-      # some queries *can* create internal junk in the url link
+-      # remove them! 
+-      $url =~ s/\/url\?sa=U&start=\d+&q=//g;
+-      $hits_found++;
+-      $hit->add_url($url);
+-      $hit->title($title);
+-      $state = $HITS;
+-      } 
+-  if ($state eq $HITS && m@^<font size=-1><br>(.*)@i) 
+-      {
+-      print "**Found First Description**\n" if 2 <= $self->{_debug};
+-      $mDesc = $1; 
+-      if (not $mDesc =~ m@&nbsp;@)
+-      { 
+-      $mDesc =~ s/<.*?>//g; 
+-      $mDesc =  $mDesc . '<br>' if not $mDesc =~ m@<br>@;
+-      $hit->description($mDesc); 
+-      $state = $HITS;
+-      }
+-      } 
+-  elsif ($state eq $HITS && 
+-           m@^(\.(.+))@i ||
+-           m@^<br><font color=green>(.*)\s@i) { 
+-      print "**Found Second Description**\n" if 2 <= $self->{_debug};
+-      $sDesc = $1; 
+-      $sDesc ||= '';
+-      $sDesc =~ s/<.*?>//g; 
+-      $sDesc = $mDesc . $sDesc;
+-      $hit->description($sDesc);
+-      $sDesc ='';
+-      $state = $HITS;
+-      } 
+-   elsif ($state eq $HITS && 
+-      m|<a href=([^<]+)><IMG SRC=/nav_next.gif.*?><br><.*?>.*?</A>|i) {
+-      my $nexturl = $self->{'_next_url'};
+-      if (defined $nexturl) {
+-      print STDERR "**Fetching Next URL-> ", $nexturl, "\n" if 2 <= $self->{_debug};
+-      } else {
+-      print STDERR "**Fetching Next URL-> UNDEF\n" if 2 <= $self->{_debug};
+-      }
+-      
+-      my $iURL = $1;
+-      $self->{'_next_url'} = $self->{'search_base_url'} . $iURL;
+-      } 
+-    else 
+-      {
+-      print STDERR "**Nothing matched.**\n" if 2 <= $self->{_debug};
+-      }
+-      } 
+-    if (defined($hit)) 
+-      {
+-      push(@{$self->{cache}}, $hit);
+-      } 
+-      return $hits_found;
+-      } # native_retrieve_some
+-1;  
++sub begin_new_hit {
++    my($self) = shift;
++    my($old_hit) = shift;
++    my($old_raw) = shift;
++
++    if (defined $old_hit) {
++      $old_hit->raw($old_raw) if (defined $old_raw);
++      push(@{$self->{cache}}, $old_hit);
++    }
++
++    return (new WWW::SearchResult, '');
++}
++
++sub native_retrieve_some {
++    my ($self) = @_;
++    # fast exit if already done
++    return undef if (!defined $self->{_next_url});
++
++    # get some
++    print STDERR "Fetching " . $self->{_next_url} . "\n" if ($self->{_debug});
++    my($response) = $self->http_request('GET', $self->{_next_url});
++    $self->{response} = $response;
++
++    return undef if (!$response->is_success);
++
++    # parse the output
++    my($HEADER, $HITS, $TRAILER, $POST_NEXT) = (1..10);
++    my($hits_found) = 0;
++    my($state) = ($HEADER);
++    my($hit) = undef;
++    my($raw) = '';
++
++    foreach ($self->split_lines($response->content())) {
++      next if m@^$@; # short circuit for blank lines
++
++      if ($state == $HEADER && m/about <b>([\d,]+)<\/b>/) {
++          my($n) = $1;
++          $self->approximate_result_count($n);
++          print STDERR "Found Total: $n\n" if ($self->{_debug});
++          $state = $HITS;
++
++      } elsif ($state == $HITS &&
++              m|<a href=(\S+)\>(.*?)</a><br><font size=-1><font color=\"#008000\"><.*?>|i
++      ) {
++
++          my ($url, $title) = ($1,$2);
++          ($hit, $raw) = $self->begin_new_hit($hit, $raw);
++          print STDERR "**Found HIT1 Line**\n" if ($self->{_debug});
++          $raw .= $_;
++          $url =~ s/(>.*)//g;
++          $hit->add_url(strip_tags($url));
++          $hits_found++;
++          $title = "No Title" if ($title =~ /^\s+/);
++          $hit->title(strip_tags($title));
++          $state = $HITS;
++
++      } elsif ($state == $HITS &&
++              m@^<p><a href=/url\?sa=U&start=\d+&q=([^<]+)\&.*?>(.*)</a><font size=-1><br>(.*)@i ||
++              m@^<p><a href=(\S+)>(.*)</a>.*?<font size=-1>(.*)@i
++      ) {
++          print STDERR "**Found HIT2 Line**\n" if ($self->{_debug});
++
++          ($hit, $raw) = $self->begin_new_hit($hit, $raw);
++
++          my ($url, $title) = ($1,$2);
++          $mDesc = $3;
++
++          $url =~ s/\/url\?sa=\w&start=\d+&q=//g;
++          $url =~ s/\?lang=(\S+)$//g;
++          $url =~ s/&(.*)//g;
++          $url =~ s/(>.*)//g;
++          $url =~ s/\/$//g;   # kill trailing slash.
++
++          $raw .= $_;
++          $hit->add_url(strip_tags($url));
++          $hits_found++;
++
++          $title = "No Title" if ($title =~ /^\s+/);
++          $hit->title(strip_tags($title));
++
++          $mDesc =~ s/<.*?>//g;
++###       $mDesc =  $mDesc . '<br>' if not $mDesc =~ m@<br>@;
++          $hit->description($mDesc) if (defined $hit);
++          $state = $HITS;
++
++# description parsing
++      } elsif ($state == $HITS && m@<b>(\.\.(.+))</b> @i
++      ) {
++          print STDERR "**Parsing Description Line**\n" if ($self->{_debug});
++          $raw .= $_;
++          # uhm...
++          $sDesc = $1 || "";
++     
++          $sDesc =~ s/<.*?>//g;
++          $mDesc ||= "";
++          $sDesc = $mDesc . $sDesc;
++#         $hit->description($sDesc) if $sDesc =~ m@^\.@;
++          $sDesc = '';
++          $state = $HITS;
++
++      } elsif ($state == $HITS && m@<div>@i
++      ) {
++          ($hit, $raw) = $self->begin_new_hit($hit, $raw);
++          print STDERR "**Found Last Line**\n" if ($self->{_debug});
++          # end of hits
++          $state = $TRAILER;
++
++      } elsif ($state == $TRAILER && 
++              m|<a href=([^<]+)><img src=/nav_next.gif.*?>.*?|i
++      ) {
++          my($relative_url) = $1;
++          print STDERR "**Fetching >>Next<< Page**\n" if ($self->{_debug});
++          $self->{_next_url} = 'http://www.google.com' . $relative_url;
++          $state = $POST_NEXT;
++      }
++    }
++
++    if ($state != $POST_NEXT) {
++      # No "Next" Tag
++      $self->{_next_url} = undef;
++      $self->begin_new_hit($hit, $raw) if ($state == $HITS);
++      $self->{_next_url} = undef;
++    }
++
++    # ZZZzzzzZZZZzzzzzzZZZZZZzzz
++    $self->user_agent_delay if (defined($self->{_next_url}));
++    return $hits_found;
++}
++
++1;
++
diff --git a/patches/WWW_Search.patch.old b/patches/WWW_Search.patch.old
new file mode 100644 (file)
index 0000000..eec3ce3
--- /dev/null
@@ -0,0 +1,31 @@
+--- WWW/Search/Google.pm.orig  Wed May 24 16:55:47 2000
++++ WWW/Search/Google.pm       Wed May 24 16:56:19 2000
+@@ -240,7 +240,7 @@
+   if ($state eq $HITS) {
+       print "\n**state == HITS**\n" if 2 <= $self->{_debug};
+   }
+-  if ($state eq $HITS && m@^<p><a href=([^<]+)>(.*)</a>$@i)      
++  if ($state eq $HITS && m@^<p><a href=([^<]+)>(.*)</a>@i)
+       {
+       print "**Found HIT**\n" if 2 <= $self->{_debug};
+       my ($url, $title) = ($1,$2);
+@@ -252,6 +252,7 @@
+       # some queries *can* create internal junk in the url link
+       # remove them! 
+       $url =~ s/\/url\?sa=U&start=\d+&q=//g;
++      $url =~ s/\&exp\=OneBoxNews\s//g;               # new junk.
+       $hits_found++;
+       $hit->add_url($url);
+       $hit->title($title);
+@@ -275,9 +276,8 @@
+       print "**Found Second Description**\n" if 2 <= $self->{_debug};
+       $sDesc = $1; 
+       $sDesc ||= '';
+-      $sDesc =~ s/<.*?>//g; 
+-      $sDesc = $mDesc . $sDesc;
+-      $hit->description($sDesc);
++      $sDesc = $mDesc . $sDesc if (defined $mDesc);
++      $hit->description($sDesc) if (defined $hit and $sDesc ne '');
+       $sDesc ='';
+       $state = $HITS;
+       } 
index a98bba782f7179f57f3196697230d8d254472156..31c1c24bae181295f07a5687bcfd1770e3dac003 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 BACKUP_SRCDIR="/var/lib/mysql/"
 #!/bin/bash
 
 BACKUP_SRCDIR="/var/lib/mysql/"
-BACKUP_TDIR="blootbot/"
+BACKUP_TDIR="infobot/"
 BACKUP_FILE="/home/a/apt/public_html/tables.tar.bz2"
 
 pwd
 BACKUP_FILE="/home/a/apt/public_html/tables.tar.bz2"
 
 pwd
@@ -18,3 +18,5 @@ else
 fi
 
 exit 0;
 fi
 
 exit 0;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index bc7cbc7d04c4c6c7fe9141b1336da1eab89e7633..c743d48a5cd9aeecdeccd54bb2f8a6642dc5326f 100755 (executable)
@@ -101,3 +101,5 @@ for(my $i=0; $i<scalar(@index); $i++) {
 close OUT;
 
 print "Done.\n";
 close OUT;
 
 print "Done.\n";
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 7ed1b0d9e8ddf8e4caa3e4c0c130131adf43e730..a93429a1a26988b52f429c21d51491c403011a8f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 BOTDIR=/home/apt/bot
 #!/bin/sh
 
 BOTDIR=/home/apt/bot
-BOTNICK=blootbot
+BOTNICK=infobot
 PIDFILE=$BOTDIR/$BOTNICK.pid
 
 if [ -f $PIDFILE ]; then       # exists.
 PIDFILE=$BOTDIR/$BOTNICK.pid
 
 if [ -f $PIDFILE ]; then       # exists.
@@ -10,10 +10,12 @@ if [ -f $PIDFILE ]; then    # exists.
        exit 0
     fi
 
        exit 0
     fi
 
-    # blootbot removes the pid file.
+    # infobot removes the pid file.
     echo "stale pid file; removing."
 #    rm -f $PIDFILE
 fi
 
 cd $BOTDIR
     echo "stale pid file; removing."
 #    rm -f $PIDFILE
 fi
 
 cd $BOTDIR
-./blootbot
+./infobot
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 922bbb5542cab2b6da4a1d8a1e193a0465f30a51..b2592827735a9d87ba1d89536f101b3723d21150 100755 (executable)
@@ -33,7 +33,7 @@ if (!dbmopen(%db, $dbfile, 0666)) {
 &status("::: opening dbm file: $dbfile");
 
 # open all the data...
 &status("::: opening dbm file: $dbfile");
 
 # open all the data...
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 $dbname = $param{'DBName'};
 my $dbh_mysql = sqlOpenDB($param{'DBName'},
        $param{'DBType'}, $param{'SQLUser'}, $param{'SQLPass'});
 $dbname = $param{'DBName'};
 my $dbh_mysql = sqlOpenDB($param{'DBName'},
        $param{'DBType'}, $param{'SQLUser'}, $param{'SQLPass'});
@@ -56,3 +56,5 @@ foreach $factoid (keys %db) {
 print "Done.\n";
 &closeDB();
 dbmclose(%db);
 print "Done.\n";
 &closeDB();
 dbmclose(%db);
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 259e6cecbe4d8ff38f712c64e0fb178a3afb71bb..ed9e354a7be34fafdc521e3edd47d4cde539731d 100755 (executable)
@@ -22,3 +22,5 @@ while (($key, $val) = each %db) {
   print "$key => $val\n";
 }
 dbmclose %db;
   print "$key => $val\n";
 }
 dbmclose %db;
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index 900920f..0a559d1
@@ -70,3 +70,5 @@ print "Conf:\n";
 foreach (sort keys %conf) {
     print "    $_\n";
 }
 foreach (sort keys %conf) {
     print "    $_\n";
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index 8f9d072..2662993
@@ -2,7 +2,7 @@
 
 use DBI;
 
 
 use DBI;
 
-my $dsn = "DBI:mysql:blootbot:localhost";
+my $dsn = "DBI:mysql:infobot:localhost";
 my $dbh = DBI->connect($dsn, "USERNAME", "PASSWORD");
 
 my @factkey;
 my $dbh = DBI->connect($dsn, "USERNAME", "PASSWORD");
 
 my @factkey;
@@ -65,3 +65,5 @@ foreach (keys %factval) {
 }
 
 $dbh->disconnect();
 }
 
 $dbh->disconnect();
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index d11cd09..802149b
@@ -9,7 +9,7 @@ require "src/logger.pl";
 require "src/modules.pl";
 require "src/Factoids/DBCommon.pl";
 
 require "src/modules.pl";
 require "src/Factoids/DBCommon.pl";
 
-&loadConfig($bot_config_dir."/blootbot.config");
+&loadConfig($bot_config_dir."/infobot.config");
 &loadDBModules();
 
 unless (@_) {
 &loadDBModules();
 
 unless (@_) {
@@ -34,3 +34,5 @@ foreach (@_) {
 
     close IN;
 }
 
     close IN;
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 9cef0188cd11fd1b5844effc49035cbb15a5e963..40e4ed271a65218030ec3e1fa3e8b1cab8b4e44d 100755 (executable)
@@ -15,7 +15,7 @@
 
 # Modified by Tim Riker <Tim@Rikers.org>
 # to work with infobot logs
 
 # Modified by Tim Riker <Tim@Rikers.org>
 # to work with infobot logs
-# then modified again for blootbot
+# then modified again for infobot
 
 # Usage: irclog2html <date> < logfile
 
 
 # Usage: irclog2html <date> < logfile
 
@@ -90,7 +90,7 @@ sub footer {
 <a href="mailto:jdub\@NOSPAMaphid.net">Jeff Waugh</a> - find it at
 <a href="http://freshmeat.net/appindex/2000/03/28/954251322.html">freshmeat.net</a>!
 Modified by <a href="http://www.Rikers.org">Tim Riker</a> to work with
 <a href="mailto:jdub\@NOSPAMaphid.net">Jeff Waugh</a> - find it at
 <a href="http://freshmeat.net/appindex/2000/03/28/954251322.html">freshmeat.net</a>!
 Modified by <a href="http://www.Rikers.org">Tim Riker</a> to work with
-<a href="http://blootbot.sourceforge.net/">blootbot</a> logs, split per channel, etc.
+<a href="http://infobot.sourceforge.net/">infobot</a> logs, split per channel, etc.
 </body></html>
 };
        return $return;
 </body></html>
 };
        return $return;
@@ -317,9 +317,10 @@ sub main {
 
 if (!scalar @ARGV) {
                print "Usage: irclog2html.pl <date> < logfile\n";
 
 if (!scalar @ARGV) {
                print "Usage: irclog2html.pl <date> < logfile\n";
-    print "Example: bzcat log/blootbot.log-20021104.bz2 | irclog2html.pl 20021104\n";
+    print "Example: bzcat log/infobot.log-20021104.bz2 | irclog2html.pl 20021104\n";
     exit 0;
 }
 my $date = shift;
 exit &main($date);
     exit 0;
 }
 my $date = shift;
 exit &main($date);
-# vim: ts=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
index b76617ccfd6f3dc4972542cb68ef1b08a74dd133..7b9d47c833e872579b54180458a218b469d6bcc1 100755 (executable)
@@ -18,3 +18,4 @@ sub mkpasswd {
     return crypt($what, $salt);
 }
 
     return crypt($what, $salt);
 }
 
+# vim:ts=4:sw=4:expandtab:tw=80
index 53f3b7763f29247fbdc3f4f057702cb49e6950b8..bc7fad665b48b7358fb50410d1b13aebed7d7ee9 100755 (executable)
@@ -18,7 +18,7 @@ if (!defined $dbname) {
 }
 
 # open the db.
 }
 
 # open the db.
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 &loadDBModules();
 
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
 &loadDBModules();
 
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
@@ -45,3 +45,5 @@ $sth->finish;
 
 print "Done.\n";
 &closeDB();
 
 print "Done.\n";
 &closeDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index 3efe8b6..70410d8
@@ -25,3 +25,5 @@ $x = 10;
 %z = (1,2,3,4, 5, 6, \@y);
 $z = 300;
 DUMPVAR::dumpvar("Test");
 %z = (1,2,3,4, 5, 6, \@y);
 $z = 300;
 DUMPVAR::dumpvar("Test");
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index db58d78..3d25165
@@ -85,3 +85,5 @@ sub print_indented {
     $spaces = ":  " x $level;
     print "${spaces}$_[0]\n";
 }
     $spaces = ":  " x $level;
     print "${spaces}$_[0]\n";
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index 0b877bd..a731473
@@ -1,7 +1,9 @@
 #!/bin/sh
 #!/bin/sh
-echo -n "DEBUG:  "; grep DEBUG `find blootbot src -type f`| wc -l
-echo -n "WARN:   "; grep WARN `find blootbot src -type f` | wc -l
-echo -n "FIXME:  "; grep FIXME `find blootbot src -type f` | wc -l
-echo -n "status: "; grep status `find blootbot src -type f` | wc -l
-echo -n "ERROR:  "; grep ERROR `find blootbot src -type f` | wc -l
-echo -n "TODO:   "; grep TODO `find blootbot src -type f` | wc -l
+echo -n "DEBUG:  "; grep DEBUG `find infobot src -type f`| wc -l
+echo -n "WARN:   "; grep WARN `find infobot src -type f` | wc -l
+echo -n "FIXME:  "; grep FIXME `find infobot src -type f` | wc -l
+echo -n "status: "; grep status `find infobot src -type f` | wc -l
+echo -n "ERROR:  "; grep ERROR `find infobot src -type f` | wc -l
+echo -n "TODO:   "; grep TODO `find infobot src -type f` | wc -l
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 53a224c45bf6d2881b92cb5bb69f4933e02e91cb..e22e024a677e511c9376c14ef1875ef789c0516d 100755 (executable)
@@ -89,3 +89,5 @@ foreach $file (keys %done) {
        print "=> error: could not open file.\n";
     }
 }
        print "=> error: could not open file.\n";
     }
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index 22c55ac..80b9c35
@@ -108,3 +108,5 @@ sub print_indented {
     $spaces = ":  " x $level;
     print "${spaces}$_[0]\n";
 }
     $spaces = ":  " x $level;
     print "${spaces}$_[0]\n";
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
index dfa71c74598bd948efdf525041f1716c1c4dc12c..86e26490b66155aaf39620a066bb791c6fa72e71 100755 (executable)
@@ -102,3 +102,5 @@ sub DumpPackage {
  print $padding."scalars $scalar, size $size\n";
  return $size;
 }
  print $padding."scalars $scalar, size $size\n";
  return $size;
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 47a70b7437c0b24d18a4a3ad0da0a953bab60442..68b134d5985e9e056f8c7e2ef33f78cd26b5a900 100755 (executable)
@@ -19,7 +19,7 @@ my $txtfile = shift;
 open(IN,$txtfile) or die "error: cannot open txtfile '$txtfile'.\n";
 
 # read the bot config file.
 open(IN,$txtfile) or die "error: cannot open txtfile '$txtfile'.\n";
 
 # read the bot config file.
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 &loadDBModules();
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
 
 &loadDBModules();
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
 
@@ -55,3 +55,5 @@ close IN;
 
 print "Done.\n";
 &closeDB();
 
 print "Done.\n";
 &closeDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
old mode 100644 (file)
new mode 100755 (executable)
index d96fcc1..1b53de8
@@ -78,3 +78,5 @@ sub vartree {
 
     print "end.\n";
 }
 
     print "end.\n";
 }
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ce6412e0feb0b2c549c7c58f60c3337125f3d099..41e43c769e388e31d8ed28db974c96f743d7c136 100755 (executable)
@@ -93,3 +93,5 @@ for(my $i=0; $i<scalar(@index); $i++) {
 close OUT;
 
 print "Done.\n";
 close OUT;
 
 print "Done.\n";
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/setup/README b/setup/README
new file mode 100644 (file)
index 0000000..90f824c
--- /dev/null
@@ -0,0 +1,24 @@
+Welcome,
+
+This directory has changed slightly. The new format allows for
+each type of database to have its own schema. The following
+directories are included:
+
+       mysql/          -- Schema for the popular MySQL
+       sqlite/         -- Schema for v2 or v3 of SQLite
+       sqlite2/        -- Schema for specifically v2 of SQLite
+       pgsql/          -- Schema for PostgreSQL
+
+Also, the included setup.pl has been modified to work with
+all of the above types of databases. (FIXME: actually, only
+MySQL until I actually change it)
+
+To automate the setup of your database and user, type:
+
+       cd ~/infobotdir
+       ./setup/setup.pl
+
+(NOTE: The setup will ask for an account capable of administrating
+the database server!)
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/setup/botmail.sql b/setup/botmail.sql
deleted file mode 100644 (file)
index 2789338..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CREATE TABLE botmail (
- srcwho VARCHAR(20) NOT NULL,
- dstwho VARCHAR(20) NOT NULL,
- srcuh VARCHAR(80) NOT NULL,
- time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
- msg TEXT NOT NULL,
- PRIMARY KEY (srcwho,dstwho)
-);
diff --git a/setup/connections.sql b/setup/connections.sql
deleted file mode 100644 (file)
index 00dbf49..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TABLE connections (
- server VARCHAR(30) NOT NULL,
- port INT NOT NULL DEFAULT '6667',
- nick VARCHAR(20) NOT NULL,
- nickservpass VARCHAR(8) NOT NULL,
- ircname VARCHAR (20) NOT NULL DEFAULT 'blootbot experimental bot',
- timeadded INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
- PRIMARY KEY (server,port,nick)
-);
diff --git a/setup/factoids.sql b/setup/factoids.sql
deleted file mode 100644 (file)
index d5189d0..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CREATE TABLE factoids (
- factoid_key VARCHAR(64) NOT NULL,
- requested_by VARCHAR(64) NOT NULL DEFAULT 'nobody',
- requested_time INT NOT NULL DEFAULT '0',
- requested_count SMALLINT UNSIGNED NOT NULL DEFAULT '0',
- created_by VARCHAR(64),
- created_time INT NOT NULL DEFAULT '0',
- modified_by VARCHAR(192),
- modified_time INT NOT NULL DEFAULT '0',
- locked_by VARCHAR(64),
- locked_time INT NOT NULL DEFAULT '0',
- factoid_value TEXT NOT NULL,
- PRIMARY KEY (factoid_key)
-);
diff --git a/setup/freshmeat.sql b/setup/freshmeat.sql
deleted file mode 100644 (file)
index 4b4f42b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CREATE TABLE freshmeat (
- projectname_short VARCHAR(64) NOT NULL,
- latest_version VARCHAR(32) DEFAULT 'none' NOT NULL,
- license VARCHAR(32),
- url_homepage VARCHAR(128),
- desc_short VARCHAR(96) NOT NULL,
- PRIMARY KEY (projectname_short,latest_version)
-);
diff --git a/setup/mysql/botmail.sql b/setup/mysql/botmail.sql
new file mode 100644 (file)
index 0000000..5303172
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `botmail`
+--
+
+CREATE TABLE `botmail` (
+  `srcwho` varchar(20) NOT NULL default '',
+  `dstwho` varchar(20) NOT NULL default '',
+  `srcuh` varchar(80) NOT NULL default '',
+  `time` int(10) unsigned default '0',
+  `msg` text NOT NULL,
+  PRIMARY KEY  (`srcwho`,`dstwho`)
+) TYPE=MyISAM;
diff --git a/setup/mysql/factoids.sql b/setup/mysql/factoids.sql
new file mode 100644 (file)
index 0000000..5052395
--- /dev/null
@@ -0,0 +1,18 @@
+--
+-- Table structure for table `factoids`
+--
+
+CREATE TABLE `factoids` (
+  `factoid_key` varchar(64) NOT NULL,
+  `requested_by` varchar(100) default NULL,
+  `requested_time` int(11) default NULL,
+  `requested_count` smallint(5) unsigned NOT NULL default '0',
+  `created_by` varchar(100) default NULL,
+  `created_time` int(11) default NULL,
+  `modified_by` varchar(100) default NULL,
+  `modified_time` int(11) default NULL,
+  `locked_by` varchar(100) default NULL,
+  `locked_time` int(11) default NULL,
+  `factoid_value` text NOT NULL,
+  PRIMARY KEY  (`factoid_key`)
+) TYPE=MyISAM;
diff --git a/setup/mysql/onjoin.sql b/setup/mysql/onjoin.sql
new file mode 100644 (file)
index 0000000..63f3514
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `onjoin`
+--
+
+CREATE TABLE `onjoin` (
+  `nick` varchar(20) NOT NULL default '',
+  `channel` varchar(30) NOT NULL default '',
+  `message` varchar(255) NOT NULL default '',
+  `modified_by` varchar(20) NOT NULL default 'nobody',
+  `modified_time` int(11) NOT NULL default '0',
+  PRIMARY KEY  (`nick`,`channel`)
+) TYPE=MyISAM;
diff --git a/setup/mysql/rootwarn.sql b/setup/mysql/rootwarn.sql
new file mode 100644 (file)
index 0000000..f5479ed
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `rootwarn`
+--
+
+CREATE TABLE `rootwarn` (
+  `nick` varchar(20) NOT NULL default '',
+  `attempt` smallint(5) unsigned default NULL,
+  `time` int(11) NOT NULL default '0',
+  `host` varchar(64) NOT NULL default '',
+  `channel` varchar(30) NOT NULL default '',
+  PRIMARY KEY  (`nick`)
+) TYPE=MyISAM;
diff --git a/setup/mysql/seen.sql b/setup/mysql/seen.sql
new file mode 100644 (file)
index 0000000..9a2b691
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `seen`
+--
+
+CREATE TABLE `seen` (
+  `nick` varchar(20) NOT NULL default '',
+  `time` int(11) NOT NULL default '0',
+  `channel` varchar(30) NOT NULL default '',
+  `host` varchar(64) NOT NULL default '',
+  `message` tinytext NOT NULL,
+  PRIMARY KEY  (`nick`)
+) TYPE=MyISAM;
diff --git a/setup/mysql/stats.sql b/setup/mysql/stats.sql
new file mode 100644 (file)
index 0000000..442817f
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- Table structure for table `stats`
+--
+
+CREATE TABLE `stats` (
+  `nick` varchar(20) NOT NULL default '',
+  `type` varchar(8) NOT NULL default '',
+  `channel` varchar(30) NOT NULL default 'PRIVATE',
+  `time` int(10) unsigned default '0',
+  `counter` smallint(5) unsigned default '0',
+  PRIMARY KEY  (`nick`,`type`,`channel`)
+) TYPE=MyISAM;
diff --git a/setup/news.sql b/setup/news.sql
deleted file mode 100644 (file)
index ebfb0e2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-CREATE TABLE news (
- channel VARCHAR(16) NOT NULL,
- id INT UNSIGNED DEFAULT '0',
- key VARCHAR(16) NOT NULL,
- value TEXT NOT NULL, # limit to ~450 or so.
- PRIMARY KEY (channel,id,key)
-);
diff --git a/setup/onjoin.sql b/setup/onjoin.sql
deleted file mode 100644 (file)
index 994cc54..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CREATE TABLE onjoin (
-       nick VARCHAR(20) NOT NULL,
-       channel VARCHAR(16) NOT NULL,
-       message VARCHAR(255) NOT NULL,
-       modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody',
-       modified_time INT NOT NULL DEFAULT '0',
-       PRIMARY KEY (nick, channel)
-);
-
--- v.2 -> v.3
--- ALTER TABLE onjoin ADD COLUMN modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody';
--- ALTER TABLE onjoin ADD COLUMN modified_time INT NOT NULL DEFAULT '0';
--- ** the following doesn't work for sqlite **
--- ALTER TABLE onjoin ADD PRIMARY KEY (nick, channel);
diff --git a/setup/pgsql/botmail.sql b/setup/pgsql/botmail.sql
new file mode 100644 (file)
index 0000000..c87c2e4
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE botmail (
+    srcwho character varying(20) NOT NULL,
+    dstwho character varying(20) NOT NULL,
+    srcuh character varying(80) NOT NULL,
+    "time" numeric DEFAULT 0 NOT NULL,
+    msg text NOT NULL
+) WITHOUT OIDS;
+
+REVOKE ALL ON TABLE botmail FROM PUBLIC;
+
+ALTER TABLE ONLY botmail
+    ADD CONSTRAINT botmail_pkey PRIMARY KEY (srcwho, dstwho);
diff --git a/setup/pgsql/factoids.sql b/setup/pgsql/factoids.sql
new file mode 100644 (file)
index 0000000..59b5d67
--- /dev/null
@@ -0,0 +1,18 @@
+CREATE TABLE factoids (
+    factoid_key VARCHAR(64) NOT NULL,
+    requested_by VARCHAR(100) DEFAULT NULL,
+    requested_time numeric(11) DEFAULT NULL,
+    requested_count numeric(5) DEFAULT 0 NOT NULL,
+    created_by VARCHAR(100) DEFAULT NULL,
+    created_time numeric(11) DEFAULT NULL,
+    modified_by VARCHAR(100) DEFAULT NULL,
+    modified_time numeric(11) DEFAULT NULL,
+    locked_by VARCHAR(100) DEFAULT NULL,
+    locked_time numeric(11) DEFAULT NULL,
+    factoid_value text NOT NULL
+) WITHOUT OIDS;
+
+CREATE INDEX factoids_idx_fvalue ON factoids USING hash (factoid_value);
+
+ALTER TABLE ONLY factoids
+    ADD CONSTRAINT factoids_pkey_fkey PRIMARY KEY (factoid_key);
diff --git a/setup/pgsql/onjoin.sql b/setup/pgsql/onjoin.sql
new file mode 100644 (file)
index 0000000..c590d1d
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE onjoin (
+    nick VARCHAR(20) NOT NULL,
+    channel VARCHAR(30) NOT NULL,
+    message VARCHAR(255) NOT NULL,
+    modified_by VARCHAR(20) DEFAULT 'nobody' NOT NULL,
+    modified_time numeric DEFAULT 0 NOT NULL
+) WITHOUT OIDS;
+
+REVOKE ALL ON TABLE onjoin FROM PUBLIC;
+
+ALTER TABLE ONLY onjoin
+    ADD CONSTRAINT onjoin_pkey PRIMARY KEY (nick, channel);
diff --git a/setup/pgsql/rootwarn.sql b/setup/pgsql/rootwarn.sql
new file mode 100644 (file)
index 0000000..41260b7
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE rootwarn (
+    nick VARCHAR(20) NOT NULL,
+    attempt numeric,
+    "time" numeric NOT NULL,
+    host VARCHAR(80) NOT NULL,
+    channel VARCHAR(30) NOT NULL
+) WITHOUT OIDS;
+
+REVOKE ALL ON TABLE rootwarn FROM PUBLIC;
+
+ALTER TABLE ONLY rootwarn
+    ADD CONSTRAINT rootwarn_pkey PRIMARY KEY (nick);
diff --git a/setup/pgsql/seen.sql b/setup/pgsql/seen.sql
new file mode 100644 (file)
index 0000000..d90a6f6
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE seen (
+    nick VARCHAR(20) NOT NULL,
+    "time" numeric NOT NULL,
+    channel VARCHAR(30) NOT NULL,
+    host VARCHAR(80) NOT NULL,
+    message text NOT NULL,
+) WITHOUT OIDS;
+
+REVOKE ALL ON TABLE seen FROM PUBLIC;
+
+ALTER TABLE ONLY seen
+    ADD CONSTRAINT seen_pkey PRIMARY KEY (nick);
diff --git a/setup/pgsql/stats.sql b/setup/pgsql/stats.sql
new file mode 100644 (file)
index 0000000..1ecd66f
--- /dev/null
@@ -0,0 +1,12 @@
+CREATE TABLE stats (
+    nick VARCHAR(20) NOT NULL,
+    "type" VARCHAR(8) NOT NULL,
+    channel VARCHAR(30) DEFAULT 'PRIVATE' NOT NULL,
+    "time" numeric DEFAULT 0 NOT NULL,
+    counter numeric DEFAULT 0
+) WITHOUT OIDS;
+
+REVOKE ALL ON TABLE stats FROM PUBLIC;
+
+ALTER TABLE ONLY stats
+    ADD CONSTRAINT stats_pkey PRIMARY KEY (nick, "type", channel);
diff --git a/setup/rootwarn.sql b/setup/rootwarn.sql
deleted file mode 100644 (file)
index afcee2c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CREATE TABLE rootwarn (
- nick VARCHAR(20) NOT NULL,
- attempt SMALLINT UNSIGNED,
- time INT NOT NULL,
- host VARCHAR(80) NOT NULL,
- channel VARCHAR(20) NOT NULL,
- PRIMARY KEY (nick)
-);
diff --git a/setup/seen.sql b/setup/seen.sql
deleted file mode 100644 (file)
index d920f79..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CREATE TABLE seen (
- nick VARCHAR(20) NOT NULL,
- time INT NOT NULL,
- channel VARCHAR(20) NOT NULL,
- host VARCHAR(80) NOT NULL,
- message TINYTEXT NOT NULL,
- PRIMARY KEY (nick,channel)
-);
index 4977b02df93b064e695db99a29b40e5fb88eeb0a..c9562aebdddd78b156671b58db35ae6c3d2177ab 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
 #!/usr/bin/perl
-# setup_tables: setup MYSQL/PGSQL side of things for blootbot.
+# setup_tables: setup MYSQL/PGSQL side of things for infobot.
 # written by the xk.
 ###
 
 # written by the xk.
 ###
 
@@ -11,8 +11,8 @@ require "src/CLI/Support.pl";
 
 $bot_src_dir = "src/";
 
 
 $bot_src_dir = "src/";
 
-# read param stuff from blootbot.config.
-&loadConfig("files/blootbot.config");
+# read param stuff from infobot.config.
+&loadConfig("files/infobot.config");
 
 &loadDBModules();
 my $dbname = $param{'DBName'};
 
 &loadDBModules();
 my $dbname = $param{'DBName'};
@@ -95,3 +95,5 @@ if ($param{'DBType'} =~ /mysql/i) {
 &status("Done.");
 
 &sqlCloseDB();
 &status("Done.");
 
 &sqlCloseDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/setup/sqlite/botmail.sql b/setup/sqlite/botmail.sql
new file mode 100644 (file)
index 0000000..2789338
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE botmail (
+ srcwho VARCHAR(20) NOT NULL,
+ dstwho VARCHAR(20) NOT NULL,
+ srcuh VARCHAR(80) NOT NULL,
+ time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
+ msg TEXT NOT NULL,
+ PRIMARY KEY (srcwho,dstwho)
+);
diff --git a/setup/sqlite/factoids.sql b/setup/sqlite/factoids.sql
new file mode 100644 (file)
index 0000000..dc3f595
--- /dev/null
@@ -0,0 +1,14 @@
+CREATE TABLE factoids (
+ factoid_key VARCHAR(64) NOT NULL,
+ requested_by VARCHAR(100) DEFAULT NULL,
+ requested_time INT DEFAULT NULL,
+ requested_count SMALLINT UNSIGNED NOT NULL DEFAULT '0',
+ created_by VARCHAR(100) DEFAULT NULL,
+ created_time INT DEFAULT NULL,
+ modified_by VARCHAR(100) DEFAULT NULL,
+ modified_time INT DEFAULT NULL,
+ locked_by VARCHAR(100) DEFAULT NULL,
+ locked_time INT DEFAULT NULL,
+ factoid_value TEXT NOT NULL,
+ PRIMARY KEY (factoid_key)
+);
diff --git a/setup/sqlite/onjoin.sql b/setup/sqlite/onjoin.sql
new file mode 100644 (file)
index 0000000..d3eb6d5
--- /dev/null
@@ -0,0 +1,14 @@
+CREATE TABLE onjoin (
+       nick VARCHAR(20) NOT NULL,
+       channel VARCHAR(30) NOT NULL,
+       message VARCHAR(255) NOT NULL,
+       modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody',
+       modified_time INT NOT NULL DEFAULT '0',
+       PRIMARY KEY (nick, channel)
+);
+
+-- v.2 -> v.3
+-- ALTER TABLE onjoin ADD COLUMN modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody';
+-- ALTER TABLE onjoin ADD COLUMN modified_time INT NOT NULL DEFAULT '0';
+-- ** the following doesn't work for sqlite **
+-- ALTER TABLE onjoin ADD PRIMARY KEY (nick, channel);
diff --git a/setup/sqlite/rootwarn.sql b/setup/sqlite/rootwarn.sql
new file mode 100644 (file)
index 0000000..d3ea912
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE rootwarn (
+ nick VARCHAR(20) NOT NULL,
+ attempt SMALLINT UNSIGNED,
+ time INT NOT NULL,
+ host VARCHAR(80) NOT NULL,
+ channel VARCHAR(30) NOT NULL,
+ PRIMARY KEY (nick)
+);
diff --git a/setup/sqlite/seen.sql b/setup/sqlite/seen.sql
new file mode 100644 (file)
index 0000000..7892d76
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE seen (
+ nick VARCHAR(20) NOT NULL,
+ time INT NOT NULL,
+ channel VARCHAR(30) NOT NULL,
+ host VARCHAR(80) NOT NULL,
+ message TINYTEXT NOT NULL,
+ PRIMARY KEY (nick)
+);
diff --git a/setup/sqlite/stats.sql b/setup/sqlite/stats.sql
new file mode 100644 (file)
index 0000000..d738dc0
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE stats (
+ nick VARCHAR(20) NOT NULL,
+ type VARCHAR(8) NOT NULL,
+ channel VARCHAR(30) NOT NULL DEFAULT "PRIVATE",
+ time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
+ counter SMALLINT UNSIGNED DEFAULT '0',
+ PRIMARY KEY (nick,type,channel)
+);
diff --git a/setup/sqlite2/botmail.sql b/setup/sqlite2/botmail.sql
new file mode 100644 (file)
index 0000000..2789338
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE botmail (
+ srcwho VARCHAR(20) NOT NULL,
+ dstwho VARCHAR(20) NOT NULL,
+ srcuh VARCHAR(80) NOT NULL,
+ time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
+ msg TEXT NOT NULL,
+ PRIMARY KEY (srcwho,dstwho)
+);
diff --git a/setup/sqlite2/factoids.sql b/setup/sqlite2/factoids.sql
new file mode 100644 (file)
index 0000000..dc3f595
--- /dev/null
@@ -0,0 +1,14 @@
+CREATE TABLE factoids (
+ factoid_key VARCHAR(64) NOT NULL,
+ requested_by VARCHAR(100) DEFAULT NULL,
+ requested_time INT DEFAULT NULL,
+ requested_count SMALLINT UNSIGNED NOT NULL DEFAULT '0',
+ created_by VARCHAR(100) DEFAULT NULL,
+ created_time INT DEFAULT NULL,
+ modified_by VARCHAR(100) DEFAULT NULL,
+ modified_time INT DEFAULT NULL,
+ locked_by VARCHAR(100) DEFAULT NULL,
+ locked_time INT DEFAULT NULL,
+ factoid_value TEXT NOT NULL,
+ PRIMARY KEY (factoid_key)
+);
diff --git a/setup/sqlite2/onjoin.sql b/setup/sqlite2/onjoin.sql
new file mode 100644 (file)
index 0000000..d3eb6d5
--- /dev/null
@@ -0,0 +1,14 @@
+CREATE TABLE onjoin (
+       nick VARCHAR(20) NOT NULL,
+       channel VARCHAR(30) NOT NULL,
+       message VARCHAR(255) NOT NULL,
+       modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody',
+       modified_time INT NOT NULL DEFAULT '0',
+       PRIMARY KEY (nick, channel)
+);
+
+-- v.2 -> v.3
+-- ALTER TABLE onjoin ADD COLUMN modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody';
+-- ALTER TABLE onjoin ADD COLUMN modified_time INT NOT NULL DEFAULT '0';
+-- ** the following doesn't work for sqlite **
+-- ALTER TABLE onjoin ADD PRIMARY KEY (nick, channel);
diff --git a/setup/sqlite2/rootwarn.sql b/setup/sqlite2/rootwarn.sql
new file mode 100644 (file)
index 0000000..d3ea912
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE rootwarn (
+ nick VARCHAR(20) NOT NULL,
+ attempt SMALLINT UNSIGNED,
+ time INT NOT NULL,
+ host VARCHAR(80) NOT NULL,
+ channel VARCHAR(30) NOT NULL,
+ PRIMARY KEY (nick)
+);
diff --git a/setup/sqlite2/seen.sql b/setup/sqlite2/seen.sql
new file mode 100644 (file)
index 0000000..75c7639
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE seen (
+ nick VARCHAR(20) NOT NULL,
+ time INT NOT NULL,
+ channel VARCHAR(30) NOT NULL,
+ host VARCHAR(80) NOT NULL,
+ message TINYTEXT NOT NULL,
+ PRIMARY KEY(nick)
+);
diff --git a/setup/sqlite2/stats.sql b/setup/sqlite2/stats.sql
new file mode 100644 (file)
index 0000000..d738dc0
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE stats (
+ nick VARCHAR(20) NOT NULL,
+ type VARCHAR(8) NOT NULL,
+ channel VARCHAR(30) NOT NULL DEFAULT "PRIVATE",
+ time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
+ counter SMALLINT UNSIGNED DEFAULT '0',
+ PRIMARY KEY (nick,type,channel)
+);
diff --git a/setup/stats.sql b/setup/stats.sql
deleted file mode 100644 (file)
index 97f773c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CREATE TABLE stats (
- nick VARCHAR(20) NOT NULL,
- type VARCHAR(8) NOT NULL,
- channel VARCHAR(16) NOT NULL DEFAULT "PRIVATE",
- time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()',
- counter SMALLINT UNSIGNED DEFAULT '0',
- PRIMARY KEY (nick,type,channel)
-);
diff --git a/setup/uptime.sql b/setup/uptime.sql
deleted file mode 100644 (file)
index 373902a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-CREATE TABLE uptime (
- uptime INT UNSIGNED DEFAULT '0', # start.
- endtime INT UNSIGNED DEFAULT '0', # end.
- string VARCHAR(128) NOT NULL,
- PRIMARY KEY (uptime)
-);
index d3c5a3d3407aafef6e0eef1b3d541e345c493c0d..33034a3f2481d5d92725396ffa227c9d7b82aec4 100644 (file)
@@ -16,17 +16,17 @@ sub cliloop {
 
     $nuh = "local!local\@local";
     $uh  = "local\@local";
 
     $nuh = "local!local\@local";
     $uh  = "local\@local";
-    $who = "local";
-    $orig{who} = "local";
+    $who = 'local';
+    $orig{who} = 'local';
     $ident = $param{'ircUser'};
     $chan = $talkchannel = "_local";
     $addressed = 1;
     $msgType = 'private';
     $ident = $param{'ircUser'};
     $chan = $talkchannel = "_local";
     $addressed = 1;
     $msgType = 'private';
-    $host = "local";
+    $host = 'local';
 
     # install libterm-readline-gnu-perl to get history support
     use Term::ReadLine;
 
     # install libterm-readline-gnu-perl to get history support
     use Term::ReadLine;
-    my $term = new Term::ReadLine 'blootbot';
+    my $term = new Term::ReadLine 'infobot';
     my $prompt = "$who> ";
     #$OUT = $term->OUT || STDOUT;
     while ( defined ($_ = $term->readline($prompt)) ) {
     my $prompt = "$who> ";
     #$OUT = $term->OUT || STDOUT;
     while ( defined ($_ = $term->readline($prompt)) ) {
@@ -47,7 +47,7 @@ sub msg {
     }
 
     if (!defined $msg) {
     }
 
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &WARN("msg: msg == $msg.");
        return;
     }
        &WARN("msg: msg == $msg.");
        return;
     }
@@ -101,3 +101,5 @@ sub performAddressedReply {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ef2e0146875b5500ecccb784668c4c63544d3f67..4a3fb572dcf9ecd4f4d16f62d678d1d18ddb46aa 100644 (file)
@@ -331,7 +331,7 @@ sub seen {
     &seenFlush();      # very evil hack. oh well, better safe than sorry.
 
     # TODO: convert to &sqlSelectRowHash();
     &seenFlush();      # very evil hack. oh well, better safe than sorry.
 
     # TODO: convert to &sqlSelectRowHash();
-    my $select = 'nick,time,channel,host,message,messagecount';
+    my $select = 'nick,time,channel,host,message';
     if ($person eq 'random') {
        @seen = &randKey('seen', $select);
     } else {
     if ($person eq 'random') {
        @seen = &randKey('seen', $select);
     } else {
@@ -363,7 +363,7 @@ sub seen {
 
        if (&IsChanConf('seenStats') > 0) {
            my $i;
 
        if (&IsChanConf('seenStats') > 0) {
            my $i;
-           $i = $seen[6] || $userstats{lc $seen[0]}{'Count'};
+           $i = $userstats{lc $seen[0]}{'Count'};
            $reply .= ". Has said a total of \002$i\002 messages" if (defined $i);
            $i = $userstats{lc $seen[0]}{'Time'};
            $reply .= '. Is idling for '.&Time2String(time() - $i) if (defined $i);
            $reply .= ". Has said a total of \002$i\002 messages" if (defined $i);
            $i = $userstats{lc $seen[0]}{'Time'};
            $reply .= '. Is idling for '.&Time2String(time() - $i) if (defined $i);
@@ -453,7 +453,7 @@ sub convert {
        return;
     }
 
        return;
     }
 
-    &NewUnits::convertUnits($from, $to);
+    &Units::convertUnits($from, $to);
 
     return;
 }
 
     return;
 }
@@ -481,7 +481,7 @@ sub lart {
        $for    = $2;
     }
 
        $for    = $2;
     }
 
-    my $line = &getRandomLineFromFile($bot_data_dir. '/blootbot.lart');
+    my $line = &getRandomLineFromFile($bot_data_dir. '/infobot.lart');
     if (defined $line) {
        if ($target =~ /^(me|you|itself|\Q$mynick\E)$/i) {
            $line =~ s/WHO/$who/g;
     if (defined $line) {
        if ($target =~ /^(me|you|itself|\Q$mynick\E)$/i) {
            $line =~ s/WHO/$who/g;
@@ -644,11 +644,6 @@ sub do_text_counters {
        $chan = $1;
     }
 
        $chan = $1;
     }
 
-    if ($message =~ /^_stats(\s+(\S+))$/i) {
-       &textstats_main($2);
-       return 1;
-    }
-
     my ($type,$arg);
     if ($message =~ /^($z)stats(\s+(\S+))?$/i) {
        $type = $1;
     my ($type,$arg);
     if ($message =~ /^($z)stats(\s+(\S+))?$/i) {
        $type = $1;
@@ -657,27 +652,21 @@ sub do_text_counters {
        return 0;
     }
 
        return 0;
     }
 
-    # even more uglier with channel/time arguments.
-    my $c      = $chan;
-#   my $c      = $chan || 'PRIVATE';
-    my $where  = 'type='.&sqlQuote($type);
-    if (defined $c) {
-       &DEBUG("c => $c");
-       $where  .= ' AND channel='.&sqlQuote($c) if (defined $c);
-    } else {
-       &DEBUG('not using chan arg');
-    }
+    my $c      = $chan || 'PRIVATE';
 
 
-    my $sum = (&sqlRawReturn('SELECT SUM(counter) FROM stats'
-                       .' WHERE '.$where ))[0];
+    # Define various types of stats in one place.
+    # Note: sqlSelectColHash has built in sqlQuote
+    my $where_chan_type  = { channel => $c, type => $type };
+    my $where_chan_type_nick = { channel => $c, type => $type, nick => $arg};
+
+    my $sum = (&sqlSelect('stats', 'SUM(counter)', $where_chan_type))[0];
 
     if (!defined $arg or $arg =~ /^\s*$/) {
 
     if (!defined $arg or $arg =~ /^\s*$/) {
-       # this is way ugly.
 
 
-       # TODO: convert $where to hash
+       # get top 3 stats of $type in $chan
        my %hash = &sqlSelectColHash('stats', 'nick,counter',
        my %hash = &sqlSelectColHash('stats', 'nick,counter',
-                       { },
-                       $where.' ORDER BY counter DESC LIMIT 3', 1
+                       $where_chan_type,
+                       'ORDER BY counter DESC LIMIT 3', 1
        );
        my $i;
        my @top;
        );
        my $i;
        my @top;
@@ -702,34 +691,32 @@ sub do_text_counters {
            &performStrictReply("zero counter for \037$type\037.");
        }
     } else {
            &performStrictReply("zero counter for \037$type\037.");
        }
     } else {
-       # TODO: convert $where to hash and use a sqlSelect
-       my $x = (&sqlRawReturn('SELECT SUM(counter) FROM stats'.
-                       " WHERE $where AND nick=".&sqlQuote($arg) ))[0];
+       my $x = (&sqlSelect('stats', 'SUM(counter)', $where_chan_type_nick))[0];
 
 
-       if (!defined $x) {      # !defined.
+       if (!defined $x) {      # If no stats were found
            &performStrictReply("$arg has not said $type yet.");
            return 1;
        }
 
            &performStrictReply("$arg has not said $type yet.");
            return 1;
        }
 
-       # defined.
-       # TODO: convert $where to hash
-       my @array = &sqlSelect('stats', 'nick', undef,
-                       $where.' ORDER BY counter', 1
+       # Get list of all nicks for channel $c and $type
+       my @array = &sqlSelectColArray('stats', 'nick',
+               $where_chan_type,
+               'ORDER BY counter DESC'
        );
        );
-       my $good = 0;
-       my $i = 0;
-       for ($i=0; $i<scalar @array; $i++) {
-           next unless ($array[0] =~ /^\Q$who\E$/);
-           $good++;
+
+       my $total = scalar(@array);
+       my $rank;
+       # Find position of nick $arg in the list
+       for (my $i=0; $i < $total; $i++) {
+           next unless ($array[$i] =~ /^\Q$arg\E$/);
+           $rank = $i + 1;
            last;
        }
            last;
        }
-       $i++;
 
 
-       my $total = scalar(@array);
-       my $xtra = '';
-       if ($total and $good) {
-           my $pct = sprintf("%.01f", 100*(1+$total-$i)/$total);
-           $xtra = ", ranked $i\002/\002$total (percentile: \002$pct\002 %)";
+       my $xtra;
+       if ($total and $rank) {
+           my $pct = sprintf("%.01f", 100*($rank)/$total);
+           $xtra = ", ranked $rank\002/\002$total (percentile: \002$pct\002 %)";
        }
 
        my $pct1 = sprintf("%.01f", 100*$x/$sum);
        }
 
        my $pct1 = sprintf("%.01f", 100*$x/$sum);
@@ -739,101 +726,6 @@ sub do_text_counters {
     return 1;
 }
 
     return 1;
 }
 
-sub textstats_main {
-    my($arg) = @_;
-
-    # even more uglier with channel/time arguments.
-    my $c      = $chan;
-#    my $c     = $chan || 'PRIVATE';
-    &DEBUG('not using chan arg') if (!defined $c);
-
-    # example of converting from RawReturn to sqlSelect.
-    my $where_href = (defined $c) ? { channel => $c } : '';
-    my $sum = &sqlSelect('stats', 'SUM(counter)', $where_href);
-
-    if (!defined $arg or $arg =~ /^\s*$/) {
-       # this is way ugly.
-       &DEBUG('_stats: !arg');
-
-       my %hash = &sqlSelectColHash('stats', 'nick,counter',
-               $where_href,
-               ' ORDER BY counter DESC LIMIT 3', 1
-       );
-       my $i;
-       my @top;
-
-       # unfortunately we have to sort it again!
-       my $tp = 0;
-       foreach $i (sort { $b <=> $a } keys %hash) {
-           foreach (keys %{ $hash{$i} }) {
-               my $p   = sprintf("%.01f", 100*$i/$sum);
-               $tp     += $p;
-               push(@top, "\002$_\002 -- $i ($p%)");
-           }
-       }
-
-       $topstr = '';
-       if (scalar @top) {
-           $topstr = '.  Top '.scalar(@top).': '.join(', ', @top);
-       }
-
-       if (defined $sum) {
-           &performStrictReply("total count of \037$type\037 on \002$c\002: $sum$topstr");
-       } else {
-           &performStrictReply("zero counter for \037$type\037.");
-       }
-
-       return;
-    }
-
-    # TODO: add nick to where_href
-    my %hash = &sqlSelectColHash('stats', 'type,counter',
-               $where_href, ' AND nick='.&sqlQuote($arg)
-    );
-
-    # this is totally messed up... needs to be fixed... and cleaned up.
-    my $total;
-    my $good;
-    my $ii;
-    my $x;
-
-    foreach (keys %hash) {
-       &DEBUG("_stats: hash{$_} => $hash{$_}");
-       # ranking.
-       # TODO: convert $where to hash
-       my $where = '';
-       my @array = &sqlSelect('stats', 'nick', undef, $where.' ORDER BY counter', 1);
-       $good = 0;
-       $ii = 0;
-       for(my $i=0; $i<scalar @array; $i++) {
-           next unless ($array[0] =~ /^\Q$who\E$/);
-           $good++;
-           last;
-       }
-       $ii++;
-
-       $total = scalar(@array);
-       &DEBUG("   i => $i, good => $good, total => $total");
-       $x .= ' '.$total.'blah blah';
-    }
-
-#    return;
-
-    if (!defined $x) { # !defined.
-       &performStrictReply("$arg has not said $type yet.");
-       return;
-    }
-
-    my $xtra = '';
-    if ($total and $good) {
-       my $pct = sprintf("%.01f", 100*(1+$total-$ii)/$total);
-       $xtra = ", ranked $ii\002/\002$total (percentile: \002$pct\002 %)";
-    }
-
-    my $pct1 = sprintf("%.01f", 100*$x/$sum);
-    &performStrictReply("\002$arg\002 has said \037$type\037 \002$x\002 times (\002$pct1\002 %)$xtra");
-}
-
 sub nullski {
     my ($arg) = @_;
     return unless (defined $arg);
 sub nullski {
     my ($arg) = @_;
     return unless (defined $arg);
@@ -852,7 +744,7 @@ sub nullski {
 &addCmdHook('bzfquery', ('CODEREF' => 'BZFlag::query', 'Identifier' => 'BZFlag', 'Cmdstats' => 'BZFlag', 'Forker' => 1, 'Module' => 'BZFlag') );
 &addCmdHook('chan(stats|info)', ('CODEREF' => 'chaninfo', ) );
 &addCmdHook('cmd(stats|info)', ('CODEREF' => 'cmdstats', ) );
 &addCmdHook('bzfquery', ('CODEREF' => 'BZFlag::query', 'Identifier' => 'BZFlag', 'Cmdstats' => 'BZFlag', 'Forker' => 1, 'Module' => 'BZFlag') );
 &addCmdHook('chan(stats|info)', ('CODEREF' => 'chaninfo', ) );
 &addCmdHook('cmd(stats|info)', ('CODEREF' => 'cmdstats', ) );
-&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'NewUnits', 'Help' => 'convert') );
+&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'Units', 'Help' => 'convert') );
 &addCmdHook('(cookie|random)', ('CODEREF' => 'cookie', 'Forker' => 1, 'Identifier' => 'Factoids') );
 &addCmdHook('countdown', ('CODEREF' => 'countdown', 'Module' => 'countdown', 'Identifier' => 'countdown', 'Cmdstats' => 'countdown') );
 &addCmdHook('countrystats', ('CODEREF' => 'countryStats') );
 &addCmdHook('(cookie|random)', ('CODEREF' => 'cookie', 'Forker' => 1, 'Identifier' => 'Factoids') );
 &addCmdHook('countdown', ('CODEREF' => 'countdown', 'Module' => 'countdown', 'Identifier' => 'countdown', 'Cmdstats' => 'countdown') );
 &addCmdHook('countrystats', ('CODEREF' => 'countryStats') );
@@ -871,6 +763,7 @@ sub nullski {
 &addCmdHook('factinfo', ('CODEREF' => 'factinfo', 'Cmdstats' => 'Factoid Info', Module => 'Factoids', ) );
 &addCmdHook('factstats?', ('CODEREF' => 'factstats', 'Cmdstats' => 'Factoid Stats', Help => 'factstats', Forker => 1, 'Identifier' => 'Factoids', ) );
 &addCmdHook('help', ('CODEREF' => 'help', 'Cmdstats' => 'Help', ) );
 &addCmdHook('factinfo', ('CODEREF' => 'factinfo', 'Cmdstats' => 'Factoid Info', Module => 'Factoids', ) );
 &addCmdHook('factstats?', ('CODEREF' => 'factstats', 'Cmdstats' => 'Factoid Stats', Help => 'factstats', Forker => 1, 'Identifier' => 'Factoids', ) );
 &addCmdHook('help', ('CODEREF' => 'help', 'Cmdstats' => 'Help', ) );
+&addCmdHook('hex2ip', ('CODEREF' => 'hex2ip::query', 'Forker' => 1, 'Identifier' => 'hex2ip', 'Cmdstats' => 'hex2ip', 'Help' => 'hex2ip') );
 &addCmdHook('HTTPDtype', ('CODEREF' => 'HTTPDtype::HTTPDtype', 'Identifier' => 'HTTPDtype', 'Cmdstats' => 'HTTPDtype', 'Forker' => 1) );
 &addCmdHook('[ia]?spell', ('CODEREF' => 'spell::query', 'Identifier' => 'spell', 'Cmdstats' => 'spell', 'Forker' => 1, 'Help' => 'spell') );
 &addCmdHook('insult', ('CODEREF' => 'Insult::Insult', 'Forker' => 1, 'Identifier' => 'insult', 'Help' => 'insult' ) );
 &addCmdHook('HTTPDtype', ('CODEREF' => 'HTTPDtype::HTTPDtype', 'Identifier' => 'HTTPDtype', 'Cmdstats' => 'HTTPDtype', 'Forker' => 1) );
 &addCmdHook('[ia]?spell', ('CODEREF' => 'spell::query', 'Identifier' => 'spell', 'Cmdstats' => 'spell', 'Forker' => 1, 'Help' => 'spell') );
 &addCmdHook('insult', ('CODEREF' => 'Insult::Insult', 'Forker' => 1, 'Identifier' => 'insult', 'Help' => 'insult' ) );
@@ -881,7 +774,7 @@ sub nullski {
 &addCmdHook('listauth', ('CODEREF' => 'CmdListAuth', 'Identifier' => 'Search', Module => 'Factoids', 'Help' => 'listauth') );
 &addCmdHook('md5(sum)?', ('CODEREF' => 'md5::md5', 'Identifier' => 'md5', 'Cmdstats' => 'md5', 'Forker' => 1, 'Module' => 'md5') );
 &addCmdHook('metar', ('CODEREF' => 'Weather::Metar', 'Identifier' => 'Weather', 'Help' => 'weather', 'Cmdstats' => 'Weather', 'Forker' => 1) );
 &addCmdHook('listauth', ('CODEREF' => 'CmdListAuth', 'Identifier' => 'Search', Module => 'Factoids', 'Help' => 'listauth') );
 &addCmdHook('md5(sum)?', ('CODEREF' => 'md5::md5', 'Identifier' => 'md5', 'Cmdstats' => 'md5', 'Forker' => 1, 'Module' => 'md5') );
 &addCmdHook('metar', ('CODEREF' => 'Weather::Metar', 'Identifier' => 'Weather', 'Help' => 'weather', 'Cmdstats' => 'Weather', 'Forker' => 1) );
-&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News' ) );
+&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News', 'Identifier' => 'News' ) );
 &addCmdHook('(?:nick|lame)ometer(?: for)?', ('CODEREF' => 'nickometer::query', 'Identifier' => 'nickometer', 'Cmdstats' => 'nickometer', 'Forker' => 1) );
 &addCmdHook('nullski', ('CODEREF' => 'nullski', ) );
 &addCmdHook('page', ('CODEREF' => 'pager::page', 'Identifier' => 'pager', 'Cmdstats' => 'pager', 'Forker' => 1, 'Help' => 'page') );
 &addCmdHook('(?:nick|lame)ometer(?: for)?', ('CODEREF' => 'nickometer::query', 'Identifier' => 'nickometer', 'Cmdstats' => 'nickometer', 'Forker' => 1) );
 &addCmdHook('nullski', ('CODEREF' => 'nullski', ) );
 &addCmdHook('page', ('CODEREF' => 'pager::page', 'Identifier' => 'pager', 'Cmdstats' => 'pager', 'Forker' => 1, 'Help' => 'page') );
@@ -892,6 +785,7 @@ sub nullski {
 &addCmdHook('RootWarn', ('CODEREF' => 'CmdrootWarn', 'Identifier' => 'RootWarn', 'Module' => 'RootWarn') );
 &addCmdHook('OnJoin', ('CODEREF' => 'Cmdonjoin', 'Identifier' => 'OnJoin', 'Module' => 'OnJoin') );
 &addCmdHook('Rss', ('CODEREF' => 'Rss::Rss', 'Identifier' => 'Rss', 'Cmdstats' => 'Rss', 'Forker' => 1, 'Help' => 'rss') );
 &addCmdHook('RootWarn', ('CODEREF' => 'CmdrootWarn', 'Identifier' => 'RootWarn', 'Module' => 'RootWarn') );
 &addCmdHook('OnJoin', ('CODEREF' => 'Cmdonjoin', 'Identifier' => 'OnJoin', 'Module' => 'OnJoin') );
 &addCmdHook('Rss', ('CODEREF' => 'Rss::Rss', 'Identifier' => 'Rss', 'Cmdstats' => 'Rss', 'Forker' => 1, 'Help' => 'rss') );
+&addCmdHook('RSSFeeds',('CODEREF' => 'RSSFeeds::RSS', 'Identifier' => 'RSSFeeds', 'Forker' => 1, 'Help' => 'rssfeeds', 'Cmdstats' => 'RSSFeeds', 'Module' => 'RSSFeeds') );
 &addCmdHook('sched(stats|info)', ('CODEREF' => 'scheduleList', ) );
 &addCmdHook('scramble', ('CODEREF' => 'scramble::scramble', 'Identifier' => 'scramble', 'Cmdstats' => 'scramble', 'Forker' => 1, 'Module' => 'scramble') );
 &addCmdHook('seen', ('CODEREF' => 'seen', 'Identifier' => 'seen') );
 &addCmdHook('sched(stats|info)', ('CODEREF' => 'scheduleList', ) );
 &addCmdHook('scramble', ('CODEREF' => 'scramble::scramble', 'Identifier' => 'scramble', 'Cmdstats' => 'scramble', 'Forker' => 1, 'Module' => 'scramble') );
 &addCmdHook('seen', ('CODEREF' => 'seen', 'Identifier' => 'seen') );
@@ -914,3 +808,5 @@ sub nullski {
 &status('loaded '.scalar(keys %cmdhooks).' command hooks.');
 
 1;
 &status('loaded '.scalar(keys %cmdhooks).' command hooks.');
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index f4ba9c3f207fd3d489a62a3672921fa5b480e471..4bdcf99d86e2fb237794110d19488cc3987c6877 100644 (file)
@@ -20,7 +20,10 @@ use vars qw($utime_userfile $ucount_userfile $utime_chanfile $who
 #####
 
 sub readUserFile {
 #####
 
 sub readUserFile {
-    my $f = "$bot_state_dir/blootbot.users";
+    my $f = "$bot_state_dir/infobot.users";
+    if (! -e $f and -e "$bot_state_dir/blootbot.users") {
+        $f = "$bot_state_dir/blootbot.users";
+    }
 
     if (! -f $f) {
        &DEBUG("userfile not found; new fresh run detected.");
 
     if (! -f $f) {
        &DEBUG("userfile not found; new fresh run detected.");
@@ -64,7 +67,7 @@ sub readUserFile {
        if (/^--(\S+)[\s\t]+(.*)$/) {           # user: middle entry.
            my ($what,$val) = ($1,$2);
 
        if (/^--(\S+)[\s\t]+(.*)$/) {           # user: middle entry.
            my ($what,$val) = ($1,$2);
 
-           if (!defined $val or $val eq "") {
+           if (!defined $val or $val eq '') {
                &WARN("$what: val == NULL.");
                next;
            }
                &WARN("$what: val == NULL.");
                next;
            }
@@ -75,7 +78,7 @@ sub readUserFile {
            }
 
            # nice little hack.
            }
 
            # nice little hack.
-           if ($what eq "HOSTS") {
+           if ($what eq 'HOSTS') {
                $users{$nick}{$what}{$val} = 1;
            } else {
                $users{$nick}{$what} = $val;
                $users{$nick}{$what}{$val} = 1;
            } else {
                $users{$nick}{$what} = $val;
@@ -86,9 +89,9 @@ sub readUserFile {
 
        } elsif (/^::(\S+) ignore$/) {          # ignore: start entry.
            $chan       = $1;
 
        } elsif (/^::(\S+) ignore$/) {          # ignore: start entry.
            $chan       = $1;
-           $type       = "ignore";
+           $type       = 'ignore';
 
 
-       } elsif (/^- (\S+):\+(\d+):\+(\d+):(\S+):(.*)$/ and $type eq "ignore") {
+       } elsif (/^- (\S+):\+(\d+):\+(\d+):(\S+):(.*)$/ and $type eq 'ignore') {
            ### ignore: middle entry.
            my $mask = $1;
            my(@array) = ($2,$3,$4,$5);
            ### ignore: middle entry.
            my $mask = $1;
            my(@array) = ($2,$3,$4,$5);
@@ -101,9 +104,9 @@ sub readUserFile {
 
        } elsif (/^::(\S+) bans$/) {            # bans: start entry.
            $chan       = $1;
 
        } elsif (/^::(\S+) bans$/) {            # bans: start entry.
            $chan       = $1;
-           $type       = "bans";
+           $type       = 'bans';
 
 
-       } elsif (/^- (\S+):\+(\d+):\+(\d+):(\d+):(\S+):(.*)$/ and $type eq "bans") {
+       } elsif (/^- (\S+):\+(\d+):\+(\d+):(\d+):(\S+):(.*)$/ and $type eq 'bans') {
            ### bans: middle entry.
            # $btime, $atime, $count, $whoby, $reason.
            my(@array) = ($2,$3,$4,$5,$6);
            ### bans: middle entry.
            # $btime, $atime, $count, $whoby, $reason.
            my(@array) = ($2,$3,$4,$5,$6);
@@ -129,14 +132,14 @@ sub writeUserFile {
        return;
     }
 
        return;
     }
 
-    if (!open OUT,">$bot_state_dir/blootbot.users") {
-       &ERROR("Cannot write userfile ($bot_state_dir/blootbot.users): $!");
+    if (!open OUT,">$bot_state_dir/infobot.users") {
+       &ERROR("Cannot write userfile ($bot_state_dir/infobot.users): $!");
        return;
     }
 
     my $time           = scalar(gmtime);
 
        return;
     }
 
     my $time           = scalar(gmtime);
 
-    print OUT "#v1: blootbot -- $ident -- written $time\n\n";
+    print OUT "#v1: infobot -- $ident -- written $time\n\n";
 
     ### USER LIST.
     my $cusers = 0;
 
     ### USER LIST.
     my $cusers = 0;
@@ -155,7 +158,7 @@ sub writeUserFile {
            my $what    = $_;
            my $val     = $users{$user}{$_};
 
            my $what    = $_;
            my $val     = $users{$user}{$_};
 
-           if (ref($val) eq "HASH") {
+           if (ref($val) eq 'HASH') {
                foreach (sort keys %{ $users{$user}{$_} }) {
                    print OUT "--$what\t\t$_\n";
                }
                foreach (sort keys %{ $users{$user}{$_} }) {
                    print OUT "--$what\t\t$_\n";
                }
@@ -235,7 +238,10 @@ sub writeUserFile {
 #####
 
 sub readChanFile {
 #####
 
 sub readChanFile {
-    my $f = "$bot_state_dir/blootbot.chan";
+    my $f = "$bot_state_dir/infobot.chan";
+    if (-e "$bot_state_dir/infobot.chan" and -e "$bot_state_dir/blootbot.chan") {
+        $f = "$bot_state_dir/blootbot.chan";
+    }
     if ( -f $f and -f "$f~") {
        my $s1 = -s $f;
        my $s2 = -s "$f~";
     if ( -f $f and -f "$f~") {
        my $s1 = -s $f;
        my $s2 = -s "$f~";
@@ -304,13 +310,13 @@ sub writeChanFile {
        return;
     }
 
        return;
     }
 
-    if (!open OUT,">$bot_state_dir/blootbot.chan") {
-       &ERROR("Cannot write chanfile ($bot_state_dir/blootbot.chan): $!");
+    if (!open OUT,">$bot_state_dir/infobot.chan") {
+       &ERROR("Cannot write chanfile ($bot_state_dir/infobot.chan): $!");
        return;
     }
 
     my $time           = scalar(gmtime);
        return;
     }
 
     my $time           = scalar(gmtime);
-    print OUT "#v1: blootbot -- $ident -- written $time\n\n";
+    print OUT "#v1: infobot -- $ident -- written $time\n\n";
 
     if ($flag_quit) {
 
 
     if ($flag_quit) {
 
@@ -407,7 +413,7 @@ sub writeChanFile {
 # TODO: return all flags for opers
 sub IsFlag {
     my $flags = shift;
 # TODO: return all flags for opers
 sub IsFlag {
     my $flags = shift;
-    my ($ret, $f, $o) = "";
+    my ($ret, $f, $o) = '';
 
     &verifyUser($who, $nuh);
 
 
     &verifyUser($who, $nuh);
 
@@ -432,7 +438,7 @@ sub verifyUser {
        return $userHandle;
     }
 
        return $userHandle;
     }
 
-    $userHandle = "";
+    $userHandle = '';
 
     foreach $user (keys %users) {
        next if ($user eq "_default");
 
     foreach $user (keys %users) {
        next if ($user eq "_default");
@@ -453,7 +459,7 @@ sub verifyUser {
            last;
        }
 
            last;
        }
 
-       last if ($userHandle ne "");
+       last if ($userHandle ne '');
 
        if ($user =~ /^\Q$nick\E$/i and !exists $cache{VUSERWARN}{$user}) {
            &status("vU: nick matched but host is not in list ($lnuh).");
 
        if ($user =~ /^\Q$nick\E$/i and !exists $cache{VUSERWARN}{$user}) {
            &status("vU: nick matched but host is not in list ($lnuh).");
@@ -472,10 +478,10 @@ sub verifyUser {
 sub ckpasswd {
     # returns true if arg1 encrypts to arg2
     my ($plain, $encrypted) = @_;
 sub ckpasswd {
     # returns true if arg1 encrypts to arg2
     my ($plain, $encrypted) = @_;
-    if ($encrypted eq "") {
+    if ($encrypted eq '') {
        ($plain, $encrypted) = split(/\s+/, $plain, 2);
     }
        ($plain, $encrypted) = split(/\s+/, $plain, 2);
     }
-    return 0 unless ($plain ne "" and $encrypted ne "");
+    return 0 unless ($plain ne '' and $encrypted ne '');
 
     # MD5 // DES. Bobby Billingsley++.
     my $salt;
 
     # MD5 // DES. Bobby Billingsley++.
     my $salt;
@@ -508,8 +514,8 @@ sub hasFlag {
 sub ignoreAdd {
     my($mask,$chan,$expire,$comment) = @_;
 
 sub ignoreAdd {
     my($mask,$chan,$expire,$comment) = @_;
 
-    $chan      ||= "*";        # global if undefined.
-    $comment   ||= "";         # optional.
+    $chan      ||= '*';        # global if undefined.
+    $comment   ||= '';         # optional.
     $expire    ||= 0;          # permament.
     my $count  ||= 0;
 
     $expire    ||= 0;          # permament.
     my $count  ||= 0;
 
@@ -603,7 +609,7 @@ sub userDel {
 sub banAdd {
     my($mask,$chan,$expire,$reason) = @_;
 
 sub banAdd {
     my($mask,$chan,$expire,$reason) = @_;
 
-    $chan      ||= "*";
+    $chan      ||= '*';
     $expire    ||= 0;
 
     if ($expire > 0) {
     $expire    ||= 0;
 
     if ($expire > 0) {
@@ -615,7 +621,7 @@ sub banAdd {
                exists $bans{'*'}{$mask});
     $bans{$chan}{$mask} = [$expire, time(), 0, $who, $reason];
 
                exists $bans{'*'}{$mask});
     $bans{$chan}{$mask} = [$expire, time(), 0, $who, $reason];
 
-    my @chans  = ($chan eq "*") ? keys %channels : $chan;
+    my @chans  = ($chan eq '*') ? keys %channels : $chan;
     my $m      = $mask;
     $m         =~ s/\?/\\./g;
     $m         =~ s/\*/\\S*/g;
     my $m      = $mask;
     $m         =~ s/\?/\\./g;
     $m         =~ s/\*/\\S*/g;
@@ -722,7 +728,7 @@ sub chanSet {
        my $was         = $chanconf{$chan}{$what};
 
        if ($set) {                     # add/set.
        my $was         = $chanconf{$chan}{$what};
 
        if ($set) {                     # add/set.
-           if (defined $was and $was eq "1") {
+           if (defined $was and $was eq '1') {
                &performStrictReply("setting $what for $chan already 1.");
                return;
            }
                &performStrictReply("setting $what for $chan already 1.");
                return;
            }
@@ -739,14 +745,16 @@ sub chanSet {
        }
 
        # alter for cosmetic (print out) reasons only.
        }
 
        # alter for cosmetic (print out) reasons only.
-       $was    = (defined $was) ? "; was '$was'" : "";
+       $was    = (defined $was) ? "; was '$was'" : '';
 
 
-       if ($val eq "0") {
+       if ($val eq '0') {
            &performStrictReply("Unsetting $what for $chan$was.");
            delete $chanconf{$chan}{$what};
            &performStrictReply("Unsetting $what for $chan$was.");
            delete $chanconf{$chan}{$what};
+           delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
        } else {
            &performStrictReply("Setting $what for $chan to '$val'$was.");
            $chanconf{$chan}{$what}     = $val;
        } else {
            &performStrictReply("Setting $what for $chan to '$val'$was.");
            $chanconf{$chan}{$what}     = $val;
+           delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
        }
 
        $update++;
        }
 
        $update++;
@@ -759,10 +767,11 @@ sub chanSet {
            &performStrictReply("setting $what for $chan already '$val'.");
            return;
        }
            &performStrictReply("setting $what for $chan already '$val'.");
            return;
        }
-       $was    = ($was) ? "; was '$was'" : "";
+       $was    = ($was) ? "; was '$was'" : '';
        &performStrictReply("Setting $what for $chan to '$val'$was.");
 
        $chanconf{$chan}{$what} = $val;
        &performStrictReply("Setting $what for $chan to '$val'$was.");
 
        $chanconf{$chan}{$what} = $val;
+       delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
 
        $update++;
 
 
        $update++;
 
@@ -826,19 +835,22 @@ sub rehashConfVars {
 
 my @regFlagsUser = (
        # possible chars to include in FLAG
 
 my @regFlagsUser = (
        # possible chars to include in FLAG
-       "A",    # bot administration over /msg
+       'A',    # bot administration over /msg
                        # default is only via DCC CHAT
                        # default is only via DCC CHAT
-       "O",    # dynamic ops (as on channel). (automatic +o)
-       "T",    # add topics.
-       "a",    # ask/request factoid.
-       "m",    # modify factoid. (includes renaming)
-       "n",    # bot owner, can "reload"
-       "o",    # master of bot (automatic +amrt)
+       'O',    # dynamic ops (as on channel). (automatic +o)
+       'T',    # add topics.
+       'a',    # ask/request factoid.
+       'm',    # modify factoid. (includes renaming)
+       'n',    # bot owner, can 'reload'
+       'o',    # master of bot (automatic +amrt)
                        # can search on factoid strings shorter than 2 chars
                        # can tell bot to join new channels
                        # can [un]lock factoids
                        # can search on factoid strings shorter than 2 chars
                        # can tell bot to join new channels
                        # can [un]lock factoids
-       "r",    # remove factoid.
-       "t",    # teach/add factoid.
+       'r',    # remove factoid.
+       't',    # teach/add factoid.
+       's',    # Bypass +silent on channels
 );
 
 1;
 );
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index e33685c91f712214a267652cb45f453f00a8f1a0..4898008d810320038b6f0f9c973e9f02c7a3701e 100644 (file)
@@ -18,7 +18,7 @@ sub validFactoid {
 
     for (lc $lhs) {
        # allow the following only if they have been made on purpose.
 
     for (lc $lhs) {
        # allow the following only if they have been made on purpose.
-       if ($rhs ne "" and $rhs !~ /^</) {
+       if ($rhs ne '' and $rhs !~ /^</) {
            / \Q$ident$/i and last;     # someone said i'm something.
            /^i('m)? / and last;
            /^(it|that|there|what)('s)?(\s+|$)/ and last;
            / \Q$ident$/i and last;     # someone said i'm something.
            /^i('m)? / and last;
            /^(it|that|there|what)('s)?(\s+|$)/ and last;
@@ -79,7 +79,7 @@ sub validFactoid {
        /\\\%/ and last;
        /\\\_/ and last;
 
        /\\\%/ and last;
        /\\\_/ and last;
 
-       # weird/special stuff. also old blootbot or stock infobot bugs.
+       # weird/special stuff. also old infobot bugs.
        $rhs =~ /( \Q$ident\E's|\Q$ident\E's )/i and last; # ownership.
 
        # duplication.
        $rhs =~ /( \Q$ident\E's|\Q$ident\E's )/i and last; # ownership.
 
        # duplication.
@@ -123,9 +123,9 @@ sub FactoidStuff {
            if ($param{'acceptUrl'} !~ /REQUIRE/ or $rhs =~ /(http|ftp|mailto|telnet|file):/) {
                &msg($target, "$who knew: $lhs $mhs $rhs");
 
            if ($param{'acceptUrl'} !~ /REQUIRE/ or $rhs =~ /(http|ftp|mailto|telnet|file):/) {
                &msg($target, "$who knew: $lhs $mhs $rhs");
 
-               # "are" hack :)
-               $rhs = "<REPLY> are" if ($mhs eq "are");
-               &setFactInfo($lhs, "factoid_value", $rhs);
+               # 'are' hack :)
+               $rhs = "<REPLY> are" if ($mhs eq 'are');
+               &setFactInfo($lhs, 'factoid_value', $rhs);
            }
 
            return 'INFOBOT REPLY';
            }
 
            return 'INFOBOT REPLY';
@@ -140,8 +140,8 @@ sub FactoidStuff {
        return 'forget: no addr' unless ($addressed);
 
        my $faqtoid = $message;
        return 'forget: no addr' unless ($addressed);
 
        my $faqtoid = $message;
-       if ($faqtoid eq "") {
-           &help("forget");
+       if ($faqtoid eq '') {
+           &help('forget');
            return;
        }
 
            return;
        }
 
@@ -155,22 +155,22 @@ sub FactoidStuff {
        }
 
        # TODO: squeeze 3 getFactInfo calls into one?
        }
 
        # TODO: squeeze 3 getFactInfo calls into one?
-       my $author      = &getFactInfo($faqtoid, "created_by");
-       my $count       = &getFactInfo($faqtoid, "requested_count") || 0;
+       my $author      = &getFactInfo($faqtoid, 'created_by');
+       my $count       = &getFactInfo($faqtoid, 'requested_count') || 0;
        # don't delete if requested $limit times
        my $limit       = &getChanConfDefault('factoidPreventForgetLimit', 100, $chan);
        # don't delete if older than $limitage seconds (modified by requests below)
        my $limitage    = &getChanConfDefault('factoidPreventForgetLimitTime', 7 * 24 * 60 * 60, $chan);
        # don't delete if requested $limit times
        my $limit       = &getChanConfDefault('factoidPreventForgetLimit', 100, $chan);
        # don't delete if older than $limitage seconds (modified by requests below)
        my $limitage    = &getChanConfDefault('factoidPreventForgetLimitTime', 7 * 24 * 60 * 60, $chan);
-       my $t           = &getFactInfo($faqtoid, "created_time") || 0;
+       my $t           = &getFactInfo($faqtoid, 'created_time') || 0;
        my $age         = time() - $t;
 
        # lets scale limitage from 1 (nearly 0) to $limit (full time).
        $limitage       = $limitage*($count+1)/$limit if ($count < $limit);
        # isauthor and isop.
        my $isau        = (defined $author and &IsHostMatch($author) == 2) ? 1 : 0;
        my $age         = time() - $t;
 
        # lets scale limitage from 1 (nearly 0) to $limit (full time).
        $limitage       = $limitage*($count+1)/$limit if ($count < $limit);
        # isauthor and isop.
        my $isau        = (defined $author and &IsHostMatch($author) == 2) ? 1 : 0;
-       my $isop        = (&IsFlag("o") eq "o") ? 1 : 0;
+       my $isop        = (&IsFlag('o') eq 'o') ? 1 : 0;
 
 
-       if (IsFlag("r") ne "r" && !$isop) {
+       if (IsFlag('r') ne 'r' && !$isop) {
            &msg($who, "you don't have access to remove factoids");
            return;
        }
            &msg($who, "you don't have access to remove factoids");
            return;
        }
@@ -198,16 +198,16 @@ sub FactoidStuff {
        # prevent deletion if other factoids redirect to it.
        # TODO: use hash instead of array.
        my @list;
        # prevent deletion if other factoids redirect to it.
        # TODO: use hash instead of array.
        my @list;
-       if (&getChanConf("factoidPreventForgetRedirect")) {
+       if (&getChanConf('factoidPreventForgetRedirect')) {
            &status("Factoids/Core: forget: checking for redirect factoids");
            &status("Factoids/Core: forget: checking for redirect factoids");
-           @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", "^<REPLY> see ");
+           @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', "^<REPLY> see ");
        }
 
        my $match = 0;
        for (@list) {
            my $f = $_;
        }
 
        my $match = 0;
        for (@list) {
            my $f = $_;
-           my $v = &getFactInfo($f, "factoid_value");
+           my $v = &getFactInfo($f, 'factoid_value');
            my $fsafe = quotemeta($faqtoid);
            next unless ($v =~ /^<REPLY> ?see( also)? $fsafe\.?$/i);
 
            my $fsafe = quotemeta($faqtoid);
            next unless ($v =~ /^<REPLY> ?see( also)? $fsafe\.?$/i);
 
@@ -234,21 +234,21 @@ sub FactoidStuff {
            # TODO: make forget limit configurable.
            # TODO: make forget ignore time configurable.
            if ($cache{forget}{$h} > 5) {
            # TODO: make forget limit configurable.
            # TODO: make forget ignore time configurable.
            if ($cache{forget}{$h} > 5) {
-               &ignoreAdd(&makeHostMask($nuh), "*", 3*24*60, "abuse of forget");
+               &ignoreAdd(&makeHostMask($nuh), '*', 3*24*60, "abuse of forget");
                &msg($who, "forget: Ignoring you for abuse!");
            }
        }
 
        # lets do it!
 
                &msg($who, "forget: Ignoring you for abuse!");
            }
        }
 
        # lets do it!
 
-       if (&IsParam("factoidDeleteDelay") or &IsChanConf("factoidDeleteDelay") > 0) {
+       if (&IsParam('factoidDeleteDelay') or &IsChanConf('factoidDeleteDelay') > 0) {
            if (!($isop or $isau) and $faqtoid =~ / #DEL#$/) {
                &msg($who, "cannot delete it ($faqtoid).");
                return;
            }
 
            &status("forgot (safe delete): '$faqtoid' - ". scalar(gmtime));
            if (!($isop or $isau) and $faqtoid =~ / #DEL#$/) {
                &msg($who, "cannot delete it ($faqtoid).");
                return;
            }
 
            &status("forgot (safe delete): '$faqtoid' - ". scalar(gmtime));
-           ### TODO: check if the "backup" exists and overwrite it
+           ### TODO: check if the 'backup' exists and overwrite it
            my $check = &getFactoid("$faqtoid #DEL#");
 
            if (!defined $check or $check =~ /^\s*$/) {
            my $check = &getFactoid("$faqtoid #DEL#");
 
            if (!defined $check or $check =~ /^\s*$/) {
@@ -260,9 +260,9 @@ sub FactoidStuff {
                        &DEBUG("forget: not overwriting backup: $faqtoid");
                    } else {
                        &status("forget: backing up '$faqtoid'");
                        &DEBUG("forget: not overwriting backup: $faqtoid");
                    } else {
                        &status("forget: backing up '$faqtoid'");
-                       &setFactInfo($faqtoid, "factoid_key", $new);
-                       &setFactInfo($new, "modified_by", $who);
-                       &setFactInfo($new, "modified_time", time());
+                       &setFactInfo($faqtoid, 'factoid_key', $new);
+                       &setFactInfo($new, 'modified_by', $who);
+                       &setFactInfo($new, 'modified_time', time());
                    }
 
                } else {
                    }
 
                } else {
@@ -289,16 +289,16 @@ sub FactoidStuff {
        return 'unforget: no addr' unless ($addressed);
 
        my $i = 0;
        return 'unforget: no addr' unless ($addressed);
 
        my $i = 0;
-       $i++ if (&IsParam("factoidDeleteDelay"));
-       $i++ if (&IsChanConf("factoidDeleteDelay") > 0);
+       $i++ if (&IsParam('factoidDeleteDelay'));
+       $i++ if (&IsChanConf('factoidDeleteDelay') > 0);
        if (!$i) {
            &performReply("safe delete has been disable so what is there to undelete?");
            return;
        }
 
        my $faqtoid = $message;
        if (!$i) {
            &performReply("safe delete has been disable so what is there to undelete?");
            return;
        }
 
        my $faqtoid = $message;
-       if ($faqtoid eq "") {
-           &help("unforget");
+       if ($faqtoid eq '') {
+           &help('unforget');
            return;
        }
 
            return;
        }
 
@@ -316,9 +316,9 @@ sub FactoidStuff {
            return;
        }
 
            return;
        }
 
-       &setFactInfo($faqtoid." #DEL#", "factoid_key",   $faqtoid);
-#      &setFactInfo($faqtoid, "modified_by",   "");
-#      &setFactInfo($faqtoid, "modified_time", 0);
+       &setFactInfo($faqtoid." #DEL#", 'factoid_key',   $faqtoid);
+#      &setFactInfo($faqtoid, 'modified_by',   '');
+#      &setFactInfo($faqtoid, 'modified_time', 0);
 
        $check  = &getFactoid($faqtoid);
        # TODO: check if $faqtoid." #DEL#" exists?
 
        $check  = &getFactoid($faqtoid);
        # TODO: check if $faqtoid." #DEL#" exists?
@@ -339,19 +339,19 @@ sub FactoidStuff {
        my $function = lc $1;
        my $faqtoid  = lc $4;
 
        my $function = lc $1;
        my $faqtoid  = lc $4;
 
-       if ($faqtoid eq "") {
+       if ($faqtoid eq '') {
            &help($function);
            return;
        }
 
            &help($function);
            return;
        }
 
-       if (&getFactoid($faqtoid) eq "") {
+       if (&getFactoid($faqtoid) eq '') {
            &msg($who, "factoid \002$faqtoid\002 does not exist");
            return;
        }
 
            &msg($who, "factoid \002$faqtoid\002 does not exist");
            return;
        }
 
-       if ($function eq "lock") {
+       if ($function eq 'lock') {
            # strongly requested by #debian on 19991028. -xk
            # strongly requested by #debian on 19991028. -xk
-           if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag("o") ne "o") {
+           if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag('o') ne 'o') {
                &msg($who,"sorry, locking cannot be used since it can be abused unneccesarily.");
                &status("Replace 1 with 0 in Process.pl#~324 for locking support.");
                return;
                &msg($who,"sorry, locking cannot be used since it can be abused unneccesarily.");
                &status("Replace 1 with 0 in Process.pl#~324 for locking support.");
                return;
@@ -369,8 +369,8 @@ sub FactoidStuff {
     if ($message =~ s/^rename(\s+|$)//) {
        return 'rename: no addr' unless ($addressed);
 
     if ($message =~ s/^rename(\s+|$)//) {
        return 'rename: no addr' unless ($addressed);
 
-       if ($message eq "") {
-           &help("rename");
+       if ($message eq '') {
+           &help('rename');
            return;
        }
 
            return;
        }
 
@@ -384,7 +384,7 @@ sub FactoidStuff {
            }
 
            # who == nick!user@host.
            }
 
            # who == nick!user@host.
-           if (&IsFlag("m") ne "m" and $author !~ /^\Q$who\E\!/i) {
+           if (&IsFlag('m') ne 'm' and $author !~ /^\Q$who\E\!/i) {
                &msg($who, "factoid '$from' is not yours to modify.");
                return;
            }
                &msg($who, "factoid '$from' is not yours to modify.");
                return;
            }
@@ -394,7 +394,7 @@ sub FactoidStuff {
                return;
            }
 
                return;
            }
 
-           &setFactInfo($from,"factoid_key",$to);
+           &setFactInfo($from,'factoid_key',$to);
 
            &status("rename: <$who> '$from' is now '$to'");
            &performReply("i renamed '$from' to '$to'");
 
            &status("rename: <$who> '$from' is now '$to'");
            &performReply("i renamed '$from' to '$to'");
@@ -421,7 +421,7 @@ sub FactoidStuff {
            return 'subst: locked' if (&IsLocked($faqtoid) == 1);
            my $was = $result;
 
            return 'subst: locked' if (&IsLocked($faqtoid) == 1);
            my $was = $result;
 
-           if (($flags eq "g" && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) {
+           if (($flags eq 'g' && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) {
                # excessive length.
                if (length $result > $param{'maxDataSize'}) {
                    &performReply("that's too long");
                # excessive length.
                if (length $result > $param{'maxDataSize'}) {
                    &performReply("that's too long");
@@ -433,17 +433,17 @@ sub FactoidStuff {
                    return;
                }
                # min length.
                    return;
                }
                # min length.
-               my $faqauth = &getFactInfo($faqtoid, "created_by");
+               my $faqauth = &getFactInfo($faqtoid, 'created_by');
                if ((length $result)*2 < length $was and
                if ((length $result)*2 < length $was and
-                       &IsFlag("o") ne "o" and
+                       &IsFlag('o') ne 'o' and
                        &IsHostMatch($faqauth) != 2
                ) {
                    &performReply("too drastic change of factoid.");
                }
 
                        &IsHostMatch($faqauth) != 2
                ) {
                    &performReply("too drastic change of factoid.");
                }
 
-               &setFactInfo($faqtoid, "factoid_value", $result);
+               &setFactInfo($faqtoid, 'factoid_value', $result);
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
-               &performReply("OK");
+               &performReply('OK');
            } else {
                &performReply("that doesn't contain '$op'");
            }
            } else {
                &performReply("that doesn't contain '$op'");
            }
@@ -460,7 +460,7 @@ sub FactoidStuff {
        # fix the string.
        s/^hey([, ]+)where/where/i;
        s/\s+\?$/?/;
        # fix the string.
        s/^hey([, ]+)where/where/i;
        s/\s+\?$/?/;
-       s/whois/who is/ig;
+       s/^whois /who is /i; # Must match ^, else factoids with "whois" anywhere break
        s/where can i find/where is/i;
        s/how about/where is/i;
        s/ da / the /ig;
        s/where can i find/where is/i;
        s/how about/where is/i;
        s/ da / the /ig;
@@ -501,7 +501,7 @@ sub FactoidStuff {
        &loadMyModule('Math');
        my $newresult = &perlMath();
 
        &loadMyModule('Math');
        my $newresult = &perlMath();
 
-       if (defined $newresult and $newresult ne "") {
+       if (defined $newresult and $newresult ne '') {
            $cmdstats{'Maths'}++;
            $result = $newresult;
            &status("math: <$who> $message => $result");
            $cmdstats{'Maths'}++;
            $result = $newresult;
            &status("math: <$who> $message => $result");
@@ -540,3 +540,5 @@ sub FactoidStuff {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 1d869ab986e9e1b084cf7de7dd0aa88b983f505e..ab37eeb5b21935af1d3dea948fd86958fc25a66f 100644 (file)
@@ -10,7 +10,7 @@
 #####
 # Usage: &setFactInfo($faqtoid, $key, $val);
 sub setFactInfo {
 #####
 # Usage: &setFactInfo($faqtoid, $key, $val);
 sub setFactInfo {
-    &sqlSet("factoids",
+    &sqlSet('factoids',
        { factoid_key => $_[0] },
        { $_[1] => $_[2] }
     );
        { factoid_key => $_[0] },
        { $_[1] => $_[2] }
     );
@@ -19,13 +19,13 @@ sub setFactInfo {
 #####
 # Usage: &getFactInfo($faqtoid, [$what]);
 sub getFactInfo {
 #####
 # Usage: &getFactInfo($faqtoid, [$what]);
 sub getFactInfo {
-    return &sqlSelect("factoids", $_[1], { factoid_key => $_[0] } );
+    return &sqlSelect('factoids', $_[1], { factoid_key => $_[0] } );
 }
 
 #####
 # Usage: &getFactoid($faqtoid);
 sub getFactoid {
 }
 
 #####
 # Usage: &getFactoid($faqtoid);
 sub getFactoid {
-    return &getFactInfo($_[0], "factoid_value");
+    return &getFactInfo($_[0], 'factoid_value');
 }
 
 #####
 }
 
 #####
@@ -33,7 +33,7 @@ sub getFactoid {
 sub delFactoid {
     my ($faqtoid) = @_;
 
 sub delFactoid {
     my ($faqtoid) = @_;
 
-    &sqlDelete("factoids", { factoid_key => $faqtoid } );
+    &sqlDelete('factoids', { factoid_key => $faqtoid } );
     &status("DELETED $faqtoid");
 
     return 1;
     &status("DELETED $faqtoid");
 
     return 1;
@@ -43,10 +43,10 @@ sub delFactoid {
 # Usage: &IsLocked($faqtoid);
 sub IsLocked {
     my ($faqtoid) = @_;
 # Usage: &IsLocked($faqtoid);
 sub IsLocked {
     my ($faqtoid) = @_;
-    my $thisnuh   = &getFactInfo($faqtoid, "locked_by");
+    my $thisnuh   = &getFactInfo($faqtoid, 'locked_by');
 
 
-    if (defined $thisnuh and $thisnuh ne "") {
-       if (!&IsHostMatch($thisnuh) and &IsFlag("o") ne "o") {
+    if (defined $thisnuh and $thisnuh ne '') {
+       if (!&IsHostMatch($thisnuh) and &IsFlag('o') ne 'o') {
            &performReply("cannot alter locked factoids");
            return 1;
        }
            &performReply("cannot alter locked factoids");
            return 1;
        }
@@ -59,7 +59,7 @@ sub IsLocked {
 # Usage: &AddModified($faqtoid,$nuh);
 sub AddModified {
     my ($faqtoid,$nuh) = @_;
 # Usage: &AddModified($faqtoid,$nuh);
 sub AddModified {
     my ($faqtoid,$nuh) = @_;
-    my $modified_by = &getFactInfo($faqtoid, "modified_by");
+    my $modified_by = &getFactInfo($faqtoid, 'modified_by');
     my (@modifiedlist, @modified, %modified);
 
     if (defined $modified_by) {
     my (@modifiedlist, @modified, %modified);
 
     if (defined $modified_by) {
@@ -83,8 +83,8 @@ sub AddModified {
     }
     shift(@modifiedlist) while (scalar @modifiedlist > 3);
 
     }
     shift(@modifiedlist) while (scalar @modifiedlist > 3);
 
-    &setFactInfo($faqtoid, "modified_by",   join(",",@modifiedlist));
-    &setFactInfo($faqtoid, "modified_time", time());
+    &setFactInfo($faqtoid, 'modified_by',   join(",",@modifiedlist));
+    &setFactInfo($faqtoid, 'modified_time', time());
 
     return 1;
 }
 
     return 1;
 }
@@ -98,28 +98,28 @@ sub AddModified {
 sub CmdLock {
     my ($faqtoid) = @_;
 
 sub CmdLock {
     my ($faqtoid) = @_;
 
-    my $thisnuh = &getFactInfo($faqtoid,"locked_by");
+    my $thisnuh = &getFactInfo($faqtoid,'locked_by');
 
 
-    if (defined $thisnuh and $thisnuh ne "") {
+    if (defined $thisnuh and $thisnuh ne '') {
        my $locked_by = (split(/\!/,$thisnuh))[0];
        &msg($who,"factoid \002$faqtoid\002 has already been locked by $locked_by.");
        return 0;
     }
 
        my $locked_by = (split(/\!/,$thisnuh))[0];
        &msg($who,"factoid \002$faqtoid\002 has already been locked by $locked_by.");
        return 0;
     }
 
-    $thisnuh ||= &getFactInfo($faqtoid,"created_by");
+    $thisnuh ||= &getFactInfo($faqtoid,'created_by');
 
     # fixes bug found on 19991103.
     # code needs to be reorganised though.
 
     # fixes bug found on 19991103.
     # code needs to be reorganised though.
-    if ($thisnuh ne "") {
-       if (!&IsHostMatch($thisnuh) && IsFlag("o") ne "o") {
+    if ($thisnuh ne '') {
+       if (!&IsHostMatch($thisnuh) && IsFlag('o') ne 'o') {
            &msg($who, "sorry, you are not allowed to lock '$faqtoid'.");
            return 0;
        }
     }
 
     &performReply("locking factoid \002$faqtoid\002");
            &msg($who, "sorry, you are not allowed to lock '$faqtoid'.");
            return 0;
        }
     }
 
     &performReply("locking factoid \002$faqtoid\002");
-    &setFactInfo($faqtoid,"locked_by",$nuh);
-    &setFactInfo($faqtoid,"locked_time", time());
+    &setFactInfo($faqtoid,'locked_by',$nuh);
+    &setFactInfo($faqtoid,'locked_time', time());
 
     return 1;
 }
 
     return 1;
 }
@@ -129,23 +129,25 @@ sub CmdLock {
 sub CmdUnLock {
     my ($faqtoid) = @_;
 
 sub CmdUnLock {
     my ($faqtoid) = @_;
 
-    my $thisnuh = &getFactInfo($faqtoid,"locked_by");
+    my $thisnuh = &getFactInfo($faqtoid,'locked_by');
 
     if (!defined $thisnuh) {
        &msg($who, "factoid \002$faqtoid\002 is not locked.");
        return 0;
     }
 
 
     if (!defined $thisnuh) {
        &msg($who, "factoid \002$faqtoid\002 is not locked.");
        return 0;
     }
 
-    if ($thisnuh ne "" and !&IsHostMatch($thisnuh) and &IsFlag("o") ne "o") {
+    if ($thisnuh ne '' and !&IsHostMatch($thisnuh) and &IsFlag('o') ne 'o') {
        &msg($who, "sorry, you are not allowed to unlock factoid '$faqtoid'.");
        return 0;
     }
 
     &performReply("unlocking factoid \002$faqtoid\002");
        &msg($who, "sorry, you are not allowed to unlock factoid '$faqtoid'.");
        return 0;
     }
 
     &performReply("unlocking factoid \002$faqtoid\002");
-    &setFactInfo($faqtoid,"locked_by",   "");
-    &setFactInfo($faqtoid,"locked_time", "");
+    &setFactInfo($faqtoid,'locked_by',   '');
+    &setFactInfo($faqtoid,'locked_time', '0'); # pgsql complains if NOT NULL set. So set 0 which is the default
 
     return 1;
 }
 
 1;
 
     return 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 0d853a984297c3d603669af02a826388bd5fb376..ba97e7dc27d528c7efd3d7b1f03143f68d88b41e 100644 (file)
@@ -86,7 +86,7 @@ sub switchPerson {
        s/(^|\W)you\'?re(\W|$)/$1you are$2/ig;
 
        if ($addressed) {
        s/(^|\W)you\'?re(\W|$)/$1you are$2/ig;
 
        if ($addressed) {
-           my $mynick = "UNDEF";
+           my $mynick = 'UNDEF';
            $mynick = $conn->nick() if ($conn);
            # is it safe to remove $in from here, too?
            $in =~ s/yourself/$mynick/i;
            $mynick = $conn->nick() if ($conn);
            # is it safe to remove $in from here, too?
            $in =~ s/yourself/$mynick/i;
@@ -101,3 +101,5 @@ sub switchPerson {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 2c2506ffcf3aed711d08fed75f679c2bfb613182..7a99e6b646c3a9b3d96c4c2fa6ded26444c99889 100644 (file)
@@ -20,7 +20,7 @@ sub doQuestion {
     # my doesn't allow variables to be inherinted, local does.
     # following is used in math()...
     local($query)      = @_;
     # my doesn't allow variables to be inherinted, local does.
     # following is used in math()...
     local($query)      = @_;
-    local($reply)      = "";
+    local($reply)      = '';
     local $finalQMark  = $query =~ s/\?+\s*$//;
     $finalQMark                += $query =~ s/\?\s*$//;
     $query             =~ s/^\s+|\s+$//g;
     local $finalQMark  = $query =~ s/\?+\s*$//;
     $finalQMark                += $query =~ s/\?\s*$//;
     $query             =~ s/^\s+|\s+$//g;
@@ -29,12 +29,11 @@ sub doQuestion {
        return '';
     }
 
        return '';
     }
 
-    my $questionWord   = "";
+    my $questionWord   = '';
 
     if (!$addressed) {
 
     if (!$addressed) {
-       return ''; #never respond if we're not addressed
        return '' unless ($finalQMark);
        return '' unless ($finalQMark);
-       return '' unless &IsChanConf("minVolunteerLength") > 0;
+       return '' unless &IsChanConf('minVolunteerLength') > 0;
        return '' if (length $query < &::getChanConf('minVolunteerLength'));
     } else {
        ### TODO: this should be caught in Process.pl?
        return '' if (length $query < &::getChanConf('minVolunteerLength'));
     } else {
        ### TODO: this should be caught in Process.pl?
@@ -42,7 +41,7 @@ sub doQuestion {
 
        # there is no flag to disable/enable asking factoids...
        # so it was added... thanks zyxep! :)
 
        # there is no flag to disable/enable asking factoids...
        # so it was added... thanks zyxep! :)
-       if (&IsFlag("a") ne "a" && &IsFlag("o") ne "o") {
+       if (&IsFlag('a') ne 'a' && &IsFlag('o') ne 'o') {
            &status("$who tried to ask us when not allowed.");
            return;
        }
            &status("$who tried to ask us when not allowed.");
            return;
        }
@@ -88,13 +87,13 @@ sub doQuestion {
        $questionWord = lc($1);
     }
 
        $questionWord = lc($1);
     }
 
-    if ($questionWord eq "" and $finalQMark and $addressed) {
-       $questionWord = "where";
+    if ($questionWord eq '' and $finalQMark and $addressed) {
+       $questionWord = 'where';
     }
     $query =~ s/^\s+|\s+$//g; # bleh. hacked.
     push(@query, $query) if ($query ne $x);
 
     }
     $query =~ s/^\s+|\s+$//g; # bleh. hacked.
     push(@query, $query) if ($query ne $x);
 
-    if (&IsChanConf("factoidArguments") > 0) {
+    if (&IsChanConf('factoidArguments') > 0) {
        $result = &factoidArgs($query[0]);
 
        return $result if (defined $result);
        $result = &factoidArgs($query[0]);
 
        return $result if (defined $result);
@@ -104,7 +103,7 @@ sub doQuestion {
     for (my$i=0; $i<scalar @query; $i++) {
        $query  = $query[$i];
        $result = &getReply($query);
     for (my$i=0; $i<scalar @query; $i++) {
        $query  = $query[$i];
        $result = &getReply($query);
-       next if (!defined $result or $result eq "");
+       next if (!defined $result or $result eq '');
 
        # 'see also' factoid redirection support.
 
 
        # 'see also' factoid redirection support.
 
@@ -139,7 +138,7 @@ sub doQuestion {
 
                return;
            }
 
                return;
            }
-           last if (!defined $newr or $newr eq "");
+           last if (!defined $newr or $newr eq '');
            $result  = $newr;
        }
 
            $result  = $newr;
        }
 
@@ -163,13 +162,13 @@ sub doQuestion {
 ###    return $result if (defined $result);
     }
 
 ###    return $result if (defined $result);
     }
 
-    if ($questionWord ne "" or $finalQMark) {
+    if ($questionWord ne '' or $finalQMark) {
        # if it has not been explicitly marked as a question
        # if it has not been explicitly marked as a question
-       if ($addressed and $reply eq "") {
+       if ($addressed and $reply eq '') {
            &status("notfound: <$who> ".join(' :: ', @query))
                                                if ($finalQMark);
 
            &status("notfound: <$who> ".join(' :: ', @query))
                                                if ($finalQMark);
 
-           return '' unless (&IsParam("friendlyBots"));
+           return '' unless (&IsParam('friendlyBots'));
 
            foreach (split /\s+/, $param{'friendlyBots'}) {
                &msg($_, ":INFOBOT:QUERY <$who> $query");
 
            foreach (split /\s+/, $param{'friendlyBots'}) {
                &msg($_, ":INFOBOT:QUERY <$who> $query");
@@ -190,9 +189,9 @@ sub factoidArgs {
 #    my $t = &timeget();
     my ($first) = split(/\s+/, $str);
 
 #    my $t = &timeget();
     my ($first) = split(/\s+/, $str);
 
-    # ignore split to commands [dumb commands vs. factoids]
+    # ignore split to commands [dumb commands vs. factoids] (editing commands?)
     return undef if $str =~ /\s+\=\~\s+s[\#\/\:]/;
     return undef if $str =~ /\s+\=\~\s+s[\#\/\:]/;
-    my @list = &searchTable("factoids", "factoid_key", "factoid_key", "^CMD: $first ");
+    my @list = &searchTable('factoids', 'factoid_key', 'factoid_key', "^cmd: $first ");
 #    my $delta_time = &timedelta($t);
 #    &DEBUG("factArgs: delta_time = $delta_time s");
 #    &DEBUG("factArgs: list => ".scalar(@list) );
 #    my $delta_time = &timedelta($t);
 #    &DEBUG("factArgs: delta_time = $delta_time s");
 #    &DEBUG("factArgs: list => ".scalar(@list) );
@@ -239,9 +238,9 @@ sub factoidArgs {
        }
 
        # update stats. old mysql/sqlite don't do +1
        }
 
        # update stats. old mysql/sqlite don't do +1
-       my ($count) = &sqlSelect("factoids", "requested_count", { factoid_key => $q });
+       my ($count) = &sqlSelect('factoids', 'requested_count', { factoid_key => $q });
        $count++;
        $count++;
-       &sqlSet("factoids", {'factoid_key' => $q}, {
+       &sqlSet('factoids', {'factoid_key' => $q}, {
                requested_by    => $nuh,
                requested_time  => time(),
                requested_count => $count
                requested_by    => $nuh,
                requested_time  => time(),
                requested_count => $count
@@ -288,8 +287,8 @@ sub factoidArgs {
            $i++;
        }
 
            $i++;
        }
 
-       # nasty hack to get partial &getReply() functionality.
-       $result = &SARit($result);
+       $result = &SARit($result);
+       # rest of nasty hack to get partial &getReply() functionality.
        $result =~ s/^\s*<action>\s*(.*)/\cAACTION $1\cA/i;
        $result =~ s/^\s*<reply>\s*//i;
 
        $result =~ s/^\s*<action>\s*(.*)/\cAACTION $1\cA/i;
        $result =~ s/^\s*<reply>\s*//i;
 
@@ -303,3 +302,5 @@ sub factoidArgs {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 0278f32469322c3c83b8e7a5588b5b6f6b1dba64..ec3649bfa1f13ea694e987853bf28a7e02eae846 100644 (file)
@@ -46,7 +46,7 @@ sub getReply {
        } else {
            $factoid = "$search $message";
        }
        } else {
            $factoid = "$search $message";
        }
-       ($count, $fauthor, $result) = &sqlSelect("factoids",
+       ($count, $fauthor, $result) = &sqlSelect('factoids',
            "requested_count,created_by,factoid_value",
            { factoid_key => $factoid }
        );
            "requested_count,created_by,factoid_value",
            { factoid_key => $factoid }
        );
@@ -55,7 +55,7 @@ sub getReply {
 
     if ($result) {
        $lhs = $message;
 
     if ($result) {
        $lhs = $message;
-       $mhs = "is";
+       $mhs = 'is';
        $rhs = $result;
 
        return "\"$factoid\" $mhs \"$rhs\"" if ($literal);
        $rhs = $result;
 
        return "\"$factoid\" $mhs \"$rhs\"" if ($literal);
@@ -76,7 +76,7 @@ sub getReply {
     $result    = &SARit($result);
 
     $reply     = $result;
     $result    = &SARit($result);
 
     $reply     = $result;
-    if ($result ne "") {
+    if ($result ne '') {
        ### AT LAST, REPEAT PREVENTION CODE REMOVED IN FAVOUR OF GLOBAL
        ### FLOOD REPETION AND PROTECTION. -20000124
 
        ### AT LAST, REPEAT PREVENTION CODE REMOVED IN FAVOUR OF GLOBAL
        ### FLOOD REPETION AND PROTECTION. -20000124
 
@@ -84,7 +84,7 @@ sub getReply {
        ### FIXME: old mysql/sqlite doesn't support
        ### "requested_count=requested_count+1".
        $count++;
        ### FIXME: old mysql/sqlite doesn't support
        ### "requested_count=requested_count+1".
        $count++;
-       &sqlSet("factoids", {'factoid_key' => $factoid}, {
+       &sqlSet('factoids', {'factoid_key' => $factoid}, {
                requested_by    => $nuh,
                requested_time  => time(),
                requested_count => $count
                requested_by    => $nuh,
                requested_time  => time(),
                requested_count => $count
@@ -92,9 +92,9 @@ sub getReply {
 
        # TODO: rename $real to something else!
        my $real   = 0;
 
        # TODO: rename $real to something else!
        my $real   = 0;
-#      my $author = &getFactInfo($lhs,"created_by") || '';
+#      my $author = &getFactInfo($lhs,'created_by') || '';
 #      $real++ if ($author =~ /^\Q$who\E\!/);
 #      $real++ if ($author =~ /^\Q$who\E\!/);
-#      $real++ if (&IsFlag("n"));
+#      $real++ if (&IsFlag('n'));
        $real = 0 if ($msgType =~ /public/);
 
        ### fix up the reply.
        $real = 0 if ($msgType =~ /public/);
 
        ### fix up the reply.
@@ -117,7 +117,7 @@ sub getReply {
            ### bot->person reply.
            # result is random if separated by '||'.
            # rhs is full factoid with '||'.
            ### bot->person reply.
            # result is random if separated by '||'.
            # rhs is full factoid with '||'.
-           if ($mhs eq "is") {
+           if ($mhs eq 'is') {
                $reply = &getRandom(keys %{ $lang{'factoid'} });
                $reply =~ s/##KEY/$lhs/;
                $reply =~ s/##VALUE/$result/;
                $reply = &getRandom(keys %{ $lang{'factoid'} });
                $reply =~ s/##KEY/$lhs/;
                $reply =~ s/##VALUE/$result/;
@@ -125,7 +125,13 @@ sub getReply {
                $reply = "$lhs $mhs $result";
            }
 
                $reply = "$lhs $mhs $result";
            }
 
-           $reply =~ s/^\Q$who\E is/you are/i;
+           if ($reply =~ s/^\Q$who\E is/you are/i) {
+               # fix the person.
+           } else {
+               if ($reply =~ /^you are / or $reply =~ / you are /) {
+                   return if ($addressed);
+               }
+           }
        }
     }
 
        }
     }
 
@@ -331,25 +337,25 @@ sub substVars {
     }
 
     if ($reply =~ /\$factoids/) {
     }
 
     if ($reply =~ /\$factoids/) {
-       my $factoids = &countKeys("factoids");
+       my $factoids = &countKeys('factoids');
        $reply =~ s/\$factoids/$factoids/;
     }
 
     if ($reply =~ /\$Fupdate/) {
        my $x = "\002$count{'Update'}\002 ".
        $reply =~ s/\$factoids/$factoids/;
     }
 
     if ($reply =~ /\$Fupdate/) {
        my $x = "\002$count{'Update'}\002 ".
-               &fixPlural("modification", $count{'Update'});
+               &fixPlural('modification', $count{'Update'});
        $reply =~ s/\$Fupdate/$x/;
     }
 
     if ($reply =~ /\$Fquestion/) {
        my $x = "\002$count{'Question'}\002 ".
        $reply =~ s/\$Fupdate/$x/;
     }
 
     if ($reply =~ /\$Fquestion/) {
        my $x = "\002$count{'Question'}\002 ".
-               &fixPlural("question", $count{'Question'});
+               &fixPlural('question', $count{'Question'});
        $reply =~ s/\$Fquestion/$x/;
     }
 
     if ($reply =~ /\$Fdunno/) {
        my $x = "\002$count{'Dunno'}\002 ".
        $reply =~ s/\$Fquestion/$x/;
     }
 
     if ($reply =~ /\$Fdunno/) {
        my $x = "\002$count{'Dunno'}\002 ".
-               &fixPlural("dunno", $count{'Dunno'});
+               &fixPlural('dunno', $count{'Dunno'});
        $reply =~ s/\$Fdunno/$x/;
     }
 
        $reply =~ s/\$Fdunno/$x/;
     }
 
@@ -359,3 +365,5 @@ sub substVars {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 6617dd649a692d42d16c8ad4688e4f3f73f351d8..0df491860dd34fd62e73f832000e19af853c138a 100644 (file)
@@ -24,13 +24,13 @@ sub doStatement {
     # check if we need to be addressed and if we are
     return unless ($learnok);
 
     # check if we need to be addressed and if we are
     return unless ($learnok);
 
-    my($urlType) = "";
+    my($urlType) = '';
 
     # prefix www with http:// and ftp with ftp://
     $in =~ s/ www\./ http:\/\/www\./ig;
     $in =~ s/ ftp\./ ftp:\/\/ftp\./ig;
 
 
     # prefix www with http:// and ftp with ftp://
     $in =~ s/ www\./ http:\/\/www\./ig;
     $in =~ s/ ftp\./ ftp:\/\/ftp\./ig;
 
-    $urlType = "about"   if ($in =~ /\babout:/i);
+    $urlType = 'about'   if ($in =~ /\babout:/i);
     $urlType = 'afp'     if ($in =~ /\bafp:/);
     $urlType = 'file'    if ($in =~ /\bfile:/);
     $urlType = 'palace'  if ($in =~ /\bpalace:/);
     $urlType = 'afp'     if ($in =~ /\bafp:/);
     $urlType = 'file'    if ($in =~ /\bfile:/);
     $urlType = 'palace'  if ($in =~ /\bpalace:/);
@@ -40,12 +40,12 @@ sub doStatement {
     }
 
     # acceptUrl.
     }
 
     # acceptUrl.
-    if (&IsParam("acceptUrl")) {
+    if (&IsParam('acceptUrl')) {
        if ($param{'acceptUrl'} eq 'REQUIRE') {         # require url type.
        if ($param{'acceptUrl'} eq 'REQUIRE') {         # require url type.
-           return if ($urlType eq "");
+           return if ($urlType eq '');
        } elsif ($param{'acceptUrl'} eq 'REJECT') {
        } elsif ($param{'acceptUrl'} eq 'REJECT') {
-           &status("REJECTED URL entry") if (&IsParam("VERBOSITY"));
-           return unless ($urlType eq "");
+           &status("REJECTED URL entry") if (&IsParam('VERBOSITY'));
+           return unless ($urlType eq '');
        } else {
            # OPTIONAL
        }
        } else {
            # OPTIONAL
        }
@@ -56,7 +56,7 @@ sub doStatement {
        my($lhs, $mhs, $rhs) = ($`, $&, $');
 
        # allows factoid arguments to be updated. -lear.
        my($lhs, $mhs, $rhs) = ($`, $&, $');
 
        # allows factoid arguments to be updated. -lear.
-       $lhs =~ s/^(cmd: )?(.*)/$1||"" . lc $2/e;
+       $lhs =~ s/^(cmd: )?(.*)/$1||'' . lc $2/e;
 
        # discard article.
        $lhs =~ s/^(the|da|an?)\s+//i;
 
        # discard article.
        $lhs =~ s/^(the|da|an?)\s+//i;
@@ -67,7 +67,7 @@ sub doStatement {
        $rhs =~ s/^\s+|\s+$//g;
 
        # break if either lhs or rhs is NULL.
        $rhs =~ s/^\s+|\s+$//g;
 
        # break if either lhs or rhs is NULL.
-       if ($lhs eq "" or $rhs eq "") {
+       if ($lhs eq '' or $rhs eq '') {
            return "NOT-A-STATEMENT";
        }
 
            return "NOT-A-STATEMENT";
        }
 
@@ -86,7 +86,7 @@ sub doStatement {
 
        &status("statement: <$who> $message");
 
 
        &status("statement: <$who> $message");
 
-       # change "#*#" back to "*" because of '\' sar to '#blah#'.
+       # change "#*#" back to '*' because of '\' sar to '#blah#'.
        $lhs =~ s/\#(\S+)\#/$1/g;
        $rhs =~ s/\#(\S+)\#/$1/g;
 
        $lhs =~ s/\#(\S+)\#/$1/g;
        $rhs =~ s/\#(\S+)\#/$1/g;
 
@@ -108,7 +108,9 @@ sub doStatement {
        return if (&update($lhs, $mhs, $rhs));
     }
 
        return if (&update($lhs, $mhs, $rhs));
     }
 
-    return "CONTINUE";
+    return 'CONTINUE';
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 475e0d9500b0b2acd04fef48d063f39811727936..9ee8e220399e8cef4517dbcd9f1f995ede0a16ce 100644 (file)
@@ -21,13 +21,13 @@ sub update {
     return if (&IsLocked($lhs) == 1);
 
     # profanity.
     return if (&IsLocked($lhs) == 1);
 
     # profanity.
-    if (&IsParam("profanityCheck") and &hasProfanity($rhs)) {
+    if (&IsParam('profanityCheck') and &hasProfanity($rhs)) {
        &performReply("please, watch your language.");
        return 1;
     }
 
     # teaching.
        &performReply("please, watch your language.");
        return 1;
     }
 
     # teaching.
-    if (&IsFlag("t") ne "t" && &IsFlag("o") ne "o") {
+    if (&IsFlag('t') ne 't' && &IsFlag('o') ne 'o') {
        &msg($who, "permission denied.");
        &status("alert: $who wanted to teach me.");
        return 1;
        &msg($who, "permission denied.");
        &status("alert: $who wanted to teach me.");
        return 1;
@@ -54,7 +54,7 @@ sub update {
 
     # factoid arguments handler.
     # must start with a non-variable
 
     # factoid arguments handler.
     # must start with a non-variable
-    if (&IsChanConf("factoidArguments") > 0 and $lhs =~ /^[^\$]+.*\$/) {
+    if (&IsChanConf('factoidArguments') > 0 and $lhs =~ /^[^\$]+.*\$/) {
        &status("Update: Factoid Arguments found.");
        &status("Update: orig lhs => '$lhs'.");
        &status("Update: orig rhs => '$rhs'.");
        &status("Update: Factoid Arguments found.");
        &status("Update: orig lhs => '$lhs'.");
        &status("Update: orig rhs => '$rhs'.");
@@ -87,23 +87,23 @@ sub update {
        # nice 'are' hack (or work-around).
        if ($mhs =~ /^are$/i and $rhs !~ /<\S+>/) {
            &status("Update: 'are' hack detected.");
        # nice 'are' hack (or work-around).
        if ($mhs =~ /^are$/i and $rhs !~ /<\S+>/) {
            &status("Update: 'are' hack detected.");
-           $mhs = "is";
+           $mhs = 'is';
            $rhs = "<REPLY> are ". $rhs;
        }
 
        &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
        $count{'Update'}++;
 
            $rhs = "<REPLY> are ". $rhs;
        }
 
        &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'");
        $count{'Update'}++;
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
 
-       &sqlReplace("factoids", {
+       &sqlInsert('factoids', {
                created_by      => $nuh,
                created_time    => time(),      # modified time.
                factoid_key     => $lhs,
                factoid_value   => $rhs,
        } );
 
                created_by      => $nuh,
                created_time    => time(),      # modified time.
                factoid_key     => $lhs,
                factoid_value   => $rhs,
        } );
 
-       if (!defined $rhs or $rhs eq "") {
+       if (!defined $rhs or $rhs eq '') {
            &ERROR("Update: rhs1 == NULL.");
        }
 
            &ERROR("Update: rhs1 == NULL.");
        }
 
@@ -190,21 +190,20 @@ sub update {
            }
        }
 
            }
        }
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
        $count{'Update'}++;
        &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
 
        $count{'Update'}++;
        &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
-       &sqlReplace("factoids", {
-               factoid_key     => $lhs,
+       &sqlSet('factoids', {'factoid_key' => $lhs}, {
                modified_by     => $nuh,
                modified_time   => time(),
                factoid_value   => $rhs,
        } );
 
                modified_by     => $nuh,
                modified_time   => time(),
                factoid_value   => $rhs,
        } );
 
-       if (!defined $rhs or $rhs eq "") {
+       if (!defined $rhs or $rhs eq '') {
            &ERROR("Update: rhs1 == NULL.");
        }
            &ERROR("Update: rhs1 == NULL.");
        }
-    } else {                           # not "also"
+    } else {                           # not 'also'
 
        if (!$correction_plausible) {   # "no, blah is ..."
            if ($addressed) {
 
        if (!$correction_plausible) {   # "no, blah is ..."
            if ($addressed) {
@@ -214,28 +213,27 @@ sub update {
            return 1;
        }
 
            return 1;
        }
 
-       my $author = &getFactInfo($lhs, "created_by") || "";
+       my $author = &getFactInfo($lhs, 'created_by') || '';
 
 
-       if (IsFlag("m") ne "m" && IsFlag("o") ne "o" &&
+       if (IsFlag('m') ne 'm' && IsFlag('o') ne 'o' &&
            $author !~ /^\Q$who\E\!/i
        ) {
            &msg($who, "you can't change that factoid.");
            return 1;
        }
 
            $author !~ /^\Q$who\E\!/i
        ) {
            &msg($who, "you can't change that factoid.");
            return 1;
        }
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
        $count{'Update'}++;
        &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
 
 
        $count{'Update'}++;
        &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'");
 
-       &sqlReplace("factoids", {
-               factoid_key     => $lhs,
+       &sqlSet('factoids', {'factoid_key' => $lhs}, {
                modified_by     => $nuh,
                modified_time   => time(),
                factoid_value   => $rhs,
        } );
 
                modified_by     => $nuh,
                modified_time   => time(),
                factoid_value   => $rhs,
        } );
 
-       if (!defined $rhs or $rhs eq "") {
+       if (!defined $rhs or $rhs eq '') {
            &ERROR("Update: rhs1 == NULL.");
        }
     }
            &ERROR("Update: rhs1 == NULL.");
        }
     }
@@ -244,3 +242,5 @@ sub update {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ffd8deaee7057236b55fef7c01f39250c37a6ec2..91610b6bf2e161f0f854321dfbc405d786d5f714 100644 (file)
@@ -26,7 +26,7 @@ sub loadLang {
 
     while (<FILE>) {
        chop;
 
     while (<FILE>) {
        chop;
-       if ($_ eq "" || /^#/) {
+       if ($_ eq '' || /^#/) {
            undef $replyName;
            next;
        }
            undef $replyName;
            next;
        }
@@ -53,7 +53,7 @@ sub loadLang {
 
 # File: Irc Servers list.
 sub loadIRCServers {
 
 # File: Irc Servers list.
 sub loadIRCServers {
-    my ($file) = $bot_config_dir."/blootbot.servers";
+    my ($file) = $bot_config_dir."/infobot.servers";
     @ircServers = ();
     %ircPort = ();
 
     @ircServers = ();
     %ircPort = ();
 
@@ -81,3 +81,5 @@ sub loadIRCServers {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 4ce64f66e247e4856c594614a1c03b9bdba41d51..c89c0db41616a95abce9df3a0a9564d9612d509c 100644 (file)
@@ -26,6 +26,9 @@ $nickserv     = 0;
 # It's probably closer to 510, but let's be cautious until we calculate it extensively.
 my $maxlinelen = 490;
 
 # It's probably closer to 510, but let's be cautious until we calculate it extensively.
 my $maxlinelen = 490;
 
+# Keep track of last time we displayed Chans: to avoid spam in logs
+my $lastChansTime = 0;
+
 sub ircloop {
     my $error  = 0;
     my $lastrun = 0;
 sub ircloop {
     my $error  = 0;
     my $lastrun = 0;
@@ -178,7 +181,7 @@ sub irc {
 
     # works? needs to actually do something
     # should likely listen on a tcp port instead
 
     # works? needs to actually do something
     # should likely listen on a tcp port instead
-    #$irc->addfh(STDIN, \&on_stdin, "r");
+    #$irc->addfh(STDIN, \&on_stdin, 'r');
 
     &status("starting main loop");
 
 
     &status("starting main loop");
 
@@ -193,7 +196,7 @@ sub rawout {
     my ($buf) = @_;
     $buf =~ s/\n//gi;
 
     my ($buf) = @_;
     $buf =~ s/\n//gi;
 
-    # slow down a bit if traffic is "high".
+    # slow down a bit if traffic is 'high'.
     # need to take into account time of last message sent.
     if ($last{buflen} > 256 and length($buf) > 256) {
        sleep 1;
     # need to take into account time of last message sent.
     if ($last{buflen} > 256 and length($buf) > 256) {
        sleep 1;
@@ -208,11 +211,17 @@ sub say {
     my ($msg) = @_;
     my $mynick = $conn->nick();
     if (!defined $msg) {
     my ($msg) = @_;
     my $mynick = $conn->nick();
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &WARN("say: msg == $msg.");
        return;
     }
 
        &WARN("say: msg == $msg.");
        return;
     }
 
+    if (&getChanConf('silent', $talkchannel) and not
+      (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) {
+       &DEBUG("say: silent in $talkchannel, not saying $msg");
+       return;
+    }
+
     if ( $postprocess ) {
        undef $postprocess;
     } elsif ($postprocess = &getChanConf('postprocess', $talkchannel)) {
     if ( $postprocess ) {
        undef $postprocess;
     } elsif ($postprocess = &getChanConf('postprocess', $talkchannel)) {
@@ -226,7 +235,7 @@ sub say {
 
     return unless (&whatInterface() =~ /IRC/);
 
 
     return unless (&whatInterface() =~ /IRC/);
 
-    $msg = "zero" if ($msg =~ /^0+$/);
+    $msg = 'zero' if ($msg =~ /^0+$/);
 
     my $t = time();
 
 
     my $t = time();
 
@@ -234,8 +243,8 @@ sub say {
        $pubcount++;
        $pubsize += length $msg;
 
        $pubcount++;
        $pubsize += length $msg;
 
-       my $i = &getChanConfDefault("sendPublicLimitLines", 3, $chan);
-       my $j = &getChanConfDefault("sendPublicLimitBytes", 1000, $chan);
+       my $i = &getChanConfDefault('sendPublicLimitLines', 3, $chan);
+       my $j = &getChanConfDefault('sendPublicLimitBytes', 1000, $chan);
 
        if ( ($pubcount % $i) == 0 and $pubcount) {
            sleep 1;
 
        if ( ($pubcount % $i) == 0 and $pubcount) {
            sleep 1;
@@ -261,11 +270,18 @@ sub msg {
     }
 
     if (!defined $msg) {
     }
 
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &WARN("msg: msg == $msg.");
        return;
     }
 
        &WARN("msg: msg == $msg.");
        return;
     }
 
+    # some say() end up here (eg +help)
+    if (&getChanConf('silent', $nick) and not
+       (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) {
+       &DEBUG("msg: silent in $nick, not saying $msg");
+       return;
+    }
+
     &status(">$nick< $msg");
 
     return unless (&whatInterface() =~ /IRC/);
     &status(">$nick< $msg");
 
     return unless (&whatInterface() =~ /IRC/);
@@ -275,8 +291,8 @@ sub msg {
        $msgcount++;
        $msgsize += length $msg;
 
        $msgcount++;
        $msgsize += length $msg;
 
-       my $i = &getChanConfDefault("sendPrivateLimitLines", 3, $chan);
-       my $j = &getChanConfDefault("sendPrivateLimitBytes", 1000, $chan);
+       my $i = &getChanConfDefault('sendPrivateLimitLines', 3, $chan);
+       my $j = &getChanConfDefault('sendPrivateLimitBytes', 1000, $chan);
        if ( ($msgcount % $i) == 0 and $msgcount) {
            sleep 1;
        } elsif ($msgsize > $j) {
        if ( ($msgcount % $i) == 0 and $msgcount) {
            sleep 1;
        } elsif ($msgsize > $j) {
@@ -302,6 +318,12 @@ sub action {
        return;
     }
 
        return;
     }
 
+    if (&getChanConf('silent', $target) and not
+       (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) {
+       &DEBUG("action: silent in $target, not doing $txt");
+       return;
+    }
+
     if (length $txt > 480) {
        &status("action: txt too long; truncating.");
        chop($txt) while (length $txt > 480);
     if (length $txt > 480) {
        &status("action: txt too long; truncating.");
        chop($txt) while (length $txt > 480);
@@ -327,8 +349,8 @@ sub notice {
        $notcount++;
        $notsize += length $txt;
 
        $notcount++;
        $notsize += length $txt;
 
-       my $i = &getChanConfDefault("sendNoticeLimitLines", 3, $chan);
-       my $j = &getChanConfDefault("sendNoticeLimitBytes", 1000, $chan);
+       my $i = &getChanConfDefault('sendNoticeLimitLines', 3, $chan);
+       my $j = &getChanConfDefault('sendNoticeLimitBytes', 1000, $chan);
 
        if ( ($notcount % $i) == 0 and $notcount) {
            sleep 1;
 
        if ( ($notcount % $i) == 0 and $notcount) {
            sleep 1;
@@ -464,8 +486,8 @@ sub dcc_close {
 
 sub joinchan {
     my ($chan, $key) = @_;
 
 sub joinchan {
     my ($chan, $key) = @_;
-    $key ||= &getChanConf("chankey", $chan);
-    $key ||= "";
+    $key ||= &getChanConf('chankey', $chan);
+    $key ||= '';
 
     # forgot for about 2 years to implement channel keys when moving
     # over to Net::IRC...
 
     # forgot for about 2 years to implement channel keys when moving
     # over to Net::IRC...
@@ -490,7 +512,7 @@ sub part {
     my $chan;
 
     foreach $chan (@_) {
     my $chan;
 
     foreach $chan (@_) {
-       next if ($chan eq "");
+       next if ($chan eq '');
        $chan =~ tr/A-Z/a-z/;   # lowercase.
 
        if ($chan !~ /^$mask{chan}$/) {
        $chan =~ tr/A-Z/a-z/;   # lowercase.
 
        if ($chan !~ /^$mask{chan}$/) {
@@ -526,24 +548,24 @@ sub mode {
 
 sub op {
     my ($chan, @who) = @_;
 
 sub op {
     my ($chan, @who) = @_;
-    my $os     = "o" x scalar(@who);
+    my $os     = 'o' x scalar(@who);
 
     &mode($chan, "+$os @who");
 }
 
 sub deop {
     my ($chan, @who) = @_;
 
     &mode($chan, "+$os @who");
 }
 
 sub deop {
     my ($chan, @who) = @_;
-    my $os = "o" x scalar(@who);
+    my $os = 'o' x scalar(@who);
 
     &mode($chan, "-$os ".@who);
 }
 
 sub kick {
     my ($nick,$chan,$msg) = @_;
 
     &mode($chan, "-$os ".@who);
 }
 
 sub kick {
     my ($nick,$chan,$msg) = @_;
-    my (@chans) = ($chan eq "") ? (keys %channels) : lc($chan);
+    my (@chans) = ($chan eq '') ? (keys %channels) : lc($chan);
     my $mynick = $conn->nick();
 
     my $mynick = $conn->nick();
 
-    if ($chan ne "" and &validChan($chan) == 0) {
+    if ($chan ne '' and &validChan($chan) == 0) {
        &ERROR("kick: invalid channel $chan.");
        return;
     }
        &ERROR("kick: invalid channel $chan.");
        return;
     }
@@ -700,7 +722,7 @@ sub joinNextChan {
     }
 
     # chanserv check: global channels, in case we missed one.
     }
 
     # chanserv check: global channels, in case we missed one.
-    foreach ( &ChanConfList("chanServ_ops") ) {
+    foreach ( &ChanConfList('chanServ_ops') ) {
        &chanServCheck($_);
     }
 }
        &chanServCheck($_);
     }
 }
@@ -820,26 +842,35 @@ sub clearIRCVars {
 }
 
 sub getJoinChans {
 }
 
 sub getJoinChans {
-    my($show)  = @_;
+    # $show should contain the min number of seconds between display
+    # of the Chans: status line. Use 0 to disable
+    my $show = shift;
 
     my @in;
     my @skip;
     my @join;
 
 
     my @in;
     my @skip;
     my @join;
 
+    # Display "Chans:" only if more than $show seconds since last display
+    if (time() - $lastChansTime > $show) {
+       $lastChansTime = time();
+    } else {
+       $show = 0; # Don't display since < 15min since last
+    }
+
     # can't join any if not connected
     return @join if (!$conn);
 
     my $nick = $conn->nick();
 
     foreach (keys %chanconf) {
     # can't join any if not connected
     return @join if (!$conn);
 
     my $nick = $conn->nick();
 
     foreach (keys %chanconf) {
-       next if ($_ eq "_default");
+       next if ($_ eq '_default');
 
        my $skip = 0;
        my $val = $chanconf{$_}{autojoin};
 
        if (defined $val) {
 
        my $skip = 0;
        my $val = $chanconf{$_}{autojoin};
 
        if (defined $val) {
-           $skip++ if ($val eq "0");
-           if ($val eq "1") {
+           $skip++ if ($val eq '0');
+           if ($val eq '1') {
                # convert old +autojoin to autojoin <nick>
                $val = lc $nick;
                $chanconf{$_}{autojoin} = $val;
                # convert old +autojoin to autojoin <nick>
                $val = lc $nick;
                $chanconf{$_}{autojoin} = $val;
@@ -861,8 +892,8 @@ sub getJoinChans {
     }
 
     my $str;
     }
 
     my $str;
-    #$str .= ' in:' . join(',', sort @in) if scalar @in;
-    #$str .= ' skip:' . join(',', sort @skip) if scalar @skip;
+    $str .= ' in:' . join(',', sort @in) if scalar @in;
+    $str .= ' skip:' . join(',', sort @skip) if scalar @skip;
     $str .= ' join:' . join(',', sort @join) if scalar @join;
 
     &status("Chans: ($nick)$str") if ($show);
     $str .= ' join:' . join(',', sort @join) if scalar @join;
 
     &status("Chans: ($nick)$str") if ($show);
@@ -896,7 +927,7 @@ sub closeDCC {
 sub joinfloodCheck {
     my($who,$chan,$userhost) = @_;
 
 sub joinfloodCheck {
     my($who,$chan,$userhost) = @_;
 
-    return unless (&IsChanConf("joinfloodCheck") > 0);
+    return unless (&IsChanConf('joinfloodCheck') > 0);
 
     if (exists $netsplit{lc $who}) {   # netsplit join.
        &DEBUG("joinfloodCheck: $who was in netsplit; not checking.");
 
     if (exists $netsplit{lc $who}) {   # netsplit join.
        &DEBUG("joinfloodCheck: $who was in netsplit; not checking.");
@@ -960,3 +991,5 @@ sub getHostMask {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ad5ec8ba52ae3c42e82fb9d6108dba80113ff4ec..4f64ca41b1e38f3f936eb72852bb7354b75bad79 100644 (file)
 #####
 # Usage: &hookMode($nick, $modes, @targets);
 sub hookMode {
 #####
 # Usage: &hookMode($nick, $modes, @targets);
 sub hookMode {
-    my ($nick, $modes, @targets) = @_;
-    my $parity = 0;
-
-    if ($chan =~ tr/A-Z/a-z/) {
-       &VERB("hookMode: cased $chan.",2);
-    }
+    my ( $nick, $modes, @targets ) = @_;
+    my $parity = 0;
 
     my $mode;
 
     my $mode;
-    foreach $mode (split(//, $modes)) {
-       # sign.
-       if ($mode =~ /[-+]/) {
-           $parity = 1         if ($mode eq "+");
-           $parity = 0         if ($mode eq "-");
-           next;
-       }
-
-       # mode with target.
-       if ($mode =~ /[bklov]/) {
-           my $target = shift @targets;
-
-           if ($parity) {
-               $chanstats{$chan}{'Op'}++    if ($mode eq "o");
-               $chanstats{$chan}{'Ban'}++   if ($mode eq "b");
-           } else {
-               $chanstats{$chan}{'Deop'}++  if ($mode eq "o");
-               $chanstats{$chan}{'Unban'}++ if ($mode eq "b");
-           }
-
-           # modes w/ target affecting nick => cache it.
-           if ($mode =~ /[bov]/) {
-               $channels{$chan}{$mode}{$target}++      if  $parity;
-               delete $channels{$chan}{$mode}{$target} if !$parity;
-
-               # lets do some custom stuff.
-               if ($mode eq "o" and $parity) {
-                   if ($nick eq "ChanServ" and $target =~ /^\Q$ident\E$/i) {
-                       &VERB("hookmode: chanserv deopped us! asking",2);
-                       &chanServCheck($chan);
-                   }
-
-                   &chanLimitVerify($chan);
-               }
-           }
-
-           if ($mode =~ /[l]/) {
-               $channels{$chan}{$mode} = $target       if  $parity;
-               delete $channels{$chan}{$mode}          if !$parity;
-           }
-       }
-
-       # important channel modes, targetless.
-       if ($mode =~ /[mt]/) {
-           $channels{$chan}{$mode}++                   if  $parity;
-           delete $channels{$chan}{$mode}              if !$parity;
-       }
+    foreach $mode ( split( //, $modes ) ) {
+
+        # sign. tmp parity needed to store current state
+        if ( $mode =~ /[-+]/ ) {
+            $parity = 1 if ( $mode eq "+" );
+            $parity = 0 if ( $mode eq "-" );
+            next;
+        }
+
+        # mode with target.
+        if ( $mode =~ /[bklov]/ ) {
+            my $target = shift @targets;
+
+            if ($parity) {
+                $chanstats{ lc $chan }{'Op'}++  if ( $mode eq 'o' );
+                $chanstats{ lc $chan }{'Ban'}++ if ( $mode eq 'b' );
+            } else {
+                $chanstats{ lc $chan }{'Deop'}++  if ( $mode eq 'o' );
+                $chanstats{ lc $chan }{'Unban'}++ if ( $mode eq 'b' );
+            }
+
+            # modes w/ target affecting nick => cache it.
+            if ( $mode =~ /[bov]/ ) {
+                $channels{ lc $chan }{$mode}{$target}++      if $parity;
+                delete $channels{ lc $chan }{$mode}{$target} if !$parity;
+
+                # lets do some custom stuff.
+                if ( $mode =~ /o/ and not $parity ) {
+                    if ( $target =~ /^\Q$ident\E$/i ) {
+                        &VERB( "hookmode: someone deopped us!", 2 );
+                        &chanServCheck($chan);
+                    }
+
+                    &chanLimitVerify($chan);
+                }
+            }
+
+            if ( $mode =~ /[l]/ ) {
+                $channels{ lc $chan }{$mode} = $target if $parity;
+                delete $channels{ lc $chan }{$mode} if !$parity;
+            }
+        }
+
+        # important channel modes, targetless.
+        if ( $mode =~ /[mt]/ ) {
+            $channels{ lc $chan }{$mode}++      if $parity;
+            delete $channels{ lc $chan }{$mode} if !$parity;
+        }
     }
 }
 
     }
 }
 
@@ -123,13 +120,13 @@ sub hookMsg {
                $addressed = 1;
            } else {
                # ignore messages addressed to other people or unaddressed.
                $addressed = 1;
            } else {
                # ignore messages addressed to other people or unaddressed.
-               $skipmessage++ if ($2 ne "" and $2 !~ /^ /);
+               $skipmessage++ if ($2 ne '' and $2 !~ /^ /);
            }
        }
     }
 
     # Determine floodwho.
            }
        }
     }
 
     # Determine floodwho.
-    my $c      = "_default";
+    my $c      = '_default';
     if ($msgType =~ /public/i) {
        # public.
        $floodwho = $c = lc $chan;
     if ($msgType =~ /public/i) {
        # public.
        $floodwho = $c = lc $chan;
@@ -141,14 +138,14 @@ sub hookMsg {
        &FIXME("floodwho = ???");
     }
 
        &FIXME("floodwho = ???");
     }
 
-    my $val = &getChanConfDefault("floodRepeat", "2:5", $c);
+    my $val = &getChanConfDefault('floodRepeat', "2:5", $c);
     my ($count, $interval) = split /:/, $val;
 
     # flood repeat protection.
     if ($addressed) {
        my $time = $flood{$floodwho}{$message} || 0;
 
     my ($count, $interval) = split /:/, $val;
 
     # flood repeat protection.
     if ($addressed) {
        my $time = $flood{$floodwho}{$message} || 0;
 
-       if (!&IsFlag('o') and $msgType eq "public" and (time() - $time < $interval)) {
+       if (!&IsFlag('o') and $msgType eq 'public' and (time() - $time < $interval)) {
            ### public != personal who so the below is kind of pointless.
            my @who;
            foreach (keys %flood) {
            ### public != personal who so the below is kind of pointless.
            my @who;
            foreach (keys %flood) {
@@ -161,7 +158,7 @@ sub hookMsg {
            return if ($lobotomized);
 
            if (!scalar @who) {
            return if ($lobotomized);
 
            if (!scalar @who) {
-               push(@who,"Someone");
+               push(@who,'Someone');
            }
            &msg($who,join(' ', @who)." already said that ". (time - $time) ." seconds ago" );
 
            }
            &msg($who,join(' ', @who)." already said that ". (time - $time) ." seconds ago" );
 
@@ -183,14 +180,14 @@ sub hookMsg {
 
        if ($addrchar) {
            &status("$b_cyan$who$ob is short-addressing $mynick");
 
        if ($addrchar) {
            &status("$b_cyan$who$ob is short-addressing $mynick");
-       } elsif ($msgType eq "private") {       # private.
+       } elsif ($msgType eq 'private') {       # private.
            &status("$b_cyan$who$ob is /msg'ing $mynick");
        } else {                                # public?
            &status("$b_cyan$who$ob is addressing $mynick");
        }
 
        $flood{$floodwho}{$message} = time();
            &status("$b_cyan$who$ob is /msg'ing $mynick");
        } else {                                # public?
            &status("$b_cyan$who$ob is addressing $mynick");
        }
 
        $flood{$floodwho}{$message} = time();
-    } elsif ($msgType eq "public" and &IsChanConf("kickOnRepeat") > 0) {
+    } elsif ($msgType eq 'public' and &IsChanConf('kickOnRepeat') > 0) {
        # unaddressed, public only.
 
        ### TODO: use a separate "short-time" hash.
        # unaddressed, public only.
 
        ### TODO: use a separate "short-time" hash.
@@ -198,7 +195,7 @@ sub hookMsg {
        @data   = keys %{ $flood{$floodwho} } if (exists $flood{$floodwho});
     }
 
        @data   = keys %{ $flood{$floodwho} } if (exists $flood{$floodwho});
     }
 
-    $val = &getChanConfDefault("floodMessages", "5:30", $c);
+    $val = &getChanConfDefault('floodMessages', "5:30", $c);
     ($count, $interval) = split /:/, $val;
 
     # flood overflow protection.
     ($count, $interval) = split /:/, $val;
 
     # flood overflow protection.
@@ -243,6 +240,8 @@ sub hookMsg {
             $orig{message} =~ /^s\/([^;\/]*)\/([^;\/]*)\/([g]*)$/) {
        my $sedmsg = $seencache{$who}{'msg'};
        eval "\$sedmsg =~ s/\Q$1\E/\Q$2\E/$3;";
             $orig{message} =~ /^s\/([^;\/]*)\/([^;\/]*)\/([g]*)$/) {
        my $sedmsg = $seencache{$who}{'msg'};
        eval "\$sedmsg =~ s/\Q$1\E/\Q$2\E/$3;";
+       $sedmsg =~ s/^(.{255}).*$/$1.../; # 255 char max to prevent flood
+
        if ($sedmsg ne $seencache{$who}{'msg'}) {
            &DEBUG("sed \"" . $orig{message} . "\" \"" .
                    $seencache{$who}{'msg'} . "\" \"" . $sedmsg. "\"");
        if ($sedmsg ne $seencache{$who}{'msg'}) {
            &DEBUG("sed \"" . $orig{message} . "\" \"" .
                    $seencache{$who}{'msg'} . "\" \"" . $sedmsg. "\"");
@@ -257,7 +256,7 @@ sub hookMsg {
        $seencache{$who}{'msg'}  = $orig{message};
        $seencache{$who}{'msgcount'}++;
     }
        $seencache{$who}{'msg'}  = $orig{message};
        $seencache{$who}{'msgcount'}++;
     }
-    if (&IsChanConf("minVolunteerLength") > 0) {
+    if (&IsChanConf('minVolunteerLength') > 0) {
        # FIXME hack to treat unaddressed as if using addrchar
        $addrchar = 1;
     }
        # FIXME hack to treat unaddressed as if using addrchar
        $addrchar = 1;
     }
@@ -310,7 +309,7 @@ sub chanLimitVerify {
     $chan      = $c;
     my $l      = $channels{$chan}{'l'};
 
     $chan      = $c;
     my $l      = $channels{$chan}{'l'};
 
-    return unless (&IsChanConf("chanlimitcheck") > 0);
+    return unless (&IsChanConf('chanlimitcheck') > 0);
 
     if (scalar keys %netsplit) {
        &WARN("clV: netsplit active (1, chan = $chan); skipping.");
 
     if (scalar keys %netsplit) {
        &WARN("clV: netsplit active (1, chan = $chan); skipping.");
@@ -324,9 +323,9 @@ sub chanLimitVerify {
     }
 
     # only change it if it's not set.
     }
 
     # only change it if it's not set.
-    my $plus  = &getChanConfDefault("chanlimitcheckPlus", 5, $chan);
+    my $plus  = &getChanConfDefault('chanlimitcheckPlus', 5, $chan);
     my $count = scalar(keys %{ $channels{$chan}{''} });
     my $count = scalar(keys %{ $channels{$chan}{''} });
-    my $int   = &getChanConfDefault("chanlimitcheckInterval", 10, $chan);
+    my $int   = &getChanConfDefault('chanlimitcheckInterval', 10, $chan);
 
     my $delta = $count + $plus - $l;
 #   $delta    =~ s/^\-//;
 
     my $delta = $count + $plus - $l;
 #   $delta    =~ s/^\-//;
@@ -361,30 +360,26 @@ sub chanServCheck {
        return 0;
     }
 
        return 0;
     }
 
-    if ($chan =~ tr/A-Z/a-z/) {
-       &DEBUG("chanServCheck: lowercased chan ($chan)");
-    }
-
-    if (! &IsChanConf("chanServ_ops") > 0) {
-       return 0;
-    }
+    return unless (&IsChanConf('chanServCheck') > 0);
 
     &VERB("chanServCheck($chan) called.",2);
 
 
     &VERB("chanServCheck($chan) called.",2);
 
-    if ( &IsParam("nickServ_pass") and !$nickserv) {
-       $conn->who("NickServ");
+    if ( &IsParam('nickServ_pass') and !$nickserv) {
+       $conn->who('NickServ');
        return 0;
     }
 
     # check for first hash then for next hash.
     # TODO: a function for &ischanop()? &isvoice()?
        return 0;
     }
 
     # check for first hash then for next hash.
     # TODO: a function for &ischanop()? &isvoice()?
-    if (exists $channels{$chan} and exists $channels{$chan}{'o'}{$ident}) {
+    if (exists $channels{lc $chan} and exists $channels{lc $chan}{'o'}{$ident}) {
        return 0;
     }
 
     &status("ChanServ ==> Requesting ops for $chan. (chanServCheck)");
        return 0;
     }
 
     &status("ChanServ ==> Requesting ops for $chan. (chanServCheck)");
-    &rawout("PRIVMSG ChanServ :OP $chan $ident");
+    &msg('ChanServ', "OP $chan");
     return 1;
 }
 
 1;
     return 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index d105d8e366b8e981f28c55ce16a3fcb7c9eb49db..07adbb2cd6b06afa93fb4a31232ff5b5b8c7f275 100644 (file)
@@ -24,15 +24,13 @@ sub on_generic {
 sub on_action {
     $conn = shift(@_);
     my ($event) = @_;
 sub on_action {
     $conn = shift(@_);
     my ($event) = @_;
-    my ($nick, @args) = ($event->nick, $event->args);
+    my ($nick, $args) = ($event->nick, $event->args);
     my $chan = ($event->to)[0];
 
     my $chan = ($event->to)[0];
 
-    shift @args;
-
     if ($chan eq $ident) {
     if ($chan eq $ident) {
-       &status("* [$nick] @args");
+       &status("* [$nick] $args");
     } else {
     } else {
-       &status("* $nick/$chan @args");
+       &status("* $nick/$chan $args");
     }
 }
 
     }
 }
 
@@ -50,7 +48,7 @@ sub on_chat {
     }
 
     ### set vars that would have been set in hookMsg.
     }
 
     ### set vars that would have been set in hookMsg.
-    $userHandle                = "";   # reset.
+    $userHandle                = '';   # reset.
     $who               = lc $nick;
     $message           = $msg;
     $orig{who}         = $nick;
     $who               = lc $nick;
     $message           = $msg;
     $orig{who}         = $nick;
@@ -66,7 +64,7 @@ sub on_chat {
        my $crypto      = $users{$userHandle}{PASS};
        my $success     = 0;
 
        my $crypto      = $users{$userHandle}{PASS};
        my $success     = 0;
 
-       if ($userHandle eq "_default") {
+       if ($userHandle eq '_default') {
            &WARN("DCC CHAT: _default/guest not allowed.");
            return;
        }
            &WARN("DCC CHAT: _default/guest not allowed.");
            return;
        }
@@ -84,7 +82,7 @@ sub on_chat {
            $conn->privmsg($sock, "Commands start with '.' (like '.quit' or '.help')");
            $conn->privmsg($sock, "Everything else goes out to the party line.");
 
            $conn->privmsg($sock, "Commands start with '.' (like '.quit' or '.help')");
            $conn->privmsg($sock, "Everything else goes out to the party line.");
 
-           &dccStatus(2) unless (exists $sched{"dccStatus"}{RUNNING});
+           &dccStatus(2) unless (exists $sched{'dccStatus'}{RUNNING});
 
            $success++;
 
 
            $success++;
 
@@ -103,7 +101,7 @@ sub on_chat {
 
            $dcc{'CHATvrfy'}{$nick} = $userHandle;
 
 
            $dcc{'CHATvrfy'}{$nick} = $userHandle;
 
-           return if ($userHandle eq "_default");
+           return if ($userHandle eq '_default');
 
            &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}");
        }
 
            &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}");
        }
@@ -117,7 +115,7 @@ sub on_chat {
        ### TODO: make use of &Forker(); here?
        &loadMyModule('UserDCC');
 
        ### TODO: make use of &Forker(); here?
        &loadMyModule('UserDCC');
 
-       &DCCBroadcast("#$who# $message","m");
+       &DCCBroadcast("#$who# $message",'m');
 
        my $retval      = &userDCC();
        return unless (defined $retval);
 
        my $retval      = &userDCC();
        return unless (defined $retval);
@@ -160,7 +158,7 @@ sub on_endofmotd {
     # first time run.
     if (!exists $users{_default}) {
        &status("!!! First time run... adding _default user.");
     # first time run.
     if (!exists $users{_default}) {
        &status("!!! First time run... adding _default user.");
-       $users{_default}{FLAGS} = "amrt";
+       $users{_default}{FLAGS} = 'amrt';
        $users{_default}{HOSTS}{"*!*@*"} = 1;
     }
 
        $users{_default}{HOSTS}{"*!*@*"} = 1;
     }
 
@@ -183,11 +181,11 @@ sub on_endofmotd {
     }
 
     if ($firsttime) {
     }
 
     if ($firsttime) {
-       &ScheduleThis(1, "setupSchedulers");
+       &ScheduleThis(1, 'setupSchedulers');
        $firsttime = 0;
     }
 
        $firsttime = 0;
     }
 
-    if (&IsParam("ircUMode")) {
+    if (&IsParam('ircUMode')) {
        &VERB("Attempting change of user modes to $param{'ircUMode'}.", 2);
        if ($param{'ircUMode'} !~ /^[-+]/) {
            &WARN("ircUMode had no +- prefix; adding +");
        &VERB("Attempting change of user modes to $param{'ircUMode'}.", 2);
        if ($param{'ircUMode'} !~ /^[-+]/) {
            &WARN("ircUMode had no +- prefix; adding +");
@@ -204,7 +202,7 @@ sub on_endofmotd {
     $conn->ison($conn->nick());
 
     # Q, as on quakenet.org.
     $conn->ison($conn->nick());
 
     # Q, as on quakenet.org.
-    if (&IsParam("Q_pass")) {
+    if (&IsParam('Q_pass')) {
        &status("Authing to Q...");
        &rawout("PRIVMSG Q\@CServe.quakenet.org :AUTH $param{'Q_user'} $param{'Q_pass'}");
     }
        &status("Authing to Q...");
        &rawout("PRIVMSG Q\@CServe.quakenet.org :AUTH $param{'Q_user'} $param{'Q_pass'}");
     }
@@ -315,7 +313,7 @@ sub on_dcc_open {
        ### TODO: run ScheduleThis inside on_dcc_open_chat recursively
        ###     1,3,5,10 seconds then fail.
        if ($nuh{$nick} eq "GETTING-NOW") {
        ### TODO: run ScheduleThis inside on_dcc_open_chat recursively
        ###     1,3,5,10 seconds then fail.
        if ($nuh{$nick} eq "GETTING-NOW") {
-           &ScheduleThis(3/60, "on_dcc_open_chat", $nick, $sock);
+           &ScheduleThis(3/60, 'on_dcc_open_chat', $nick, $sock);
        } else {
            on_dcc_open_chat(undef, $nick, $sock);
        }
        } else {
            on_dcc_open_chat(undef, $nick, $sock);
        }
@@ -355,7 +353,7 @@ sub on_dcc_open_chat {
     $dcc{'CHAT'}{$nick} = $sock;
 
     # TODO: don't make DCC CHAT established in the first place.
     $dcc{'CHAT'}{$nick} = $sock;
 
     # TODO: don't make DCC CHAT established in the first place.
-    if ($userHandle eq "_default") {
+    if ($userHandle eq '_default') {
        &dccsay($nick, "_default/guest not allowed");
        $sock->close();
        return;
        &dccsay($nick, "_default/guest not allowed");
        $sock->close();
        return;
@@ -365,7 +363,7 @@ sub on_dcc_open_chat {
        &status("DCC CHAT: going to use ".$nick."'s crypt.");
        &dccsay($nick,"Enter your password.");
     } else {
        &status("DCC CHAT: going to use ".$nick."'s crypt.");
        &dccsay($nick,"Enter your password.");
     } else {
-#      &dccsay($nick,"Welcome to blootbot DCC CHAT interface, $userHandle.");
+#      &dccsay($nick,"Welcome to infobot DCC CHAT interface, $userHandle.");
     }
 }
 
     }
 }
 
@@ -397,7 +395,7 @@ sub on_disconnect {
 
     &WARN("scheduling call ircCheck() in 60s");
     &clearIRCVars();
 
     &WARN("scheduling call ircCheck() in 60s");
     &clearIRCVars();
-    &ScheduleThis(1, "ircCheck");
+    &ScheduleThis(1, 'ircCheck');
 }
 
 sub on_endofnames {
 }
 
 sub on_endofnames {
@@ -420,13 +418,13 @@ sub on_endofnames {
 
     my $txt;
     my @array;
 
     my $txt;
     my @array;
-    foreach ("o","v","") {
+    foreach ('o','v','') {
        my $count = scalar(keys %{ $channels{$chan}{$_} });
        next unless ($count);
 
        my $count = scalar(keys %{ $channels{$chan}{$_} });
        next unless ($count);
 
-       $txt = "total" if ($_ eq "");
-       $txt = "voice" if ($_ eq "v");
-       $txt = "ops"   if ($_ eq "o");
+       $txt = 'total' if ($_ eq '');
+       $txt = 'voice' if ($_ eq 'v');
+       $txt = 'ops'   if ($_ eq 'o');
 
        push(@array, "$count $txt");
     }
 
        push(@array, "$count $txt");
     }
@@ -477,17 +475,17 @@ sub on_join {
     my ($user,$host)   = split(/\@/, $event->userhost);
     $chan              = lc( ($event->to)[0] ); # CASING!!!!
     $who               = $event->nick();
     my ($user,$host)   = split(/\@/, $event->userhost);
     $chan              = lc( ($event->to)[0] ); # CASING!!!!
     $who               = $event->nick();
-    $msgType           = "public";
+    $msgType           = 'public';
     my $i              = scalar(keys %{ $channels{$chan} });
     my $j              = $cache{maxpeeps}{$chan} || 0;
 
     my $i              = scalar(keys %{ $channels{$chan} });
     my $j              = $cache{maxpeeps}{$chan} || 0;
 
-    if (!&IsParam("noSHM") && time() > ($sched{shmFlush}{TIME} || time()) + 3600) {
+    if (!&IsParam('noSHM') && time() > ($sched{shmFlush}{TIME} || time()) + 3600) {
        &DEBUG("looks like schedulers died somewhere... restarting...");
        &setupSchedulers();
     }
 
     $chanstats{$chan}{'Join'}++;
        &DEBUG("looks like schedulers died somewhere... restarting...");
        &setupSchedulers();
     }
 
     $chanstats{$chan}{'Join'}++;
-    $userstats{lc $who}{'Join'} = time() if (&IsChanConf("seenStats") > 0);
+    $userstats{lc $who}{'Join'} = time() if (&IsChanConf('seenStats') > 0);
     $cache{maxpeeps}{$chan}    = $i if ($i > $j);
 
     &joinfloodCheck($who, $chan, $event->userhost);
     $cache{maxpeeps}{$chan}    = $i if ($i > $j);
 
     &joinfloodCheck($who, $chan, $event->userhost);
@@ -518,7 +516,7 @@ sub on_join {
 
     # how to tell if there's a netjoin???
 
 
     # how to tell if there's a netjoin???
 
-    my $netsplitstr = "";
+    my $netsplitstr = '';
     $netsplitstr = " $b_yellow\[${ob}NETSPLIT VICTIM$b_yellow]$ob" if ($netsplit);
     &status(">>> join/$b_blue$chan$ob $b_cyan$who$ob $b_yellow($ob$user\@$host$b_yellow)$ob$netsplitstr");
 
     $netsplitstr = " $b_yellow\[${ob}NETSPLIT VICTIM$b_yellow]$ob" if ($netsplit);
     &status(">>> join/$b_blue$chan$ob $b_cyan$who$ob $b_yellow($ob$user\@$host$b_yellow)$ob$netsplitstr");
 
@@ -529,7 +527,7 @@ sub on_join {
     ### on-join bans.
     my @bans;
     push(@bans, keys %{ $bans{$chan} }) if (exists $bans{$chan});
     ### on-join bans.
     my @bans;
     push(@bans, keys %{ $bans{$chan} }) if (exists $bans{$chan});
-    push(@bans, keys %{ $bans{"*"} })   if (exists $bans{"*"});
+    push(@bans, keys %{ $bans{'*'} })   if (exists $bans{'*'});
 
     foreach (@bans) {
        my $ban = $_;
 
     foreach (@bans) {
        my $ban = $_;
@@ -544,7 +542,7 @@ sub on_join {
        }
 
        my $reason = "no reason";
        }
 
        my $reason = "no reason";
-       foreach ($chan, "*") {
+       foreach ($chan, '*') {
            next unless (exists $bans{$_});
            next unless (exists $bans{$_}{$ban});
 
            next unless (exists $bans{$_});
            next unless (exists $bans{$_}{$ban});
 
@@ -637,7 +635,7 @@ sub on_mode {
     $chan      = ($event->to)[0];
 
     # last element is empty... so nuke it.
     $chan      = ($event->to)[0];
 
     # last element is empty... so nuke it.
-    pop @args while ($args[$#args] eq "");
+    pop @args while ($args[$#args] eq '');
 
     if ($nick eq $chan) {      # UMODE
        &status(">>> mode $b_yellow\[$ob$b@args$b_yellow\]$ob by $b_cyan$nick$ob");
 
     if ($nick eq $chan) {      # UMODE
        &status(">>> mode $b_yellow\[$ob$b@args$b_yellow\]$ob by $b_cyan$nick$ob");
@@ -670,7 +668,7 @@ sub on_msg {
     $h         = $host;
 
     if ($nick eq $ident) { # hopefully ourselves.
     $h         = $host;
 
     if ($nick eq $ident) { # hopefully ourselves.
-       if ($msg eq "TEST") {
+       if ($msg eq 'TEST') {
            &status("IRCTEST: Yes, we're alive.");
            delete $cache{connect};
            return;
            &status("IRCTEST: Yes, we're alive.");
            delete $cache{connect};
            return;
@@ -678,9 +676,9 @@ sub on_msg {
     }
 
     &hookMsg('private', undef, $nick, $msg);
     }
 
     &hookMsg('private', undef, $nick, $msg);
-    $who       = "";
-    $chan      = "";
-    $msgType   = "";
+    $who       = '';
+    $chan      = '';
+    $msgType   = '';
 }
 
 sub on_names {
 }
 
 sub on_names {
@@ -739,7 +737,7 @@ sub on_nick_taken {
     $conn = shift(@_);
     my $nick   = $conn->nick();
     #my $newnick = $nick . int(rand 10);
     $conn = shift(@_);
     my $nick   = $conn->nick();
     #my $newnick = $nick . int(rand 10);
-    my $newnick = $nick . "_";
+    my $newnick = $nick . '_';
 
     &DEBUG("on_nick_taken: nick => $nick");
 
 
     &DEBUG("on_nick_taken: nick => $nick");
 
@@ -769,7 +767,7 @@ sub on_notice {
        if ($check) {
            &status("nickserv told us to register; doing it.");
 
        if ($check) {
            &status("nickserv told us to register; doing it.");
 
-           if (&IsParam("nickServ_pass")) {
+           if (&IsParam('nickServ_pass')) {
                &status("NickServ: ==> Identifying.");
                &rawout("PRIVMSG NickServ :IDENTIFY $param{'nickServ_pass'}");
                return;
                &status("NickServ: ==> Identifying.");
                &rawout("PRIVMSG NickServ :IDENTIFY $param{'nickServ_pass'}");
                return;
@@ -782,7 +780,7 @@ sub on_notice {
        if ($args =~ /^Password a/i) {
            my $done    = 0;
 
        if ($args =~ /^Password a/i) {
            my $done    = 0;
 
-           foreach ( &ChanConfList("chanServ_ops") ) {
+           foreach ( &ChanConfList('chanServ_ops') ) {
                next unless &chanServCheck($_);
                next if ($done);
                &DEBUG("nickserv activated or restarted; doing chanserv check.");
                next unless &chanServCheck($_);
                next if ($done);
                &DEBUG("nickserv activated or restarted; doing chanserv check.");
@@ -823,7 +821,7 @@ sub on_part {
     my $nick   = $event->nick;
     my $userhost = $event->userhost;
     $who       = $nick;
     my $nick   = $event->nick;
     my $userhost = $event->userhost;
     $who       = $nick;
-    $msgType   = "public";
+    $msgType   = 'public';
 
     if (!exists $channels{$chan}) {
        &DEBUG("on_part: found out $mynick is on $chan!");
 
     if (!exists $channels{$chan}) {
        &DEBUG("on_part: found out $mynick is on $chan!");
@@ -840,7 +838,7 @@ sub on_part {
        &clearChanVars($chan);
     }
 
        &clearChanVars($chan);
     }
 
-    if (!&IsNickInAnyChan($nick) and &IsChanConf("seenStats") > 0) {
+    if (!&IsNickInAnyChan($nick) and &IsChanConf('seenStats') > 0) {
        delete $userstats{lc $nick};
     }
 
        delete $userstats{lc $nick};
     }
 
@@ -880,7 +878,7 @@ sub on_public {
     $who       = $nick;
     $uh                = $event->userhost();
     $nuh       = $nick."!".$uh;
     $who       = $nick;
     $uh                = $event->userhost();
     $nuh       = $nick."!".$uh;
-    $msgType   = "public";
+    $msgType   = 'public';
     # TODO: move this out of hookMsg to here?
     ($user,$host) = split(/\@/, $uh);
     $h         = $host;
     # TODO: move this out of hookMsg to here?
     ($user,$host) = split(/\@/, $uh);
     $h         = $host;
@@ -894,7 +892,7 @@ sub on_public {
     $msgtime           = time();
     $lastWho{$chan}    = $nick;
     ### TODO: use $nick or lc $nick?
     $msgtime           = time();
     $lastWho{$chan}    = $nick;
     ### TODO: use $nick or lc $nick?
-    if (&IsChanConf("seenStats") > 0) {
+    if (&IsChanConf('seenStats') > 0) {
        $userstats{lc $nick}{'Count'}++;
        $userstats{lc $nick}{'Time'} = time();
     }
        $userstats{lc $nick}{'Count'}++;
        $userstats{lc $nick}{'Time'} = time();
     }
@@ -903,7 +901,7 @@ sub on_public {
     my $time   = time();
     if (!$cache{ircTextCounters}) {
        &DEBUG("caching ircTextCounters for first time.");
     my $time   = time();
     if (!$cache{ircTextCounters}) {
        &DEBUG("caching ircTextCounters for first time.");
-       my @str = split(/\s+/, &getChanConf("ircTextCounters"));
+       my @str = split(/\s+/, &getChanConf('ircTextCounters'));
        for (@str) { $_ = quotemeta($_); }
        $cache{ircTextCounters} = join('|', @str);
     }
        for (@str) { $_ = quotemeta($_); }
        $cache{ircTextCounters} = join('|', @str);
     }
@@ -913,11 +911,11 @@ sub on_public {
        my $x = $1;
 
        &VERB("textcounters: $x matched for $who",2);
        my $x = $1;
 
        &VERB("textcounters: $x matched for $who",2);
-       my $c = $chan || "PRIVATE";
+       my $c = $chan || 'PRIVATE';
 
        # better to do "counter=counter+1".
        # but that will avoid time check.
 
        # better to do "counter=counter+1".
        # but that will avoid time check.
-       my ($v,$t) = &sqlSelect("stats", "counter,time", {
+       my ($v,$t) = &sqlSelect('stats', "counter,time", {
                        nick    => $who,
                        type    => $x,
                        channel => $c,
                        nick    => $who,
                        type    => $x,
                        channel => $c,
@@ -925,9 +923,8 @@ sub on_public {
        $v++;
 
        # don't allow ppl to cheat the stats :-)
        $v++;
 
        # don't allow ppl to cheat the stats :-)
-       if (defined $t && $time - $t > 60) {
-           &sqlReplace("stats", {
-               nick    => $who,
+       if ((defined $t && $time - $t > 60) or (!defined $t)) {
+           &sqlSet('stats', {'nick' => $who}, {
                type    => $x,
                channel => $c,
                time    => $time,
                type    => $x,
                channel => $c,
                time    => $time,
@@ -938,9 +935,9 @@ sub on_public {
 
     &hookMsg('public', $chan, $nick, $msg);
     $chanstats{$chan}{'PublicMsg'}++;
 
     &hookMsg('public', $chan, $nick, $msg);
     $chanstats{$chan}{'PublicMsg'}++;
-    $who       = "";
-    $chan      = "";
-    $msgType   = "";
+    $who       = '';
+    $chan      = '';
+    $msgType   = '';
 }
 
 sub on_quit {
 }
 
 sub on_quit {
@@ -950,7 +947,7 @@ sub on_quit {
     my $reason = ($event->args)[0];
 
     # hack for ICC.
     my $reason = ($event->args)[0];
 
     # hack for ICC.
-    $msgType   = "public";
+    $msgType   = 'public';
     $who       = $nick;
 ###    $chan   = $reason;      # no.
 
     $who       = $nick;
 ###    $chan   = $reason;      # no.
 
@@ -974,7 +971,7 @@ sub on_quit {
 
        # chanlimit code.
        foreach $chan ( &getNickInChans($nick) ) {
 
        # chanlimit code.
        foreach $chan ( &getNickInChans($nick) ) {
-           next unless ( &IsChanConf("chanlimitcheck") > 0);
+           next unless ( &IsChanConf('chanlimitcheck') > 0);
            next unless ( exists $channels{$_}{'l'} );
 
            &DEBUG("on_quit: netsplit detected on $_; disabling chan limit.");
            next unless ( exists $channels{$_}{'l'} );
 
            &DEBUG("on_quit: netsplit detected on $_; disabling chan limit.");
@@ -1001,7 +998,7 @@ sub on_quit {
        # well.. it's good but weird that this has happened - lets just
        # be quiet about it.
     }
        # well.. it's good but weird that this has happened - lets just
        # be quiet about it.
     }
-    delete $userstats{lc $nick} if (&IsChanConf("seenStats") > 0);
+    delete $userstats{lc $nick} if (&IsChanConf('seenStats') > 0);
     delete $chanstats{lc $nick};
     ###
 
     delete $chanstats{lc $nick};
     ###
 
@@ -1280,3 +1277,5 @@ sub on_stdin {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 1327833e457e29ef50dcf9bb45815c2c4d432837..18c649d384eb9a9b7c056181bbe633dc7fa65317 100644 (file)
@@ -18,7 +18,7 @@ use vars qw(%sched %schedule);
 # )
 
 #%schedule = {
 # )
 
 #%schedule = {
-#      uptimeLoop => ("", 60, 1),
+#      uptimeLoop => ('', 60, 1),
 #};
 
 sub setupSchedulersII {
 #};
 
 sub setupSchedulersII {
@@ -70,6 +70,7 @@ sub setupSchedulers {
     &factoidCheck(2);  # takes a couple of seconds on a 486. defer it
 # TODO: convert to new format... or nuke altogether.
     &newsFlush(2);
     &factoidCheck(2);  # takes a couple of seconds on a 486. defer it
 # TODO: convert to new format... or nuke altogether.
     &newsFlush(2);
+    &rssFeeds(2);
 
     # 1 for run straight away
     &uptimeLoop(1);
 
     # 1 for run straight away
     &uptimeLoop(1);
@@ -99,7 +100,8 @@ sub setupSchedulers {
 
 sub ScheduleThis {
     my ($interval, $codename, @args) = @_;
 
 sub ScheduleThis {
     my ($interval, $codename, @args) = @_;
-    my $waittime = &getRandomInt($interval);
+    # Set to supllied value plus a random 0-60 seconds to avoid simultaneous runs
+    my $waittime = &getRandomInt("$interval-" . ($interval+&getRandomInt(60) ) );
 
     if (!defined $waittime) {
        &WARN("interval == waittime == UNDEF for $codename.");
 
     if (!defined $waittime) {
        &WARN("interval == waittime == UNDEF for $codename.");
@@ -124,17 +126,33 @@ sub ScheduleThis {
 #### LET THE FUN BEGIN.
 ####
 
 #### LET THE FUN BEGIN.
 ####
 
+sub rssFeeds {
+  my $interval = $param{'rssFeedTime'} || 30;
+  if (@_) {
+    &ScheduleThis( $interval*60, 'rssFeeds' ); # minutes
+    return if ( $_[0] eq '2' );    # defer.
+  }
+  &Forker(
+    'RSSFeeds',
+    sub {
+      my $line = &RSSFeeds::RSS();
+      return unless ( defined $line );
+
+    }
+  );
+}
+
 sub randomQuote {
 sub randomQuote {
-    my $interval = &getChanConfDefault("randomQuoteInterval", 60, $chan);
+    my $interval = &getChanConfDefault('randomQuoteInterval', 60, $chan);
     if (@_) {
     if (@_) {
-       &ScheduleThis($interval, "randomQuote");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis($interval*60, 'randomQuote'); # every hour
+       return if ($_[0] eq '2');       # defer.
     }
 
     }
 
-    foreach ( &ChanConfList("randomQuote") ) {
+    foreach ( &ChanConfList('randomQuote') ) {
        next unless (&validChan($_));
 
        next unless (&validChan($_));
 
-       my $line = &getRandomLineFromFile($bot_data_dir. "/blootbot.randtext");
+       my $line = &getRandomLineFromFile($bot_data_dir. "/infobot.randtext");
        if (!defined $line) {
            &ERROR("random Quote: weird error?");
            return;
        if (!defined $line) {
            &ERROR("random Quote: weird error?");
            return;
@@ -151,18 +169,18 @@ sub randomFactoid {
     my ($key,$val);
     my $error = 0;
 
     my ($key,$val);
     my $error = 0;
 
-    my $interval = &getChanConfDefault("randomFactoidInterval", 60, $chan);
+    my $interval = &getChanConfDefault('randomFactoidInterval', 60, $chan);
     if (@_) {
     if (@_) {
-       &ScheduleThis($interval, "randomFactoid");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis($interval*60, 'randomFactoid'); # minutes
+       return if ($_[0] eq '2');       # defer.
     }
 
     }
 
-    foreach ( &ChanConfList("randomFactoid") ) {
+    foreach ( &ChanConfList('randomFactoid') ) {
        next unless (&validChan($_));
 
        &status("sending random Factoid to $_.");
        while (1) {
        next unless (&validChan($_));
 
        &status("sending random Factoid to $_.");
        while (1) {
-           ($key,$val) = &randKey("factoids","factoid_key,factoid_value");
+           ($key,$val) = &randKey('factoids',"factoid_key,factoid_value");
            &DEBUG("rF: $key, $val");
 ###        $val =~ tr/^[A-Z]/[a-z]/;   # blah is Good => blah is good.
            last if ((defined $val) and ($val !~ /^</) and ($key !~ /\#DEL\#/) and ($key !~ /^cmd:/));
            &DEBUG("rF: $key, $val");
 ###        $val =~ tr/^[A-Z]/[a-z]/;   # blah is Good => blah is good.
            last if ((defined $val) and ($val !~ /^</) and ($key !~ /\#DEL\#/) and ($key !~ /^cmd:/));
@@ -181,13 +199,13 @@ sub randomFactoid {
 
 sub logLoop {
     if (@_) {
 
 sub logLoop {
     if (@_) {
-       &ScheduleThis(60, "logLoop");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(3600, 'logLoop'); # 1 hour
+       return if ($_[0] eq '2');       # defer.
     }
 
     return unless (defined fileno LOG);
     }
 
     return unless (defined fileno LOG);
-    return unless (&IsParam("logfile"));
-    return unless (&IsParam("maxLogSize"));
+    return unless (&IsParam('logfile'));
+    return unless (&IsParam('maxLogSize'));
 
     ### check if current size is too large.
     if ( -s $file{log} > $param{'maxLogSize'}) {
 
     ### check if current size is too large.
     if ( -s $file{log} > $param{'maxLogSize'}) {
@@ -250,18 +268,16 @@ sub logLoop {
 
 sub seenFlushOld {
     if (@_) {
 
 sub seenFlushOld {
     if (@_) {
-       &ScheduleThis(1440, "seenFlushOld");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(86400, 'seenFlushOld'); # 1 day
+       return if ($_[0] eq '2');       # defer.
     }
 
     }
 
-    # NO SEEN FLUSHING!!!
-    return;
     # is this global-only?
     # is this global-only?
-    return unless (&IsChanConf("seen") > 0);
-    return unless (&IsChanConf("seenFlushInterval") > 0);
+    return unless (&IsChanConf('seen') > 0);
+    return unless (&IsChanConf('seenFlushInterval') > 0);
 
     # global setting. does not make sense for per-channel.
 
     # global setting. does not make sense for per-channel.
-    my $max_time = &getChanConfDefault("seenMaxDays", 30, $chan) *60*60*24;
+    my $max_time = &getChanConfDefault('seenMaxDays', 30, $chan) *60*60*24;
     my $delete   = 0;
 
     if ($param{'DBType'} =~ /^(pgsql|mysql|sqlite(2)?)$/i) {
     my $delete   = 0;
 
     if ($param{'DBType'} =~ /^(pgsql|mysql|sqlite(2)?)$/i) {
@@ -280,7 +296,7 @@ sub seenFlushOld {
            while (my @row = $sth->fetchrow_array) {
                my ($nick,$time) = @row;
 
            while (my @row = $sth->fetchrow_array) {
                my ($nick,$time) = @row;
 
-               &sqlDelete("seen", { nick => $nick } );
+               &sqlDelete('seen', { nick => $nick } );
                $delete++;
            }
            $sth->finish;
                $delete++;
            }
            $sth->finish;
@@ -294,8 +310,8 @@ sub seenFlushOld {
 
 sub newsFlush {
     if (@_) {
 
 sub newsFlush {
     if (@_) {
-       &ScheduleThis(60, "newsFlush");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(3600, 'newsFlush'); # 1 hour
+       return if ($_[0] eq '2');       # defer.
     }
 
     if (!&ChanConfList('News')) {
     }
 
     if (!&ChanConfList('News')) {
@@ -371,25 +387,25 @@ sub newsFlush {
 }
 
 sub chanlimitCheck {
 }
 
 sub chanlimitCheck {
-    my $interval = &getChanConfDefault("chanlimitcheckInterval", 10, $chan);
+    my $interval = &getChanConfDefault('chanlimitcheckInterval', 10, $chan);
     my $mynick=$conn->nick();
 
     if (@_) {
     my $mynick=$conn->nick();
 
     if (@_) {
-       &ScheduleThis($interval, "chanlimitCheck");
-       return if ($_[0] eq "2");
+       &ScheduleThis($interval*60, 'chanlimitCheck'); # default 10 minutes
+       return if ($_[0] eq '2');
     }
 
     }
 
-    my $str = join(' ', &ChanConfList("chanlimitcheck") );
+    my $str = join(' ', &ChanConfList('chanlimitcheck') );
 
 
-    foreach $chan ( &ChanConfList("chanlimitcheck") ) {
+    foreach $chan ( &ChanConfList('chanlimitcheck') ) {
        next unless (&validChan($chan));
 
        next unless (&validChan($chan));
 
-       if ($chan eq "_default") {
+       if ($chan eq '_default') {
            &WARN("chanlimit: we're doing $chan!! HELP ME!");
            next;
        }
 
            &WARN("chanlimit: we're doing $chan!! HELP ME!");
            next;
        }
 
-       my $limitplus   = &getChanConfDefault("chanlimitcheckPlus", 5, $chan);
+       my $limitplus   = &getChanConfDefault('chanlimitcheckPlus', 5, $chan);
        my $newlimit    = scalar(keys %{ $channels{$chan}{''} }) + $limitplus;
        my $limit       = $channels{$chan}{'l'};
 
        my $newlimit    = scalar(keys %{ $channels{$chan}{''} }) + $limitplus;
        my $limit       = $channels{$chan}{'l'};
 
@@ -443,8 +459,8 @@ sub netsplitCheck {
     my ($s1,$s2);
 
     if (@_) {
     my ($s1,$s2);
 
     if (@_) {
-       &ScheduleThis(15, "netsplitCheck");
-       return if ($_[0] eq "2");
+       &ScheduleThis(300, 'netsplitCheck'); # every 5 minutes
+       return if ($_[0] eq '2');
     }
 
     $cache{'netsplitCache'}++;
     }
 
     $cache{'netsplitCache'}++;
@@ -491,9 +507,10 @@ sub netsplitCheck {
     }
 
     # yet another hack.
     }
 
     # yet another hack.
-    foreach (keys %channels) {
-       my $i = $cache{maxpeeps}{$chan} || 0;
-       my $j = scalar(keys %{ $channels{$chan} });
+    # FIXED: $ch should be used rather than $chan since it creates NULL channels in the hash
+    foreach my $ch (keys %channels) {
+       my $i = $cache{maxpeeps}{$ch} || 0;
+       my $j = scalar(keys %{ $channels{$ch} });
        next unless ($i > 10 and 0.25*$i > $j);
 
        &DEBUG("netsplit: 0.25*max($i) > current($j); possible netsplit?");
        next unless ($i > 10 and 0.25*$i > $j);
 
        &DEBUG("netsplit: 0.25*max($i) > current($j); possible netsplit?");
@@ -520,12 +537,12 @@ sub floodLoop {
     my $who;
 
     if (@_) {
     my $who;
 
     if (@_) {
-       &ScheduleThis(60, "floodLoop"); # minutes.
-       return if ($_[0] eq "2");
+       &ScheduleThis(60, 'floodLoop'); # 1 minute
+       return if ($_[0] eq '2');
     }
 
     my $time           = time();
     }
 
     my $time           = time();
-    my $interval       = &getChanConfDefault("floodCycle",60, $chan);
+    my $interval       = &getChanConfDefault('floodCycle',60, $chan);
 
     foreach $who (keys %flood) {
        foreach (keys %{ $flood{$who} }) {
 
     foreach $who (keys %flood) {
        foreach (keys %{ $flood{$who} }) {
@@ -545,29 +562,25 @@ sub floodLoop {
 
 sub seenFlush {
     if (@_) {
 
 sub seenFlush {
     if (@_) {
-       my $interval = &getChanConfDefault("seenFlushInterval", 60, $chan);
-       &ScheduleThis($interval, "seenFlush");
-       return if ($_[0] eq "2");
+       my $interval = &getChanConfDefault('seenFlushInterval', 60, $chan);
+       &ScheduleThis($interval*60, 'seenFlush'); # minutes
+       return if ($_[0] eq '2');
     }
 
     my %stats;
     my $nick;
     my $flushed = 0;
     }
 
     my %stats;
     my $nick;
     my $flushed = 0;
-    $stats{'count_old'} = &countKeys("seen") || 0;
+    $stats{'count_old'} = &countKeys('seen') || 0;
     $stats{'new'}      = 0;
     $stats{'old'}      = 0;
 
     if ($param{'DBType'} =~ /^(mysql|pgsql|sqlite(2)?)$/i) {
        foreach $nick (keys %seencache) {
     $stats{'new'}      = 0;
     $stats{'old'}      = 0;
 
     if ($param{'DBType'} =~ /^(mysql|pgsql|sqlite(2)?)$/i) {
        foreach $nick (keys %seencache) {
-           my $lastcount = &sqlSelect('seen','messagecount',{nick=>lc $seencache{$nick}{'nick'}}) || 0;
-           my $retval = &sqlReplace("seen", {
-                       nick    => lc $seencache{$nick}{'nick'},
+           my $retval = &sqlSet('seen', {'nick' => lc $seencache{$nick}{'nick'}}, {
                        time    => $seencache{$nick}{'time'},
                        host    => $seencache{$nick}{'host'},
                        channel => $seencache{$nick}{'chan'},
                        message => $seencache{$nick}{'msg'},
                        time    => $seencache{$nick}{'time'},
                        host    => $seencache{$nick}{'host'},
                        channel => $seencache{$nick}{'chan'},
                        message => $seencache{$nick}{'msg'},
-                       messagecount => $lastcount+$seencache{$nick}{'msgcount'},
-                                               
            } );
 
            delete $seencache{$nick};
            } );
 
            delete $seencache{$nick};
@@ -582,8 +595,8 @@ sub seenFlush {
        $stats{'new'}*100/($stats{'count_old'} || 1),
        $stats{'new'}, ( $stats{'count_old'} || 1) ), 2) if ($stats{'new'});
     &VERB(sprintf("  now seen: %3.1f%% (%d/%d)",
        $stats{'new'}*100/($stats{'count_old'} || 1),
        $stats{'new'}, ( $stats{'count_old'} || 1) ), 2) if ($stats{'new'});
     &VERB(sprintf("  now seen: %3.1f%% (%d/%d)",
-       $stats{'old'}*100 / ( &countKeys("seen") || 1),
-       $stats{'old'}, &countKeys("seen") ), 2)         if ($stats{'old'});
+       $stats{'old'}*100 / ( &countKeys('seen') || 1),
+       $stats{'old'}, &countKeys('seen') ), 2)         if ($stats{'old'});
 
     &WARN("scalar keys seenflush != 0!")       if (scalar keys %seenflush);
 }
 
     &WARN("scalar keys seenflush != 0!")       if (scalar keys %seenflush);
 }
@@ -593,8 +606,8 @@ sub leakCheck {
     my $count = 0;
 
     if (@_) {
     my $count = 0;
 
     if (@_) {
-       &ScheduleThis(240, "leakCheck");
-       return if ($_[0] eq "2");
+       &ScheduleThis(14400, 'leakCheck'); # every 4 hours
+       return if ($_[0] eq '2');
     }
 
     # flood. this is dealt with in floodLoop()
     }
 
     # flood. this is dealt with in floodLoop()
@@ -649,8 +662,8 @@ sub leakCheck {
 
 sub ignoreCheck {
     if (@_) {
 
 sub ignoreCheck {
     if (@_) {
-       &ScheduleThis(60, "ignoreCheck");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(60, 'ignoreCheck'); # once every minute
+       return if ($_[0] eq '2');       # defer.
     }
 
     my $time   = time();
     }
 
     my $time   = time();
@@ -677,8 +690,8 @@ sub ignoreCheck {
 
 sub ircCheck {
     if (@_) {
 
 sub ircCheck {
     if (@_) {
-       &ScheduleThis(15, "ircCheck");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(300, 'ircCheck'); # every 5 minutes
+       return if ($_[0] eq '2');       # defer.
     }
 
     $cache{statusSafe} = 1;
     }
 
     $cache{statusSafe} = 1;
@@ -686,17 +699,13 @@ sub ircCheck {
        $conn=$conns{$_};
        my $mynick=$conn->nick();
        &DEBUG("ircCheck for $_");
        $conn=$conns{$_};
        my $mynick=$conn->nick();
        &DEBUG("ircCheck for $_");
-       my @join = &getJoinChans(1);
+       my @join = &getJoinChans(900); # Display with min of 900sec delay between redisplay
        if (scalar @join) {
            &FIXME('ircCheck: found channels to join! ' . join(',',@join));
            &joinNextChan();
        }
 
        if (scalar @join) {
            &FIXME('ircCheck: found channels to join! ' . join(',',@join));
            &joinNextChan();
        }
 
-    my @join = &getJoinChans(1);
-    if (scalar @join) {
-       &FIXME('ircCheck: found channels to join! ' . join(',',@join));
-       &joinNextChan();
-    }
+       # TODO: fix on_disconnect()
 
        if (time() - $msgtime > 3600) {
            # TODO: shouldn't we use cache{connect} somewhere?
 
        if (time() - $msgtime > 3600) {
            # TODO: shouldn't we use cache{connect} somewhere?
@@ -708,28 +717,28 @@ sub ircCheck {
            } else {
                &status('ircCheck: possible lost in space; checking.'.
                    scalar(gmtime) );
            } else {
                &status('ircCheck: possible lost in space; checking.'.
                    scalar(gmtime) );
-               &msg($mynick, "TEST");
+               &msg($mynick, 'TEST');
                $cache{connect} = time();
            }
        }
     }
 
                $cache{connect} = time();
            }
        }
     }
 
-       if (grep /^\s*$/, keys %channels) {
-           &WARN('ircCheck: we have a NULL chan in hash channels? removing!');
-           if (!exists $channels{''}) {
-               &DEBUG('ircCheck: this should never happen!');
-           }
-      }
-    if ($ident !~ /^\Q$param{ircNick}\E$/) {
-       # this does not work unfortunately.
-       &WARN("ircCheck: ident($ident) != param{ircNick}($param{ircNick}).");
-
-       # this check is misleading... perhaps we should do a notify.
-       if (! &IsNickInAnyChan( $param{ircNick} ) ) {
-           &DEBUG("$param{ircNick} not in use... changing!");
-           &nick( $param{ircNick} );
-       } else {
-           &WARN("$param{ircNick} is still in use...");
+        if (grep /^\s*$/, keys %channels) {
+            &WARN('ircCheck: we have a NULL chan in hash channels? removing!');
+            if (!exists $channels{''}) {
+                &DEBUG('ircCheck: this should never happen!');
+            }
+       }
+     if ($ident !~ /^\Q$param{ircNick}\E$/) {
+       # this does not work unfortunately.
+       &WARN("ircCheck: ident($ident) != param{ircNick}($param{ircNick}).");
+
+       # this check is misleading... perhaps we should do a notify.
+       if (! &IsNickInAnyChan( $param{ircNick} ) ) {
+           &DEBUG("$param{ircNick} not in use... changing!");
+           &nick( $param{ircNick} );
+       } else {
+           &WARN("$param{ircNick} is still in use...");
        }
     }
 
        }
     }
 
@@ -749,8 +758,8 @@ sub ircCheck {
 
 sub miscCheck {
     if (@_) {
 
 sub miscCheck {
     if (@_) {
-       &ScheduleThis(120, "miscCheck");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(7200, 'miscCheck'); # every 2 hours
+       return if ($_[0] eq '2');       # defer.
     }
 
     # SHM check.
     }
 
     # SHM check.
@@ -763,9 +772,9 @@ sub miscCheck {
     }
 
     # make backup of important files.
     }
 
     # make backup of important files.
-    &mkBackup( $bot_state_dir."/blootbot.chan", 60*60*24*3);
-    &mkBackup( $bot_state_dir."/blootbot.users", 60*60*24*3);
-    &mkBackup( $bot_base_dir."/blootbot-news.txt", 60*60*24*1);
+    &mkBackup( $bot_state_dir."/infobot.chan", 60*60*24*3);
+    &mkBackup( $bot_state_dir."/infobot.users", 60*60*24*3);
+    &mkBackup( $bot_base_dir."/infobot-news.txt", 60*60*24*1);
 
     # flush cache{lobotomy}
     foreach (keys %{ $cache{lobotomy} }) {
 
     # flush cache{lobotomy}
     foreach (keys %{ $cache{lobotomy} }) {
@@ -796,7 +805,7 @@ sub miscCheck {
            # don't touch other bots, if they're running.
            next unless ($param{ircUser} =~ /^\Q$n\E$/);
        } else {
            # don't touch other bots, if they're running.
            next unless ($param{ircUser} =~ /^\Q$n\E$/);
        } else {
-           &DEBUG("shm: $shmid is not ours or old blootbot => ($z)");
+           &DEBUG("shm: $shmid is not ours or old infobot => ($z)");
            next;
        }
 
            next;
        }
 
@@ -807,8 +816,8 @@ sub miscCheck {
 
 sub miscCheck2 {
     if (@_) {
 
 sub miscCheck2 {
     if (@_) {
-       &ScheduleThis(240, "miscCheck2");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(14400, 'miscCheck2'); # every 4 hours
+       return if ($_[0] eq '2');       # defer.
     }
 
     # debian check.
     }
 
     # debian check.
@@ -853,8 +862,8 @@ sub getNickInUse {
 #    }
 #
 #    if (@_) {
 #    }
 #
 #    if (@_) {
-#      &ScheduleThis(30, "getNickInUse");
-#      return if ($_[0] eq "2");       # defer.
+#      &ScheduleThis(30, 'getNickInUse');
+#      return if ($_[0] eq '2');       # defer.
 #    }
 #
 #    &nick( $param{'ircNick'} );
 #    }
 #
 #    &nick( $param{'ircNick'} );
@@ -865,7 +874,7 @@ sub uptimeLoop {
 #    return unless &IsParam('Uptime');
 
     if (@_) {
 #    return unless &IsParam('Uptime');
 
     if (@_) {
-       &ScheduleThis(60, 'uptimeLoop');
+       &ScheduleThis(3600, 'uptimeLoop'); # once per hour
        return if ($_[0] eq '2');       # defer.
     }
 
        return if ($_[0] eq '2');       # defer.
     }
 
@@ -875,8 +884,8 @@ sub uptimeLoop {
 sub slashdotLoop {
 
     if (@_) {
 sub slashdotLoop {
 
     if (@_) {
-       &ScheduleThis(60, 'slashdotLoop');
-       return if ($_[0] eq "2");
+       &ScheduleThis(3600, 'slashdotLoop'); # once per hour
+       return if ($_[0] eq '2');
     }
 
     my @chans = &ChanConfList('slashdotAnnounce');
     }
 
     my @chans = &ChanConfList('slashdotAnnounce');
@@ -898,8 +907,8 @@ sub slashdotLoop {
 sub plugLoop {
 
     if (@_) {
 sub plugLoop {
 
     if (@_) {
-       &ScheduleThis(60, 'plugLoop');
-       return if ($_[0] eq "2");
+       &ScheduleThis(3600, 'plugLoop'); # once per hour
+       return if ($_[0] eq '2');
     }
 
     my @chans = &ChanConfList('plugAnnounce');
     }
 
     my @chans = &ChanConfList('plugAnnounce');
@@ -920,14 +929,14 @@ sub plugLoop {
 
 sub kernelLoop {
     if (@_) {
 
 sub kernelLoop {
     if (@_) {
-       &ScheduleThis(240, "kernelLoop");
-       return if ($_[0] eq "2");
+       &ScheduleThis(14400, 'kernelLoop'); # once every 4 hours
+       return if ($_[0] eq '2');
     }
 
     }
 
-    my @chans = &ChanConfList("kernelAnnounce");
+    my @chans = &ChanConfList('kernelAnnounce');
     return unless (scalar @chans);
 
     return unless (scalar @chans);
 
-    &Forker("Kernel", sub {
+    &Forker('Kernel', sub {
        my @data = &Kernel::kernelAnnounce();
 
        foreach (@chans) {
        my @data = &Kernel::kernelAnnounce();
 
        foreach (@chans) {
@@ -948,12 +957,12 @@ sub wingateCheck {
     ### FILE CACHE OF OFFENDING WINGATES.
     foreach (grep /^$host$/, @wingateBad) {
        &status("Wingate: RUNNING ON $host BY $who");
     ### FILE CACHE OF OFFENDING WINGATES.
     foreach (grep /^$host$/, @wingateBad) {
        &status("Wingate: RUNNING ON $host BY $who");
-       &ban("*!*\@$host", "") if &IsChanConf('wingateBan') > 0;
+       &ban("*!*\@$host", '') if &IsChanConf('wingateBan') > 0;
 
        my $reason      = &getChanConf('wingateKick');
 
        next unless ($reason);
 
        my $reason      = &getChanConf('wingateKick');
 
        next unless ($reason);
-       &kick($who, "", $reason)
+       &kick($who, '', $reason)
     }
 
     ### RUN CACHE OF TRIED WINGATES.
     }
 
     ### RUN CACHE OF TRIED WINGATES.
@@ -978,8 +987,8 @@ sub wingateCheck {
 ### TODO: ??
 sub wingateWriteFile {
     if (@_) {
 ### TODO: ??
 sub wingateWriteFile {
     if (@_) {
-       &ScheduleThis(60, 'wingateWriteFile');
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(3600, 'wingateWriteFile'); # once per hour
+       return if ($_[0] eq '2');       # defer.
     }
 
     return unless (scalar @wingateCache);
     }
 
     return unless (scalar @wingateCache);
@@ -1010,21 +1019,21 @@ sub wingateWriteFile {
 
 sub factoidCheck {
     if (@_) {
 
 sub factoidCheck {
     if (@_) {
-       &ScheduleThis(720, "factoidCheck");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(43200, 'factoidCheck'); # ever 12 hours
+       return if ($_[0] eq '2');       # defer.
     }
 
     }
 
-    my @list   = &searchTable("factoids", "factoid_key", "factoid_key", " #DEL#");
-    my $stale  = &getChanConfDefault("factoidDeleteDelay", 14, $chan) *60*60*24;
+    my @list   = &searchTable('factoids', 'factoid_key', 'factoid_key', " #DEL#");
+    my $stale  = &getChanConfDefault('factoidDeleteDelay', 14, $chan) *60*60*24;
     if ($stale < 1) {
     if ($stale < 1) {
-       # disable it since it's "illegal".
+       # disable it since it's 'illegal'.
        return;
     }
 
     my $time   = time();
 
     foreach (@list) {
        return;
     }
 
     my $time   = time();
 
     foreach (@list) {
-       my $age = &getFactInfo($_, "modified_time");
+       my $age = &getFactInfo($_, 'modified_time');
 
        if (!defined $age or $age !~ /^\d+$/) {
            if (scalar @list > 50) {
 
        if (!defined $age or $age !~ /^\d+$/) {
            if (scalar @list > 50) {
@@ -1055,8 +1064,8 @@ sub dccStatus {
     return unless (scalar keys %{ $dcc{CHAT} });
 
     if (@_) {
     return unless (scalar keys %{ $dcc{CHAT} });
 
     if (@_) {
-       &ScheduleThis(10, "dccStatus");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(600, 'dccStatus'); # every 10 minutes
+       return if ($_[0] eq '2');       # defer.
     }
 
     my $time = strftime("%H:%M", gmtime(time()) );
     }
 
     my $time = strftime("%H:%M", gmtime(time()) );
@@ -1117,9 +1126,9 @@ sub mkBackup {
        return;
     }
 
        return;
     }
 
-    my $age    = "New";
+    my $age    = 'New';
     if ( -e "$file~" ) {
     if ( -e "$file~" ) {
-       $backup++       if ((stat $file)[9] - (stat "$file~")[9] > $time);
+       $backup++       if ((stat $file)[9] - (stat "$file~")[9] > $time);
        my $delta       = time() - (stat "$file~")[9];
        $age            = &Time2String($delta);
     } else {
        my $delta       = time() - (stat "$file~")[9];
        $age            = &Time2String($delta);
     } else {
@@ -1134,3 +1143,5 @@ sub mkBackup {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index bf95b602216638c250c00dae377f83a13fe2f12d..db0c523d66d391103ebeeb35a041f7862f06ab6b 100644 (file)
@@ -13,11 +13,11 @@ use vars qw($msgType $who $bot_pid $nuh $shm $force_public_reply
 
 sub help {
     my $topic = shift;
 
 sub help {
     my $topic = shift;
-    my $file  = $bot_data_dir."/blootbot.help";
+    my $file  = $bot_data_dir."/infobot.help";
     my %help  = ();
 
     # crude hack for performStrictReply() to work as expected.
     my %help  = ();
 
     # crude hack for performStrictReply() to work as expected.
-    $msgType = "private" if ($msgType eq "public");
+    $msgType = 'private' if ($msgType eq 'public');
 
     if (!open(FILE, $file)) {
        &ERROR("Failed reading help file ($file): $!");
 
     if (!open(FILE, $file)) {
        &ERROR("Failed reading help file ($file): $!");
@@ -39,12 +39,12 @@ sub help {
        $val =~ s/__/\037/g;
        $val =~ s/==/        /;
 
        $val =~ s/__/\037/g;
        $val =~ s/==/        /;
 
-       $help{$key}  = ""                if (!exists $help{$key});
+       $help{$key}  = ''                if (!exists $help{$key});
        $help{$key} .= $val."\n";
     }
     close FILE;
 
        $help{$key} .= $val."\n";
     }
     close FILE;
 
-    if (!defined $topic or $topic eq "") {
+    if (!defined $topic or $topic eq '') {
        &msg($who, $help{'main'});
 
        my $i = 0;
        &msg($who, $help{'main'});
 
        my $i = 0;
@@ -165,7 +165,7 @@ sub formListReply {
 # Usage: &IJoin(@array);
 sub IJoin {
     if (!scalar @_) {
 # Usage: &IJoin(@array);
 sub IJoin {
     if (!scalar @_) {
-       return "NULL";
+       return 'NULL';
     } elsif (scalar @_ == 1) {
        return $_[0];
     } else {
     } elsif (scalar @_ == 1) {
        return $_[0];
     } else {
@@ -177,10 +177,10 @@ sub IJoin {
 # Usage: &Time2String(seconds);
 sub Time2String {
     my ($time) = @_;
 # Usage: &Time2String(seconds);
 sub Time2String {
     my ($time) = @_;
-    my $prefix = "";
+    my $prefix = '';
     my (@s, @t);
 
     my (@s, @t);
 
-    return "NULL" if (!defined $time);
+    return 'NULL' if (!defined $time);
     return $time  if ($time !~ /\d+/);
 
     if ($time < 0) {
     return $time  if ($time !~ /\d+/);
 
     if ($time < 0) {
@@ -279,24 +279,24 @@ sub fixPlural {
        return $str;
     }
 
        return $str;
     }
 
-    if ($str eq "has") {
-       $str = "have"   if ($int > 1);
-    } elsif ($str eq "is") {
-       $str = "are"    if ($int > 1);
-    } elsif ($str eq "was") {
-       $str = "were"   if ($int > 1);
-    } elsif ($str eq "this") {
-       $str = "these"  if ($int > 1);
+    if ($str eq 'has') {
+       $str = 'have'   if ($int > 1);
+    } elsif ($str eq 'is') {
+       $str = 'are'    if ($int > 1);
+    } elsif ($str eq 'was') {
+       $str = 'were'   if ($int > 1);
+    } elsif ($str eq 'this') {
+       $str = 'these'  if ($int > 1);
     } elsif ($str =~ /y$/) {
        if ($int > 1) {
            if ($str =~ /ey$/) {
     } elsif ($str =~ /y$/) {
        if ($int > 1) {
            if ($str =~ /ey$/) {
-               $str .= "s";    # eg: "money" => "moneys".
+               $str .= 's';    # eg: 'money' => 'moneys'.
            } else {
                $str =~ s/y$/ies/;
            }
        }
     } else {
            } else {
                $str =~ s/y$/ies/;
            }
        }
     } else {
-       $str .= "s"     if ($int != 1);
+       $str .= 's'     if ($int != 1);
     }
 
     return $str;
     }
 
     return $str;
@@ -367,36 +367,28 @@ sub getRandom {
     return $array[int(rand(scalar @array))];
 }
 
     return $array[int(rand(scalar @array))];
 }
 
-# Usage: &getRandomInt("30-60");
+# Usage: &getRandomInt("30-60"); &getRandomInt(5);
+# Desc : Returns a randomn integer between "X-Y" or 1 and the value passed
 sub getRandomInt {
 sub getRandomInt {
-    my $str = $_[0];
+       my $str = shift;
 
 
-    if (!defined $str) {
-       &WARN("gRI: str == NULL.");
-       return;
-    }
-
-    srand();
-
-    if ($str =~ /^(\d+(\.\d+)?)$/) {
-       my $i = $1;
-       my $fuzzy = int(rand 5);
-       if ($i < 10) {
-           return $i;
+       if ( !defined $str ) {
+               &WARN("getRandomInt: str == NULL.");
+               return undef;
        }
        }
-       if (rand > 0.5) {
-           return ($i - $fuzzy)*60;
+
+       if ( $str =~ /^(\d+(\.\d+)?)$/ ) {
+               return int( rand $str ) + 1;
+       } elsif ( $str =~ /^(\d+)-(\d+)$/ ) {
+               return $1 if $1 == $2;
+               my $min = $1 < $2 ? $1 : $2;    # Swap is backwords
+               my $max = $2 > $1 ? $2 : $1;
+               return int( rand( $max - $min + 1 ) ) + $min;
        } else {
        } else {
-           return ($i + $fuzzy)*60;
-       }
-    } elsif ($str =~ /^(\d+)-(\d+)$/) {
-       return ($2 - $1)*int(rand $1)*60;
-    } else {
-       return $str;    # hope we're safe.
-    }
 
 
-    &ERROR("getRandomInt: invalid arg '$str'.");
-    return 1800;
+               # &ERROR("getRandomInt: invalid arg '$str'.");
+               return undef;
+       }
 }
 
 ##########
 }
 
 ##########
@@ -436,7 +428,7 @@ sub IsHostMatch {
        $this{'host'} = &makeHostMask(lc $3);
     } else {
        &WARN("IHM: thisnuh is invalid '$thisnuh'.");
        $this{'host'} = &makeHostMask(lc $3);
     } else {
        &WARN("IHM: thisnuh is invalid '$thisnuh'.");
-       return 1 if ($thisnuh eq "");
+       return 1 if ($thisnuh eq '');
        return 0;
     }
 
        return 0;
     }
 
@@ -501,7 +493,7 @@ sub isFileUpdated {
 # Usage: &makeHostMask($host);
 sub makeHostMask {
     my ($host) = @_;
 # Usage: &makeHostMask($host);
 sub makeHostMask {
     my ($host) = @_;
-    my $nu     = "";
+    my $nu     = '';
 
     if ($host =~ s/^(\S+!\S+\@)//) {
        &DEBUG("mHM: detected nick!user\@ for host arg; fixing");
 
     if ($host =~ s/^(\S+!\S+\@)//) {
        &DEBUG("mHM: detected nick!user\@ for host arg; fixing");
@@ -548,7 +540,7 @@ sub makeRandom {
 
 sub checkMsgType {
     my ($reply) = @_;
 
 sub checkMsgType {
     my ($reply) = @_;
-    return unless (&IsParam("minLengthBeforePrivate"));
+    return unless (&IsParam('minLengthBeforePrivate'));
     return if ($force_public_reply);
 
     if (length $reply > $param{'minLengthBeforePrivate'}) {
     return if ($force_public_reply);
 
     if (length $reply > $param{'minLengthBeforePrivate'}) {
@@ -609,7 +601,7 @@ sub Forker {
     &shmFlush();
     &VERB("double fork detected; not forking.",2) if ($$ != $bot_pid);
 
     &shmFlush();
     &VERB("double fork detected; not forking.",2) if ($$ != $bot_pid);
 
-    if (&IsParam("forking") and $$ == $bot_pid) {
+    if (&IsParam('forking') and $$ == $bot_pid) {
        return unless &addForked($label);
 
        $SIG{CHLD} = 'IGNORE';
        return unless &addForked($label);
 
        $SIG{CHLD} = 'IGNORE';
@@ -655,13 +647,13 @@ sub mkcrypt {
 }
 
 sub closeStats {
 }
 
 sub closeStats {
-    return unless (&getChanConfList("ircTextCounters"));
+    return unless (&getChanConfList('ircTextCounters'));
 
     foreach (keys %cmdstats) {
        my $type        = $_;
 
     foreach (keys %cmdstats) {
        my $type        = $_;
-       my $i   = &sqlSelect("stats", "counter", {
+       my $i   = &sqlSelect('stats', 'counter', {
                nick    => $type,
                nick    => $type,
-               type    => "cmdstats",
+               type    => 'cmdstats',
        } );
        my $z   = 0;
        $z++ unless ($i);
        } );
        my $z   = 0;
        $z++ unless ($i);
@@ -669,9 +661,8 @@ sub closeStats {
        $i      += $cmdstats{$type};
 
 
        $i      += $cmdstats{$type};
 
 
-       &sqlReplace("stats", {
-           nick        => $type,
-           type        => "cmdstats",
+       &sqlSet('stats', {'nick' => $type}, {
+           type        => 'cmdstats',
            'time'      => time(),
            counter     => $i,
        } );
            'time'      => time(),
            counter     => $i,
        } );
@@ -679,3 +670,5 @@ sub closeStats {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 518efbe8d500d98613e2546225d61ba8bdad6007..ef988c48a9fabe265795f0cf78a639759233e944 100755 (executable)
@@ -44,7 +44,7 @@ sub BZFlag {
 sub list {
        my ($response);
        my $ua = new LWP::UserAgent;
 sub list {
        my ($response);
        my $ua = new LWP::UserAgent;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(5);
 
 
        $ua->timeout(5);
 
@@ -58,7 +58,7 @@ sub list {
                my ($style, $maxShots, $shakeWins, $shakeTimeout, $maxPlayerScore, $maxTeamScore, $maxTime,
                                $maxPlayers, $rogueSize, $rogueMax, $redSize, $redMax, $greenSize, $greenMax,
                                $blueSize, $blueMax, $purpleSize, $purpleMax, $observerSize, $observerMax) =
                my ($style, $maxShots, $shakeWins, $shakeTimeout, $maxPlayerScore, $maxTeamScore, $maxTime,
                                $maxPlayers, $rogueSize, $rogueMax, $redSize, $redMax, $greenSize, $greenMax,
                                $blueSize, $blueMax, $purpleSize, $purpleMax, $observerSize, $observerMax) =
-                               unpack("A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2", $flags);
+                               unpack('A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2', $flags);
                my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize)
                                + hex($blueSize) + hex($purpleSize) + hex($observerSize);
                $servers{$serverport} = $playerSize;
                my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize)
                                + hex($blueSize) + hex($purpleSize) + hex($observerSize);
                $servers{$serverport} = $playerSize;
@@ -79,7 +79,7 @@ sub list {
 sub list17 {
        my ($response);
        my $ua = new LWP::UserAgent;
 sub list17 {
        my ($response);
        my $ua = new LWP::UserAgent;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(5);
 
 
        $ua->timeout(5);
 
@@ -96,7 +96,7 @@ sub list17 {
                                $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                                $shakeWins,$shakeTimeout,
                                $maxPlayerScore,$maxTeamScore,$maxTime) =
                                $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                                $shakeWins,$shakeTimeout,
                                $maxPlayerScore,$maxTeamScore,$maxTime) =
-                               unpack("A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4", $flags);
+                               unpack('A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4', $flags);
                my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize)
                                + hex($blueSize) + hex($purpleSize);
                $servers{$serverport} = $playerSize;
                my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize)
                                + hex($blueSize) + hex($purpleSize);
                $servers{$serverport} = $playerSize;
@@ -120,8 +120,8 @@ sub querytext {
                &::status("BZFlag module requires Socket.");
                return 'BZFlag module not active';
        }
                &::status("BZFlag module requires Socket.");
                return 'BZFlag module not active';
        }
-       #my @teamName = ("Rogue", "Red", "Green", "Blue", "Purple", "Observer", "Rabbit");
-       my @teamName = ("X", "R", "G", "B", "P", "O", "K");
+       #my @teamName = ('Rogue', 'Red', 'Green', 'Blue', 'Purple', 'Observer', 'Rabbit');
+       my @teamName = ('X', 'R', 'G', 'B', 'P', 'O', 'K');
        my ($message, $server, $response);
        $port = 5154 unless $port;
 
        my ($message, $server, $response);
        $port = 5154 unless $port;
 
@@ -154,26 +154,26 @@ sub querytext {
        my ($version) = $magic . $major . $minor . $something . $revision;
 
        # quit if version isn't valid
        my ($version) = $magic . $major . $minor . $something . $revision;
 
        # quit if version isn't valid
-       return 'not a bzflag server' if ($magic ne "BZFS");
+       return 'not a bzflag server' if ($magic ne 'BZFS');
        $response .= "$major$minor$something$revision ";
        # check version
        $response .= "$major$minor$something$revision ";
        # check version
-       if ($version eq "BZFS0026") {
+       if ($version eq 'BZFS0026') {
                # 1.11.x handled here
                return 'read error' unless read(S1, $buffer, 1) == 1;
                # 1.11.x handled here
                return 'read error' unless read(S1, $buffer, 1) == 1;
-               my ($id) = unpack("C", $buffer);
+               my ($id) = unpack('C', $buffer);
                return "rejected by server" if ($id == 255);
 
                # send game request
                return "rejected by server" if ($id == 255);
 
                # send game request
-               print S1 pack("n2", 0, 0x7167);
+               print S1 pack('n2', 0, 0x7167);
 
                # get reply
                my $nbytes = read(S1, $buffer, 4);
 
                # get reply
                my $nbytes = read(S1, $buffer, 4);
-               my ($infolen, $infocode) = unpack("n2", $buffer);
+               my ($infolen, $infocode) = unpack('n2', $buffer);
                if ($infocode == 0x6774) {
                        # read and ignore MsgGameTime from new servers
                        $nbytes = read(S1, $buffer, 8);
                        $nbytes = read(S1, $buffer, 4);
                if ($infocode == 0x6774) {
                        # read and ignore MsgGameTime from new servers
                        $nbytes = read(S1, $buffer, 8);
                        $nbytes = read(S1, $buffer, 4);
-                 ($infolen, $infocode) = unpack("n2", $buffer);
+                 ($infolen, $infocode) = unpack('n2', $buffer);
                }
                $nbytes = read(S1, $buffer, 42);
                if ($nbytes != 42) {
                }
                $nbytes = read(S1, $buffer, 42);
                if ($nbytes != 42) {
@@ -184,15 +184,15 @@ sub querytext {
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,$observerSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,$observerMax,
                        $shakeWins,$shakeTimeout,
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,$observerSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,$observerMax,
                        $shakeWins,$shakeTimeout,
-                       $maxPlayerScore,$maxTeamScore,$maxTime,$timeElapsed) = unpack("n23", $buffer);
+                       $maxPlayerScore,$maxTeamScore,$maxTime,$timeElapsed) = unpack('n23', $buffer);
                return "bad server data $infocode" unless $infocode == 0x7167;
 
                # send players request
                return "bad server data $infocode" unless $infocode == 0x7167;
 
                # send players request
-               print S1 pack("n2", 0, 0x7170);
+               print S1 pack('n2', 0, 0x7170);
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S1, $buffer, 8) == 8;
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S1, $buffer, 8) == 8;
-               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer);
+               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer);
 
                # get the teams
                return 'bad count data' unless $countcode == 0x7170;
 
                # get the teams
                return 'bad count data' unless $countcode == 0x7170;
@@ -200,7 +200,7 @@ sub querytext {
                ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer);
                for (1..$numTeams) {
                        return 'team read error' unless read(S1, $buffer, 8) == 8;
                ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer);
                for (1..$numTeams) {
                        return 'team read error' unless read(S1, $buffer, 8) == 8;
-                       my ($team,$size,$won,$lost) = unpack("n4", $buffer);
+                       my ($team,$size,$won,$lost) = unpack('n4', $buffer);
                        if ($size > 0) {
                                my $score = $won - $lost;
                                $response .= "$teamName[$team]:$score($won-$lost) ";
                        if ($size > 0) {
                                my $score = $won - $lost;
                                $response .= "$teamName[$team]:$score($won-$lost) ";
@@ -211,7 +211,7 @@ sub querytext {
                for (1..$numPlayers) {
                        last unless read(S1, $buffer, 175) == 175;
                        my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) =
                for (1..$numPlayers) {
                        last unless read(S1, $buffer, 175) == 175;
                        my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) =
-                                       unpack("n2Cn5A32A128", $buffer);
+                                       unpack('n2Cn5A32A128', $buffer);
                        #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) =
                        #               unpack("n2Nn2 n4A32A128", $buffer);
                        return 'bad player data' unless $playercode == 0x6170;
                        #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) =
                        #               unpack("n2Nn2 n4A32A128", $buffer);
                        return 'bad player data' unless $playercode == 0x6170;
@@ -227,10 +227,10 @@ sub querytext {
                # 1.10.x handled here
                $revision = $something * 10 + $revision;
                return 'read error' unless read(S1, $buffer, 1) == 1;
                # 1.10.x handled here
                $revision = $something * 10 + $revision;
                return 'read error' unless read(S1, $buffer, 1) == 1;
-               my ($id) = unpack("C", $buffer);
+               my ($id) = unpack('C', $buffer);
 
                # send game request
 
                # send game request
-               print S1 pack("n2", 0, 0x7167);
+               print S1 pack('n2', 0, 0x7167);
 
                # FIXME the packets are wrong from here down
                # get reply
 
                # FIXME the packets are wrong from here down
                # get reply
@@ -239,15 +239,15 @@ sub querytext {
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                        $shakeWins,$shakeTimeout,
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                        $shakeWins,$shakeTimeout,
-                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer);
+                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer);
                return 'bad server data' unless $infocode == 0x7167;
 
                # send players request
                return 'bad server data' unless $infocode == 0x7167;
 
                # send players request
-               print S1 pack("n2", 0, 0x7170);
+               print S1 pack('n2', 0, 0x7170);
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S1, $buffer, 8) == 8;
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S1, $buffer, 8) == 8;
-               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer);
+               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer);
 
                # get the teams
                return 'bad count data' unless $countcode == 0x7170;
 
                # get the teams
                return 'bad count data' unless $countcode == 0x7170;
@@ -255,7 +255,7 @@ sub querytext {
                ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer);
                for (1..$numTeams) {
                        return 'team read error' unless read(S1, $buffer, 8) == 8;
                ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer);
                for (1..$numTeams) {
                        return 'team read error' unless read(S1, $buffer, 8) == 8;
-                       my ($team,$size,$won,$lost) = unpack("n4", $buffer);
+                       my ($team,$size,$won,$lost) = unpack('n4', $buffer);
                        if ($size > 0) {
                                my $score = $won - $lost;
                                $response .= "$teamName[$team]:$score($won-$lost) ";
                        if ($size > 0) {
                                my $score = $won - $lost;
                                $response .= "$teamName[$team]:$score($won-$lost) ";
@@ -266,7 +266,7 @@ sub querytext {
                for (1..$numPlayers) {
                        last unless read(S1, $buffer, 175) == 175;
                        my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) =
                for (1..$numPlayers) {
                        last unless read(S1, $buffer, 175) == 175;
                        my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) =
-                                       unpack("n2Cn5A32A128", $buffer);
+                                       unpack('n2Cn5A32A128', $buffer);
                        #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) =
                        #               unpack("n2Nn2 n4A32A128", $buffer);
                        return 'bad player data' unless $playercode == 0x6170;
                        #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) =
                        #               unpack("n2Nn2 n4A32A128", $buffer);
                        return 'bad player data' unless $playercode == 0x6170;
@@ -283,7 +283,7 @@ sub querytext {
                # 1.7* versions handled here
                # old servers send a reconnect port number
                return 'read error' unless read(S1, $buffer, 2) == 2;
                # 1.7* versions handled here
                # old servers send a reconnect port number
                return 'read error' unless read(S1, $buffer, 2) == 2;
-               my ($reconnect) = unpack("n", $buffer);
+               my ($reconnect) = unpack('n', $buffer);
                $minor = $minor * 10 + $something;
                # quit if rejected
                return 'rejected by server' if ($reconnect == 0);
                $minor = $minor * 10 + $something;
                # quit if rejected
                return 'rejected by server' if ($reconnect == 0);
@@ -298,7 +298,7 @@ sub querytext {
                close(S1);
 
                # send game request
                close(S1);
 
                # send game request
-               print S pack("n2", 0, 0x7167);
+               print S pack('n2', 0, 0x7167);
 
                # get reply
                return 'server read error' unless read(S, $buffer, 40) == 40;
 
                # get reply
                return 'server read error' unless read(S, $buffer, 40) == 40;
@@ -306,21 +306,21 @@ sub querytext {
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                        $shakeWins,$shakeTimeout,
                        $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,
                        $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,
                        $shakeWins,$shakeTimeout,
-                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer);
+                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer);
                return 'bad server data' unless $infocode == 0x7167;
 
                # send players request
                return 'bad server data' unless $infocode == 0x7167;
 
                # send players request
-               print S pack("n2", 0, 0x7170);
+               print S pack('n2', 0, 0x7170);
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S, $buffer, 8) == 8;
 
                # get number of teams and players we'll be receiving
                return 'count read error' unless read(S, $buffer, 8) == 8;
-               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer);
+               my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer);
                return 'bad count data' unless $countcode == 0x7170;
 
                # get the teams
                for (1..$numTeams) {
                        return 'team read error' unless read(S, $buffer, 14) == 14;
                return 'bad count data' unless $countcode == 0x7170;
 
                # get the teams
                for (1..$numTeams) {
                        return 'team read error' unless read(S, $buffer, 14) == 14;
-                       my ($teamlen,$teamcode,$team,$size,$aSize,$won,$lost) = unpack("n7", $buffer);
+                       my ($teamlen,$teamcode,$team,$size,$aSize,$won,$lost) = unpack('n7', $buffer);
                        return 'bad team data' unless $teamcode == 0x7475;
                        if ($size > 0) {
                                my $score = $won - $lost;
                        return 'bad team data' unless $teamcode == 0x7475;
                        if ($size > 0) {
                                my $score = $won - $lost;
@@ -357,4 +357,5 @@ sub query {
 }
 
 1;
 }
 
 1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 4dfadfb8c2a29c78e535b49d164940b94d6ef36c..8ec592b67d99aec36731cdab24516b67eb7ad397 100644 (file)
@@ -17,9 +17,11 @@ my $announce = 0;
 my $defaultdist        = 'sid';
 my $refresh = &::getChanConfDefault('debianRefreshInterval', 7, $::chan) * 60 * 60 * 24;
 my $debug      = 0;
 my $defaultdist        = 'sid';
 my $refresh = &::getChanConfDefault('debianRefreshInterval', 7, $::chan) * 60 * 60 * 24;
 my $debug      = 0;
-my $debian_dir = $::bot_state_dir . 'debian';
-my $country    = 'us'; # well .config it yourself then. ;-)
+my $debian_dir = $::bot_state_dir . '/debian';
+my $country    = 'nl'; # well .config it yourself then. ;-)
 my $protocol   = 'http';
 my $protocol   = 'http';
+# EDIT THIS (i386, amd64, powerpc, [etc.]):
+my $arch = "i386";
 
 # format: "alias=real".
 my %dists      = (
 
 # format: "alias=real".
 my %dists      = (
@@ -42,55 +44,43 @@ my %archived_dists = (
 );
 
 my %archiveurlcontents = (
 );
 
 my %archiveurlcontents = (
-       "Contents-##DIST-i386.gz" =>
+       "Contents-##DIST-$arch.gz" =>
                "$protocol://debian.crosslink.net/debian-archive".
                "$protocol://debian.crosslink.net/debian-archive".
-               "/dists/##DIST/Contents-i386.gz",
+               "/dists/##DIST/Contents-$arch.gz",
 );
 
 my %archiveurlpackages = (
 );
 
 my %archiveurlpackages = (
-       "Packages-##DIST-main-i386.gz" =>
+       "Packages-##DIST-main-$arch.gz" =>
                "$protocol://debian.crosslink.net/debian-archive".
                "$protocol://debian.crosslink.net/debian-archive".
-               "/dists/##DIST/main/binary-i386/Packages.gz",
-       "Packages-##DIST-contrib-i386.gz" =>
+               "/dists/##DIST/main/binary-$arch/Packages.gz",
+       "Packages-##DIST-contrib-$arch.gz" =>
                "$protocol://debian.crosslink.net/debian-archive".
                "$protocol://debian.crosslink.net/debian-archive".
-               "/dists/##DIST/contrib/binary-i386/Packages.gz",
-       "Packages-##DIST-non-free-i386.gz" =>
+               "/dists/##DIST/contrib/binary-$arch/Packages.gz",
+       "Packages-##DIST-non-free-$arch.gz" =>
                "$protocol://debian.crosslink.net/debian-archive".
                "$protocol://debian.crosslink.net/debian-archive".
-               "/dists/##DIST/non-free/binary-i386/Packages.gz",
+               "/dists/##DIST/non-free/binary-$arch/Packages.gz",
 );
 );
-    
-
 
 
 my %urlcontents = (
 
 
 my %urlcontents = (
-       "Contents-##DIST-i386.gz" =>
-               "$protocol://debian.usc.edu".
-               "/dists/##DIST/Contents-i386.gz",
-       "Contents-##DIST-i386-non-US.gz" =>
+       "Contents-##DIST-$arch.gz" =>
+               "$protocol://ftp.$country.debian.org".
+               "/debian/dists/##DIST/Contents-$arch.gz",
+       "Contents-##DIST-$arch-non-US.gz" =>
                "$protocol://non-us.debian.org".
                "$protocol://non-us.debian.org".
-               "/debian-non-US/dists/##DIST/non-US/Contents-i386.gz",
+               "/debian-non-US/dists/##DIST/non-US/Contents-$arch.gz",
 );
 
 my %urlpackages = (
 );
 
 my %urlpackages = (
-       "Packages-##DIST-main-i386.gz" =>
-               "$protocol://debian.usc.edu".
-               "/dists/##DIST/main/binary-i386/Packages.gz",
-       "Packages-##DIST-contrib-i386.gz" =>
-               "$protocol://debian.usc.edu".
-               "/dists/##DIST/contrib/binary-i386/Packages.gz",
-       "Packages-##DIST-non-free-i386.gz" =>
-               "$protocol://debian.usc.edu".
-               "/dists/##DIST/non-free/binary-i386/Packages.gz",
-
-#      "Packages-##DIST-non-US-main-i386.gz" =>
-#              "$protocol://non-us.debian.org".
-#              "/debian-non-US/dists/##DIST/non-US/main/binary-i386/Packages.gz",
-#      "Packages-##DIST-non-US-contrib-i386.gz" =>
-#              "$protocol://non-us.debian.org".
-#              "/debian-non-US/dists/##DIST/non-US/contrib/binary-i386/Packages.gz",
-#      "Packages-##DIST-non-US-non-free-i386.gz" =>
-#              "$protocol://non-us.debian.org".
-#              "/debian-non-US/dists/##DIST/non-US/non-free/binary-i386/Packages.gz",
+       "Packages-##DIST-main-$arch.gz" =>
+               "$protocol://ftp.$country.debian.org".
+               "/debian/dists/##DIST/main/binary-$arch/Packages.gz",
+       "Packages-##DIST-contrib-$arch.gz" =>
+               "$protocol://ftp.$country.debian.org".
+               "/debian/dists/##DIST/contrib/binary-$arch/Packages.gz",
+       "Packages-##DIST-non-free-$arch.gz" =>
+               "$protocol://ftp.$country.debian.org".
+               "/debian/dists/##DIST/non-free/binary-$arch/Packages.gz",
 );
 
 #####################
 );
 
 #####################
@@ -1083,14 +1073,14 @@ sub fixDist {
     my %new;
     my ($key,$val);
     my %dist_urls;
     my %new;
     my ($key,$val);
     my %dist_urls;
-    
+
     if (exists $archived_dists{$dist}){
        if ($type eq 'contents'){
            %dist_urls = %archiveurlcontents;
        }
        else {
            %dist_urls = %archiveurlpackages;
     if (exists $archived_dists{$dist}){
        if ($type eq 'contents'){
            %dist_urls = %archiveurlcontents;
        }
        else {
            %dist_urls = %archiveurlpackages;
-       }  
+       }
     }
     else {
        if ($type eq 'contents'){
     }
     else {
        if ($type eq 'contents'){
@@ -1100,7 +1090,7 @@ sub fixDist {
            %dist_urls = %urlpackages;
        }
     }
            %dist_urls = %urlpackages;
        }
     }
-       
+
     while (($key,$val) = each %dist_urls) {
        $key =~ s/##DIST/$dist/;
        $val =~ s/##DIST/$dist/;
     while (($key,$val) = each %dist_urls) {
        $key =~ s/##DIST/$dist/;
        $val =~ s/##DIST/$dist/;
@@ -1195,3 +1185,5 @@ sub searchDescFE {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 661247c77f4563894982b3cc120bf8144e5d3989..42a99484436caaf300ec4becd6507a4f72473315 100644 (file)
@@ -121,3 +121,5 @@ sub package_bugs($){
 
 
 __END__
 
 
 __END__
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a9d4d34628a132bc92a3dbc69c088177377ce722..66455964e09cfb5a88f06cdacdad3a378a5a014f 100644 (file)
@@ -179,3 +179,5 @@ sub do_pkg {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 288b06ebf34e475005c41d87ca7924a26c3dfe95..2522a1ca2dfa6da87bd537cf47aa267beadc21bb 100644 (file)
@@ -37,7 +37,7 @@ sub Dict {
     my $socket = new IO::Socket;
     socket($socket, PF_INET, SOCK_STREAM, $proto) or return "error: socket: $!";
     eval {
     my $socket = new IO::Socket;
     socket($socket, PF_INET, SOCK_STREAM, $proto) or return "error: socket: $!";
     eval {
-       local $SIG{ALRM} = sub { die "alarm" };
+       local $SIG{ALRM} = sub { die 'alarm' };
        alarm 10;
        connect($socket, sockaddr_in($port, inet_aton($server))) or die "error: connect: $!";
        alarm 0;
        alarm 10;
        connect($socket, sockaddr_in($port, inet_aton($server))) or die "error: connect: $!";
        alarm 0;
@@ -53,16 +53,25 @@ sub Dict {
        if ($query =~ s/^(\d+)\s+//) {
            $num = $1;
        }
        if ($query =~ s/^(\d+)\s+//) {
            $num = $1;
        }
+       my $dict = '*';
+       if ($query =~ s/\/(\S+)$//) {
+           $dict = $1;
+       }
 
        # body.
 
        # body.
-       push(@results, &Dict_Wordnet($socket,$query));
-       push(@results, &Dict_Foldoc($socket,$query));
-       push(@results, &Dict_web1913($socket,$query));
+       push(@results, &Define($socket,$query,$dict));
+       #push(@results, &Define($socket,$query,'foldoc'));
+       #push(@results, &Define($socket,$query,'web1913'));
        # end.
 
        print $socket "QUIT\n";
        close $socket;
 
        # end.
 
        print $socket "QUIT\n";
        close $socket;
 
+       my $count=0;
+       foreach (@results) {
+           $count++;
+           &::DEBUG("$count: $_");
+       }
        my $total = scalar @results;
 
        if ($total == 0) {
        my $total = scalar @results;
 
        if ($total == 0) {
@@ -87,138 +96,91 @@ sub Dict {
            $retval = "Dictionary '$query' ".$results[0];
        } else {
            $retval = "could not find definition for \002$query\002";
            $retval = "Dictionary '$query' ".$results[0];
        } else {
            $retval = "could not find definition for \002$query\002";
+           $retval .= " in $dict" if ($dict ne '*');
        }
     }
 
     &::performStrictReply($retval);
 }
 
        }
     }
 
     &::performStrictReply($retval);
 }
 
-sub Dict_Wordnet {
-    my ($socket, $query) = @_;
+sub Define {
+    my ($socket, $query, $dict) = @_;
     my @results;
 
     my @results;
 
-    &::status("Dict: asking Wordnet.");
-    print $socket "DEFINE wn \"$query\"\n";
+    &::DEBUG("Dict: asking $dict.");
+    print $socket "DEFINE $dict \"$query\"\n";
 
 
-    my $def            = "";
-    my $wordtype       = "";
+    my $def = '';
+    my $term = $query;
 
     while (<$socket>) {
        chop;   # remove \n
        chop;   # remove \r
 
 
     while (<$socket>) {
        chop;   # remove \n
        chop;   # remove \r
 
-       &::DEBUG("got '$_'");
-       if ($_ eq ".") {                                # end of def.
-           push(@results, $def);
-       } elsif (/^250 /) {                             # stats.
-           last;
-       } elsif (/^552 no match/) {                     # no match.
+       &::DEBUG("$term/$dict '$_'");
+       if (/^552 /) {
+           # no match.
            return;
            return;
-       } elsif (/^\s+(\S+ )?(\d+)?: (.*)/) {   # start of sub def.
-           my $text = $3;
-           $def =~ s/\s+$//;
-###        &::DEBUG("def => '$def'.");
-           push(@results, $def)                if ($def ne "");
-           $def = $text;
-
-           if (0) {    # old non-fLR format.
-               $def = "$query $wordtype: $text" if (defined $text);
-               $wordtype = substr($1,0,-1)     if (defined $1);
-###            &::DEBUG("_ => '$_'.") if (!defined $text);
+       } elsif (/^250 /) {
+            # end w/ optional stats
+           last;
+       } elsif (/^151 "([^"]*)" (\S+) .*/) {
+            # 151 "Good Thing" jargon "Jargon File (4.3.0, 30 APR 2001)"
+            $term=$1;
+           $dict=$2;
+           $def = '';
+            &::DEBUG("term=$term dict=$dict");
+       } else {
+           my $line = $_;
+           # some dicts put part of the definition on the same line ie: jargon
+           $line =~ s/^$term//i;
+           $line =~ s/^\s+/ /;
+           if ($dict eq 'wn') {
+               # special processing for sub defs in wordnet
+               if ($line eq '.') {
+                   # end of def.
+                   $def =~ s/\s+$//;
+                   $def =~ s/\[[^\]]*\]//g;
+                   push(@results, $def);
+               } elsif ($line =~ m/^\s+(\S+ )?(\d+)?: (.*)/) {
+                   # start of sub def.
+                   my $text = $3;
+                   $def =~ s/\s+$//;
+                   #&::DEBUG("def => '$def'.");
+                   $def =~ s/\[[^\]]*\]//g;
+                   push(@results, $def) if ($def ne '');
+                   $def = $text;
+               } elsif (/^\s+(.*)/) {
+                   $def .= $line;
+               } else {
+                   &::DEBUG("ignored '$line'");
+               }
+           } else {
+               # would be nice to divide other dicts
+               # but many are not always in a parsable format
+               if ($line eq '.') {
+                   # end of def.
+                   next if ($def eq '');
+                   push(@results, $def);
+                   $def = '';
+               } elsif ($line =~ m/^\s+(\S.*\S)\s*$/) {
+                   #&::DEBUG("got '$1'");
+                   $def .= ' ' if ($def ne '');
+                   $def .= $1;
+               } else {
+                   &::DEBUG("ignored '$line'");
+               }
            }
            }
-
-       } elsif (/^\s+(.*)/) {
-           s/^\s{2,}/ /;
-           $def        .= $_;
-           $def =~ s/\[.*?\]$//g;
-       }
-    }
-
-    &::status("Dict: wordnet: found ". scalar(@results) ." defs.");
-
-    return if (!scalar @results);
-
-    return @results;
-}
-
-sub Dict_Foldoc {
-    my ($socket,$query) = @_;
-    my @results;
-
-    &::status("Dict: asking Foldoc.");
-    print $socket "DEFINE foldoc \"$query\"\n";
-
-    my $firsttime = 1;
-    my $string;
-    while (<$socket>) {
-       chomp;  # remove \r\n
-
-       &::DEBUG("got '$_'");
-       return if /^552 /;              # no match.
-
-       last if (/^250/ or /^\.$/);     # stats; end of def.
-
-       s/^\s+|\s+$//g;                 # each line.
-
-       if ($_ eq "") {                 # sub def separator.
-           $string =~ s/^\s+|\s+$//g;  # sub def.
-           $string =~ s/[{}]//g;
-
-           next if ($string eq "");
-
-           push(@results, $string);
-           $string = "";
        }
        }
-
-       $string .= $_." ";
     }
 
     }
 
-    &::status("Dict: foldoc: found ". scalar(@results) ." defs.");
+    &::DEBUG("Dict: $dict: found ". scalar(@results) ." defs.");
 
     return if (!scalar @results);
 
     return if (!scalar @results);
-    pop @results;      # last def is date of entry.
-
-    return @results;
-}
-
-sub Dict_web1913 {
-    my ($socket,$query) = @_;
-    my @results;
-
-    &::status("Dict: asking web1913.");
-    print $socket "DEFINE web1913 \"$query\"\n";
-
-    my $string;
-    while (<$socket>) {
-       chop;   # remove \n
-       chop;   # remove \r
-
-       return if /^552/;               # no match.
-
-       last if (/^250/);       # stats; end of def.
-       next if (/^151/ or /^150/);       # definition and/or retrieval
-
-       s/^\s+|\s+$//g;                 # each line.
-
-       if ($_ eq "" or $_ =~ /^\.$/) {                 # sub def separator.
-           $string =~ s/^\s+|\s+$//g;  # sub def.
-           $string =~ s/[{}]//g;
-
-           next if ($string eq "");
-
-           push(@results, $string);
-           $string = "";
-       }
-
-       $string .= $_." ";
-    }
-
-    &::status("Dict: web1913: found ". scalar(@results) ." defs.");
-
-    return if (!scalar @results);
-    pop @results;      # last def is date of entry.
 
     return @results;
 }
 
 1;
 
     return @results;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 2e9fa976c304942ec856b74739e01ba9602dc013..5b36b2248b0eeecd11763462ff1eebf9c1f1649b 100644 (file)
@@ -15,7 +15,7 @@ my $countlines = 0;
 
 sub dumpvarslog {
     my ($line) = @_;
 
 sub dumpvarslog {
     my ($line) = @_;
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        print DUMPVARS $line."\n";
     } else {
        &status("DV: ".$line);
        print DUMPVARS $line."\n";
     } else {
        &status("DV: ".$line);
@@ -28,7 +28,7 @@ sub DumpNames(\%$) {
     my $line;
 
     if ($packname eq 'main::') {
     my $line;
 
     if ($packname eq 'main::') {
-       &dumpvarslog("Packages");
+       &dumpvarslog('Packages');
 
        foreach $symname (sort keys %$package) {
            local *sym = $$package{$symname};
 
        foreach $symname (sort keys %$package) {
            local *sym = $$package{$symname};
@@ -113,7 +113,7 @@ sub DumpNames(\%$) {
 }
 
 sub dumpallvars {
 }
 
 sub dumpallvars {
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        my $file = $param{'dumpvarsLogFile'};
        &status("opening fh to dumpvars ($file)");
        if (!open(DUMPVARS,">$file")) {
        my $file = $param{'dumpvarsLogFile'};
        &status("opening fh to dumpvars ($file)");
        if (!open(DUMPVARS,">$file")) {
@@ -124,7 +124,7 @@ sub dumpallvars {
 
     DumpNames(%main::,'main::');
 
 
     DumpNames(%main::,'main::');
 
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        &status("closing fh to dumpvars");
        close DUMPVARS;
     }
        &status("closing fh to dumpvars");
        close DUMPVARS;
     }
@@ -133,3 +133,5 @@ sub dumpallvars {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ddff6fae289492aa5b41d18882fda07f3d01eee9..a6e70e5e472c23f145d026a9d1a6426491bcf827 100644 (file)
@@ -32,7 +32,7 @@ sub symdumpAll {
 sub symdumpRecur {
     my $x = shift;
 
 sub symdumpRecur {
     my $x = shift;
 
-    if (ref $x eq "HASH") {
+    if (ref $x eq 'HASH') {
        foreach (keys %$x) {
            &symdumpRecur($_);
        }
        foreach (keys %$x) {
            &symdumpRecur($_);
        }
@@ -64,3 +64,5 @@ sub symdumpAllFile {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ae8470f3e85f2f8cf74796793ab3e01385d1f97a..9c9e320a8e9b658540029288950d332aa1d3b8f9 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 
 #!/usr/bin/perl
 
-# Exchange.pl - currency exchange "module"
+# Exchange.pl - currency exchange 'module'
 #
 # Last update: 990818 08:30:10, bobby@bofh.dk
 # 20021111 Tim Riker <Tim@Rikers.org>
 #
 # Last update: 990818 08:30:10, bobby@bofh.dk
 # 20021111 Tim Riker <Tim@Rikers.org>
@@ -30,245 +30,245 @@ sub GetAbb {
 
 sub GetTlds {
     my %Hash = (
 
 sub GetTlds {
     my %Hash = (
-       "AF", "AFGHANISTAN",
-       "AL", "ALBANIA",
-       "DZ", "ALGERIA",
-       "AS", "AMERICAN SAMOA",
-       "AD", "ANDORRA",
-       "AO", "ANGOLA",
-       "AI", "ANGUILLA",
-       "AQ", "ANTARCTICA",
-       "AG", "ANTIGUA AND BARBUDA",
-       "AR", "ARGENTINA",
-       "AM", "ARMENIA",
-       "AW", "ARUBA",
-       "AU", "AUSTRALIA",
-       "AT", "AUSTRIA",
-       "AZ", "AZERBAIJAN",
-       "BS", "BAHAMAS",
-       "BH", "BAHRAIN",
-       "BD", "BANGLADESH",
-       "BB", "BARBADOS",
-       "BY", "BELARUS",
-       "BE", "BELGIUM",
-       "BZ", "BELIZE",
-       "BJ", "BENIN",
-       "BM", "BERMUDA",
-       "BT", "BHUTAN",
-       "BO", "BOLIVIA",
-       "BA", "BOSNIA AND HERZEGOWINA",
-       "BW", "BOTSWANA",
-       "BV", "BOUVET ISLAND",
-       "BR", "BRAZIL",
-       "IO", "BRITISH INDIAN OCEAN TERRITORY",
-       "BN", "BRUNEI DARUSSALAM",
-       "BG", "BULGARIA",
-       "BF", "BURKINA FASO",
-       "BI", "BURUNDI",
-       "KH", "CAMBODIA",
-       "CM", "CAMEROON",
-       "CA", "CANADA",
-       "CV", "CAPE VERDE",
-       "KY", "CAYMAN ISLANDS",
-       "CF", "CENTRAL AFRICAN REPUBLIC",
-       "TD", "CHAD",
-       "CL", "CHILE",
-       "CN", "CHINA",
-       "CX", "CHRISTMAS ISLAND",
-       "CC", "COCOS (KEELING) ISLANDS",
-       "CO", "COLOMBIA",
-       "KM", "COMOROS",
-       "CG", "CONGO",
-       "CD", "CONGO, THE DEMOCRATIC REPUBLIC OF THE",
-       "CK", "COOK ISLANDS",
-       "CR", "COSTA RICA",
-       "CI", "COTE D'IVOIRE",
-       "HR", "CROATIA (local name: Hrvatska)",
-       "CU", "CUBA",
-       "CY", "CYPRUS",
-       "CZ", "CZECH REPUBLIC",
-       "DK", "DENMARK",
-       "DJ", "DJIBOUTI",
-       "DM", "DOMINICA",
-       "DO", "DOMINICAN REPUBLIC",
-       "TP", "EAST TIMOR",
-       "EC", "ECUADOR",
-       "EG", "EGYPT",
-       "SV", "EL SALVADOR",
-       "GQ", "EQUATORIAL GUINEA",
-       "ER", "ERITREA",
-       "EE", "ESTONIA",
-       "ET", "ETHIOPIA",
-       "FK", "FALKLAND ISLANDS (MALVINAS)",
-       "FO", "FAROE ISLANDS",
-       "FJ", "FIJI",
-       "FI", "FINLAND",
-       "FR", "FRANCE",
-       "FX", "FRANCE, METROPOLITAN",
-       "GF", "FRENCH GUIANA",
-       "PF", "FRENCH POLYNESIA",
-       "TF", "FRENCH SOUTHERN TERRITORIES",
-       "GA", "GABON",
-       "GM", "GAMBIA",
-       "GE", "GEORGIA",
-       "DE", "GERMANY",
-       "GH", "GHANA",
-       "GI", "GIBRALTAR",
-       "GR", "GREECE",
-       "GL", "GREENLAND",
-       "GD", "GRENADA",
-       "GP", "GUADELOUPE",
-       "GU", "GUAM",
-       "GT", "GUATEMALA",
-       "GN", "GUINEA",
-       "GW", "GUINEA-BISSAU",
-       "GY", "GUYANA",
-       "HT", "HAITI",
-       "HM", "HEARD AND MC DONALD ISLANDS",
-       "VA", "HOLY SEE (VATICAN CITY STATE)",
-       "HN", "HONDURAS",
-       "HK", "HONG KONG",
-       "HU", "HUNGARY",
-       "IS", "ICELAND",
-       "IN", "INDIA",
-       "ID", "INDONESIA",
-       "IR", "IRAN (ISLAMIC REPUBLIC OF)",
-       "IQ", "IRAQ",
-       "IE", "IRELAND",
-       "IL", "ISRAEL",
-       "IT", "ITALY",
-       "JM", "JAMAICA",
-       "JP", "JAPAN",
-       "JO", "JORDAN",
-       "KZ", "KAZAKHSTAN",
-       "KE", "KENYA",
-       "KI", "KIRIBATI",
-       "KP", "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF",
-       "KR", "KOREA, REPUBLIC OF",
-       "KW", "KUWAIT",
-       "KG", "KYRGYZSTAN",
-       "LA", "LAO PEOPLE'S DEMOCRATIC REPUBLIC",
-       "LV", "LATVIA",
-       "LB", "LEBANON",
-       "LS", "LESOTHO",
-       "LR", "LIBERIA",
-       "LY", "LIBYAN ARAB JAMAHIRIYA",
-       "LI", "LIECHTENSTEIN",
-       "LT", "LITHUANIA",
-       "LU", "LUXEMBOURG",
-       "MO", "MACAU",
-       "MK", "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF",
-       "MG", "MADAGASCAR",
-       "MW", "MALAWI",
-       "MY", "MALAYSIA",
-       "MV", "MALDIVES",
-       "ML", "MALI",
-       "MT", "MALTA",
-       "MH", "MARSHALL ISLANDS",
-       "MQ", "MARTINIQUE",
-       "MR", "MAURITANIA",
-       "MU", "MAURITIUS",
-       "YT", "MAYOTTE",
-       "MX", "MEXICO",
-       "FM", "MICRONESIA, FEDERATED STATES OF",
-       "MD", "MOLDOVA, REPUBLIC OF",
-       "MC", "MONACO",
-       "MN", "MONGOLIA",
-       "MS", "MONTSERRAT",
-       "MA", "MOROCCO",
-       "MZ", "MOZAMBIQUE",
-       "MM", "MYANMAR",
-       "NA", "NAMIBIA",
-       "NR", "NAURU",
-       "NP", "NEPAL",
-       "NL", "NETHERLANDS",
-       "AN", "NETHERLANDS ANTILLES",
-       "NC", "NEW CALEDONIA",
-       "NZ", "NEW ZEALAND",
-       "NI", "NICARAGUA",
-       "NE", "NIGER",
-       "NG", "NIGERIA",
-       "NU", "NIUE",
-       "NF", "NORFOLK ISLAND",
-       "MP", "NORTHERN MARIANA ISLANDS",
-       "NO", "NORWAY",
-       "OM", "OMAN",
-       "PK", "PAKISTAN",
-       "PW", "PALAU",
-       "PA", "PANAMA",
-       "PG", "PAPUA NEW GUINEA",
-       "PY", "PARAGUAY",
-       "PE", "PERU",
-       "PH", "PHILIPPINES",
-       "PN", "PITCAIRN",
-       "PL", "POLAND",
-       "PT", "PORTUGAL",
-       "PR", "PUERTO RICO",
-       "QA", "QATAR",
-       "RE", "REUNION",
-       "RO", "ROMANIA",
-       "RU", "RUSSIAN FEDERATION",
-       "RW", "RWANDA",
-       "KN", "SAINT KITTS AND NEVIS",
-       "LC", "SAINT LUCIA",
-       "VC", "SAINT VINCENT AND THE GRENADINES",
-       "WS", "SAMOA",
-       "SM", "SAN MARINO",
-       "ST", "SAO TOME AND PRINCIPE",
-       "SA", "SAUDI ARABIA",
-       "SN", "SENEGAL",
-       "SC", "SEYCHELLES",
-       "SL", "SIERRA LEONE",
-       "SG", "SINGAPORE",
-       "SK", "SLOVAKIA (Slovak Republic)",
-       "SI", "SLOVENIA",
-       "SB", "SOLOMON ISLANDS",
-       "SO", "SOMALIA",
-       "ZA", "SOUTH AFRICA",
-       "GS", "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS",
-       "ES", "SPAIN",
-       "LK", "SRI LANKA",
-       "SH", "ST. HELENA",
-       "PM", "ST. PIERRE AND MIQUELON",
-       "SD", "SUDAN",
-       "SR", "SURINAME",
-       "SJ", "SVALBARD AND JAN MAYEN ISLANDS",
-       "SZ", "SWAZILAND",
-       "SE", "SWEDEN",
-       "CH", "SWITZERLAND",
-       "SY", "SYRIAN ARAB REPUBLIC",
-       "TW", "TAIWAN, PROVINCE OF CHINA",
-       "TJ", "TAJIKISTAN",
-       "TZ", "TANZANIA, UNITED REPUBLIC OF",
-       "TH", "THAILAND",
-       "TG", "TOGO",
-       "TK", "TOKELAU",
-       "TO", "TONGA",
-       "TT", "TRINIDAD AND TOBAGO",
-       "TN", "TUNISIA",
-       "TR", "TURKEY",
-       "TM", "TURKMENISTAN",
-       "TC", "TURKS AND CAICOS ISLANDS",
-       "TV", "TUVALU",
-       "UG", "UGANDA",
-       "UA", "UKRAINE",
-       "AE", "UNITED ARAB EMIRATES",
-       "GB", "UNITED KINGDOM",
-       "US", "UNITED STATES",
-       "UM", "UNITED STATES MINOR OUTLYING ISLANDS",
-       "UY", "URUGUAY",
-       "UZ", "UZBEKISTAN",
-       "VU", "VANUATU",
-       "VE", "VENEZUELA",
-       "VN", "VIET NAM",
-       "VG", "VIRGIN ISLANDS (BRITISH)",
-       "VI", "VIRGIN ISLANDS (U.S.)",
-       "WF", "WALLIS AND FUTUNA ISLANDS",
-       "EH", "WESTERN SAHARA",
-       "YE", "YEMEN",
-       "YU", "YUGOSLAVIA",
-       "ZM", "ZAMBIA",
-       "ZW", "ZIMBABWE",
+       'AF', 'AFGHANISTAN',
+       'AL', 'ALBANIA',
+       'DZ', 'ALGERIA',
+       'AS', 'AMERICAN SAMOA',
+       'AD', 'ANDORRA',
+       'AO', 'ANGOLA',
+       'AI', 'ANGUILLA',
+       'AQ', 'ANTARCTICA',
+       'AG', 'ANTIGUA AND BARBUDA',
+       'AR', 'ARGENTINA',
+       'AM', 'ARMENIA',
+       'AW', 'ARUBA',
+       'AU', 'AUSTRALIA',
+       'AT', 'AUSTRIA',
+       'AZ', 'AZERBAIJAN',
+       'BS', 'BAHAMAS',
+       'BH', 'BAHRAIN',
+       'BD', 'BANGLADESH',
+       'BB', 'BARBADOS',
+       'BY', 'BELARUS',
+       'BE', 'BELGIUM',
+       'BZ', 'BELIZE',
+       'BJ', 'BENIN',
+       'BM', 'BERMUDA',
+       'BT', 'BHUTAN',
+       'BO', 'BOLIVIA',
+       'BA', 'BOSNIA AND HERZEGOWINA',
+       'BW', 'BOTSWANA',
+       'BV', 'BOUVET ISLAND',
+       'BR', 'BRAZIL',
+       'IO', 'BRITISH INDIAN OCEAN TERRITORY',
+       'BN', 'BRUNEI DARUSSALAM',
+       'BG', 'BULGARIA',
+       'BF', 'BURKINA FASO',
+       'BI', 'BURUNDI',
+       'KH', 'CAMBODIA',
+       'CM', 'CAMEROON',
+       'CA', 'CANADA',
+       'CV', 'CAPE VERDE',
+       'KY', 'CAYMAN ISLANDS',
+       'CF', 'CENTRAL AFRICAN REPUBLIC',
+       'TD', 'CHAD',
+       'CL', 'CHILE',
+       'CN', 'CHINA',
+       'CX', 'CHRISTMAS ISLAND',
+       'CC', 'COCOS (KEELING) ISLANDS',
+       'CO', 'COLOMBIA',
+       'KM', 'COMOROS',
+       'CG', 'CONGO',
+       'CD', 'CONGO, THE DEMOCRATIC REPUBLIC OF THE',
+       'CK', 'COOK ISLANDS',
+       'CR', 'COSTA RICA',
+       'CI', "COTE D'IVOIRE",
+       'HR', 'CROATIA (local name: Hrvatska)',
+       'CU', 'CUBA',
+       'CY', 'CYPRUS',
+       'CZ', 'CZECH REPUBLIC',
+       'DK', 'DENMARK',
+       'DJ', 'DJIBOUTI',
+       'DM', 'DOMINICA',
+       'DO', 'DOMINICAN REPUBLIC',
+       'TP', 'EAST TIMOR',
+       'EC', 'ECUADOR',
+       'EG', 'EGYPT',
+       'SV', 'EL SALVADOR',
+       'GQ', 'EQUATORIAL GUINEA',
+       'ER', 'ERITREA',
+       'EE', 'ESTONIA',
+       'ET', 'ETHIOPIA',
+       'FK', 'FALKLAND ISLANDS (MALVINAS)',
+       'FO', 'FAROE ISLANDS',
+       'FJ', 'FIJI',
+       'FI', 'FINLAND',
+       'FR', 'FRANCE',
+       'FX', 'FRANCE, METROPOLITAN',
+       'GF', 'FRENCH GUIANA',
+       'PF', 'FRENCH POLYNESIA',
+       'TF', 'FRENCH SOUTHERN TERRITORIES',
+       'GA', 'GABON',
+       'GM', 'GAMBIA',
+       'GE', 'GEORGIA',
+       'DE', 'GERMANY',
+       'GH', 'GHANA',
+       'GI', 'GIBRALTAR',
+       'GR', 'GREECE',
+       'GL', 'GREENLAND',
+       'GD', 'GRENADA',
+       'GP', 'GUADELOUPE',
+       'GU', 'GUAM',
+       'GT', 'GUATEMALA',
+       'GN', 'GUINEA',
+       'GW', 'GUINEA-BISSAU',
+       'GY', 'GUYANA',
+       'HT', 'HAITI',
+       'HM', 'HEARD AND MC DONALD ISLANDS',
+       'VA', 'HOLY SEE (VATICAN CITY STATE)',
+       'HN', 'HONDURAS',
+       'HK', 'HONG KONG',
+       'HU', 'HUNGARY',
+       'IS', 'ICELAND',
+       'IN', 'INDIA',
+       'ID', 'INDONESIA',
+       'IR', 'IRAN (ISLAMIC REPUBLIC OF)',
+       'IQ', 'IRAQ',
+       'IE', 'IRELAND',
+       'IL', 'ISRAEL',
+       'IT', 'ITALY',
+       'JM', 'JAMAICA',
+       'JP', 'JAPAN',
+       'JO', 'JORDAN',
+       'KZ', 'KAZAKHSTAN',
+       'KE', 'KENYA',
+       'KI', 'KIRIBATI',
+       'KP', "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF",
+       'KR', 'KOREA, REPUBLIC OF',
+       'KW', 'KUWAIT',
+       'KG', 'KYRGYZSTAN',
+       'LA', "LAO PEOPLE'S DEMOCRATIC REPUBLIC",
+       'LV', 'LATVIA',
+       'LB', 'LEBANON',
+       'LS', 'LESOTHO',
+       'LR', 'LIBERIA',
+       'LY', 'LIBYAN ARAB JAMAHIRIYA',
+       'LI', 'LIECHTENSTEIN',
+       'LT', 'LITHUANIA',
+       'LU', 'LUXEMBOURG',
+       'MO', 'MACAU',
+       'MK', 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF',
+       'MG', 'MADAGASCAR',
+       'MW', 'MALAWI',
+       'MY', 'MALAYSIA',
+       'MV', 'MALDIVES',
+       'ML', 'MALI',
+       'MT', 'MALTA',
+       'MH', 'MARSHALL ISLANDS',
+       'MQ', 'MARTINIQUE',
+       'MR', 'MAURITANIA',
+       'MU', 'MAURITIUS',
+       'YT', 'MAYOTTE',
+       'MX', 'MEXICO',
+       'FM', 'MICRONESIA, FEDERATED STATES OF',
+       'MD', 'MOLDOVA, REPUBLIC OF',
+       'MC', 'MONACO',
+       'MN', 'MONGOLIA',
+       'MS', 'MONTSERRAT',
+       'MA', 'MOROCCO',
+       'MZ', 'MOZAMBIQUE',
+       'MM', 'MYANMAR',
+       'NA', 'NAMIBIA',
+       'NR', 'NAURU',
+       'NP', 'NEPAL',
+       'NL', 'NETHERLANDS',
+       'AN', 'NETHERLANDS ANTILLES',
+       'NC', 'NEW CALEDONIA',
+       'NZ', 'NEW ZEALAND',
+       'NI', 'NICARAGUA',
+       'NE', 'NIGER',
+       'NG', 'NIGERIA',
+       'NU', 'NIUE',
+       'NF', 'NORFOLK ISLAND',
+       'MP', 'NORTHERN MARIANA ISLANDS',
+       'NO', 'NORWAY',
+       'OM', 'OMAN',
+       'PK', 'PAKISTAN',
+       'PW', 'PALAU',
+       'PA', 'PANAMA',
+       'PG', 'PAPUA NEW GUINEA',
+       'PY', 'PARAGUAY',
+       'PE', 'PERU',
+       'PH', 'PHILIPPINES',
+       'PN', 'PITCAIRN',
+       'PL', 'POLAND',
+       'PT', 'PORTUGAL',
+       'PR', 'PUERTO RICO',
+       'QA', 'QATAR',
+       'RE', 'REUNION',
+       'RO', 'ROMANIA',
+       'RU', 'RUSSIAN FEDERATION',
+       'RW', 'RWANDA',
+       'KN', 'SAINT KITTS AND NEVIS',
+       'LC', 'SAINT LUCIA',
+       'VC', 'SAINT VINCENT AND THE GRENADINES',
+       'WS', 'SAMOA',
+       'SM', 'SAN MARINO',
+       'ST', 'SAO TOME AND PRINCIPE',
+       'SA', 'SAUDI ARABIA',
+       'SN', 'SENEGAL',
+       'SC', 'SEYCHELLES',
+       'SL', 'SIERRA LEONE',
+       'SG', 'SINGAPORE',
+       'SK', 'SLOVAKIA (Slovak Republic)',
+       'SI', 'SLOVENIA',
+       'SB', 'SOLOMON ISLANDS',
+       'SO', 'SOMALIA',
+       'ZA', 'SOUTH AFRICA',
+       'GS', 'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS',
+       'ES', 'SPAIN',
+       'LK', 'SRI LANKA',
+       'SH', 'ST. HELENA',
+       'PM', 'ST. PIERRE AND MIQUELON',
+       'SD', 'SUDAN',
+       'SR', 'SURINAME',
+       'SJ', 'SVALBARD AND JAN MAYEN ISLANDS',
+       'SZ', 'SWAZILAND',
+       'SE', 'SWEDEN',
+       'CH', 'SWITZERLAND',
+       'SY', 'SYRIAN ARAB REPUBLIC',
+       'TW', 'TAIWAN, PROVINCE OF CHINA',
+       'TJ', 'TAJIKISTAN',
+       'TZ', 'TANZANIA, UNITED REPUBLIC OF',
+       'TH', 'THAILAND',
+       'TG', 'TOGO',
+       'TK', 'TOKELAU',
+       'TO', 'TONGA',
+       'TT', 'TRINIDAD AND TOBAGO',
+       'TN', 'TUNISIA',
+       'TR', 'TURKEY',
+       'TM', 'TURKMENISTAN',
+       'TC', 'TURKS AND CAICOS ISLANDS',
+       'TV', 'TUVALU',
+       'UG', 'UGANDA',
+       'UA', 'UKRAINE',
+       'AE', 'UNITED ARAB EMIRATES',
+       'GB', 'UNITED KINGDOM',
+       'US', 'UNITED STATES',
+       'UM', 'UNITED STATES MINOR OUTLYING ISLANDS',
+       'UY', 'URUGUAY',
+       'UZ', 'UZBEKISTAN',
+       'VU', 'VANUATU',
+       'VE', 'VENEZUELA',
+       'VN', 'VIET NAM',
+       'VG', 'VIRGIN ISLANDS (BRITISH)',
+       'VI', 'VIRGIN ISLANDS (U.S.)',
+       'WF', 'WALLIS AND FUTUNA ISLANDS',
+       'EH', 'WESTERN SAHARA',
+       'YE', 'YEMEN',
+       'YU', 'YUGOSLAVIA',
+       'ZM', 'ZAMBIA',
+       'ZW', 'ZIMBABWE',
        );
     return %Hash;
 }
        );
     return %Hash;
 }
@@ -277,7 +277,7 @@ sub exchange {
     my ($message) = @_;
     &::DEBUG("exchange(@_)");
 
     my ($message) = @_;
     &::DEBUG("exchange(@_)");
 
-    return "Exchange.pl needs LWP::UserAgent and HTTP::Request::Common"
+    return 'Exchange.pl needs LWP::UserAgent and HTTP::Request::Common'
        if ($no_exchange);
 
     my ($From, $To, $Amount, $Country);
        if ($no_exchange);
 
     my ($From, $To, $Amount, $Country);
@@ -294,9 +294,9 @@ sub exchange {
 
     my $ua = new LWP::UserAgent;
     # Let's pretend
 
     my $ua = new LWP::UserAgent;
     # Let's pretend
-    #$ua->agent("Mozilla/5.0 " . $ua->agent);
-    $ua->agent("Mozilla/5.0");
-    $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+    #$ua->agent('Mozilla/5.0 ' . $ua->agent);
+    $ua->agent('Mozilla/5.0');
+    $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
     $ua->timeout(10);
 
     my $Referer = 'http://www.xe.net/ucc/full.shtml';
     $ua->timeout(10);
 
     my $Referer = 'http://www.xe.net/ucc/full.shtml';
@@ -306,7 +306,7 @@ sub exchange {
     my $grab = GET $Referer;
     my $reply = $ua->request($grab);
     if (!$reply->is_success) {
     my $grab = GET $Referer;
     my $reply = $ua->request($grab);
     if (!$reply->is_success) {
-       return "EXCHANGE: ".$reply->status_line;
+       return 'EXCHANGE: '.$reply->status_line;
     }
     my $html = $reply->as_string;
     my %Currencies = (grep /\S+/,
     }
     my $html = $reply->as_string;
     my %Currencies = (grep /\S+/,
@@ -373,7 +373,7 @@ sub exchange {
                    return "$Cfrom $Currencies{$From} makes ".
                        "$Cto $Currencies{$To} (from http://www.xe.com/)"; # ." ($When)\n";
                } else {
                    return "$Cfrom $Currencies{$From} makes ".
                        "$Cto $Currencies{$To} (from http://www.xe.com/)"; # ." ($When)\n";
                } else {
-                   return "i got some error trying that";
+                   return 'i got some error trying that';
                }
            } else {
                # Oh dear.
                }
            } else {
                # Oh dear.
@@ -392,7 +392,7 @@ sub query {
   return;
 }
 
   return;
 }
 
-
+#print &exchange('1 usd to eur') . "\n";
 1;
 
 __END__
 1;
 
 __END__
@@ -422,3 +422,5 @@ currency code is a bit cranky.
 =head1 AUTHORS
 
 Bobby <bobby@bofh.dk>
 =head1 AUTHORS
 
 Bobby <bobby@bofh.dk>
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 9a2a8592bbce4c4a59b9bb4713fcdf80d547e5ef..12e64954ef980543df0d16cdf90a58bcb9edd09f 100644 (file)
@@ -15,14 +15,14 @@ use vars qw(%param);
 sub CmdFactInfo {
     my ($faqtoid, $query) = (lc $_[0], $_[1]);
     my @array;
 sub CmdFactInfo {
     my ($faqtoid, $query) = (lc $_[0], $_[1]);
     my @array;
-    my $string = "";
+    my $string = '';
 
 
-    if ($faqtoid eq "") {
-       &help("factinfo");
+    if ($faqtoid eq '') {
+       &help('factinfo');
        return;
     }
 
        return;
     }
 
-    my %factinfo = &sqlSelectRowHash("factoids", "*",
+    my %factinfo = &sqlSelectRowHash('factoids', '*',
        { factoid_key => $faqtoid }
     );
 
        { factoid_key => $faqtoid }
     );
 
@@ -47,7 +47,7 @@ sub CmdFactInfo {
     if ($factinfo{'created_by'}) {
 
        $factinfo{'created_by'} =~ s/\!/ </;
     if ($factinfo{'created_by'}) {
 
        $factinfo{'created_by'} =~ s/\!/ </;
-       $factinfo{'created_by'} .= ">";
+       $factinfo{'created_by'} .= '>';
        $string  = "created by $factinfo{'created_by'}";
 
        my $time = $factinfo{'created_time'};
        $string  = "created by $factinfo{'created_by'}";
 
        my $time = $factinfo{'created_time'};
@@ -57,27 +57,27 @@ sub CmdFactInfo {
                $string .= " at \037". scalar(gmtime $time). "\037" .
                                " ($days days)";
            } else {
                $string .= " at \037". scalar(gmtime $time). "\037" .
                                " ($days days)";
            } else {
-               $string .= " ".&Time2String(time() - $time)." ago";
+               $string .= ' '.&Time2String(time() - $time).' ago';
            }
        }
 
        push(@array,$string);
     }
 
            }
        }
 
        push(@array,$string);
     }
 
-    # modified: (TimRiker asks "why do you keep turning this off?)
+    # modified: (TimRiker askswhy do you keep turning this off?)
     if ($factinfo{'modified_by'}) {
     if ($factinfo{'modified_by'}) {
-       $string = "last modified";
+       $string = 'last modified';
 
        my $time = $factinfo{'modified_time'};
        if ($time) {
            if (time() - $time > 60*60*24*7) {
                $string .= " at \037". scalar(gmtime $time). "\037";
            } else {
 
        my $time = $factinfo{'modified_time'};
        if ($time) {
            if (time() - $time > 60*60*24*7) {
                $string .= " at \037". scalar(gmtime $time). "\037";
            } else {
-               $string .= " ".&Time2String(time() - $time)." ago ";
+               $string .= ' '.&Time2String(time() - $time).' ago ';
            }
        }
 
            }
        }
 
-       $string .= " by ".(split ",", $factinfo{'modified_by'})[0];
+       $string .= ' by '.(split ',', $factinfo{'modified_by'})[0];
 
        push(@array,$string);
     }
 
        push(@array,$string);
     }
@@ -87,12 +87,12 @@ sub CmdFactInfo {
        my $requested_count = $factinfo{'requested_count'};
 
        if ($requested_count) {
        my $requested_count = $factinfo{'requested_count'};
 
        if ($requested_count) {
-           $string  = "it has been requested ";
+           $string  = 'it has been requested ';
            if ($requested_count == 1) {
                $string .= "\002once\002";
            } else {
                $string .= "\002". $requested_count. "\002 ".
            if ($requested_count == 1) {
                $string .= "\002once\002";
            } else {
                $string .= "\002". $requested_count. "\002 ".
-                       &fixPlural("time", $requested_count);
+                       &fixPlural('time', $requested_count);
            }
 
            my $requested_by = $factinfo{'requested_by'};
            }
 
            my $requested_by = $factinfo{'requested_by'};
@@ -104,11 +104,11 @@ sub CmdFactInfo {
                if (time() - $requested_time > 60*60*24*7) {
                    $string .= " at \037". scalar(localtime $requested_time). "\037";
                } else {
                if (time() - $requested_time > 60*60*24*7) {
                    $string .= " at \037". scalar(localtime $requested_time). "\037";
                } else {
-                   $string .= ", ".&Time2String(time() - $requested_time)." ago";
+                   $string .= ', '.&Time2String(time() - $requested_time).' ago';
                }
            }
        } else {
                }
            }
        } else {
-           $string  = "has not been requested yet";
+           $string  = 'has not been requested yet';
        }
 
        push(@array, $string);
        }
 
        push(@array, $string);
@@ -128,7 +128,7 @@ sub CmdFactInfo {
        return;
     }
 
        return;
     }
 
-    &performStrictReply("$factinfo{'factoid_key'} -- ". join("; ", @array) .".");
+    &performStrictReply("$factinfo{'factoid_key'} -- ". join('; ', @array) .'.');
     return;
 }
 
     return;
 }
 
@@ -136,9 +136,9 @@ sub CmdFactStats {
     my ($type) = @_;
 
     if ($type =~ /^author$/i) {
     my ($type) = @_;
 
     if ($type =~ /^author$/i) {
-       my %hash = &sqlSelectColHash("factoids",
-               "factoid_key,created_by", undef,
-               "WHERE created_by IS NOT NULL"
+       my %hash = &sqlSelectColHash('factoids',
+               'factoid_key,created_by', undef,
+               'WHERE created_by IS NOT NULL'
        );
        my %author;
 
        );
        my %author;
 
@@ -163,24 +163,24 @@ sub CmdFactStats {
        my $count;
        my @list;
        foreach $count (sort { $b <=> $a } keys %count) {
        my $count;
        my @list;
        foreach $count (sort { $b <=> $a } keys %count) {
-           my $author = join(", ", sort keys %{ $count{$count} });
+           my $author = join(', ', sort keys %{ $count{$count} });
            push(@list, "$count by $author");
        }
 
            push(@list, "$count by $author");
        }
 
-       my $prefix = "factoid statistics by author: ";
+       my $prefix = 'factoid statistics by author: ';
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^vandalism$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^vandalism$/i) {
-       &status("factstats(vandalism): starting...");
+       &status('factstats(vandalism): starting...');
        my $start_time  = &timeget();
        my $start_time  = &timeget();
-       my %data        = &sqlSelectColHash("factoids",
-               "factoid_key,factoid_value", undef,
-               "WHERE factoid_value IS NOT NULL"
+       my %data        = &sqlSelectColHash('factoids',
+               'factoid_key,factoid_value', undef,
+               'WHERE factoid_value IS NOT NULL'
        );
        my @list;
 
        my $delta_time  = &timedelta($start_time);
        );
        my @list;
 
        my $delta_time  = &timedelta($start_time);
-       &status(sprintf("factstats(vandalism): %.02f sec to retreive all factoids.", $delta_time)) if ($delta_time > 0);
+       &status(sprintf('factstats(vandalism): %.02f sec to retreive all factoids.', $delta_time)) if ($delta_time > 0);
        $start_time     = &timeget();
 
        # parse the factoids.
        $start_time     = &timeget();
 
        # parse the factoids.
@@ -192,7 +192,7 @@ sub CmdFactStats {
        }
 
        $delta_time     = &timedelta($start_time);
        }
 
        $delta_time     = &timedelta($start_time);
-       &status(sprintf("factstats(vandalism): %.02f sec to complete.", $delta_time)) if ($delta_time > 0);
+       &status(sprintf('factstats(vandalism): %.02f sec to complete.', $delta_time)) if ($delta_time > 0);
 
        # bail out on no results.
        if (scalar @list == 0) {
 
        # bail out on no results.
        if (scalar @list == 0) {
@@ -200,11 +200,11 @@ sub CmdFactStats {
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "Vandalised factoid ";
+       my $prefix = 'Vandalised factoid ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^total$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^total$/i) {
-       &status("factstats(total): starting...");
+       &status('factstats(total): starting...');
        my $start_time  = &timeget();
        my @list;
        my $str;
        my $start_time  = &timeget();
        my @list;
        my $str;
@@ -213,50 +213,50 @@ sub CmdFactStats {
 
        ### lets do it.
        # total factoids requests.
 
        ### lets do it.
        # total factoids requests.
-       $i = &sumKey("factoids", "requested_count");
+       $i = &sumKey('factoids', 'requested_count');
        push(@list, "total requests - $i");
 
        # total factoids modified.
        push(@list, "total requests - $i");
 
        # total factoids modified.
-       $str = &countKeys("factoids", "modified_by");
+       $str = &countKeys('factoids', 'modified_by');
        push(@list, "total modified - $str");
 
        # total factoids modified.
        push(@list, "total modified - $str");
 
        # total factoids modified.
-       $j      = &countKeys("factoids", "requested_count");
-       $str    = &countKeys("factoids", "factoid_key");
-       push(@list, "total non-requested - ".($str - $i));
+       $j      = &countKeys('factoids', 'requested_count');
+       $str    = &countKeys('factoids', 'factoid_key');
+       push(@list, 'total non-requested - '.($str - $i));
 
        # average request/factoid.
        # i/j == total(requested_count)/count(requested_count)
 
        # average request/factoid.
        # i/j == total(requested_count)/count(requested_count)
-       $str = sprintf("%.01f", $i/$j);
+       $str = sprintf('%.01f', $i/$j);
        push(@list, "average requested per factoid - $str");
 
        # total prepared for deletion.
        push(@list, "average requested per factoid - $str");
 
        # total prepared for deletion.
-       $str    = scalar( &searchTable("factoids", "factoid_key", "factoid_value", " #DEL") );
+       $str    = scalar( &searchTable('factoids', 'factoid_key', 'factoid_value', ' #DEL') );
        push(@list, "total prepared for deletion - $str");
 
        # total unique authors.
        # TODO: convert to sqlSelectColHash ? (or ColArray?)
        push(@list, "total prepared for deletion - $str");
 
        # total unique authors.
        # TODO: convert to sqlSelectColHash ? (or ColArray?)
-       foreach ( &sqlRawReturn("SELECT created_by FROM factoids WHERE created_by IS NOT NULL") ) {
+       foreach ( &sqlRawReturn('SELECT created_by FROM factoids WHERE created_by IS NOT NULL') ) {
            /^(\S+)!/;
            my $nick = lc $1;
            $hash{$nick}++;
        }
            /^(\S+)!/;
            my $nick = lc $1;
            $hash{$nick}++;
        }
-       push(@list, "total unique authors - ".(scalar keys %hash) );
+       push(@list, 'total unique authors - '.(scalar keys %hash) );
        undef %hash;
 
        # total unique requesters.
        undef %hash;
 
        # total unique requesters.
-       foreach ( &sqlRawReturn("SELECT requested_by FROM factoids WHERE requested_by IS NOT NULL") ) {
+       foreach ( &sqlRawReturn('SELECT requested_by FROM factoids WHERE requested_by IS NOT NULL') ) {
            /^(\S+)!/;
            my $nick = lc $1;
            $hash{$nick}++;
        }
            /^(\S+)!/;
            my $nick = lc $1;
            $hash{$nick}++;
        }
-       push(@list, "total unique requesters - ".(scalar keys %hash) );
+       push(@list, 'total unique requesters - '.(scalar keys %hash) );
        undef %hash;
 
        undef %hash;
 
-       ### end of "job".
+       ### end of 'job'.
 
        my $delta_time  = &timedelta($start_time);
 
        my $delta_time  = &timedelta($start_time);
-       &status(sprintf("factstats(broken): %.02f sec to retreive all factoids.", $delta_time)) if ($delta_time > 0);
+       &status(sprintf('factstats(broken): %.02f sec to retreive all factoids.', $delta_time)) if ($delta_time > 0);
        $start_time     = &timeget();
 
        # bail out on no results.
        $start_time     = &timeget();
 
        # bail out on no results.
@@ -265,21 +265,21 @@ sub CmdFactStats {
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "General factoid statistics ";
+       my $prefix = 'General factoid statistics ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^deadredir$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^deadredir$/i) {
-       my @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", "^<REPLY> see ");
+       my @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', '^<REPLY> see ');
        my %redir;
        my $f;
 
        for (@list) {
            my $factoid = $_;
        my %redir;
        my $f;
 
        for (@list) {
            my $factoid = $_;
-           my $val = &getFactInfo($factoid, "factoid_value");
+           my $val = &getFactInfo($factoid, 'factoid_value');
            if ($val =~ /^<REPLY> ?see( also)? (.*?)\.?$/i) {
                my $redirf = lc $2;
            if ($val =~ /^<REPLY> ?see( also)? (.*?)\.?$/i) {
                my $redirf = lc $2;
-               my $redir = &getFactInfo($redirf, "factoid_value");
+               my $redir = &getFactInfo($redirf, 'factoid_value');
                next if (defined $redir);
                next if (length $val > 50);
 
                next if (defined $redir);
                next if (length $val > 50);
 
@@ -298,15 +298,15 @@ sub CmdFactStats {
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "Loose link (dead) redirections in factoids ";
+       my $prefix = 'Loose link (dead) redirections in factoids ';
        return &formListReply(1, $prefix, @newlist);
 
     } elsif ($type =~ /^dup(licate|e)$/i) {
        return &formListReply(1, $prefix, @newlist);
 
     } elsif ($type =~ /^dup(licate|e)$/i) {
-       &status("factstats(dupe): starting...");
+       &status('factstats(dupe): starting...');
        my $start_time  = &timeget();
        my $start_time  = &timeget();
-       my %hash        = &sqlSelectColHash("factoids",
-               "factoid_key,factoid_value", undef,
-               "WHERE factoid_value IS NOT NULL", 1
+       my %hash        = &sqlSelectColHash('factoids',
+               'factoid_key,factoid_value', undef,
+               'WHERE factoid_value IS NOT NULL', 1
        );
        my $refs        = 0;
        my @list;
        );
        my $refs        = 0;
        my @list;
@@ -324,8 +324,8 @@ sub CmdFactStats {
                }
 
                s/([\,\;]+)/\037$1\037/g;
                }
 
                s/([\,\;]+)/\037$1\037/g;
-               if ($_ eq "") {
-                   &WARN("dupe: _ = NULL. should never happen!.");
+               if ($_ eq '') {
+                   &WARN('dupe: _ = NULL. should never happen!.');
                    next;
                }
                push(@sublist, $_);
                    next;
                }
                push(@sublist, $_);
@@ -333,20 +333,20 @@ sub CmdFactStats {
 
            next unless (scalar @sublist);
 
 
            next unless (scalar @sublist);
 
-           push(@list, join(", ", @sublist));
+           push(@list, join(', ', @sublist));
        }
 
        &status("factstats(dupe): (good) dupe refs: $refs.");
        my $delta_time  = &timedelta($start_time);
        }
 
        &status("factstats(dupe): (good) dupe refs: $refs.");
        my $delta_time  = &timedelta($start_time);
-       &status(sprintf("factstats(dupe): %.02f sec to complete", $delta_time)) if ($delta_time > 0);
+       &status(sprintf('factstats(dupe): %.02f sec to complete', $delta_time)) if ($delta_time > 0);
 
        # bail out on no results.
        if (scalar @list == 0) {
 
        # bail out on no results.
        if (scalar @list == 0) {
-           return "no duplicate factoids... woohoo.";
+           return 'no duplicate factoids... woohoo.';
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "dupe factoid ";
+       my $prefix = 'dupe factoid ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^nullfactoids$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^nullfactoids$/i) {
@@ -356,7 +356,7 @@ sub CmdFactStats {
 
        my @list;
        while (my @row = $sth->fetchrow_array) {
 
        my @list;
        while (my @row = $sth->fetchrow_array) {
-           if ($row[1] ne "") {
+           if ($row[1] ne '') {
                &DEBUG("row[1] != NULL for $row[0].");
                next;
            }
                &DEBUG("row[1] != NULL for $row[0].");
                next;
            }
@@ -367,12 +367,12 @@ sub CmdFactStats {
        $sth->finish;
 
        # parse the results.
        $sth->finish;
 
        # parse the results.
-       my $prefix = "NULL factoids (not deleted yet) ";
+       my $prefix = 'NULL factoids (not deleted yet) ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^(2|too)short$/i) {
        # Custom select statement.
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^(2|too)short$/i) {
        # Custom select statement.
-       my $query = "SELECT factoid_key,factoid_value FROM factoids WHERE length(factoid_value) <= 40";
+       my $query = 'SELECT factoid_key,factoid_value FROM factoids WHERE length(factoid_value) <= 40';
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(lame): => '$query'.") unless $sth->execute;
 
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(lame): => '$query'.") unless $sth->execute;
 
@@ -394,12 +394,12 @@ sub CmdFactStats {
        $sth->finish;
 
        # parse the results.
        $sth->finish;
 
        # parse the results.
-       my $prefix = "Lame factoids ";
+       my $prefix = 'Lame factoids ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^listfix$/i) {
        # Custom select statement.
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^listfix$/i) {
        # Custom select statement.
-       my $query = "SELECT factoid_key,factoid_value FROM factoids";
+       my $query = 'SELECT factoid_key,factoid_value FROM factoids';
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(listfix): => '$query'.") unless $sth->execute;
 
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(listfix): => '$query'.") unless $sth->execute;
 
@@ -414,18 +414,18 @@ sub CmdFactStats {
            push(@list, $key);
            $val =~ s/,? or /, /g;
            &DEBUG("fixed: => $val.");
            push(@list, $key);
            $val =~ s/,? or /, /g;
            &DEBUG("fixed: => $val.");
-           &setFactInfo($key,"factoid_value", $val);
+           &setFactInfo($key,'factoid_value', $val);
        }
        $sth->finish;
 
        # parse the results.
        }
        $sth->finish;
 
        # parse the results.
-       my $prefix = "Inefficient lists fixed ";
+       my $prefix = 'Inefficient lists fixed ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^locked$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^locked$/i) {
-       my %hash = &sqlSelectColhash("factoids",
-               "factoid_key,locked_by", undef,
-               "WHERE locked_by IS NOT NULL"
+       my %hash = &sqlSelectColHash('factoids',
+               'factoid_key,locked_by', undef,
+               'WHERE locked_by IS NOT NULL'
        );
        my @list = keys %hash;
 
        );
        my @list = keys %hash;
 
@@ -437,9 +437,9 @@ sub CmdFactStats {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^new$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^new$/i) {
-       my %hash = &sqlSelectColHash("factoids",
-               "factoid_key,created_time", undef,
-               "WHERE created_time IS NOT NULL"
+       my %hash = &sqlSelectColHash('factoids',
+               'factoid_key,created_time', undef,
+               'WHERE created_time IS NOT NULL'
        );
        my %age;
 
        );
        my %age;
 
@@ -452,24 +452,24 @@ sub CmdFactStats {
        }
 
        if (scalar keys %age == 0) {
        }
 
        if (scalar keys %age == 0) {
-           return "sorry, no new factoids.";
+           return 'sorry, no new factoids.';
        }
 
        my @list;
        foreach (sort {$a <=> $b} keys %age) {
        }
 
        my @list;
        foreach (sort {$a <=> $b} keys %age) {
-           push(@list, join(",", keys %{ $age{$_} }));
+           push(@list, join(',', keys %{ $age{$_} }));
        }
 
        }
 
-       my $prefix = "new factoids in the last 24hours ";
+       my $prefix = 'new factoids in the last 24hours ';
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^part(ial)?dupe$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^part(ial)?dupe$/i) {
-       ### requires "custom" select statement... oh well...
+       ### requires 'custom' select statement... oh well...
        my $start_time  = &timeget();
 
        # form length|key and key=length hash list.
        my $start_time  = &timeget();
 
        # form length|key and key=length hash list.
-       &status("factstats(partdupe): forming length hash list.");
-       my $query = "SELECT factoid_key,factoid_value,length(factoid_value) AS length FROM factoids WHERE length(factoid_value) >= 192 ORDER BY length";
+       &status('factstats(partdupe): forming length hash list.');
+       my $query = 'SELECT factoid_key,factoid_value,length(factoid_value) AS length FROM factoids WHERE length(factoid_value) >= 192 ORDER BY length';
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(partdupe): => '$query'.") unless $sth->execute;
 
        my $sth = $dbh->prepare($query);
        &ERROR("factstats(partdupe): => '$query'.") unless $sth->execute;
 
@@ -482,7 +482,7 @@ sub CmdFactStats {
        }
        $sth->finish;
        &status("factstats(partdupe): total keys => '". scalar(@key) ."'.");
        }
        $sth->finish;
        &status("factstats(partdupe): total keys => '". scalar(@key) ."'.");
-       &status("factstats(partdupe): now deciphering data gathered");
+       &status('factstats(partdupe): now deciphering data gathered');
 
        my @length = sort { $a <=> $b } keys %length;
        my $key;
 
        my @length = sort { $a <=> $b } keys %length;
        my $key;
@@ -498,53 +498,53 @@ sub CmdFactStats {
                    if ($key{$_} =~ /^$val/i) {
                        s/([\,\;]+)/\037$1\037/g;
                        s/( and|and )/\037$1\037/g;
                    if ($key{$_} =~ /^$val/i) {
                        s/([\,\;]+)/\037$1\037/g;
                        s/( and|and )/\037$1\037/g;
-                       push(@sublist,$key." and ".$_);
+                       push(@sublist,$key.' and '.$_);
                    }
                }
            }
                    }
                }
            }
-           push(@list, join(" ,",@sublist)) if (scalar @sublist);
+           push(@list, join(' ,',@sublist)) if (scalar @sublist);
        }
 
        }
 
-       my $delta_time = sprintf("%.02fs", &timedelta($start_time) );
+       my $delta_time = sprintf('%.02fs', &timedelta($start_time) );
        &status("factstats(partdupe): $delta_time sec to complete.") if ($delta_time > 0);
 
        # bail out on no results.
        if (scalar @list == 0) {
        &status("factstats(partdupe): $delta_time sec to complete.") if ($delta_time > 0);
 
        # bail out on no results.
        if (scalar @list == 0) {
-           return "no initial partial duplicate factoids... woohoo.";
+           return 'no initial partial duplicate factoids... woohoo.';
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "initial partial dupe factoid ";
+       my $prefix = 'initial partial dupe factoid ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^profanity$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^profanity$/i) {
-       my %data = &sqlSelectColHash("factoids",
-               "factoid_key,factoid_value", undef,
-               "WHERE factoid_value IS NOT NULL"
+       my %data = &sqlSelectColHash('factoids',
+               'factoid_key,factoid_value', undef,
+               'WHERE factoid_value IS NOT NULL'
        );
        my @list;
 
        foreach (keys %data) {
        );
        my @list;
 
        foreach (keys %data) {
-           push(@list, $_) if (&hasProfanity($_." ".$data{$_}));
+           push(@list, $_) if (&hasProfanity($_.' '.$data{$_}));
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "Profanity in factoids ";
+       my $prefix = 'Profanity in factoids ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^redir(ection)?$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^redir(ection)?$/i) {
-       my @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", "^<REPLY> see ");
+       my @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', '^<REPLY> see ');
        my %redir;
        my $f;
        my $dangling = 0;
 
        for (@list) {
            my $factoid = $_;
        my %redir;
        my $f;
        my $dangling = 0;
 
        for (@list) {
            my $factoid = $_;
-           my $val = &getFactInfo($factoid, "factoid_value");
+           my $val = &getFactInfo($factoid, 'factoid_value');
            if ($val =~ /^<REPLY> see( also)? (.*?)\.?$/i) {
                my $redir       = lc $2;
            if ($val =~ /^<REPLY> see( also)? (.*?)\.?$/i) {
                my $redir       = lc $2;
-               my $redirval    = &getFactInfo($redir, "factoid_value");
+               my $redirval    = &getFactInfo($redir, 'factoid_value');
                if (defined $redirval) {
                    $redir{$redir}{$factoid} = 1;
                } else {
                if (defined $redirval) {
                    $redir{$redir}{$factoid} = 1;
                } else {
@@ -569,9 +569,9 @@ sub CmdFactStats {
        return &formListReply(1, $prefix, @newlist);
 
     } elsif ($type =~ /^request(ed)?$/i) {
        return &formListReply(1, $prefix, @newlist);
 
     } elsif ($type =~ /^request(ed)?$/i) {
-       my %hash = &sqlSelectColHash("factoids",
-               "factoid_key,requested_count", undef,
-               "WHERE requested_count IS NOT NULL", 1
+       my %hash = &sqlSelectColHash('factoids',
+               'factoid_key,requested_count', undef,
+               'WHERE requested_count IS NOT NULL', 1
        );
 
        if (!scalar keys %hash) {
        );
 
        if (!scalar keys %hash) {
@@ -589,7 +589,7 @@ sub CmdFactStats {
            }
            $total      += $count * scalar(@faqtoids);
 
            }
            $total      += $count * scalar(@faqtoids);
 
-           push(@list, "$count - ". join(", ", @faqtoids));
+           push(@list, "$count - ". join(', ', @faqtoids));
        }
        unshift(@list, "\037$total - TOTAL\037");
 
        }
        unshift(@list, "\037$total - TOTAL\037");
 
@@ -597,9 +597,9 @@ sub CmdFactStats {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^reqrate$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^reqrate$/i) {
-       my %hash = &sqlSelectColHash("factoids",
+       my %hash = &sqlSelectColHash('factoids',
                "factoid_key,(unix_timestamp() - created_time)/requested_count as rate", undef,
                "factoid_key,(unix_timestamp() - created_time)/requested_count as rate", undef,
-               "WHERE requested_by IS NOT NULL and created_time IS NOT NULL ORDER BY rate LIMIT 15", 1
+               'WHERE requested_by IS NOT NULL and created_time IS NOT NULL ORDER BY rate LIMIT 15', 1
        );
 
        my $rate;
        );
 
        my $rate;
@@ -607,7 +607,7 @@ sub CmdFactStats {
        my $total       = 0;
        my $users       = 0;
        foreach $rate (sort { $b <=> $a } keys %hash) {
        my $total       = 0;
        my $users       = 0;
        foreach $rate (sort { $b <=> $a } keys %hash) {
-           my $f       = join(", ", sort keys %{ $hash{$rate} });
+           my $f       = join(', ', sort keys %{ $hash{$rate} });
            my $str     = "$f - ".&Time2String($rate);
            $str        =~ s/\002//g;
            push(@list, $str);
            my $str     = "$f - ".&Time2String($rate);
            $str        =~ s/\002//g;
            push(@list, $str);
@@ -617,9 +617,9 @@ sub CmdFactStats {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^requesters?$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^requesters?$/i) {
-       my %hash = &sqlSelectColHash("factoids",
-               "factoid_key,requested_by", undef,
-               "WHERE requested_by IS NOT NULL"
+       my %hash = &sqlSelectColHash('factoids',
+               'factoid_key,requested_by', undef,
+               'WHERE requested_by IS NOT NULL'
        );
        my %requester;
 
        );
        my %requester;
 
@@ -646,7 +646,7 @@ sub CmdFactStats {
        my $total       = 0;
        my $users       = 0;
        foreach $count (sort { $b <=> $a } keys %count) {
        my $total       = 0;
        my $users       = 0;
        foreach $count (sort { $b <=> $a } keys %count) {
-           my $requester = join(", ", sort keys %{ $count{$count} });
+           my $requester = join(', ', sort keys %{ $count{$count} });
            $total      += $count * scalar(keys %{ $count{$count} });
            $users      += scalar(keys %{ $count{$count} });
            push(@list, "$count by $requester");
            $total      += $count * scalar(keys %{ $count{$count} });
            $users      += scalar(keys %{ $count{$count} });
            push(@list, "$count by $requester");
@@ -655,12 +655,12 @@ sub CmdFactStats {
        # should not the above value be the same as collected by
        # 'requested'? soemthing weird is going on!
 
        # should not the above value be the same as collected by
        # 'requested'? soemthing weird is going on!
 
-       my $prefix = "rank of top factoid requesters: ";
+       my $prefix = 'rank of top factoid requesters: ';
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^seefix$/i) {
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^seefix$/i) {
-       my @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", "^see ");
+       my @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', '^see ');
        my @newlist;
        my $fixed = 0;
        my %loop;
        my @newlist;
        my $fixed = 0;
        my %loop;
@@ -668,12 +668,12 @@ sub CmdFactStats {
 
        for (@list) {
            my $factoid = $_;
 
        for (@list) {
            my $factoid = $_;
-           my $val = &getFactInfo($factoid, "factoid_value");
+           my $val = &getFactInfo($factoid, 'factoid_value');
 
            next unless ($val =~ /^see( also)? (.*?)\.?$/i);
 
            my $redirf  = lc $2;
 
            next unless ($val =~ /^see( also)? (.*?)\.?$/i);
 
            my $redirf  = lc $2;
-           my $redir   = &getFactInfo($redirf, "factoid_value");
+           my $redir   = &getFactInfo($redirf, 'factoid_value');
 
            if ($redirf =~ /^\Q$factoid\W$/i) {
                &delFactoid($factoid);
 
            if ($redirf =~ /^\Q$factoid\W$/i) {
                &delFactoid($factoid);
@@ -681,7 +681,7 @@ sub CmdFactStats {
            }
 
            if (defined $redir) {       # good.
            }
 
            if (defined $redir) {       # good.
-               &setFactInfo($factoid,"factoid_value","<REPLY> see $redir");
+               &setFactInfo($factoid,'factoid_value',"<REPLY> see $redir");
                $fixed++;
            } else {
                push(@newlist, $redirf);
                $fixed++;
            } else {
                push(@newlist, $redirf);
@@ -690,8 +690,7 @@ sub CmdFactStats {
 
        # parse the results.
        &msg($who, "Fixed $fixed factoids.");
 
        # parse the results.
        &msg($who, "Fixed $fixed factoids.");
-       &msg($who, "Self looped factoids removed: ".
-               sort(keys %loop) ) if (scalar keys %loop);
+       &msg($who, 'Self looped factoids removed: '. keys %loop ) if (scalar keys %loop);
 
        my $prefix = "Loose link (dead) redirections in factoids ";
        return &formListReply(1, $prefix, @newlist);
 
        my $prefix = "Loose link (dead) redirections in factoids ";
        return &formListReply(1, $prefix, @newlist);
@@ -719,11 +718,11 @@ sub CmdFactStats {
        $sth->finish;
 
        if (scalar @list == 0) {
        $sth->finish;
 
        if (scalar @list == 0) {
-           return "good. no factoids exceed length.";
+           return 'good. no factoids exceed length.';
        }
 
        # parse the results.
        }
 
        # parse the results.
-       my $prefix = "factoid key||value exceeding length ";
+       my $prefix = 'factoid key||value exceeding length ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^unrequest(ed)?$/i) {
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^unrequest(ed)?$/i) {
@@ -739,7 +738,7 @@ sub CmdFactStats {
 sub CmdListAuth {
     my ($query) = @_;
     my $maxshow = &::getChanConfDefault('maxListReplyCount', 15, $chan);
 sub CmdListAuth {
     my ($query) = @_;
     my $maxshow = &::getChanConfDefault('maxListReplyCount', 15, $chan);
-    my @list = &searchTable("factoids","factoid_key", "created_by", "^$query!");
+    my @list = &searchTable('factoids','factoid_key', 'created_by', "^$query!");
     @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow);
 
     my $prefix = "factoid author list by '$query' ";
     @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow);
 
     my $prefix = "factoid author list by '$query' ";
@@ -747,3 +746,5 @@ sub CmdListAuth {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index c91ecd01a87416ee1a01540935644d25c5c557ae..ac60d61072f5c9f134a641619dbcfa8e9fbed1e9 100644 (file)
@@ -21,13 +21,15 @@ sub HTTPDtype {
        $s->write_request(HEAD => "/");
 
        my $sel = IO::Select->new($s);
        $s->write_request(HEAD => "/");
 
        my $sel = IO::Select->new($s);
-       $line = "Header timeout" unless $sel->can_read(10);
+       $line = 'Header timeout' unless $sel->can_read(10);
        ($code, $mess, %h) = $s->read_response_headers;
 
        $line = (length($h{Server}) > 0) ? $h{Server} :
          "Couldn't fetch headers from $HOST";
 
        ($code, $mess, %h) = $s->read_response_headers;
 
        $line = (length($h{Server}) > 0) ? $h{Server} :
          "Couldn't fetch headers from $HOST";
 
-    &::performStrictReply($line||"Unknown Error Condition");
+    &::performStrictReply($line||'Unknown Error Condition');
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 1a762b886e0176ad6ca1fed03ba32348dd16af77..12ae9d0d6eb53f75aada6ffd213cf42a8837ce94 100644 (file)
@@ -12,7 +12,7 @@ sub kernelGetInfo {
 }
 
 sub Kernel {
 }
 
 sub Kernel {
-    my $retval = "Linux kernel versions";
+    my $retval = 'Linux kernel versions';
     my @now = &kernelGetInfo();
     if (!scalar @now) {
        &::msg($::who, "failed.");
     my @now = &kernelGetInfo();
     if (!scalar @now) {
        &::msg($::who, "failed.");
@@ -20,8 +20,8 @@ sub Kernel {
     }
 
     if ($::who =~ /^\#/) {
     }
 
     if ($::who =~ /^\#/) {
-       &::msg($::who, "No, I won't harass the entire channel."); 
-       return undef;
+       &::msg($::who, "No, I won't harass the entire channel."); 
+       return undef;
     }
 
     foreach $line (@now) {
     }
 
     foreach $line (@now) {
@@ -37,7 +37,7 @@ sub Kernel {
        $line =~ s/ for 2.4//;
        $line =~ s/ for 2.2//;
        $line =~ s/ is: */: /;
        $line =~ s/ for 2.4//;
        $line =~ s/ for 2.2//;
        $line =~ s/ is: */: /;
-       $retval .= ", " . $line;
+       $retval .= ', ' . $line;
     }
     &::performStrictReply($retval);
 }
     }
     &::performStrictReply($retval);
 }
@@ -48,7 +48,7 @@ sub kernelAnnounce {
     my @old;
 
     if (!scalar @now) {
     my @old;
 
     if (!scalar @now) {
-       &::DEBUG("kA: failure to retrieve.");
+       &::DEBUG('kA: failure to retrieve.');
        return;
     }
 
        return;
     }
 
@@ -96,3 +96,5 @@ sub kernelAnnounce {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index b91f8fe64ff7d1f5bc8623b271cf5cfd8183dc2b..a3b966b247ceadc88b3d29393aa269ba277a665c 100644 (file)
@@ -7,26 +7,26 @@ use strict;
 use vars qw($message);
 
 my %digits = (
 use vars qw($message);
 
 my %digits = (
-       "first",   "1",
-       "second",  "2",
-       "third",   "3",
-       "fourth",  "4",
-       "fifth",   "5",
-       "sixth",   "6",
-       "seventh", "7",
-       "eighth",  "8",
-       "ninth",   "9",
-       "tenth",   "10",
-       "one",     "1",
-       "two",     "2",
-       "three",   "3",
-       "four",    "4",
-       "five",    "5",
-       "six",     "6",
-       "seven",   "7",
-       "eight",   "8",
-       "nine",    "9",
-       "ten",     "10"
+       'first',   '1',
+       'second',  '2',
+       'third',   '3',
+       'fourth',  '4',
+       'fifth',   '5',
+       'sixth',   '6',
+       'seventh', '7',
+       'eighth',  '8',
+       'ninth',   '9',
+       'tenth',   '10',
+       'one',     '1',
+       'two',     '2',
+       'three',   '3',
+       'four',    '4',
+       'five',    '5',
+       'six',     '6',
+       'seven',   '7',
+       'eight',   '8',
+       'nine',    '9',
+       'ten',     '10'
 );
 
 sub perlMath {
 );
 
 sub perlMath {
@@ -60,13 +60,13 @@ sub perlMath {
 
     while ($locMsg =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/) {
        my ($exp, $res) = ($1, $2);
 
     while ($locMsg =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/) {
        my ($exp, $res) = ($1, $2);
-       my $val = ($res) ? log($res) : "Infinity";
+       my $val = ($res) ? log($res) : 'Infinity';
        $locMsg =~ s/$exp/+$val/g;
     }
 
     while ($locMsg =~ /(bin2dec ([01]+))/) {
        my $exp = $1;
        $locMsg =~ s/$exp/+$val/g;
     }
 
     while ($locMsg =~ /(bin2dec ([01]+))/) {
        my $exp = $1;
-       my $val = join ("", unpack("B*",$2)) ;
+       my $val = join ('', unpack('B*',$2)) ;
        $locMsg =~ s/$exp/+$val/g;
     }
 
        $locMsg =~ s/$exp/+$val/g;
     }
 
@@ -121,11 +121,11 @@ sub perlMath {
                &FIXME("math: locMsg => '$locMsg'...");
            } else {
                &status("math: could not really compute.");
                &FIXME("math: locMsg => '$locMsg'...");
            } else {
                &status("math: could not really compute.");
-               $locMsg = "";
+               $locMsg = '';
            }
        }
     } else {
            }
        }
     } else {
-       $locMsg = "";
+       $locMsg = '';
     }
 
     if (defined $locMsg and $locMsg ne $message) {
     }
 
     if (defined $locMsg and $locMsg ne $message) {
@@ -138,3 +138,5 @@ sub perlMath {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/src/Modules/NewUnits.pl b/src/Modules/NewUnits.pl
deleted file mode 100644 (file)
index 2e4f25f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#   Units.pl: convert units of measurement
-#     Author: M-J. Dominus (mjd-perl-units-id-iut+buobvys+@plover.com)
-#    License: GPL, Copyright (C) 1996,1999
-#       NOTE: Integrated into blootbot by xk.
-
-package NewUnits;
-
-#use strict;   # TODO
-
-
-sub convertUnits {
-  my ($from,$to) = @_;
-
-  if ($from =~ /([+-]?[\d\.]+(?:e[+-]?[\d]+)?)\s+(temp[CFK])/){
-    $from = qq|${2}(${1})|;
-  }
-
-  my $units = new IO::File;
-  open $units, '-|', 'units', $from, $to or &::DEBUG("Unable to run units: $!") and return;
-  my $response = readline ($units);
-  if ($response =~ /\s+\*\s+([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/ or $response =~ /\t([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/){
-    &::performStrictReply(sprintf("$from is approximately \002%.6g\002 $to", $1));
-  }
-  else {
-    &::performStrictReply("$from cannot be converted to ${to}: $response");
-  }
-  return;
-}
-
-
-1;
index d28400486252b404537071fc10dbd5a69ca4eaa6..07c037ac7a8f2427fac40f506f29062a694bf54b 100644 (file)
@@ -35,13 +35,8 @@ sub Parse {
        &readNews();
     }
 
        &readNews();
     }
 
-    if ($::msgType ne "private") {
-       if ($who =~ /^#/){
-            &::msg($who, "I'm not noticing the entire channel. /msg me instead");
-            return;
-       }
-       &::notice($who, "I'm not noticing the entire channel. /msg me instead");
-       return;
+    if ($::msgType ne 'private') {
+       $chan = $::chan;
     }
 
     if (defined $what and $what =~ s/^($::mask{chan})\s*//) {
     }
 
     if (defined $what and $what =~ s/^($::mask{chan})\s*//) {
@@ -123,8 +118,8 @@ sub Parse {
     } elsif ($what =~ /^(un)?notify$/i) {
        my $state = ($1) ? 0 : 1;
 
     } elsif ($what =~ /^(un)?notify$/i) {
        my $state = ($1) ? 0 : 1;
 
-       # TODO: don't notify even if "News" is called.
-       if (&::IsChanConf("newsNotifyAll") <= 0) {
+       # TODO: don't notify even if 'News' is called.
+       if (&::IsChanConf('newsNotifyAll') <= 0) {
            &::DEBUG("news: chan => $chan, ::chan => $::chan.");
            &::notice($who, "not available for this channel or disabled altogether.");
            return;
            &::DEBUG("news: chan => $chan, ::chan => $::chan.");
            &::notice($who, "not available for this channel or disabled altogether.");
            return;
@@ -142,7 +137,7 @@ sub Parse {
        } else {                # state = 0
            my $x = $::newsuser{$chan}{$who};
            if (defined $x and ($x == 0 or $x == -1)) {
        } else {                # state = 0
            my $x = $::newsuser{$chan}{$who};
            if (defined $x and ($x == 0 or $x == -1)) {
-               &::notice($who, "notify already disabled");
+               &::notice($who, 'notify already disabled');
                return;
            }
            $::newsuser{$chan}{$who} = -1;
                return;
            }
            $::newsuser{$chan}{$who} = -1;
@@ -155,7 +150,7 @@ sub Parse {
 }
 
 sub readNews {
 }
 
 sub readNews {
-    my $file = "$::bot_base_dir/blootbot-news.txt";
+    my $file = "$::bot_base_dir/infobot-news.txt";
     if (! -f $file or -z $file) {
        return;
     }
     if (! -f $file or -z $file) {
        return;
     }
@@ -203,9 +198,9 @@ sub readNews {
     return unless ($ci or $cn or $cu);
 
     &::status("News: read ".
     return unless ($ci or $cn or $cu);
 
     &::status("News: read ".
-       $ci. &::fixPlural(" item", $ci). " for ".
-       $cn. &::fixPlural(" chan", $cn). ", ".
-       $cu. &::fixPlural(" user", $cu), " cache"
+       $ci. &::fixPlural(' item', $ci). ' for '.
+       $cn. &::fixPlural(' chan', $cn). ', '.
+       $cu. &::fixPlural(' user', $cu), ' cache'
     );
 }
 
     );
 }
 
@@ -216,7 +211,7 @@ sub writeNews {
     }
 
     # should define this at the top of file.
     }
 
     # should define this at the top of file.
-    my $file = "$::bot_base_dir/blootbot-news.txt";
+    my $file = "$::bot_base_dir/infobot-news.txt";
 
     if (fileno NEWS) {
        &::ERROR("News: write: fileno NEWS exists, should never happen.");
 
     if (fileno NEWS) {
        &::ERROR("News: write: fileno NEWS exists, should never happen.");
@@ -249,7 +244,7 @@ sub writeNews {
     }
 
     # TODO: show how many users we wrote down.
     }
 
     # TODO: show how many users we wrote down.
-    if (&::getChanConfList("newsKeepRead")) {
+    if (&::getChanConfList('newsKeepRead')) {
        # old users are removed in newsFlush(), perhaps it should be
        # done here.
 
        # old users are removed in newsFlush(), perhaps it should be
        # done here.
 
@@ -271,7 +266,7 @@ sub add {
     my($str) = @_;
 
     if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
     my($str) = @_;
 
     if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
-       &::help("news add");
+       &::help('news add');
        return;
     }
 
        return;
     }
 
@@ -286,7 +281,7 @@ sub add {
     }
 
     $::news{$chan}{$str}{Time} = time();
     }
 
     $::news{$chan}{$str}{Time} = time();
-    my $expire = &::getChanConfDefault("newsDefaultExpire",7, $chan);
+    my $expire = &::getChanConfDefault('newsDefaultExpire',7, $chan);
     $::news{$chan}{$str}{Expire}       = time() + $expire*60*60*24;
     $::news{$chan}{$str}{Author}       = $::who;       # case!
 
     $::news{$chan}{$str}{Expire}       = time() + $expire*60*60*24;
     $::news{$chan}{$str}{Author}       = $::who;       # case!
 
@@ -307,7 +302,7 @@ sub del {
     my $item   = 0;
 
     if (!defined $what) {
     my $item   = 0;
 
     if (!defined $what) {
-       &::help("news del");
+       &::help('news del');
        return;
     }
 
        return;
     }
 
@@ -355,7 +350,7 @@ sub del {
     if (exists $::news{$chan}{$what}) {
        my $auth = 0;
        $auth++ if ($::who eq $::news{$chan}{$what}{Author});
     if (exists $::news{$chan}{$what}) {
        my $auth = 0;
        $auth++ if ($::who eq $::news{$chan}{$what}{Author});
-       $auth++ if (&::IsFlag("o"));
+       $auth++ if (&::IsFlag('o'));
 
        if (!$auth) {
            # TODO: show when it'll expire.
 
        if (!$auth) {
            # TODO: show when it'll expire.
@@ -376,7 +371,7 @@ sub list {
        return;
     }
 
        return;
     }
 
-    if (&::IsChanConf("newsKeepRead") > 0) {
+    if (&::IsChanConf('newsKeepRead') > 0) {
        my $x = $::newsuser{$chan}{$who};
 
        if (defined $x and ($x == 0 or $x == -1)) {
        my $x = $::newsuser{$chan}{$who};
 
        if (defined $x and ($x == 0 or $x == -1)) {
@@ -409,7 +404,7 @@ sub list {
     }
     my $timestr = &::Time2String(time() - $newest);
     &::msg($who, "|= Last updated $timestr ago.");
     }
     my $timestr = &::Time2String(time() - $newest);
     &::msg($who, "|= Last updated $timestr ago.");
-    &::msg($who, " \037Num\037  \037Item ".(" "x40)." \037");
+    &::msg($who, " \037Num\037  \037Item ".(' 'x40)." \037");
 
 #    &::DEBUG("news: list: expire = $expire");
 #    &::DEBUG("news: list: eno    = $eno");
 
 #    &::DEBUG("news: list: expire = $expire");
 #    &::DEBUG("news: list: eno    = $eno");
@@ -418,7 +413,7 @@ sub list {
     foreach ( &getNewsAll() ) {
        my $subtopic    = $_;
        my $setby       = $::news{$chan}{$subtopic}{Author};
     foreach ( &getNewsAll() ) {
        my $subtopic    = $_;
        my $setby       = $::news{$chan}{$subtopic}{Author};
-       my $chr         = (exists $::News{$chan}{$subtopic}{Text}) ? "" : "*";
+       my $chr         = (exists $::News{$chan}{$subtopic}{Text}) ? '' : '*';
 
        if (!defined $subtopic) {
            &::DEBUG("news: warn: subtopic == undef.");
 
        if (!defined $subtopic) {
            &::DEBUG("news: warn: subtopic == undef.");
@@ -446,7 +441,7 @@ sub read {
     my($str) = @_;
 
     if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
     my($str) = @_;
 
     if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
-       &::help("news read");
+       &::help('news read');
        return;
     }
 
        return;
     }
 
@@ -471,7 +466,7 @@ sub read {
     }
 
     if (!exists $::news{$chan}{$item}{Text}) {
     }
 
     if (!exists $::news{$chan}{$item}{Text}) {
-       &::notice($who, "Someone forgot to add info to this news item");
+       &::notice($who, 'Someone forgot to add info to this news item');
        return;
     }
 
        return;
     }
 
@@ -516,8 +511,8 @@ sub read {
 sub mod {
     my($item, $str) = split /\s+/, $_[0], 2;
 
 sub mod {
     my($item, $str) = split /\s+/, $_[0], 2;
 
-    if (!defined $item or $item eq "" or $str =~ /^\s*$/) {
-       &::help("news mod");
+    if (!defined $item or $item eq '' or $str =~ /^\s*$/) {
+       &::help('news mod');
        return;
     }
 
        return;
     }
 
@@ -544,10 +539,10 @@ sub mod {
        # TODO: make code safer.
        my $done = 0;
        # TODO: use eval to deal with flags easily.
        # TODO: make code safer.
        my $done = 0;
        # TODO: use eval to deal with flags easily.
-       if ($flags eq "") {
+       if ($flags eq '') {
            $done++ if (!$done and $mod_news  =~ s/\Q$op\E/$np/);
            $done++ if (!$done and $mod_nnews =~ s/\Q$op\E/$np/);
            $done++ if (!$done and $mod_news  =~ s/\Q$op\E/$np/);
            $done++ if (!$done and $mod_nnews =~ s/\Q$op\E/$np/);
-       } elsif ($flags eq "g") {
+       } elsif ($flags eq 'g') {
            $done++ if ($mod_news  =~ s/\Q$op\E/$np/g);
            $done++ if ($mod_nnews =~ s/\Q$op\E/$np/g);
        }
            $done++ if ($mod_news  =~ s/\Q$op\E/$np/g);
            $done++ if ($mod_nnews =~ s/\Q$op\E/$np/g);
        }
@@ -603,8 +598,8 @@ sub set {
     $what = $1 if ($args =~ s/^(\S+)\s*//);
     $value = $args;
 
     $what = $1 if ($args =~ s/^(\S+)\s*//);
     $value = $args;
 
-    if ($item eq "") {
-       &::help("news set");
+    if ($item eq '') {
+       &::help('news set');
        return;
     }
 
        return;
     }
 
@@ -622,7 +617,7 @@ sub set {
     }
 
     my $ok = 0;
     }
 
     my $ok = 0;
-    my @elements = ("Expire","Text");
+    my @elements = ('Expire','Text');
     foreach (@elements) {
        next unless ($what =~ /^$_$/i);
        $what = $_;
     foreach (@elements) {
        next unless ($what =~ /^$_$/i);
        $what = $_;
@@ -646,7 +641,7 @@ sub set {
        return;
     }
 
        return;
     }
 
-    if ($what eq "Expire") {
+    if ($what eq 'Expire') {
        # TODO: use do_set().
 
        my $time = 0;
        # TODO: use do_set().
 
        my $time = 0;
@@ -702,7 +697,7 @@ sub set {
 #    &::DEBUG("news: who => '$who'");
     my $author = $::news{$chan}{$news}{Author};
     $auth++ if ($::who eq $author);
 #    &::DEBUG("news: who => '$who'");
     my $author = $::news{$chan}{$news}{Author};
     $auth++ if ($::who eq $author);
-    $auth++ if (&::IsFlag("o"));
+    $auth++ if (&::IsFlag('o'));
     if (!defined $author) {
        &::DEBUG("news: news{$chan}{$news}{Author} is not defined! auth'd anyway");
        $::news{$chan}{$news}{Author} = $::who;
     if (!defined $author) {
        &::DEBUG("news: news{$chan}{$news}{Author} is not defined! auth'd anyway");
        $::news{$chan}{$news}{Author} = $::who;
@@ -756,7 +751,7 @@ sub latest {
     }
 
     $::chan    = $chan;
     }
 
     $::chan    = $chan;
-    return if (&::IsChanConf("newsNotifyAll") <= 0);
+    return if (&::IsChanConf('newsNotifyAll') <= 0);
 
     # I don't understand this code ;)
     $t = 1 if (!defined $t);
 
     # I don't understand this code ;)
     $t = 1 if (!defined $t);
@@ -796,7 +791,7 @@ sub latest {
     # scalar @new, !$flag
     my $unread = scalar @new;
     my $total  = scalar keys %{ $::news{$chan} };
     # scalar @new, !$flag
     my $unread = scalar @new;
     my $total  = scalar keys %{ $::news{$chan} };
-    if (!$flag && &::IsChanConf("newsTellUnread") <= 0) {
+    if (!$flag && &::IsChanConf('newsTellUnread') <= 0) {
        return;
     }
 
        return;
     }
 
@@ -1033,3 +1028,5 @@ sub stats {
 sub AUTOLOAD { &::AUTOLOAD(@_); }
 
 1;
 sub AUTOLOAD { &::AUTOLOAD(@_); }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 9a603c124af0f9b25436bca5fb99bc0a3b7b7476..5ef7aa95eb3dbb919986838715b5f4883b9850eb 100644 (file)
@@ -48,7 +48,7 @@ sub Cmdonjoin {
        my $nick = $3;
        my $msg = $5;
 
        my $nick = $3;
        my $msg = $5;
 
-       # get options 
+       # get options
        my $strict = &getChanConf('onjoinStrict');
        my $ops = &getChanConf('onjoinOpsOnly');
 
        my $strict = &getChanConf('onjoinStrict');
        my $ops = &getChanConf('onjoinOpsOnly');
 
@@ -111,7 +111,7 @@ sub Cmdonjoin {
        &sqlDelete('onjoin', { nick => $nick, channel => $ch });
        my $insert = &sqlInsert('onjoin', { nick => $nick, channel => $ch, message => $msg, modified_by => $who, modified_time => time() });
        if ($insert){
        &sqlDelete('onjoin', { nick => $nick, channel => $ch });
        my $insert = &sqlInsert('onjoin', { nick => $nick, channel => $ch, message => $msg, modified_by => $who, modified_time => time() });
        if ($insert){
-               &performReply("ok");
+               &performReply('ok');
        }
        else{
                &performReply('whoops. database error');
        }
        else{
                &performReply('whoops. database error');
@@ -120,3 +120,5 @@ sub Cmdonjoin {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 067b391b11157c94044a778b1a96c17a017a3acb..d80a1dbaca4fae28b4b6580411d170b5ec2c2e3f 100644 (file)
@@ -39,7 +39,7 @@ sub Plug {
     my $retval  = "i could not get the headlines.";
 
     if (scalar @results) {
     my $retval  = "i could not get the headlines.";
 
     if (scalar @results) {
-       my $prefix      = "Plug Headlines ";
+       my $prefix      = 'Plug Headlines ';
        my @list        = &plugParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
        my @list        = &plugParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
@@ -103,3 +103,5 @@ sub plugAnnounce {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 147c230662cb9943e1776b2ac83f8fd128540391..0fafefcafd192b37e15756cb15291713f5f9100a 100644 (file)
@@ -20,7 +20,7 @@ sub commify {
 
 sub Quote {
     my $stock = shift;
 
 sub Quote {
     my $stock = shift;
-    my @results = &::getURL("http://quote.yahoo.com/d/quotes.csv" .
+    my @results = &::getURL('http://quote.yahoo.com/d/quotes.csv' .
            "?s=$stock&f=sl1d1t1c1ohgv&e=.csv");
 
 
            "?s=$stock&f=sl1d1t1c1ohgv&e=.csv");
 
 
@@ -45,7 +45,7 @@ sub Quote {
                "Opened $open, Volume $newvol, Change $change";
     }
 
                "Opened $open, Volume $newvol, Change $change";
     }
 
-    if ($reply eq "") {
+    if ($reply eq '') {
        $reply = "i couldn't get the quote for $stock. sorry. :(";
     }
 
        $reply = "i couldn't get the quote for $stock. sorry. :(";
     }
 
@@ -53,3 +53,5 @@ sub Quote {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/src/Modules/RSSFeeds.pl b/src/Modules/RSSFeeds.pl
new file mode 100644 (file)
index 0000000..035ea98
--- /dev/null
@@ -0,0 +1,163 @@
+#
+#     RSSTest.pl: RSS Tractker hacked from Plug.pl/Rss.pl
+#     Author: Dan McGrath <djmcgrath@users.sourceforge.net>
+#  Licensing: Artistic License (as perl itself)
+#    Version: v0.1
+#
+
+package RSSFeeds;
+
+use strict;
+use XML::Feed;
+
+use vars qw(%channels %param $dbh $who $chan);
+
+sub getCacheEntry {
+       my ( $file, $url ) = @_;
+       my @entries;
+
+       &::DEBUG("rssFeed: Searching cache for $url");
+
+       open CACHE, "<$file" or return;
+       binmode( CACHE, ":encoding(UTF-8)" );
+
+       while (<CACHE>) {
+               next unless /^$url:/;
+               chop;
+               s/^$url:(.*)/$1/;
+               push @entries, $_;
+       }
+       close CACHE;
+
+       return @entries;
+}
+
+sub saveCache {
+       my ( $file, $url, @entries ) = @_;
+
+       open IN,  "<$file"     or return;
+       open OUT, ">$file.tmp" or return;
+
+       binmode( IN,  ":encoding(UTF-8)" );
+       binmode( OUT, ":encoding(UTF-8)" );
+
+       # copy all but old ones
+       while (<IN>) {
+               next if /^$url:/;
+               print OUT $_;
+       }
+
+       # append new ones
+       foreach (@entries) {
+               print OUT "$url:$_\n";
+       }
+
+       close IN;
+       close OUT;
+
+       rename "$file.tmp", "$file";
+}
+
+sub createCache {
+       my $file = shift;
+
+       &::status("rssFeed: Creating cache in $file");
+
+       open CACHE, ">$file" or return;
+       close CACHE;
+}
+
+sub getFeed {
+       my ( $cacheFile, $chan, $rssFeedUrl ) = @_;
+
+       &::DEBUG("rssFeed: URL: $rssFeedUrl");
+
+       my $feed = XML::Feed->parse( URI->new($rssFeedUrl) )
+               or return XML::Feed->errstr;
+
+       my $curTitle = $feed->title;
+       &::DEBUG("rssFeed: TITLE: $curTitle");
+       my @curEntries;
+
+       for my $entry ( $feed->entries ) {
+               &::DEBUG( "rssFeed: ENTRY: " . $entry->title );
+               push @curEntries, $entry->title;
+       }
+
+       # Create the cache if it doesnt exist
+       &createCache($cacheFile)
+               if ( !-e $cacheFile );
+
+       my @oldEntries = &getCacheEntry( $cacheFile, $rssFeedUrl );
+       my @newEntries;
+       foreach (@curEntries) {
+               &::DEBUG("rssFeed: CACHE: $_");
+               last if ( $_ eq $oldEntries[0] );
+               push @newEntries, $_;
+       }
+
+       if ( scalar @newEntries == 0 ) {    # if there wasn't anything new
+               return "rssFeed: No new headlines for $curTitle.";
+       }
+
+       # save to hash again
+       &saveCache( $cacheFile, $rssFeedUrl, @curEntries )
+               or return "rssFeed: Could not save cache!";
+
+       my $reply = &::formListReply( 0, $curTitle, @newEntries );
+       &::msg( $chan, $reply );
+
+       #               "\002<<\002$curTitle\002>>\002 " . join( " \002::\002 ", @newEntries ) );
+
+       return;
+}
+
+sub RSS {
+       my ($command) = @_;
+       my $cacheFile = "$::param{tempDir}/rssFeed.cache";
+       my %feeds;
+
+       if ( not $command =~ /^(flush|update)?$/i ) {
+               &::status("rssFeed: Unknown command: $command");
+               return;
+       }
+
+       if ( $command =~ /^flush$/i ) {
+               if ( not &::IsFlag("o") ) {
+                       &::status("rssFeed: User $::who tried to flush the cache, but isn't +o!");
+                       return;
+               }
+               unlink $cacheFile if ( -e $cacheFile );
+               &::status("rssFeed: Flushing cache.");
+               &::performStrictReply("$::who: Flushed RSS Feed cache.");
+               return;
+       }
+
+       if ( $command =~ /^update$/i ) {
+               if ( not &::IsFlag("o") ) {
+                       &::status("rssFeed: User $::who tried to manually update feeds, but isn't +o!");
+                       return;
+               }
+               &::status("rssFeed: Manual update of feeds requested by $::who.");
+       }
+
+       foreach my $chan ( keys %::channels ) {
+               my $rssFeedUrl = &::getChanConf( 'rssFeedUrl', $chan );
+               my @urls = split / /, $rssFeedUrl;
+
+               # Store by url then chan to allow for same url's in multiple channels
+               foreach (@urls) { $feeds{$chan}{$_} = 1 }
+       }
+
+       foreach my $chans ( keys %feeds ) {
+               foreach ( keys %{ $feeds{$chans} } ) {
+                       my $result = &getFeed( $cacheFile, $chans, $_ );
+                       &::status($result) if $result;
+               }
+       }
+       return;
+}
+
+1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index fc3055069c750479a25a726ecca934a173d41bce..37f7ac17af5052d12cb999afb8466d7879721185 100644 (file)
@@ -21,7 +21,7 @@ sub rootWarn {
            &status('RootWarn: Detected root user; notifying user');
        } else {
            &status('RootWarn: Detected root user; notifying nick and channel.');
            &status('RootWarn: Detected root user; notifying user');
        } else {
            &status('RootWarn: Detected root user; notifying nick and channel.');
-           &msg($chan, "ROO".("O" x int(rand 8))."T has landed!");
+           &msg($chan, 'ROO'.('O' x int(rand 8))."T has landed!");
        }
 
        if ($_ = &getFactoid('root')) {
        }
 
        if ($_ = &getFactoid('root')) {
@@ -57,7 +57,7 @@ sub rootWarn {
     $attempt++;
     ### TODO: OPTIMIZE THIS.
     # ok... don't record the attempt if nick==root.
     $attempt++;
     ### TODO: OPTIMIZE THIS.
     # ok... don't record the attempt if nick==root.
-    return if ($nick eq "root");
+    return if ($nick eq 'root');
 
     &sqlSet('rootwarn', { nick => lc($nick) }, {
        attempt => $attempt,
 
     &sqlSet('rootwarn', { nick => lc($nick) }, {
        attempt => $attempt,
@@ -81,8 +81,8 @@ sub CmdrootWarn {
     }
 
     # reply #1.
     }
 
     # reply #1.
-    $reply = "there ".&fixPlural("has",$count) ." been \002$count\002 ".
-               &fixPlural("rooter",$count) ." warned about root.";
+    $reply = 'there '.&fixPlural('has',$count) ." been \002$count\002 ".
+               &fixPlural('rooter',$count) ." warned about root.";
 
     if ($param{'DBType'} !~ /^(pg|my)sql$/i) {
        &FIXME("rootwarn does not yet support non-{my,pg}sql.");
 
     if ($param{'DBType'} !~ /^(pg|my)sql$/i) {
        &FIXME("rootwarn does not yet support non-{my,pg}sql.");
@@ -103,8 +103,8 @@ sub CmdrootWarn {
 
     if ($found) {
        $reply .= " Of which, \002$found\002 ".
 
     if ($found) {
        $reply .= " Of which, \002$found\002 ".
-               &fixPlural("rooter",$found)." ".
-               &fixPlural("has",$found).
+               &fixPlural('rooter',$found).' '.
+               &fixPlural('has',$found).
                " done it at least 3 times.";
     }
 
                " done it at least 3 times.";
     }
 
@@ -112,3 +112,5 @@ sub CmdrootWarn {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a9c39e98df3d1123a785a43be15b600cd4b27519..68df8d408cd1b0414fbb1a4274f0a7140ca2a3ff 100644 (file)
@@ -25,4 +25,5 @@ sub Rss::Rss {
 }
 
 1;
 }
 
 1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a71bd9c70a0b5d01450b134ce77235b83f0d09e1..6541c0cd47e9a68ea3d47baf7133b66d8b9a46b8 100644 (file)
@@ -17,12 +17,12 @@ sub Search {
 
     $type =~ s/s$//;   # nice work-around.
 
 
     $type =~ s/s$//;   # nice work-around.
 
-    if ($type eq "value") {
+    if ($type eq 'value') {
        # search by value.
        # search by value.
-       @list = &::searchTable("factoids", "factoid_key", "factoid_value", $str);
+       @list = &::searchTable('factoids', 'factoid_key', 'factoid_value', $str);
     } else {
        # search by key.
     } else {
        # search by key.
-       @list = &::searchTable("factoids", "factoid_key", "factoid_key", $str);
+       @list = &::searchTable('factoids', 'factoid_key', 'factoid_key', $str);
     }
 
     @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow);
     }
 
     @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow);
@@ -35,3 +35,5 @@ sub Search {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 2a07c2ee59b99cfb519d172be22850933a05b2cb..36c1a3f03984fae43c0c5bf1b77ee68425a8a6d9 100644 (file)
@@ -33,7 +33,7 @@ sub topicDecipher {
        }
 
        my $subtopic    = $_;
        }
 
        my $subtopic    = $_;
-       my $owner       = "Unknown";
+       my $owner       = 'Unknown';
 
        if (/(.*)\s+\((.*?)\)$/) {
            $subtopic   = $1;
 
        if (/(.*)\s+\((.*?)\)$/) {
            $subtopic   = $1;
@@ -60,10 +60,10 @@ sub topicCipher {
     foreach (@_) {
        my ($subtopic, $setby) = split /\|\|/;
 
     foreach (@_) {
        my ($subtopic, $setby) = split /\|\|/;
 
-       if ($setby =~ /^(unknown|)$/i) {
-           push(@topic, $subtopic);
-       } else {
+       if ($param{'topicAuthor'} eq '1' and (!$setby =~ /^(unknown|)$/i)) {
            push(@topic, "$subtopic ($setby)");
            push(@topic, "$subtopic ($setby)");
+       } else {
+           push(@topic, "$subtopic");
        }
     }
 
        }
     }
 
@@ -101,7 +101,7 @@ sub topicNew {
        return 1;
     }
 
        return 1;
     }
 
-    if (defined $updateMsg && $updateMsg ne "") {
+    if (defined $updateMsg && $updateMsg ne '') {
        &msg($who, $updateMsg);
     }
 
        &msg($who, $updateMsg);
     }
 
@@ -113,7 +113,7 @@ sub topicNew {
        $conn->topic($chan, $topic);
        &topicAddHistory($chan, $topic);
     } else {
        $conn->topic($chan, $topic);
        &topicAddHistory($chan, $topic);
     } else {
-       $conn->topic($chan, " ");
+       $conn->topic($chan, ' ');
     }
 
     return 1;
     }
 
     return 1;
@@ -125,10 +125,10 @@ sub topicAddHistory {
     my ($chan, $topic) = @_;
     my $dupe           = 0;
 
     my ($chan, $topic) = @_;
     my $dupe           = 0;
 
-    return 1 if ($topic eq "");                        # required fix.
+    return 1 if ($topic eq '');                        # required fix.
 
     foreach (@{ $topic{$chan}{'History'} }) {
 
     foreach (@{ $topic{$chan}{'History'} }) {
-       next if ($_ ne "" and $_ ne $topic);
+       next if ($_ ne '' and $_ ne $topic);
        # checking length is required.
 
        # slightly weird to put a return statement in a loop.
        # checking length is required.
 
        # slightly weird to put a return statement in a loop.
@@ -153,21 +153,27 @@ sub topicAddHistory {
 sub do_add {
     my ($chan, $args) = @_;
 
 sub do_add {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic add");
+    if ($args eq '') {
+       &help('topic add');
        return;
     }
 
     # heh, joeyh. 19990819. -xk
     if ($who =~ /\|\|/) {
        return;
     }
 
     # heh, joeyh. 19990819. -xk
     if ($who =~ /\|\|/) {
-       &msg($who, "error: you have an invalid nick, loser!");
+       &msg($who, 'error: you have an invalid nick, loser!');
        return;
     }
 
        return;
     }
 
-    return if ($channels{$chan}{t} and !&hasFlag("T"));
+    return if ($channels{$chan}{t} and !&hasFlag('T'));
 
     my @prev = &topicDecipher($chan);
 
     my @prev = &topicDecipher($chan);
-    my $new  = "$args ($orig{who})";
+    my $new;
+    # If bot new to chan and topic is blank, it still got a (owner). This is fix
+    if ($param{'topicAuthor'} eq '1') {
+       $new  = "$args ($orig{who})";
+    } else {
+       $new  = "$args";
+    }
     $topic{$chan}{'What'} = "Added '$args'.";
 
     if (scalar @prev) {
     $topic{$chan}{'What'} = "Added '$args'.";
 
     if (scalar @prev) {
@@ -175,7 +181,7 @@ sub do_add {
        $new = &topicCipher(@prev, $str);
     }
 
        $new = &topicCipher(@prev, $str);
     }
 
-    &topicNew($chan, $new, "");
+    &topicNew($chan, $new, '');
 }
 
 # cmd: delete.
 }
 
 # cmd: delete.
@@ -185,12 +191,12 @@ sub do_delete {
     my $topiccount     = scalar @subtopics;
 
     if ($topiccount == 0) {
     my $topiccount     = scalar @subtopics;
 
     if ($topiccount == 0) {
-       &msg($who, "No topic set.");
+       &msg($who, 'No topic set.');
        return;
     }
 
        return;
     }
 
-    if ($args eq "") {
-       &help("topic del");
+    if ($args eq '') {
+       &help('topic del');
        return;
     }
 
        return;
     }
 
@@ -209,8 +215,8 @@ sub do_delete {
     }
 
     my @delete;
     }
 
     my @delete;
-    foreach (split ",", $args) {
-       next if ($_ eq "");
+    foreach (split ',', $args) {
+       next if ($_ eq '');
 
        # change to hash list instead of array?
        if (/^(\d+)-(\d+)$/) {
 
        # change to hash list instead of array?
        if (/^(\d+)-(\d+)$/) {
@@ -225,7 +231,7 @@ sub do_delete {
            return;
        }
 
            return;
        }
 
-       $topic{$chan}{'What'} = "Deleted ".join("/",@delete);
+       $topic{$chan}{'What'} = 'Deleted '.join("/",@delete);
     }
 
     foreach (@delete) {
     }
 
     foreach (@delete) {
@@ -240,7 +246,7 @@ sub do_delete {
 
        my ($subtopic,$whoby) = split('\|\|', $subtopics[$_-1]);
 
 
        my ($subtopic,$whoby) = split('\|\|', $subtopics[$_-1]);
 
-       $whoby = "unknown" if ($whoby eq "");
+       $whoby = 'unknown' if ($whoby eq '');
 
        &msg($who, "Deleting topic: $subtopic ($whoby)");
        undef $subtopics[$_-1];
 
        &msg($who, "Deleting topic: $subtopic ($whoby)");
        undef $subtopics[$_-1];
@@ -252,7 +258,7 @@ sub do_delete {
        push(@newtopics, $_);
     }
 
        push(@newtopics, $_);
     }
 
-    &topicNew($chan, &topicCipher(@newtopics), "");
+    &topicNew($chan, &topicCipher(@newtopics), '');
 }
 
 # cmd: list
 }
 
 # cmd: list
@@ -288,8 +294,8 @@ sub do_list {
 sub do_modify {
     my ($chan, $args) = @_;
 
 sub do_modify {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic mod");
+    if ($args eq '') {
+       &help('topic mod');
        return;
     }
 
        return;
     }
 
@@ -312,8 +318,8 @@ sub do_modify {
        my $topic = $topic{$chan}{'Current'};
 
        ### TODO: use m### to make code safe!
        my $topic = $topic{$chan}{'Current'};
 
        ### TODO: use m### to make code safe!
-       if (($flags eq "g" and $topic =~ s/\Q$op\E/$np/g) ||
-           ($flags eq ""  and $topic =~ s/\Q$op\E/$np/)
+       if (($flags eq 'g' and $topic =~ s/\Q$op\E/$np/g) ||
+           ($flags eq ''  and $topic =~ s/\Q$op\E/$np/)
        ) {
 
            $_ = "Modifying topic with sar s/$op/$np/.";
        ) {
 
            $_ = "Modifying topic with sar s/$op/$np/.";
@@ -332,8 +338,8 @@ sub do_modify {
 sub do_move {
     my ($chan, $args) = @_;
 
 sub do_move {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic mv");
+    if ($args eq '') {
+       &help('topic mv');
        return;
     }
 
        return;
     }
 
@@ -402,7 +408,7 @@ sub do_move {
 
     undef @subtopics;                  # lets reuse this array.
     foreach (@newtopics) {
 
     undef @subtopics;                  # lets reuse this array.
     foreach (@newtopics) {
-       next if (!defined $_ or $_ eq "");
+       next if (!defined $_ or $_ eq '');
        push(@subtopics, $_);
     }
 
        push(@subtopics, $_);
     }
 
@@ -416,7 +422,7 @@ sub do_shuffle {
     my @subtopics      = &topicDecipher($chan);
     my @newtopics;
 
     my @subtopics      = &topicDecipher($chan);
     my @newtopics;
 
-    $topic{$chan}{'What'} = "shuffled";
+    $topic{$chan}{'What'} = 'shuffled';
 
     foreach (&makeRandom(scalar @subtopics)) {
        push(@newtopics, $subtopics[$_]);
 
     foreach (&makeRandom(scalar @subtopics)) {
        push(@newtopics, $subtopics[$_]);
@@ -451,8 +457,8 @@ sub do_history {
 sub do_restore {
     my ($chan, $args) = @_;
 
 sub do_restore {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic restore");
+    if ($args eq '') {
+       &help('topic restore');
        return;
     }
 
        return;
     }
 
@@ -486,7 +492,7 @@ sub do_rehash {
     my ($chan) = @_;
 
     $_ = "Rehashing topic...";
     my ($chan) = @_;
 
     $_ = "Rehashing topic...";
-    $topic{$chan}{'What'} = "Rehash";
+    $topic{$chan}{'What'} = 'Rehash';
     &topicNew($chan, $topic{$chan}{'Current'}, $_, 1);
 }
 
     &topicNew($chan, $topic{$chan}{'Current'}, $_, 1);
 }
 
@@ -498,7 +504,7 @@ sub do_info {
     if (exists $topic{$chan}{'Who'} and exists $topic{$chan}{'Time'}) {
        $reply = "topic on \002$chan\002 was last set by ".
                $topic{$chan}{'Who'}. ".  This was done ".
     if (exists $topic{$chan}{'Who'} and exists $topic{$chan}{'Time'}) {
        $reply = "topic on \002$chan\002 was last set by ".
                $topic{$chan}{'Who'}. ".  This was done ".
-               &Time2String(time() - $topic{$chan}{'Time'}) ." ago".
+               &Time2String(time() - $topic{$chan}{'Time'}) .' ago'.
                ".  Length: ".length($topic{$chan}{'Current'});
        my $change = $topic{$chan}{'What'};
        $reply .= ".  Change => $change" if (defined $change);
                ".  Length: ".length($topic{$chan}{'Current'});
        my $change = $topic{$chan}{'What'};
        $reply .= ".  Change => $change" if (defined $change);
@@ -553,16 +559,18 @@ sub Topic {
 
     } else {
        ### HELP:
 
     } else {
        ### HELP:
-       if ($cmd ne "" and $cmd !~ /^help/i) {
+       if ($cmd ne '' and $cmd !~ /^help/i) {
            &msg($who, "Invalid command [$cmd].");
            &msg($who, "Try 'help topic'.");
            return;
        }
 
            &msg($who, "Invalid command [$cmd].");
            &msg($who, "Try 'help topic'.");
            return;
        }
 
-       &help("topic");
+       &help('topic');
     }
 
     return;
 }
 
 1;
     }
 
     return;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ff16e7e91215413256092f922af750218487510f..3f7a6e243ab8f4785ab180714cf6ec72776f7f66 100644 (file)
 #   Units.pl: convert units of measurement
 #     Author: M-J. Dominus (mjd-perl-units-id-iut+buobvys+@plover.com)
 #    License: GPL, Copyright (C) 1996,1999
 #   Units.pl: convert units of measurement
 #     Author: M-J. Dominus (mjd-perl-units-id-iut+buobvys+@plover.com)
 #    License: GPL, Copyright (C) 1996,1999
-#       NOTE: Integrated into blootbot by xk.
+#       NOTE: Integrated into infobot by xk.
 
 package Units;
 
 
 package Units;
 
-# use strict;  # TODO
-
-#$DEBUG_p = 1;
-#$DEBUG_o = 1;
-#$DEBUG_l = 1;
-my %unittab;                   # Definitions loaded here
-
-# Metric prefixes.  These must be powers of ten or change the
-# token_value subroutine
-BEGIN {
-  %PREF = (yocto => -24,
-          zepto => -21,
-          atto => -18,
-          femto => -15,
-          pico => -12,
-          nano => -9,
-          micro => -6,
-#            u => -6,
-          milli => -3,
-          centi => -2,
-          deci => -1,
-          deca => 1,
-          deka => 1,
-          hecto => 2,
-          hect => 2,
-          kilo => 3,
-          myria => 4,
-          mega => 6,
-          giga => 9,
-          tera => 12,
-          peta => 15,
-          exa => 18,
-          yotta => 21,
-          zetta => 24,
-         );
-  $PREF = join '|', sort { $PREF{$a} <=> $PREF{$b} } (keys %PREF);
-}
-
-
-################################################################
-#
-# Main program here
-#
-################################################################
-
-{ my $defs_read = 0;
-  $defs_read += read_defs("$::bot_data_dir/unittab");
-
-  unless ($defs_read) {
-    &::ERROR("Could not read any of the initialization files UNITTAB");
-    return;
-  }
-}
+use strict;
 
 sub convertUnits {
   my ($from,$to) = @_;
 
 
 sub convertUnits {
   my ($from,$to) = @_;
 
-  # POWER HACK.
-  $from =~ s/\^(\-?\d+)/$1/;
-  $to   =~ s/\^(\-?\d+)/$1/;
-  my %powers = (
-       2       => 'squared?',
-       3       => 'cubed?',
-  );
-  foreach (keys %powers) {
-    $from =~ s/(\D+) $powers{$_}$/$1\Q$_/;
-    $to   =~ s/(\D+) $powers{$_}$/$1\Q$_/;
-  }
-  # END OF POWER HACK.
-
-  ### FROM:
-  trim($from);
-  if ($from =~ s/^\s*\#\s*//) {
-    if (definition_line($from)) {
-      &::DEBUG("Defined.");
-    } else {
-      &::DEBUG("Error: $PARSE_ERROR.");
-    }
-    &::DEBUG("FAILURE 1.");
-    return;
-  }
-  unless ($from =~ /\S/) {
-    &::DEBUG("FAILURE 2");
-    return;
-  }
-
-  my $hu = parse_unit($from);
-  if (is_Zero($hu)) {
-    &::DEBUG($PARSE_ERROR);
-    &::msg($::who, $PARSE_ERROR);
-    return;
+  if ($from =~ /([+-]?[\d\.]+(?:e[+-]?[\d]+)?)\s+(temp[CFK])/){
+    $from = qq|${2}(${1})|;
   }
 
   }
 
-  ### TO:
-  my $wu;
-  trim($to);
-  redo unless $to =~ /\S/;
-  $wu = parse_unit($to);
-  if (is_Zero($wu)) {
-    &::DEBUG($PARSE_ERROR);
+  my $units = new IO::File;
+  open $units, '-|', 'units', $from, $to or &::DEBUG("Unable to run units: $!") and return;
+  my $response = readline ($units);
+  if ($response =~ /\s+\*\s+([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/ or $response =~ /\t([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/){
+    &::performStrictReply(sprintf("$from is approximately \002%.6g\002 $to", $1));
   }
   }
-
-  my $quot = unit_divide($hu, $wu);
-  if (is_dimensionless($quot)) {
-    my $q = $quot->{_};
-    if ($q == 0) {
-       &::performStrictReply("$to is an invalid unit?");
-       return;
-    }
-    # yet another powers hack.
-    $from =~ s/([[:alpha:]]+)(\d)/$1\^$2/g;
-    $to   =~ s/([[:alpha:]]+)(\d)/$1\^$2/g;
-
-    &::performStrictReply(sprintf("$from is approximately \002%.6g\002 $to", $q));
-  } else {
-    &::performStrictReply("$from cannot be correctly converted to $to.");
-
-#    print
-#      "conformability (Not the same dimension)\n",
-#      "\t", $from, " is ", text_unit($hu), "\n",
-#      "\t", $to, " is ", text_unit($wu), "\n",
-#      ;
+  else {
+    &::performStrictReply("$from cannot be converted to ${to}: $response");
   }
   }
-}
-
-
-################################################################
-
-sub read_defs {
-  my ($file) = @_;
-  unless (open D, $file) {
-    if ($show_file_loading) {
-      print STDERR "Couldn't open file `$file': $!; skipping.\n";
-    }
-    return 0;
-  }
-  while (<D>) {
-    s/\#.*$//;
-    trim($_);
-    next unless /\S/;
-
-    print ">>> $_\n" if $DEBUG_d;
-    my $r = definition_line($_);
-    unless (defined $r) {
-      warn "Error in line $. of $file: $PARSE_ERROR.  Skipping.\n";
-    }
-  }
-  print STDERR "Loaded file `$file'.\n" if $show_file_loading;
-  return 1;
-}
-
-sub definition_line {
-  my ($line) = @_;
-  my ($name, $data) = split /\s+/, $line, 2;
-  my $value = parse_unit($data);
-  if (is_Zero($value)) {
-    return;
-  }
-  if (is_fundamental($value)) {
-    return $unittab{$name} = {_ => 1, $name => 1};
-  } else {
-    return $unittab{$name} = $value;
-  }
-}
-
-sub trim {
-  $_[0] =~ s/\s+$//;
-  $_[0] =~ s/^\s+//;
-}
-
-sub Zero () { +{ _ => 0 } }
-
-sub is_Zero {
-  $_[0]{_} == 0;
-}
-
-sub unit_lookup {
-  my ($name) = @_;
-  print STDERR "Looking up unit `$name'\n" if $DEBUG_l;
-  return $unittab{$name} if exists $unittab{$name};
-  if ($name =~ /s$/) {
-    my $shortname = $name;
-    $shortname =~ s/s$//;
-    return $unittab{$shortname} if exists $unittab{$shortname};
-  }
-  my ($prefix, $rest) = ($name =~ /^($PREF-?)(.*)/o);
-  unless ($prefix) {
-    $PARSE_ERROR = "Unknown unit `$name'";
-    return Zero;
-  }
-  my $base_unit = unit_lookup($rest); # Recursive
-  con_multiply($base_unit, 10**$PREF{$prefix});
-}
-
-sub unit_multiply {
-  my ($a, $b) = @_;
-  print STDERR "Multiplying @{[%$a]} by @{[%$b]}: \n" if $DEBUG_o;
-  my $r = {%$a};
-  $r->{_} *= $b->{_};
-  my $u;
-  for $u (keys %$b) {
-    next if $u eq '_';
-    $r->{$u} += $b->{$u};
-  }
-  print STDERR "\tResult: @{[%$r]}\n" if $DEBUG_o;
-  $r;
-}
-
-sub unit_divide {
-  my ($a, $b) = @_;
-  if ($b->{_} == 0) {
-    &::DEBUG("Division by zero error");
-    return;
-  }
-  my $r = {%$a};
-  $r->{_} /= $b->{_};
-  my $u;
-  for $u (keys %$b) {
-    next if $u eq '_';
-    $r->{$u} -= $b->{$u};
-  }
-  $r;
-}
-
-sub unit_power {
-  my ($p, $u) = @_;
-  print STDERR "Raising unit @{[%$u]} to power $p.\n" if $DEBUG_o;
-  my $r = {%$u};
-  $r->{_} **= $p;
-  my $d;
-  for $d (keys %$r) {
-    next if $d eq '_';
-    $r->{$d} *= $p;
-  }
-  print STDERR "\tResult: @{[%$r]}\n" if $DEBUG_o;
-  $r;
-}
-
-sub unit_dimensionless {
-  print "Turning $_[0] into a dimensionless unit.\n" if $DEBUG_o;
-  return +{_ => $_[0]};
-}
-
-sub con_multiply {
-  my ($u, $c) = @_;
-  print STDERR "Multiplying unit @{[%$u]} by constant $c.\n" if $DEBUG_o;
-  my $r = {%$u};
-  $r->{_} *= $c;
-  print STDERR "\tResult: @{[%$r]}\n" if $DEBUG_o;
-  $r;
-}
-
-sub is_dimensionless {
-  my ($r) = @_;
-  my $u;
-  for $u (keys %$r) {
-    next if $u eq '_';
-    return if $r->{$u} != 0;
-  }
-  return 1;
-}
-
-# Generate bogus unit value that signals that a new fundamental unit
-# is being defined
-sub new_fundamental_unit {
-  return +{__ => 'new', _ => 1};
-}
-
-# Recognize this  bogus value when it appears again.
-sub is_fundamental {
-  exists $_[0]{__};
-}
-
-sub text_unit {
-  my ($u) = @_;
-  my (@pos, @neg);
-  my $k;
-  my $c = $u->{_};
-  for $k (sort keys %$u) {
-    next if $k eq '_';
-    push @pos, $k if $u->{$k} > 0;
-    push @neg, $k if $u->{$k} < 0;
-  }
-  my $text = ($c == 1 ? '' : $c);
-  my $d;
-  for $d (@pos) {
-    my $e = $u->{$d};
-    $text .= " $d";
-    $text .= "^$e" if $e > 1;
-  }
-
-  $text .= ' per' if @neg;
-  for $d (@neg) {
-    my $e = - $u->{$d};
-    $text .= " $d";
-    $text .= "^$e" if $e > 1;
-  }
-
-  $text;
-}
-################################################################
-#
-# I'm the parser
-#
-
-BEGIN {
-  sub sh { ['shift', $_[0]]  };
-  sub go { ['goto', $_[0]] };
-  @actions =
-    (
-     # Initial state
-     {PREFIX => sh(1),
-      NUMBER => sh(2),
-      NAME   => sh(3),
-      FUNDAMENTAL => sh(4),
-      FRACTION => sh(5),
-      '(' => sh(6),
-      'unit' => go(7),
-      'topunit' => go(17),
-      'constant' => go(8),
-     },
-     # State 1:   constant -> PREFIX .
-     { _ => ['reduce', 1, 'constant']},
-     # State 2:   constant -> NUMBER .
-     { _ => ['reduce', 1, 'constant']},
-     # State 3:   unit -> NAME .
-     { _ => ['reduce', 1, 'unit', \&unit_lookup ]},
-     # State 4:   unit -> FUNDAMENTAL .
-     { _ => ['reduce', 1, 'unit', \&new_fundamental_unit ]},
-     # State 5:   constant -> FRACTION .
-     { _ => ['reduce', 1, 'constant']},
-     # State 6:   unit -> '(' . unit ')'
-     {PREFIX => sh(1),
-      NUMBER => sh(2),
-      NAME   => sh(3),
-      FUNDAMENTAL => sh(4),
-      FRACTION => sh(5),
-      '(' => sh(6),
-      'unit' => go(9),
-      'constant' => go(8),
-     },
-     # State 7:   topunit -> unit .
-     #            unit  ->  unit . TIMES unit
-     #            unit  ->  unit . DIVIDE unit
-     #            unit  ->  unit . NUMBER
-     {NUMBER => sh(10),
-      TIMES => sh(11),
-      DIVIDE => sh(12),
-      _ =>  ['reduce', 1, 'topunit'],
-     },
-     # State 8:   unit -> constant . unit
-     #            unit -> constant .
-     {PREFIX => sh(1),
-      NUMBER => sh(2), # Shift-reduce conflict resolved in favor of shift
-      NAME   => sh(3),
-      FUNDAMENTAL => sh(4),
-      FRACTION => sh(5),
-      '(' => sh(6),
-      _ =>   ['reduce', 1, 'unit', \&unit_dimensionless],
-      'unit' => go(13),
-      'constant' => go(8),
-     },
-     # State 9:   unit -> unit . TIMES unit
-     #            unit -> unit . DIVIDE unit
-     #            unit -> '(' unit . ')'
-     #            unit -> unit . NUMBER
-     {NUMBER => sh(10),
-      TIMES => sh(11),
-      DIVIDE => sh(12),
-      ')' => sh(14),
-     },
-     # State 10:  unit -> unit NUMBER .
-     { _ => ['reduce', 2, 'unit',
-            sub {
-              unless (int($_[1]) == $_[1]) {
-                ABORT("Nonintegral power $_[1]");
-                return Zero;
-              }
-              unit_power(@_);
-            }
-           ],
-     },
-     # State 11:  unit -> unit TIMES . unit
-     {PREFIX => sh(1),
-      NUMBER => sh(2),
-      NAME   => sh(3),
-      FUNDAMENTAL => sh(4),
-      FRACTION => sh(5),
-      '(' => sh(6),
-      'unit' => go(15),
-      'constant' => go(8),
-     },
-     # State 12:  unit -> unit DIVIDE . unit
-     {PREFIX => sh(1),
-      NUMBER => sh(2),
-      NAME   => sh(3),
-      FUNDAMENTAL => sh(4),
-      FRACTION => sh(5),
-      '(' => sh(6),
-      'unit' => go(16),
-      'constant' => go(8),
-     },
-     # State 13:  unit -> unit . TIMES unit
-     #            unit -> unit . DIVIDE unit
-     #            unit -> constant unit .
-     #            unit -> unit . NUMBER
-     {NUMBER => sh(10), # Shift-reduce conflict resolved in favor of shift
-      TIMES => sh(11),  # Shift-reduce conflict resolved in favor of shift
-      DIVIDE => sh(12), # Shift-reduce conflict resolved in favor of shift
-      _ => ['reduce', 2, 'unit', \&con_multiply],
-     },
-     # State 14: unit => '(' unit ')' .
-     { _ => ['reduce', 3, 'unit', sub {$_[1]}] },
-     # State 15: unit  ->  unit . TIMES unit
-     #           unit  ->  unit TIMES unit .
-     #           unit  ->  unit . DIVIDE unit
-     #           unit  ->  unit . NUMBER
-     {NUMBER => sh(10), # Shift-reduce conflict resolved in favor of shift
-      _ => ['reduce', 3, 'unit', sub {unit_multiply($_[0], $_[2])}],
-     },
-     # State 16: unit  ->  unit . TIMES unit
-     #           unit  ->  unit DIVIDE unit .
-     #           unit  ->  unit . DIVIDE unit
-     #           unit  ->  unit . NUMBER
-     {NUMBER => sh(10), # Shift-reduce conflict resolved in favor of shift
-      _ => ['reduce', 3, 'unit', sub{unit_divide($_[2], $_[0])}],
-     },
-     # State 17: Finishing path
-     {EOF => go(18),},
-     # State 18: Final state
-     {_ => ['accept']},
-    );
-}
-
-sub ABORT {
-  $PARSE_ERROR = shift;
-}
-
-sub parse_unit {
-  my ($s) = @_;
-  my $tokens = lex($s);
-  my $STATE = 0;
-  my (@state_st, @val_st);
-
-  $PARSE_ERROR = undef;
-
-  # Now let's run the parser
-  for (;;) {
-    return Zero if $PARSE_ERROR;
-    my $la = @$tokens ? token_type($tokens->[0]) : 'EOF';
-    print STDERR "Now in state $STATE.  Lookahead type is $la.\n" if $DEBUG_p;
-    print STDERR "State stack is (@state_st).\n" if $DEBUG_p;
-    my $actiontab = $actions[$STATE];
-    my $action = $actiontab->{$la} || $actiontab->{_};
-    unless ($action) {
-      $PARSE_ERROR = 'Syntax error';
-      return Zero;
-    }
-
-    my ($primary, @actargs) = @$action;
-    print STDERR "  $primary (@actargs)\n" if $DEBUG_p;
-    if ($primary eq 'accept') {
-      return $val_st[0];       # Success!
-    } elsif ($primary eq 'shift') {
-      my $token = shift @$tokens;
-      my $val = token_value($token);
-      push @val_st, $val;
-      push @state_st, $STATE;
-      $STATE = $actargs[0];
-    } elsif ($primary eq 'goto') {
-      $STATE = $actargs[0];
-    } elsif ($primary eq 'reduce') {
-      my ($n_args, $result_type, $semantic) = @actargs;
-      my @arglist;
-#      push @state_st, 'FAKE'; # So that we only really remove n-1 states
-      while ($n_args--) {
-       push @arglist, pop @val_st;
-       $STATE = pop @state_st;
-      }
-      my $result = $semantic ? &$semantic(@arglist) : $arglist[0];
-      push @val_st, $result;
-      push @state_st, $STATE;
-#      $STATE = $state_st[-1];
-      print STDERR "Post-reduction state is $STATE.\n" if $DEBUG_p;
-
-      # Now look for `goto' actions
-      my $goto = $actions[$STATE]{$result_type};
-      unless ($goto && $goto->[0] eq 'goto') {
-       &::ERROR("No post-reduction goto in state $STATE for $result_type.");
-       return;
-      }
-      print STDERR "goto $goto->[1]\n" if $DEBUG_p;
-      $STATE = $goto->[1];
-    } else {
-      &::ERROR("Bad primary $primary");
-      return;
-    }
-  }
-}
-
-
-sub lex {
-  my ($s) = @_;
-  my @t = split /(
-                  \*{3}        # Special `new unit' symbol
-               |  [()*-]       # Symbol
-               |  \s*(?:\/|\bper\b)\s*      # Division
-               |  \d*\.\d+(?:[eE]-?\d+)? # Decimal number
-               |  \d+\|\d+     # Fraction
-               |  \d+          # Integer
-#              |  (?:$PREF)-?  # Prefix (handle differently)
-               |  [A-Za-z_][A-Za-z_.]* # identifier
-               |  \s+          # White space
-               )/ox, $s;
-  @t = grep {$_ ne ''} @t;     # Discard empty and all-white tokens
-  \@t;
-}
-
-sub token_type {
-  my ($token) = @_;
-  return $token->[0] if ref $token;
-  return $token if $token =~ /[()]/;
-  return TIMES if $token =~ /^\s+$/;
-  return FUNDAMENTAL if $token eq '***';
-  return DIVIDE if $token =~ /^\s*(\/|\bper\b)\s*$/;
-  return TIMES if $token eq '*' || $token eq '-';
-  return FRACTION if $token =~ /^\d+\|\d+$/;
-  return NUMBER if $token =~ /^[.\d]/;
-#  return PREFIX if $token =~ /^$PREF/o;
-  return NAME;
-}
-
-sub token_value {
-  my ($token) = @_;
-  return $token if $token =~ /^([()*\/-]|\s*\bper\b\s*)$/;
-  if ($token =~ /(\d+)\|(\d+)/) {
-    if ($2 == 0) {
-      ABORT("Zero denominator in fraction `$token'");
-      return 0;
-    }
-    return $1/$2;
-#  } elsif ($token =~ /$PREF/o) {
-#    $token =~ s/-$//;
-#    return 10**($PREF{$token});
-  }
-  return $token;               # Perl takes care of the others.
+  return;
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ac962f0d03fc2ca0513de9b47a6deb6575c49f12..5c7431613c3f983eb5647f199a3fdc69abd5ab37 100644 (file)
@@ -83,11 +83,9 @@ sub uptimeWriteFile {
   }
 
   close OUT;
   }
 
   close OUT;
-  &status("--- Saved uptime records.");
-
-  return unless defined $conn;
-
-  $conn->schedule(&getRandomInt("1800-3600"), \&uptimeWriteFile, "");
+  &status('--- Saved uptime records.');
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index b7f56ebc83b636157545dd175e138b2ee301f829..d6c306bdd93f633369744239303de4e2d927ca8f 100644 (file)
@@ -48,7 +48,7 @@ sub userDCC {
     if ($message =~ /^tellme(\s+(.*))?$/i) {
        my $args = $2;
        if ($args =~ /^\s*$/) {
     if ($message =~ /^tellme(\s+(.*))?$/i) {
        my $args = $2;
        if ($args =~ /^\s*$/) {
-           &help("tellme");
+           &help('tellme');
            return;
        }
 
            return;
        }
 
@@ -60,12 +60,12 @@ sub userDCC {
 
     # 4op.
     if ($message =~ /^4op(\s+($mask{chan}))?$/i) {
 
     # 4op.
     if ($message =~ /^4op(\s+($mask{chan}))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        my $chan = $2;
 
 
        my $chan = $2;
 
-       if ($chan eq "") {
-           &help("4op");
+       if ($chan eq '') {
+           &help('4op');
            return;
        }
 
            return;
        }
 
@@ -86,13 +86,13 @@ sub userDCC {
 
     # opme.
     if ($message =~ /^opme(\s+($mask{chan}))?$/i) {
 
     # opme.
     if ($message =~ /^opme(\s+($mask{chan}))?$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&hasFlag("A"));
+       return unless (&hasFlag('o'));
+       return unless (&hasFlag('A'));
 
        my $chan = $2;
 
 
        my $chan = $2;
 
-       if ($chan eq "") {
-           &help("4op");
+       if ($chan eq '') {
+           &help('4op');
            return;
        }
 
            return;
        }
 
@@ -104,13 +104,13 @@ sub userDCC {
 
     # backlog.
     if ($message =~ /^backlog(\s+(.*))?$/i) {
 
     # backlog.
     if ($message =~ /^backlog(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&IsParam("backlog"));
+       return unless (&hasFlag('o'));
+       return unless (&IsParam('backlog'));
        my $num = $2;
        my $max = $param{'backlog'};
 
        if (!defined $num) {
        my $num = $2;
        my $max = $param{'backlog'};
 
        if (!defined $num) {
-           &help("backlog");
+           &help('backlog');
            return;
        } elsif ($num !~ /^\d+/) {
            &msg($who, "error: argument is not positive integer.");
            return;
        } elsif ($num !~ /^\d+/) {
            &msg($who, "error: argument is not positive integer.");
@@ -132,8 +132,8 @@ sub userDCC {
 
     # dump variables.
     if ($message =~ /^dumpvars$/i) {
 
     # dump variables.
     if ($message =~ /^dumpvars$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&IsParam("DumpVars"));
+       return unless (&hasFlag('o'));
+       return unless (&IsParam('DumpVars'));
 
        &status("Dumping all variables...");
        &dumpallvars();
 
        &status("Dumping all variables...");
        &dumpallvars();
@@ -154,12 +154,12 @@ sub userDCC {
 
     # kick.
     if ($message =~ /^kick(\s+(.*?))$/) {
 
     # kick.
     if ($message =~ /^kick(\s+(.*?))$/) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        my $arg = $2;
 
 
        my $arg = $2;
 
-       if ($arg eq "") {
-           &help("kick");
+       if ($arg eq '') {
+           &help('kick');
            return;
        }
        my @args = split(/\s+/, $arg);
            return;
        }
        my @args = split(/\s+/, $arg);
@@ -182,11 +182,11 @@ sub userDCC {
 
     # mode.
     if ($message =~ /^mode(\s+(.*))?$/) {
 
     # mode.
     if ($message =~ /^mode(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my ($chan,$mode) = split /\s+/,$2,2;
 
        my ($chan,$mode) = split /\s+/,$2,2;
 
-       if ($chan eq "") {
-           &help("mode");
+       if ($chan eq '') {
+           &help('mode');
            return;
        }
 
            return;
        }
 
@@ -207,12 +207,12 @@ sub userDCC {
 
     # part.
     if ($message =~ /^part(\s+(\S+))?$/i) {
 
     # part.
     if ($message =~ /^part(\s+(\S+))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $jchan = $2;
 
        if ($jchan !~ /^$mask{chan}$/) {
            &msg($who, "error, invalid chan.");
        my $jchan = $2;
 
        if ($jchan !~ /^$mask{chan}$/) {
            &msg($who, "error, invalid chan.");
-           &help("part");
+           &help('part');
            return;
        }
 
            return;
        }
 
@@ -228,12 +228,12 @@ sub userDCC {
 
     # lobotomy. sometimes we want the bot to be _QUIET_.
     if ($message =~ /^(lobotomy|bequiet)$/i) {
 
     # lobotomy. sometimes we want the bot to be _QUIET_.
     if ($message =~ /^(lobotomy|bequiet)$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        if ($lobotomized) {
            &performReply("i'm already lobotomized");
        } else {
 
        if ($lobotomized) {
            &performReply("i'm already lobotomized");
        } else {
-           &performReply("i have been lobotomized");
+           &performReply('i have been lobotomized');
            $lobotomized = 1;
        }
 
            $lobotomized = 1;
        }
 
@@ -242,10 +242,10 @@ sub userDCC {
 
     # unlobotomy.
     if ($message =~ /^(unlobotomy|benoisy)$/i) {
 
     # unlobotomy.
     if ($message =~ /^(unlobotomy|benoisy)$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        if ($lobotomized) {
 
        if ($lobotomized) {
-           &performReply("i have been unlobotomized, woohoo");
+           &performReply('i have been unlobotomized, woohoo');
            $lobotomized = 0;
            delete $cache{lobotomy};
 #          undef $cache{lobotomy};     # ??
            $lobotomized = 0;
            delete $cache{lobotomy};
 #          undef $cache{lobotomy};     # ??
@@ -258,7 +258,7 @@ sub userDCC {
 
     # op.
     if ($message =~ /^op(\s+(.*))?$/i) {
 
     # op.
     if ($message =~ /^op(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
        my ($opee) = lc $2;
        my @chans;
 
@@ -305,7 +305,7 @@ sub userDCC {
 
     # deop.
     if ($message =~ /^deop(\s+(.*))?$/i) {
 
     # deop.
     if ($message =~ /^deop(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
        my ($opee) = lc $2;
        my @chans;
 
@@ -352,41 +352,31 @@ sub userDCC {
 
     # say.
     if ($message =~ s/^say\s+(\S+)\s+(.*)//) {
 
     # say.
     if ($message =~ s/^say\s+(\S+)\s+(.*)//) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($chan,$msg) = (lc $1, $2);
 
        &DEBUG("chan => '$1', msg => '$msg'.");
 
        my ($chan,$msg) = (lc $1, $2);
 
        &DEBUG("chan => '$1', msg => '$msg'.");
 
-       # TODO: add nick destination.
-       if (&validChan($chan)) {
-           &msg($chan, $msg);
-       } else {
-           &msg($who,"i'm not on \002$chan\002, sorry.");
-       }
+       &msg($chan, $msg);
 
        return;
     }
 
     # do.
     if ($message =~ s/^do\s+(\S+)\s+(.*)//) {
 
        return;
     }
 
     # do.
     if ($message =~ s/^do\s+(\S+)\s+(.*)//) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($chan,$msg) = (lc $1, $2);
 
        &DEBUG("chan => '$1', msg => '$msg'.");
 
        my ($chan,$msg) = (lc $1, $2);
 
        &DEBUG("chan => '$1', msg => '$msg'.");
 
-       # TODO: add nick destination.
-       if (&validChan($chan)) {
-           &action($chan, $msg);
-       } else {
-           &msg($who,"i'm not on \002$chan\002, sorry.");
-       }
+       &action($chan, $msg);
 
        return;
     }
 
     # die.
     if ($message =~ /^die$/) {
 
        return;
     }
 
     # die.
     if ($message =~ /^die$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &doExit();
 
 
        &doExit();
 
@@ -397,7 +387,7 @@ sub userDCC {
     # global factoid substitution.
     if ($message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
        my ($delim,$op,$np) = ($1, $2, $3);
     # global factoid substitution.
     if ($message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
        my ($delim,$op,$np) = ($1, $2, $3);
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        ### TODO: support flags to do full-on global.
 
        # incorrect format.
        ### TODO: support flags to do full-on global.
 
        # incorrect format.
@@ -408,8 +398,8 @@ sub userDCC {
 
        ### TODO: fix up $op to support mysql/sqlite/pgsql
        ### TODO: => add db/sql specific function to fix this.
 
        ### TODO: fix up $op to support mysql/sqlite/pgsql
        ### TODO: => add db/sql specific function to fix this.
-       my @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", $op);
+       my @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', $op);
 
        if (!scalar @list) {
            &performReply("Expression didn't match anything.");
 
        if (!scalar @list) {
            &performReply("Expression didn't match anything.");
@@ -422,7 +412,7 @@ sub userDCC {
        }
 
        &status("gsubst: going to alter ".scalar(@list)." factoids.");
        }
 
        &status("gsubst: going to alter ".scalar(@list)." factoids.");
-       &performReply("going to alter ".scalar(@list)." factoids.");
+       &performReply('going to alter '.scalar(@list)." factoids.");
 
        my $error = 0;
        foreach (@list) {
 
        my $error = 0;
        foreach (@list) {
@@ -440,7 +430,7 @@ sub userDCC {
                    &performReply("that's too long (or was long)");
                    return;
                }
                    &performReply("that's too long (or was long)");
                    return;
                }
-               &setFactInfo($faqtoid, "factoid_value", $result);
+               &setFactInfo($faqtoid, 'factoid_value', $result);
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
            } else {
                &WARN("subst: that's weird... thought we found the string ($op) in '$faqtoid'.");
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
            } else {
                &WARN("subst: that's weird... thought we found the string ($op) in '$faqtoid'.");
@@ -453,17 +443,17 @@ sub userDCC {
        }
 
        &performReply("Ok... did s/$op/$np/ for ".
        }
 
        &performReply("Ok... did s/$op/$np/ for ".
-                               (scalar(@list) - $error)." factoids");
+                               (scalar(@list) - $error).' factoids');
 
        return;
     }
 
     # jump.
     if ($message =~ /^jump(\s+(\S+))?$/i) {
 
        return;
     }
 
     # jump.
     if ($message =~ /^jump(\s+(\S+))?$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
 
-       if ($2 eq "") {
-           &help("jump");
+       if ($2 eq '') {
+           &help('jump');
            return;
        }
 
            return;
        }
 
@@ -486,7 +476,7 @@ sub userDCC {
 
     # reload.
     if ($message =~ /^reload$/i) {
 
     # reload.
     if ($message =~ /^reload$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
@@ -498,7 +488,7 @@ sub userDCC {
 
     # reset.
     if ($message =~ /^reset$/i) {
 
     # reset.
     if ($message =~ /^reset$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"resetting...");
        my @done;
 
        &msg($who,"resetting...");
        my @done;
@@ -511,26 +501,26 @@ sub userDCC {
            push(@done, $_);
            sleep 1;
        }
            push(@done, $_);
            sleep 1;
        }
-       &DEBUG("before clearircvars");
+       &DEBUG('before clearircvars');
        &clearIRCVars();
        &clearIRCVars();
-       &DEBUG("before joinnextchan");
+       &DEBUG('before joinnextchan');
        &joinNextChan();
        &joinNextChan();
-       &DEBUG("after joinnextchan");
+       &DEBUG('after joinnextchan');
 
        &status("USER reset $who");
 
        &status("USER reset $who");
-       &msg($who,"reset complete");
+       &msg($who,'reset complete');
 
        return;
     }
 
     # rehash.
     if ($message =~ /^rehash$/) {
 
        return;
     }
 
     # rehash.
     if ($message =~ /^rehash$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"rehashing...");
 
        &msg($who,"rehashing...");
-       &restart("REHASH");
+       &restart('REHASH');
        &status("USER rehash $who");
        &status("USER rehash $who");
-       &msg($who,"rehashed");
+       &msg($who,'rehashed');
 
        return;
     }
 
        return;
     }
@@ -543,7 +533,7 @@ sub userDCC {
        my @args = split /[\s\t]+/, $2; # hrm.
 
        if (scalar @args != 1) {
        my @args = split /[\s\t]+/, $2; # hrm.
 
        if (scalar @args != 1) {
-           &help("chaninfo");
+           &help('chaninfo');
            return;
        }
 
            return;
        }
 
@@ -578,14 +568,14 @@ sub userDCC {
        }
 
        if (!scalar @chans) {
        }
 
        if (!scalar @chans) {
-           push(@chans, "_default");
+           push(@chans, '_default');
            $no_chan    = 1;
        }
 
        my($what,$val) = split /[\s\t]+/, $args, 2;
 
        ### TODO: "cannot set values without +m".
            $no_chan    = 1;
        }
 
        my($what,$val) = split /[\s\t]+/, $args, 2;
 
        ### TODO: "cannot set values without +m".
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        # READ ONLY.
        if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) {
 
        # READ ONLY.
        if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) {
@@ -612,17 +602,17 @@ sub userDCC {
        }
 
        ### TODO: move to UserDCC again.
        }
 
        ### TODO: move to UserDCC again.
-       if ($cmd eq "chanset" and !defined $what) {
+       if ($cmd eq 'chanset' and !defined $what) {
            &DEBUG("showing channel conf.");
 
            foreach $chan (@chans) {
                if ($chan eq '_default') {
            &DEBUG("showing channel conf.");
 
            foreach $chan (@chans) {
                if ($chan eq '_default') {
-                   &performStrictReply("Default channel settings");
+                   &performStrictReply('Default channel settings');
                } else {
                    &performStrictReply("chan: $chan (see _default also)");
                }
                my @items;
                } else {
                    &performStrictReply("chan: $chan (see _default also)");
                }
                my @items;
-               my $str = "";
+               my $str = '';
                foreach (sort keys %{ $chanconf{$chan} }) {
                    my $newstr = join(', ', @items);
                    ### TODO: make length use channel line limit?
                foreach (sort keys %{ $chanconf{$chan} }) {
                    my $newstr = join(', ', @items);
                    ### TODO: make length use channel line limit?
@@ -652,12 +642,12 @@ sub userDCC {
     }
 
     if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) {
     }
 
     if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my $args        = $3;
        my $no_chan     = 0;
 
        if (!defined $args) {
        my $args        = $3;
        my $no_chan     = 0;
 
        if (!defined $args) {
-           &help("chanunset");
+           &help('chanunset');
            return;
        }
 
            return;
        }
 
@@ -668,7 +658,7 @@ sub userDCC {
            $delete     = ($1) ? 1 : 0;
        } else {
            &VERB("no chan arg; setting to default.",2);
            $delete     = ($1) ? 1 : 0;
        } else {
            &VERB("no chan arg; setting to default.",2);
-           $chan       = "_default";
+           $chan       = '_default';
            $no_chan    = 1;
        }
 
            $no_chan    = 1;
        }
 
@@ -677,7 +667,7 @@ sub userDCC {
            return;
        }
 
            return;
        }
 
-       if ($args ne "") {
+       if ($args ne '') {
 
            if (!&getChanConf($args,$chan)) {
                &performStrictReply("$args does not exist for $chan");
 
            if (!&getChanConf($args,$chan)) {
                &performStrictReply("$args does not exist for $chan");
@@ -686,7 +676,7 @@ sub userDCC {
 
            my @chans = &ChanConfList($args);
            &DEBUG("scalar chans => ".scalar(@chans) );
 
            my @chans = &ChanConfList($args);
            &DEBUG("scalar chans => ".scalar(@chans) );
-           if (scalar @chans == 1 and $chans[0] eq "_default" and !$no_chan) {
+           if (scalar @chans == 1 and $chans[0] eq '_default' and !$no_chan) {
                &performStrictReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans.");
 
                my $val = $chanconf{$_}{_default};
                &performStrictReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans.");
 
                my $val = $chanconf{$_}{_default};
@@ -740,7 +730,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (scalar @args != 1) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (scalar @args != 1) {
-           &help("newpass");
+           &help('newpass');
            return;
        }
 
            return;
        }
 
@@ -760,7 +750,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chpass");
+           &help('chpass');
            return;
        }
 
            return;
        }
 
@@ -777,7 +767,7 @@ sub userDCC {
 
        if (scalar @args == 1) {
            # del pass.
 
        if (scalar @args == 1) {
            # del pass.
-           if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
+           if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
                &performStrictReply("cannot remove passwd of others.");
                return;
            }
                &performStrictReply("cannot remove passwd of others.");
                return;
            }
@@ -811,7 +801,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chattr");
+           &help('chattr');
            return;
        }
 
            return;
        }
 
@@ -842,9 +832,9 @@ sub userDCC {
 
        &DEBUG("who => $who");
        &DEBUG("verifyUser => $verifyUser");
 
        &DEBUG("who => $who");
        &DEBUG("verifyUser => $verifyUser");
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
            &performStrictReply("cannto change attributes of others.");
            &performStrictReply("cannto change attributes of others.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        my $state;
        }
 
        my $state;
@@ -862,7 +852,7 @@ sub userDCC {
                next if ($flags =~ /\Q$_\E/);
                $flags .= $_;
            } else {
                next if ($flags =~ /\Q$_\E/);
                $flags .= $_;
            } else {
-               if (&IsParam("owner")
+               if (&IsParam('owner')
                        and $param{owner} =~ /^\Q$user\E$/i
                        and $flags =~ /[nmo]/
                ) {
                        and $param{owner} =~ /^\Q$user\E$/i
                        and $flags =~ /[nmo]/
                ) {
@@ -892,13 +882,13 @@ sub userDCC {
     if ($message =~ /^chnick(\s+(.*))?$/) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
     if ($message =~ /^chnick(\s+(.*))?$/) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
-       if ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run chnick.");
            &WARN("$who or verifyuser tried to run chnick.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        if (!scalar @args or scalar @args > 2) {
        }
 
        if (!scalar @args or scalar @args > 2) {
-           &help("chnick");
+           &help('chnick');
            return;
        }
 
            return;
        }
 
@@ -927,9 +917,9 @@ sub userDCC {
            return;
        }
 
            return;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
            &performStrictReply("cannto change nick of others.");
            &performStrictReply("cannto change nick of others.");
-           return "REPLY" if ($who eq "_default");
+           return 'REPLY' if ($who eq '_default');
            return;
        }
 
            return;
        }
 
@@ -948,7 +938,7 @@ sub userDCC {
     }
 
     if ($message =~ /^([-+])host(\s+(.*))?$/) {
     }
 
     if ($message =~ /^([-+])host(\s+(.*))?$/) {
-       my $cmd         = $1."host";
+       my $cmd         = $1.'host';
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
 
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
 
@@ -957,14 +947,14 @@ sub userDCC {
            return;
        }
 
            return;
        }
 
-       if ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run $cmd.");
            &WARN("$who or verifyuser tried to run $cmd.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        my ($user,$mask);
        if ($args[0] =~ /^$mask{nick}$/i) {     # <nick>
        }
 
        my ($user,$mask);
        if ($args[0] =~ /^$mask{nick}$/i) {     # <nick>
-           return unless (&hasFlag("n"));
+           return unless (&hasFlag('n'));
            $user       = &getUser($args[0]);
            $mask       = $args[1];
        } else {                                # <mask>
            $user       = &getUser($args[0]);
            $mask       = $args[1];
        } else {                                # <mask>
@@ -979,11 +969,11 @@ sub userDCC {
        }
 
        if (!defined $mask) {
        }
 
        if (!defined $mask) {
-           &performStrictReply("Hostmasks for $user: " . join(" ", keys %{$users{$user}{HOSTS}}));
+           &performStrictReply("Hostmasks for $user: " . join(' ', keys %{$users{$user}{HOSTS}}));
            return;
        }
 
            return;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
            &performStrictReply("cannto change masks of others.");
            return;
        }
            &performStrictReply("cannto change masks of others.");
            return;
        }
@@ -1031,7 +1021,7 @@ sub userDCC {
     }
 
     if ($message =~ /^([-+])ban(\s+(.*))?$/) {
     }
 
     if ($message =~ /^([-+])ban(\s+(.*))?$/) {
-       my $cmd         = $1."ban";
+       my $cmd         = $1.'ban';
        my $flatarg     = $3;
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
        my $flatarg     = $3;
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
@@ -1052,7 +1042,7 @@ sub userDCC {
        if ($flatarg =~ s/^($mask{chan})\s*//) {
            $chan = $1;
        } else {
        if ($flatarg =~ s/^($mask{chan})\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";        # _default instead?
+           $chan = '*';        # _default instead?
        }
 
        if ($state == 0) {              # delete.
        }
 
        if ($state == 0) {              # delete.
@@ -1091,7 +1081,7 @@ sub userDCC {
            $reason     = $1;
        }
 
            $reason     = $1;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
            &performStrictReply("cannto change masks of others.");
            return;
        }
            &performStrictReply("cannto change masks of others.");
            return;
        }
@@ -1113,7 +1103,7 @@ sub userDCC {
        my $arg = $2;
 
        if (!defined $arg) {
        my $arg = $2;
 
        if (!defined $arg) {
-           &help("whois");
+           &help('whois');
            return;
        }
 
            return;
        }
 
@@ -1128,7 +1118,7 @@ sub userDCC {
        foreach (keys %{ $users{$user} }) {
            my $ref = ref $users{$user}{$_};
 
        foreach (keys %{ $users{$user} }) {
            my $ref = ref $users{$user}{$_};
 
-           if ($ref eq "HASH") {
+           if ($ref eq 'HASH') {
                my $type = $_;
                ### DOES NOT WORK???
                foreach (keys %{ $users{$user}{$type} }) {
                my $type = $_;
                ### DOES NOT WORK???
                foreach (keys %{ $users{$user}{$type} }) {
@@ -1148,7 +1138,7 @@ sub userDCC {
        my $arg = $2;
 
        if (defined $arg) {
        my $arg = $2;
 
        if (defined $arg) {
-           if ($arg ne "_default" and !&validChan($arg) ) {
+           if ($arg ne '_default' and !&validChan($arg) ) {
                &performStrictReply("error: chan $chan is invalid.");
                return;
            }
                &performStrictReply("error: chan $chan is invalid.");
                return;
            }
@@ -1168,7 +1158,7 @@ sub userDCC {
            foreach (keys %{ $bans{$c} }) {
                my $val = $bans{$c}{$_};
 
            foreach (keys %{ $bans{$c} }) {
                my $val = $bans{$c}{$_};
 
-               if (ref $val eq "ARRAY") {
+               if (ref $val eq 'ARRAY') {
                    my @array = @{ $val };
                    &performStrictReply("    $_: @array");
                } else {
                    my @array = @{ $val };
                    &performStrictReply("    $_: @array");
                } else {
@@ -1201,11 +1191,11 @@ sub userDCC {
     }
 
     if ($message =~ /^save$/) {
     }
 
     if ($message =~ /^save$/) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        &writeUserFile();
        &writeChanFile();
 
        &writeUserFile();
        &writeChanFile();
-       &performStrictReply("saved user and chan files");
+       &performStrictReply('saved user and chan files');
 
        return;
     }
 
        return;
     }
@@ -1216,9 +1206,9 @@ sub userDCC {
 
     # ignore.
     if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) {
 
     # ignore.
     if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $state       = ($1 eq "+") ? 1 : 0;
        my $state       = ($1 eq "+") ? 1 : 0;
-       my $str         = $1."ignore";
+       my $str         = $1.'ignore';
        my $args        = $3;
 
        if (!$args) {
        my $args        = $3;
 
        if (!$args) {
@@ -1253,7 +1243,7 @@ sub userDCC {
        if ($args =~ s/^($mask{chan}|\*)\s*//) {
            $chan = $1;
        } else {
        if ($args =~ s/^($mask{chan}|\*)\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";
+           $chan = '*';
        }
 
        # time.
        }
 
        # time.
@@ -1310,7 +1300,7 @@ sub userDCC {
 
            foreach (keys %{ $ignore{$c} }) {
                my $ref = ref $ignore{$c}{$_};
 
            foreach (keys %{ $ignore{$c} }) {
                my $ref = ref $ignore{$c}{$_};
-               if ($ref eq "ARRAY") {
+               if ($ref eq 'ARRAY') {
                    my @array = @{ $ignore{$c}{$_} };
                    &performStrictReply("      $_: @array");
                } else {
                    my @array = @{ $ignore{$c}{$_} };
                    &performStrictReply("      $_: @array");
                } else {
@@ -1326,7 +1316,7 @@ sub userDCC {
     # adduser/deluser.
     if ($message =~ /^(add|del)user(\s+(.*))?$/i) {
        my $str         = $1;
     # adduser/deluser.
     if ($message =~ /^(add|del)user(\s+(.*))?$/i) {
        my $str         = $1;
-       my $strstr      = $1."user";
+       my $strstr      = $1.'user';
        my @args        = split /\s+/, $3 || '';
        my $args        = $3;
        my $state       = ($str =~ /^(add)$/) ? 1 : 0;
        my @args        = split /\s+/, $3 || '';
        my $args        = $3;
        my $state       = ($str =~ /^(add)$/) ? 1 : 0;
@@ -1412,7 +1402,7 @@ sub userDCC {
 
        my @time;
        foreach (sort { $a <=> $b } keys %time) {
 
        my @time;
        foreach (sort { $a <=> $b } keys %time) {
-           my $str = join(", ", sort keys %{ $time{$_} });
+           my $str = join(', ', sort keys %{ $time{$_} });
            &DEBUG("time => $_, str => $str");
            push(@time, "$str (".&Time2String($_).")");
        }
            &DEBUG("time => $_, str => $str");
            push(@time, "$str (".&Time2String($_).")");
        }
@@ -1425,7 +1415,7 @@ sub userDCC {
     }
 
     # quite a cool hack: reply in DCC CHAT.
     }
 
     # quite a cool hack: reply in DCC CHAT.
-    $msgType = "chat" if (exists $dcc{'CHAT'}{$who});
+    $msgType = 'chat' if (exists $dcc{'CHAT'}{$who});
 
     my $done = 0;
     $done++ if &parseCmdHook($message);
 
     my $done = 0;
     $done++ if &parseCmdHook($message);
@@ -1436,7 +1426,9 @@ sub userDCC {
        return;
     }
 
        return;
     }
 
-    return "REPLY";
+    return 'REPLY';
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index e35373b04900216dcb8ca53199f63b073a13fcb6..a172d478d209d7338425254e0759b4a551c09eb1 100644 (file)
@@ -9,13 +9,13 @@
 
 use strict;
 
 
 use strict;
 
-my $orderOfInfo = "RN,J,C,W,D";
+my $orderOfInfo = 'RN,J,C,W,D';
 my %infoDesc = (
 my %infoDesc = (
-       "RN"    => "Real Name",
-       "J"     => "Occupation",
-       "C"     => "Contact",
-       "W"     => "URL",
-       "D"     => "Description",
+       'RN'    => 'Real Name',
+       'J'     => 'Occupation',
+       'C'     => 'Contact',
+       'W'     => 'URL',
+       'D'     => 'Description',
 );
 
 sub UserInfo2Hash {
 );
 
 sub UserInfo2Hash {
@@ -61,7 +61,7 @@ sub UserInfoGet {
     }
 
     my $result;
     }
 
     my $result;
-    if ($result = &getFactoid($query." info")) {
+    if ($result = &getFactoid($query.' info')) {
        # good.
     } else { # bad.
        &performReply("No User Information on \002$query\002");
        # good.
     } else { # bad.
        &performReply("No User Information on \002$query\002");
@@ -160,7 +160,7 @@ sub UserInfoSet {
        $userInfo{$info} = $what;
     }
 
        $userInfo{$info} = $what;
     }
 
-    &setFactInfo($who." info", "factoid_value", &Hash2UserInfo(%userInfo));
+    &setFactInfo($who.' info', 'factoid_value', &Hash2UserInfo(%userInfo));
     if ($new) {
        &DEBUG("UIS: locking '$who info'.");
        &DEBUG("UIS: nuh => '$nuh'.");
     if ($new) {
        &DEBUG("UIS: locking '$who info'.");
        &DEBUG("UIS: nuh => '$nuh'.");
@@ -170,3 +170,5 @@ sub UserInfoSet {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index eee5ff0f343855ef3db469c2b96c8b86f71bdde0..26af692b49e2ea13b083bd315a8d4532d5bc7a12 100644 (file)
@@ -7,7 +7,7 @@ package W3Search;
 use strict;
 use vars qw(@W3Search_engines $W3Search_regex);
 @W3Search_engines = qw(AltaVista Dejanews Excite Gopher HotBot Infoseek
 use strict;
 use vars qw(@W3Search_engines $W3Search_regex);
 @W3Search_engines = qw(AltaVista Dejanews Excite Gopher HotBot Infoseek
-               Lycos Magellan PLweb SFgate Simple Verity Google);
+               Lycos Magellan PLweb SFgate Simple Verity Google z);
 $W3Search_regex = join '|', @W3Search_engines;
 
 my $maxshow    = 5;
 $W3Search_regex = join '|', @W3Search_engines;
 
 my $maxshow    = 5;
@@ -28,42 +28,37 @@ sub W3Search {
     return unless &::loadPerlModule("WWW::Search");
 
     eval {
     return unless &::loadPerlModule("WWW::Search");
 
     eval {
-       if ($where eq 'Google') {
-           # key is your Google API key.
-           # Get it from http://api.google.com/createkey
-           $Search = new WWW::Search('Google',key => '')
-       }
-       else {
-           $Search     = new WWW::Search($where);
-       }
-       if (!defined $Search) {
-           &::msg($::who, "$where is invalid search.");
-           return;
+       $Search = new WWW::Search($where, agent_name => 'Mozilla/4.5');
+    };
+
+    if (!defined $Search) {
+       &::msg($::who, "$where is invalid search.");
+       return;
+    }
+
+    my $Query  = WWW::Search::escape_query($what);
+    $Search->native_query($Query,
+       {
+               num => 10,
+#              search_debug => 2,
+#              search_parse_debug => 2,
        }
        }
-       
-       my $Query       = WWW::Search::escape_query($what);
-       $Search->native_query($Query,{   num => 10,
-                                        search_debug => 2,
-                                        search_parse_debug => 2,
-                                    }
-       );
-       $Search->http_proxy($::param{'httpProxy'}) if (&::IsParam("httpProxy"));
-       #my $max = $Search->maximum_to_retrieve(10);    # DOES NOT WORK.
+    );
+    $Search->http_proxy($::param{'httpProxy'}) if (&::IsParam('httpProxy'));
+    #my $max = $Search->maximum_to_retrieve(10);       # DOES NOT WORK.
 
 
-       my (@results, $count, $r);
-       $count=0;
+    my (@results, $count, $r);
        $retval = "$where says \002$what\002 is at ";
        $retval = "$where says \002$what\002 is at ";
-       while ($r = $Search->next_result()) {
-           my $url = $r->url();
-           $retval .= ' or ' if ($count > 0);
-           $retval .= $url;
-           last if ++$count >= $maxshow;
-       }
-       
-       $retval = "$where was unable to find any results for \002$what\002" unless $count > 0;
-       
-       &::performStrictReply($retval);
+    while ($r = $Search->next_result()) {
+       my $url = $r->url();
+       $retval .= ' or ' if ($count > 0);
+       $retval .= $url;
+       last if ++$count >= $maxshow;
     }
     }
-}    
+
+    &::performStrictReply($retval);
+}
+
 1;
 1;
-    
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ecf37cf69262f4d64923db09ae748c9d10e91293..d6a2f802e4cdd91e5a59429471863cd4936b4b73 100644 (file)
@@ -51,7 +51,7 @@ sub queryText {
        }
 
        my $ua = new LWP::UserAgent;
        }
 
        my $ua = new LWP::UserAgent;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(10);
        my $request = new HTTP::Request('GET', "http://weather.noaa.gov/weather/current/$station.html");
 
        $ua->timeout(10);
        my $request = new HTTP::Request('GET', "http://weather.noaa.gov/weather/current/$station.html");
@@ -64,7 +64,7 @@ sub queryText {
                    . " or http://www.nws.noaa.gov/tg/siteloc.shtml"
                    . " for ICAO locations codes).";
            } else {
                    . " or http://www.nws.noaa.gov/tg/siteloc.shtml"
                    . " for ICAO locations codes).";
            } else {
-               return "Something failed in connecting to the NOAA web"
+               return 'Something failed in connecting to the NOAA web'
                    . " server. Try again later.";
            }
        }
                    . " server. Try again later.";
            }
        }
@@ -105,7 +105,7 @@ sub queryText {
 
        if ($time) {
            if ($wxmode eq 'metar' && defined($feat{'ob'})) {
 
        if ($time) {
            if ($wxmode eq 'metar' && defined($feat{'ob'})) {
-               return ("METAR " . $place . ": " . $feat{'ob'});
+               return ('METAR ' . $place . ": " . $feat{'ob'});
            }
 
            $result = "$place; $id; last updated: $time";
            }
 
            $result = "$place; $id; last updated: $time";
@@ -132,6 +132,8 @@ if (0) {
 
 1;
 
 
 1;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __END__
 
 =head1 NAME
 __END__
 
 =head1 NAME
index bb93593bf4f7176ad85a7577a31e86f978b40677..ae3e973c415579c48edf2f0a5aab86ab6aa7c014 100644 (file)
@@ -12,7 +12,7 @@ use strict;
 my $select = IO::Select->new;
 
 sub Wingates {
 my $select = IO::Select->new;
 
 sub Wingates {
-    my $file = "$::blootbot_base_dir/$::param{'ircUser'}.wingate";
+    my $file = "$::infobot_base_dir/$::param{'ircUser'}.wingate";
     my @hosts;
 
     open(IN, $file);
     my @hosts;
 
     open(IN, $file);
@@ -73,7 +73,7 @@ sub Wingate {
            &::status("Wingate: RUNNING ON $host BY $::who.");
 
            if (&::IsChanConf('wingateBan') > 0) {
            &::status("Wingate: RUNNING ON $host BY $::who.");
 
            if (&::IsChanConf('wingateBan') > 0) {
-               &::ban("*!*\@$host", "");
+               &::ban("*!*\@$host", '');
            }
 
            my $reason  = &::getChanConf('wingateKick');
            }
 
            my $reason  = &::getChanConf('wingateKick');
@@ -96,3 +96,5 @@ sub Wingate {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index d496537c8b891ac005d4ddb1e6031f5d4fd26ae5..fbddb764658e6e7cd7af88b80336e1e65bb5e3fd 100644 (file)
@@ -13,7 +13,7 @@ my $no_zippy; # Can't think of any situation in which this won't work..
 
 sub zippy::get {
     my @yows;
 
 sub zippy::get {
     my @yows;
-    &::DEBUG("Reading zippy data");
+    &::DEBUG('Reading zippy data');
     while (<DATA>) {
        chomp;
        push @yows, $_;
     while (<DATA>) {
        chomp;
        push @yows, $_;
@@ -31,6 +31,8 @@ sub zippy::get {
 
 1;
 
 
 1;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 =pod
 
 =head1 NAME
 =pod
 
 =head1 NAME
index 850292b172df2d6868cd3f499b7469b16ca55590..fcefe4e484215fc384ebe33e2f45f82797823165 100644 (file)
@@ -63,7 +63,7 @@ sub babelfishParam {
   $to = $lang_code{$to};
 
   my $ua = new LWP::UserAgent;
   $to = $lang_code{$to};
 
   my $ua = new LWP::UserAgent;
-  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
@@ -145,3 +145,5 @@ if (0) {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 846d611a3487adcbc7bde680e57847005d6abd78..587cc55f47f6c1c097d6ae9da43e4849f022d5ef 100644 (file)
@@ -15,7 +15,7 @@ sub parse {
     my($what) = @_;
 
     if (!defined $what or $what =~ /^\s*$/) {
     my($what) = @_;
 
     if (!defined $what or $what =~ /^\s*$/) {
-       &::help("botmail");
+       &::help('botmail');
        return;
     }
 
        return;
     }
 
@@ -36,8 +36,8 @@ sub parse {
 }
 
 sub stats {
 }
 
 sub stats {
-    my $botmail        = &::countKeys("botmail");
-    &::msg($::who, "I have \002$botmail\002 ". &::fixPlural("message", $botmail). ".");
+    my $botmail        = &::countKeys('botmail');
+    &::msg($::who, "I have \002$botmail\002 ". &::fixPlural('message', $botmail). ".");
 }
 
 #####
 }
 
 #####
@@ -46,7 +46,7 @@ sub check {
     my($recipient, $always) = @_;
     $recipient ||= $::who;
 
     my($recipient, $always) = @_;
     $recipient ||= $::who;
 
-    my %from = &::sqlSelectColHash("botmail", "srcwho,time", {
+    my %from = &::sqlSelectColHash('botmail', "srcwho,time", {
        dstwho => lc $recipient
     } );
     my $t      = keys %from;
        dstwho => lc $recipient
     } );
     my $t      = keys %from;
@@ -64,7 +64,7 @@ sub check {
 sub next {
     my($recipient) = @_;
 
 sub next {
     my($recipient) = @_;
 
-    my %hash = &::sqlSelectRowHash("botmail", "*", {
+    my %hash = &::sqlSelectRowHash('botmail', '*', {
        dstwho => lc $recipient
     } );
 
        dstwho => lc $recipient
     } );
 
@@ -75,7 +75,7 @@ sub next {
        my $ago = &::Time2String(time() - $hash{'time'});
        &::msg($recipient, "From $hash{srcwho} ($hash{srcuh}) on $date ($ago ago):");
        &::msg($recipient, $hash{'msg'});
        my $ago = &::Time2String(time() - $hash{'time'});
        &::msg($recipient, "From $hash{srcwho} ($hash{srcuh}) on $date ($ago ago):");
        &::msg($recipient, $hash{'msg'});
-       &::sqlDelete("botmail", { 'dstwho'=>$hash{dstwho}, 'srcwho'=>$hash{srcwho}});
+       &::sqlDelete('botmail', { 'dstwho'=>$hash{dstwho}, 'srcwho'=>$hash{srcwho}});
     }
 }
 
     }
 }
 
@@ -90,9 +90,10 @@ sub add {
 
     # only support 1 botmail with unique dstwho/srcwho to have same
     # functionality as botmail from infobot.
 
     # only support 1 botmail with unique dstwho/srcwho to have same
     # functionality as botmail from infobot.
-    my %hash = &::sqlSelectRowHash("botmail", "*", {
-       srcwho => &::sqlQuote(lc $::who),
-       dstwho => &::sqlQuote(lc $recipient)
+    # Note: I removed the &::sqlQuote reference. Seems to be working and inserting fine without it here. -- troubled
+    my %hash = &::sqlSelectRowHash('botmail', '*', {
+       srcwho => lc $::who,
+       dstwho => lc $recipient
     } );
 
     if (scalar (keys %hash) > 1) {
     } );
 
     if (scalar (keys %hash) > 1) {
@@ -100,7 +101,7 @@ sub add {
        return;
     }
 
        return;
     }
 
-    &::sqlReplace("botmail", {
+    &::sqlInsert('botmail', {
        'dstwho'        => lc $recipient,
        'srcwho'        => lc $::who,
        'srcuh'         => $::nuh,
        'dstwho'        => lc $recipient,
        'srcwho'        => lc $::who,
        'srcuh'         => $::nuh,
@@ -112,3 +113,5 @@ sub add {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index c41937cde8f5d29efc9fa0906369552c3fec94d7..0d5c932bb00accde1bd9d7439545bfe4f9fdd09d 100644 (file)
@@ -9,7 +9,8 @@ package case;
 
 sub upper {
     my($message) = @_;
 
 sub upper {
     my($message) = @_;
-    &::performStrictReply(uc $message);
+    # make it green like an old terminal
+    &::performStrictReply("\00303" . uc $message);
 }
 
 sub lower {
 }
 
 sub lower {
@@ -18,3 +19,5 @@ sub lower {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 912a463d9109703fd1801aed54b7a993417880c6..60abd6aeea34f81a1aba576ec376da09c1b1af56 100644 (file)
@@ -93,3 +93,5 @@ sub countdown {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 778361800f1f0b789cc38a1ca18f8d97af0137ee..ebcd0b49d485853f8f660d8d432bdf672623af67 100755 (executable)
@@ -191,3 +191,5 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 
 =cut
 POSSIBILITY OF SUCH DAMAGE.
 
 =cut
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 415444d5535a41b78efa213e24fa13a2c688e186..1893b3a050dadadb689f7786aa60ac8534a3e873 100644 (file)
@@ -51,4 +51,5 @@ sub dns::query {
 }
 
 1;
 }
 
 1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
diff --git a/src/Modules/hex2ip.pl b/src/Modules/hex2ip.pl
new file mode 100644 (file)
index 0000000..6ac4585
--- /dev/null
@@ -0,0 +1,44 @@
+#
+#  hex2ip.pl: Convert hex gateway idents to an IP (eg:ABCDEF12)
+#     Author: Dan McGrath <djmcgrath@users.sourceforget.net>
+#  Licensing: Artistic License (as perl itself)
+#    Version: v0.1
+#
+#  Copyright (c) 2007 Dan McGrath
+#
+
+package hex2ip;
+
+use strict;
+
+sub hex2ip::convert {
+    my $hexstr = shift;
+    my $result;
+
+    &::VERB("hex2ip: Converting Hex address $hexstr to IP");
+
+    if ( $hexstr =~ /^([a-fA-F0-9]{2}){4}$/ ) {
+        my @conv;
+        $hexstr =~ /(..)(..)(..)(..)/;
+
+        push @conv, hex($1);
+        push @conv, hex($2);
+        push @conv, hex($3);
+        push @conv, hex($4);
+
+        $result = uc "$hexstr = " . join(".", @conv);
+    } else {
+        $result = "Invalid string: $hexstr";
+    }
+
+       return($result);
+}
+
+sub hex2ip::query {
+       &::performStrictReply(&convert(@_));
+       return;
+}
+
+1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index e39fbccf03c2a65d480faa2474555e5ebc356516..57acc2de8aebf453ae7d234f9c20da19c4f9c7f7 100644 (file)
@@ -14,12 +14,12 @@ sub Insult {
     my @adjs;
     my @amts;
     my @nouns;
     my @adjs;
     my @amts;
     my @nouns;
-    &::DEBUG("Reading insult data");
+    &::DEBUG('Reading insult data');
     while (<DATA>) {
        chomp;
     while (<DATA>) {
        chomp;
-       push(@adjs, split(" ", $1)) if /^adj\s*(.*)/;
-       push(@amts, split(" ", $1)) if /^amt\s*(.*)/;
-       push(@nouns, split(" ", $1)) if /^noun\s*(.*)/;
+       push(@adjs, split(' ', $1)) if /^adj\s*(.*)/;
+       push(@amts, split(' ', $1)) if /^amt\s*(.*)/;
+       push(@nouns, split(' ', $1)) if /^noun\s*(.*)/;
     }
     grep(s/\|/ /g, @adjs);
     grep(s/\|/ /g, @amts);
     }
     grep(s/\|/ /g, @adjs);
     grep(s/\|/ /g, @amts);
@@ -32,13 +32,15 @@ sub Insult {
     my $adj2 = @adjs[rand(@adjs)];
     my $noun = @nouns[rand(@nouns)];
     my $whois = "$insultwho is";
     my $adj2 = @adjs[rand(@adjs)];
     my $noun = @nouns[rand(@nouns)];
     my $whois = "$insultwho is";
-    $whois = "You are" if ($insultwho eq $::who or $insultwho eq "me");
+    $whois = 'You are' if ($insultwho eq $::who or $insultwho eq 'me');
 
     &::performStrictReply("$whois nothing but a$n $adj $amt of $adj2 $noun");
 }
 
 1;
 
 
     &::performStrictReply("$whois nothing but a$n $adj $amt of $adj2 $noun");
 }
 
 1;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __DATA__
 #
 # configuration file for colorado insult server
 __DATA__
 #
 # configuration file for colorado insult server
index 440e603566be2645525fba57bdc7a84caa9eccba..d32cf83a6bbbb1908bd404accdd595fa03ac6f0f 100644 (file)
@@ -9,9 +9,11 @@ package md5;
 
 sub md5 {
     my($message) = @_;
 
 sub md5 {
     my($message) = @_;
-    return unless &::loadPerlModule("Digest::MD5");
+    return unless &::loadPerlModule('Digest::MD5');
 
     &::performStrictReply(&Digest::MD5::md5_hex($message));
 }
 
 1;
 
     &::performStrictReply(&Digest::MD5::md5_hex($message));
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 881153e48a4f310c412df067ecc9b74e3333944c..b5790e3dbee153dd307f1d37eaebe8b2c627db42 100644 (file)
@@ -46,7 +46,7 @@ sub query {
     ### TODO: compact with map?
     my @list;
     foreach (sort {$b <=> $a} keys %nickometer) {
     ### TODO: compact with map?
     my @list;
     foreach (sort {$b <=> $a} keys %nickometer) {
-      my $str = join(", ", sort keys %{ $nickometer{$_} });
+      my $str = join(', ', sort keys %{ $nickometer{$_} });
       push(@list, "$str ($_%)");
     }
 
       push(@list, "$str ($_%)");
     }
 
@@ -58,7 +58,7 @@ sub query {
   my $percentage = &nickometer($term);
 
   if ($percentage =~ /NaN/) {
   my $percentage = &nickometer($term);
 
   if ($percentage =~ /NaN/) {
-    $percentage = "off the scale";
+    $percentage = 'off the scale';
   } else {
     $percentage = sprintf("%0.4f", $percentage);
     $percentage =~ s/(\.\d+)0+$/$1/;
   } else {
     $percentage = sprintf("%0.4f", $percentage);
     $percentage =~ s/(\.\d+)0+$/$1/;
@@ -143,7 +143,7 @@ sub nickometer ($) {
         $text =~ s/^([^\[\]]*) (\[) (.*) (\]) ([^\[\]]*) $/$1$3$5/x)
   {
     print "Removed $2$4 outside parentheses; nick now $_\n" if $verbose;
         $text =~ s/^([^\[\]]*) (\[) (.*) (\]) ([^\[\]]*) $/$1$3$5/x)
   {
     print "Removed $2$4 outside parentheses; nick now $_\n" if $verbose;
-    &punish(15, "brackets");
+    &punish(15, 'brackets');
   }
   my $parentheses = $text =~ tr/(){}[]/(){}[]/;
   &punish(&slow_pow(10, $parentheses),
   }
   my $parentheses = $text =~ tr/(){}[]/(){}[]/;
   &punish(&slow_pow(10, $parentheses),
@@ -267,3 +267,5 @@ sub punish ($$) {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 3d211754e93d86cdffca58a9477f167a5adecae6..6ebd76c866f5b0a7d7414ed62753ac02c1505882 100644 (file)
@@ -64,14 +64,14 @@ sub pager::page {
                }
 
                my $channel = $::chan || 'infobot';
                }
 
                my $channel = $::chan || 'infobot';
-               # TODO disallow use from private message? $chan="_default"
+               # TODO disallow use from private message? $chan='_default'
 
                &::status("pager: from $from <$fromaddr>, to $to <$toaddr>, msg \"$msg\"");
                my %headers = (
                        To => "$to <$toaddr>",
                        From => "$from <$fromaddr>",
                        Subject => "Message from $channel!",
 
                &::status("pager: from $from <$fromaddr>, to $to <$toaddr>, msg \"$msg\"");
                my %headers = (
                        To => "$to <$toaddr>",
                        From => "$from <$fromaddr>",
                        Subject => "Message from $channel!",
-                       'X-Mailer' => "blootbot",
+                       'X-Mailer' => 'infobot',
                );
 
 #              my $logmsg;
                );
 
 #              my $logmsg;
@@ -98,5 +98,6 @@ sub pager::page {
        &::performStrictReply($retval);
 }
 
        &::performStrictReply($retval);
 }
 
-"pager";
-# vim: ts=2 sw=2
+'pager';
+
+# vim:ts=4:sw=4:expandtab:tw=80
index d15135bd72792e258bd5c93c1f6763871ff7b5bf..7e1bcd42e039f3c599b945d352f4fb14b2bc606b 100644 (file)
@@ -14,7 +14,7 @@ sub piglatin
 
   # FIXME: does not handle:
   #  non-trailing punctuation and hyphens
 
   # FIXME: does not handle:
   #  non-trailing punctuation and hyphens
-  #  y as vowel "style" -> "ylestay"
+  #  y as vowel 'style' -> 'ylestay'
   #  contractions
   for my $word (split /\s+/, $text) {
     my ($pigword, $postfix);
   #  contractions
   for my $word (split /\s+/, $text) {
     my ($pigword, $postfix);
@@ -40,3 +40,5 @@ sub piglatin
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a6e2fd6018fecd0042279319c38001eaea1f8cf1..5a8231075eae4efb0b2daa5639c0346c9b90d084 100644 (file)
@@ -9,7 +9,9 @@ package reverse;
 
 sub reverse {
     my($message) = @_;
 
 sub reverse {
     my($message) = @_;
-    &::performStrictReply(join("",reverse(split("",$message))));
+    &::performStrictReply(join('',reverse(split('',$message))));
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index fbe91c500810cf94881c55fdeb690cbcc545462d..96fce80e9ead40cfd9dc29d698e0ab13e54c3574 100644 (file)
@@ -44,7 +44,7 @@ sub scramble
       }
 
       # shuffle the middle letters
       }
 
       # shuffle the middle letters
-      $new_middle = join "", List::Util::shuffle(split //, $middle);
+      $new_middle = join '', List::Util::shuffle(split //, $middle);
     }
     while (($cnt < 10) && ($middle eq $new_middle));
 
     }
     while (($cnt < 10) && ($middle eq $new_middle));
 
@@ -56,7 +56,9 @@ sub scramble
   # been included in the original string
   $scrambled =~ s/\s+$//;
 
   # been included in the original string
   $scrambled =~ s/\s+$//;
 
-  &::performStrictReply($scrambled||"Unknown Error Condition");
+  &::performStrictReply($scrambled||'Unknown Error Condition');
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 7b94b09c1ae255e89469f111063cf14b7028ad33..297af5b8726b887fd35a853933ceb6f33fb671a1 100644 (file)
@@ -37,7 +37,7 @@ sub Slashdot {
     my $retval  = "i could not get the headlines.";
 
     if (scalar @results) {
     my $retval  = "i could not get the headlines.";
 
     if (scalar @results) {
-       my $prefix      = "Slashdot Headlines ";
+       my $prefix      = 'Slashdot Headlines ';
        my @list        = &slashdotParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
        my @list        = &slashdotParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
@@ -101,3 +101,5 @@ sub slashdotAnnounce {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index f6ff8896de92130e245bd356de9d33e8f9674825..f8d38bde85dfe57163af9ca1c06e4d46f5d75cfe 100644 (file)
@@ -15,7 +15,7 @@ use strict;
 sub spell::spell {
        my $query = shift;
        if ($query =~ m/[^[:alpha:]]/) {
 sub spell::spell {
        my $query = shift;
        if ($query =~ m/[^[:alpha:]]/) {
-               return("only one word of alphabetic characters supported");
+               return('only one word of alphabetic characters supported');
        }
 
        my $binary;
        }
 
        my $binary;
@@ -33,11 +33,11 @@ sub spell::spell {
        }
 
        if (!$binary) {
        }
 
        if (!$binary) {
-               return("no binary found.");
+               return('no binary found.');
        }
 
        if (!&::validExec($query)) {
        }
 
        if (!&::validExec($query)) {
-               return("argument appears to be fuzzy.");
+               return('argument appears to be fuzzy.');
        }
 
        my $reply = "I can't find alternate spellings for '$query'";
        }
 
        my $reply = "I can't find alternate spellings for '$query'";
@@ -77,4 +77,5 @@ sub spell::query {
 }
 
 1;
 }
 
 1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 9117b87f590c741d26589705d696ef10d4f7e768..52cc05c08f83be87bfa57d750909c1f97679e365 100644 (file)
@@ -1,4 +1,4 @@
-# This program is distributed under the same terms as blootbot.
+# This program is distributed under the same terms as infobot.
 
 package wikipedia;
 use strict;
 
 package wikipedia;
 use strict;
@@ -50,7 +50,7 @@ sub wikipedia_lookup {
   &::DEBUG("wikipedia($phrase)");
 
   my $ua = new LWP::UserAgent;
   &::DEBUG("wikipedia($phrase)");
 
   my $ua = new LWP::UserAgent;
-  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
@@ -137,7 +137,7 @@ sub wikipedia_lookup {
        #$text = substr($text, 0, 330);
        #$text =~ s/(.+)\.([^.]*)$/$1./g;
 
        #$text = substr($text, 0, 330);
        #$text =~ s/(.+)\.([^.]*)$/$1./g;
 
-       return("At " . $url . " (URL), Wikipedia explains: " . $text,
+       return('At ' . $url . " (URL), Wikipedia explains: " . $text,
               1);
       }
     }
               1);
       }
     }
@@ -150,7 +150,7 @@ sub wikipedia_get_text {
   &::DEBUG("wikipedia_get_text($article)");
 
   my $ua = new LWP::UserAgent;
   &::DEBUG("wikipedia_get_text($article)");
 
   my $ua = new LWP::UserAgent;
-  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+  $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
   # Let's pretend
   $ua->agent("Mozilla/5.0 " . $ua->agent);
   $ua->timeout(5);
@@ -174,19 +174,19 @@ sub wikipedia_get_text {
        } elsif (/#REDIRECT\s*\[\[(.*?)\]\]/i) {
          $redirect = $1;
          $redirect =~ tr/ /_/;
        } elsif (/#REDIRECT\s*\[\[(.*?)\]\]/i) {
          $redirect = $1;
          $redirect =~ tr/ /_/;
-         &::DEBUG("wiki redirect to " . $redirect);
+         &::DEBUG('wiki redirect to ' . $redirect);
          last;
        } elsif (/<text[^>]*>(.*)/) {
          $text = '"' . $1;
        } elsif (/(.*)<\/text>/) {
          last;
        } elsif (/<text[^>]*>(.*)/) {
          $text = '"' . $1;
        } elsif (/(.*)<\/text>/) {
-         $text = $text . " " . $1 . '"';
+         $text = $text . ' ' . $1 . '"';
          last;
        } elsif ($text) {
          last;
        } elsif ($text) {
-         $text = $text . " " . $_;
+         $text = $text . ' ' . $_;
        }
       }
       &::DEBUG("wikipedia returned text: " . $text .
        }
       }
       &::DEBUG("wikipedia returned text: " . $text .
-                  ", redirect " . $redirect. "\n");
+                  ', redirect ' . $redirect. "\n");
 
       if (!$redirect and !$text) {
        return ($res->as_string);
 
       if (!$redirect and !$text) {
        return ($res->as_string);
@@ -198,3 +198,5 @@ sub wikipedia_get_text {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index e654f361d348a89888dc68650475e5e346218cd2..f79da4f9aa265fdd44b02eecaac7756990b5892c 100644 (file)
@@ -35,7 +35,7 @@ sub wtf::wtf {
                return("argument appears to be fuzzy.");
        }
 
                return("argument appears to be fuzzy.");
        }
 
-       my $reply ="";
+       my $reply ='';
        foreach (`$binary '$query' 2>&1`){
                $reply .= $_;
        }
        foreach (`$binary '$query' 2>&1`){
                $reply .= $_;
        }
@@ -50,4 +50,5 @@ sub wtf::query {
 }
 
 1;
 }
 
 1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 103f56f8d4abb7ac4a7bdc00efd4c5fcde8be352..13cc5ef2b6fb060fb3f0b7c39e4bd50182660054 100644 (file)
@@ -45,7 +45,7 @@ sub queryText {
        my $res_return = 5;
 
        my $ua = new LWP::UserAgent;
        my $res_return = 5;
 
        my $ua = new LWP::UserAgent;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(10);
 
 
        $ua->timeout(10);
 
@@ -101,5 +101,6 @@ sub query {
 }
 
 1;
 }
 
 1;
-# vim: shiftwidth=2 tabstop=2
 __END__
 __END__
+
+# vim:ts=4:sw=4:expandtab:tw=80
index b11c2778478069fb6cf6271079f6d09ad461645c..41f7d4f62a4e5553671cdad1506799b322692c02 100644 (file)
@@ -45,7 +45,7 @@ sub queryText {
        my $res_return = 5;
 
        my $ua = new LWP::UserAgent;
        my $res_return = 5;
 
        my $ua = new LWP::UserAgent;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(10);
 
 
        $ua->timeout(10);
 
@@ -101,5 +101,7 @@ sub query {
 }
 
 1;
 }
 
 1;
-# vim: shiftwidth=2 tabstop=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __END__
 __END__
index 035ceba84001833a50b4d58c36c0cb62fa9936ac..e1f091087ee8292c8f8d56b24188daad7e737a02 100644 (file)
@@ -84,10 +84,10 @@ sub ftpGet {
     my $delta_time     = &timedelta($start_time);
     if ($delta_time > 0 and $verbose_ftp) {
        &status(sprintf("FTP: %.02f sec to complete.", $delta_time));
     my $delta_time     = &timedelta($start_time);
     if ($delta_time > 0 and $verbose_ftp) {
        &status(sprintf("FTP: %.02f sec to complete.", $delta_time));
-       my ($rateunit,$rate) = ("B", $size / $delta_time);
+       my ($rateunit,$rate) = ('B', $size / $delta_time);
        if ($rate > 1024) {
            $rate /= 1024;
        if ($rate > 1024) {
            $rate /= 1024;
-           $rateunit = "kB";
+           $rateunit = 'kB';
        }
        &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate));
     }
        }
        &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate));
     }
@@ -153,7 +153,7 @@ sub getURL {
     return unless &loadPerlModule("LWP::UserAgent");
 
     $ua = new LWP::UserAgent;
     return unless &loadPerlModule("LWP::UserAgent");
 
     $ua = new LWP::UserAgent;
-    $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy");
+    $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy');
 
     if (defined $post) {
        $req = new HTTP::Request('POST',$url);
 
     if (defined $post) {
        $req = new HTTP::Request('POST',$url);
@@ -189,7 +189,7 @@ sub getURLAsFile {
     }
 
     $ua = new LWP::UserAgent;
     }
 
     $ua = new LWP::UserAgent;
-    $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy");
+    $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy');
     $req = HTTP::Request->new('GET', $url);
     &status("getURLAsFile: getting '$url' as '$file'");
     $res = $ua->request($req, $file);
     $req = HTTP::Request->new('GET', $url);
     &status("getURLAsFile: getting '$url' as '$file'");
     $res = $ua->request($req, $file);
@@ -205,3 +205,5 @@ sub getURLAsFile {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 36cffd423054a12cfaebfdb9fb5a5c2d1da70a76..f21cb02292b20acb0ceb5edf6b3aaeb43ed68032 100644 (file)
@@ -36,19 +36,19 @@ sub process {
     # hack to support channel +o as "+o" in bot user file.
     # requires +O in user file.
     # is $who arg lowercase?
     # hack to support channel +o as "+o" in bot user file.
     # requires +O in user file.
     # is $who arg lowercase?
-    if (exists $channels{$chan}{o}{ $orig{who} } && &IsFlag("O") eq "O") {
+    if (exists $channels{$chan}{o}{ $orig{who} } && &IsFlag('O') eq 'O') {
        &status("Gave $who/$chan +o (+O)\'ness");
        &status("Gave $who/$chan +o (+O)\'ness");
-       $users{$userHandle}{FLAGS} .= "o";
+       $users{$userHandle}{FLAGS} .= 'o';
     }
 
     # check if we have our head intact.
     if ($lobotomized) {
     }
 
     # check if we have our head intact.
     if ($lobotomized) {
-       if ($addressed and IsFlag("o") eq "o") {
+       if ($addressed and IsFlag('o') eq 'o') {
            my $delta_time      = time() - ($cache{lobotomy}{$who} || 0);
            &msg($who, "give me an unlobotomy.") if ($delta_time > 60*60);
            $cache{lobotomy}{$who} = time();
        }
            my $delta_time      = time() - ($cache{lobotomy}{$who} || 0);
            &msg($who, "give me an unlobotomy.") if ($delta_time > 60*60);
            $cache{lobotomy}{$who} = time();
        }
-       return 'LOBOTOMY' unless IsFlag("A");
+       return 'LOBOTOMY' unless IsFlag('A');
     }
 
     # talkMethod.
     }
 
     # talkMethod.
@@ -68,8 +68,8 @@ sub process {
        $2 =~ /^($mask{chan})(\s+(\S+))?/;
        my($joinchan, $key) = (lc $1, $3);
 
        $2 =~ /^($mask{chan})(\s+(\S+))?/;
        my($joinchan, $key) = (lc $1, $3);
 
-       if ($joinchan eq "") {
-           &help("join");
+       if ($joinchan eq '') {
+           &help('join');
            return;
        }
 
            return;
        }
 
@@ -78,7 +78,7 @@ sub process {
            return;
        }
 
            return;
        }
 
-       if (&IsFlag("o") ne "o") {
+       if (&IsFlag('o') ne 'o') {
            if (!exists $chanconf{$joinchan}) {
                &msg($who, "I am not allowed to join $joinchan.");
                return;
            if (!exists $chanconf{$joinchan}) {
                &msg($who, "I am not allowed to join $joinchan.");
                return;
@@ -109,7 +109,7 @@ sub process {
        }
 
        if (!scalar @array or scalar @array > 2) {
        }
 
        if (!scalar @array or scalar @array > 2) {
-           &help("identify");
+           &help('identify');
            return;
        }
 
            return;
        }
 
@@ -151,7 +151,7 @@ sub process {
        }
 
        if (scalar @array != 1) {
        }
 
        if (scalar @array != 1) {
-           &help("pass");
+           &help('pass');
            return;
        }
 
            return;
        }
 
@@ -171,7 +171,7 @@ sub process {
 
        if ($first) {
            &performStrictReply("First time user... adding you as Master.");
 
        if ($first) {
            &performStrictReply("First time user... adding you as Master.");
-           $users{$who}{FLAGS} = "aemnorst";
+           $users{$who}{FLAGS} = 'aemnorst';
        }
 
        my $crypt = $users{$who}{PASS};
        }
 
        my $crypt = $users{$who}{PASS};
@@ -199,7 +199,7 @@ sub process {
     }
 
     # allowOutsiders.
     }
 
     # allowOutsiders.
-    if (&IsParam("disallowOutsiders") and $msgType =~ /private/i) {
+    if (&IsParam('disallowOutsiders') and $msgType =~ /private/i) {
        my $found = 0;
 
        foreach (keys %channels) {
        my $found = 0;
 
        foreach (keys %channels) {
@@ -262,7 +262,7 @@ sub process {
        }
 
        # customized random message.
        }
 
        # customized random message.
-       my $tmp = (rand() < 0.5) ? ", $who" : "";
+       my $tmp = (rand() < 0.5) ? ", $who" : '';
        &performStrictReply( &getRandom(keys %{ $lang{'hello'} }) . $tmp );
        return;
     }
        &performStrictReply( &getRandom(keys %{ $lang{'hello'} }) . $tmp );
        return;
     }
@@ -298,7 +298,7 @@ sub process {
 
     # karma. set...
     if ($msgType =~ /public/i && $message =~ /^(\S+)(--|\+\+)\s*$/ &&
 
     # karma. set...
     if ($msgType =~ /public/i && $message =~ /^(\S+)(--|\+\+)\s*$/ &&
-       $addressed && &IsChanConfOrWarn("karma")
+       $addressed && &IsChanConfOrWarn('karma')
     ) {
        # to request factoids such as "g++" or "libstdc++", append "?" to the query.
        my ($term,$inc) = (lc $1,$2);
     ) {
        # to request factoids such as "g++" or "libstdc++", append "?" to the query.
        my ($term,$inc) = (lc $1,$2);
@@ -308,17 +308,15 @@ sub process {
            return;
        }
 
            return;
        }
 
-       my $karma = &sqlSelect("stats", "counter",
-               { nick => $term, type => "karma" }) || 0;
+       my $karma = &sqlSelect('stats', 'counter',
+               { nick => $term, type => 'karma' }) || 0;
        if ($inc eq '++') {
            $karma++;
        } else {
            $karma--;
        }
 
        if ($inc eq '++') {
            $karma++;
        } else {
            $karma--;
        }
 
-       &sqlReplace("stats", {
-           nick        => $term,
-           type        => "karma",
+       &sqlSet('stats', {'nick' => $term, type => 'karma', channel => 'PRIVATE'}, {
            'time'      => time(),
            counter     => $karma,
        } );
            'time'      => time(),
            counter     => $karma,
        } );
@@ -327,7 +325,7 @@ sub process {
     }
 
     # here's where the external routines get called.
     }
 
     # here's where the external routines get called.
-    # if they return anything but null, that's the "answer".
+    # if they return anything but null, that's the 'answer'.
     if ($addressed) {
        my $er = &Modules();
        if (!defined $er) {
     if ($addressed) {
        my $er = &Modules();
        if (!defined $er) {
@@ -335,7 +333,7 @@ sub process {
        }
 
        # allow administration of bot via messages (default is DCC CHAT only)
        }
 
        # allow administration of bot via messages (default is DCC CHAT only)
-       if (&IsFlag("A")) {
+       if (&IsFlag('A')) {
            &loadMyModule('UserDCC');
            $er = &userDCC();
            if (!defined $er) {
            &loadMyModule('UserDCC');
            $er = &userDCC();
            if (!defined $er) {
@@ -349,7 +347,7 @@ sub process {
        }
     }
 
        }
     }
 
-    if (&IsParam("factoids") and $param{'DBType'} =~ /^(mysql|sqlite(2)?|pgsql)$/i) {
+    if (&IsParam('factoids') and $param{'DBType'} =~ /^(mysql|sqlite(2)?|pgsql)$/i) {
        &FactoidStuff();
     } elsif ($param{'DBType'} =~ /^none$/i) {
        return "NO FACTOIDS.";
        &FactoidStuff();
     } elsif ($param{'DBType'} =~ /^none$/i) {
        return "NO FACTOIDS.";
@@ -361,3 +359,5 @@ sub process {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 646c2097ff9c8bbeaa001a3b808ac2caff15bced..73b30fab86784ac08291d499fc89eac550787f0d 100644 (file)
@@ -15,7 +15,7 @@ sub openSHM {
     my $IPC_PRIVATE = 0;
     my $size = 2000;
 
     my $IPC_PRIVATE = 0;
     my $size = 2000;
 
-    if (&IsParam("noSHM")) {
+    if (&IsParam('noSHM')) {
        &status("Shared memory: Disabled. WARNING: bot may become unreliable");
        return 0;
     }
        &status("Shared memory: Disabled. WARNING: bot may become unreliable");
        return 0;
     }
@@ -51,7 +51,7 @@ sub shmRead {
     my $size = 3*80;
     my $retval = '';
 
     my $size = 3*80;
     my $retval = '';
 
-    return '' if (&IsParam("noSHM"));
+    return '' if (&IsParam('noSHM'));
 
     if (shmread($key,$retval,$position,$size)) {
        #&DEBUG("shmRead($key): $retval");
 
     if (shmread($key,$retval,$position,$size)) {
        #&DEBUG("shmRead($key): $retval");
@@ -73,7 +73,7 @@ sub shmWrite {
     my $position = 0;
     my $size = 80*3;
 
     my $position = 0;
     my $size = 80*3;
 
-    return if (&IsParam("noSHM"));
+    return if (&IsParam('noSHM'));
 
     $shm_keys{$keys}{accessed} = 1;
 
 
     $shm_keys{$keys}{accessed} = 1;
 
@@ -93,7 +93,7 @@ sub shmWrite {
 
     my $read = &shmRead($key);
     $read =~ s/\0+//g;
 
     my $read = &shmRead($key);
     $read =~ s/\0+//g;
-    if ($read eq "") {
+    if ($read eq '') {
        $str = sprintf("%s:%d:%d: ", $param{ircUser}, $bot_pid, time());
     } else {
        $str = $read ."||". $str;
        $str = sprintf("%s:%d:%d: ", $param{ircUser}, $bot_pid, time());
     } else {
        $str = $read ."||". $str;
@@ -241,8 +241,8 @@ sub shmFlush {
     return if ($$ != $::bot_pid); # fork protection.
 
     if (@_) {
     return if ($$ != $::bot_pid); # fork protection.
 
     if (@_) {
-       &ScheduleThis(15, "shmFlush");
-       return if ($_[0] eq "2");
+       &ScheduleThis(15, 'shmFlush');
+       return if ($_[0] eq '2');
     }
 
     my $time;
     }
 
     my $time;
@@ -284,7 +284,9 @@ sub shmFlush {
        }
     }
 
        }
     }
 
-    &shmWrite($shm,"") if ($shmmsg ne "");
+    &shmWrite($shm,'') if ($shmmsg ne '');
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 12ec9c324a2f6729c5381cf2341b602f9da802c5..3a33008631a70dcfcafd9ca221303016f3e812f7 100644 (file)
@@ -6,7 +6,7 @@
 use strict;
 use vars qw($message $arg $qWord $verb $lobotomized $who $result $chan
        $conn $msgType $query $talkchannel $ident $memusage);
 use strict;
 use vars qw($message $arg $qWord $verb $lobotomized $who $result $chan
        $conn $msgType $query $talkchannel $ident $memusage);
-use vars qw(%channels %chanstats %cmdstats %count %ircstats %param
+use vars qw(%channels %chanstats %cmdstats %count %forked %ircstats %param
        %cache %mask %userstats);
 
 ### hooks get added in CommandHooks.pl.
        %cache %mask %userstats);
 
 ### hooks get added in CommandHooks.pl.
@@ -19,15 +19,16 @@ sub chaninfo {
     my $chan = lc shift(@_);
     my $mode;
 
     my $chan = lc shift(@_);
     my $mode;
 
-    if ($chan eq "") {         # all channels.
+    if ($chan eq '') {         # all channels.
        my $i           = keys %channels;
        my $i           = keys %channels;
-       my $reply       = "I'm on \002$i\002 ".&fixPlural("channel",$i);
+       my $reply       = "I'm on \002$i\002 ".&fixPlural('channel',$i);
        my $tucount     = 0;    # total user count.
        my $uucount     = 0;    # unique user count.
        my $tucount     = 0;    # total user count.
        my $uucount     = 0;    # unique user count.
+       my %chans;
        my @array;
 
        ### line 1.
        my @array;
 
        ### line 1.
-       foreach (sort keys %channels) {
+       foreach (keys %channels) {
            if ( /^\s*$/ or / / ) {
                &status("chanstats: fe channels: chan == NULL.");
                #&ircCheck();
            if ( /^\s*$/ or / / ) {
                &status("chanstats: fe channels: chan == NULL.");
                #&ircCheck();
@@ -35,8 +36,10 @@ sub chaninfo {
            }
            next if (/^_default$/);
 
            }
            next if (/^_default$/);
 
-           my $str = sprintf("%s/%d", $_, scalar(keys %{ $channels{$_}{''} }));
-           push(@array, $str);
+           $chans{$_} = scalar(keys %{ $channels{$_}{''} });
+       }
+       foreach $chan (sort {$chans{$b} <=> $chans{$a}} keys %chans) {
+           push(@array, "$chan/" . $chans{$chan});
        }
        &performStrictReply($reply.": ".join(', ', @array));
 
        }
        &performStrictReply($reply.": ".join(', ', @array));
 
@@ -57,10 +60,10 @@ sub chaninfo {
 
        my $chans = scalar(keys %channels);
        &performStrictReply(
 
        my $chans = scalar(keys %channels);
        &performStrictReply(
-           "i've cached \002$tucount\002 ". &fixPlural("user",$tucount).
-           ", \002$uucount\002 unique ". &fixPlural("user",$uucount).
+           "i've cached \002$tucount\002 ". &fixPlural('user',$tucount).
+           ", \002$uucount\002 unique ". &fixPlural('user',$uucount).
            ", distributed over \002$chans\002 ".
            ", distributed over \002$chans\002 ".
-           &fixPlural("channel", $chans)."."
+           &fixPlural('channel', $chans)."."
        );
        &ircCheck();
 
        );
        &ircCheck();
 
@@ -83,7 +86,7 @@ sub chaninfo {
        push(@array, "\002$int\002 ". &fixPlural($_,$int));
     }
     my $reply = "On \002$chan\002, there ".
        push(@array, "\002$int\002 ". &fixPlural($_,$int));
     }
     my $reply = "On \002$chan\002, there ".
-               &fixPlural("has",scalar(@array)). " been ".
+               &fixPlural('has',scalar(@array)). " been ".
                &IJoin(@array);
 
     # Step 1b: check channel inconstencies.
                &IJoin(@array);
 
     # Step 1b: check channel inconstencies.
@@ -107,13 +110,13 @@ sub chaninfo {
     # Step 2:
     undef @array;
     my $type;
     # Step 2:
     undef @array;
     my $type;
-    foreach ("v","o","") {
+    foreach ('v','o','') {
        my $int = scalar(keys %{ $channels{$chan}{$_} });
        next unless ($int);
 
        my $int = scalar(keys %{ $channels{$chan}{$_} });
        next unless ($int);
 
-       $type = "Voice" if ($_ eq "v");
-       $type = "Opped" if ($_ eq "o");
-       $type = "Total" if ($_ eq "");
+       $type = 'Voice' if ($_ eq 'v');
+       $type = 'Opped' if ($_ eq 'o');
+       $type = 'Total' if ($_ eq '');
 
        push(@array,"\002$int\002 $type");
     }
 
        push(@array,"\002$int\002 $type");
     }
@@ -167,7 +170,7 @@ sub cmdstats {
 # Factoid extension info. xk++
 sub factinfo {
     my $faqtoid = lc shift(@_);
 # Factoid extension info. xk++
 sub factinfo {
     my $faqtoid = lc shift(@_);
-    my $query   = "";
+    my $query   = '';
 
     if ($faqtoid =~ /^\-(\S+)(\s+(.*))$/) {
        &msg($who,"error: individual factoid info queries not supported as yet.");
 
     if ($faqtoid =~ /^\-(\S+)(\s+(.*))$/) {
        &msg($who,"error: individual factoid info queries not supported as yet.");
@@ -184,15 +187,15 @@ sub factinfo {
 sub factstats {
     my $type = shift(@_);
 
 sub factstats {
     my $type = shift(@_);
 
-    &Forker("Factoids", sub {
+    &Forker('Factoids', sub {
        &performStrictReply( &CmdFactStats($type) );
     } );
 }
 
 sub karma {
     my $target = lc( shift || $who );
        &performStrictReply( &CmdFactStats($type) );
     } );
 }
 
 sub karma {
     my $target = lc( shift || $who );
-    my $karma  = &sqlSelect("stats", "counter",
-       { nick => $target, type => "karma" }) || 0;
+    my $karma  = &sqlSelect('stats', 'counter',
+       { nick => $target, type => 'karma'}) || 0;
 
     if ($karma != 0) {
        &performStrictReply("$target has karma of $karma");
 
     if ($karma != 0) {
        &performStrictReply("$target has karma of $karma");
@@ -249,7 +252,7 @@ sub tell {
 
     &status("tell: target = $target, query = $query");
 
 
     &status("tell: target = $target, query = $query");
 
-    # "intrusive".
+    # 'intrusive'.
 #    if ($target !~ /^$mask{chan}$/ and !&IsNickInAnyChan($target)) {
 #      &msg($who, "No, $target is not in any of my chans.");
 #      return;
 #    if ($target !~ /^$mask{chan}$/ and !&IsNickInAnyChan($target)) {
 #      &msg($who, "No, $target is not in any of my chans.");
 #      return;
@@ -271,7 +274,7 @@ sub tell {
     # no such factoid.
     if (!defined $result || $result =~ /^0?$/) {
        $who            = $target;
     # no such factoid.
     if (!defined $result || $result =~ /^0?$/) {
        $who            = $target;
-       $msgType        = "private";
+       $msgType        = 'private';
 
        # support command redirection.
        # recursive cmdHooks aswell :)
 
        # support command redirection.
        # recursive cmdHooks aswell :)
@@ -316,12 +319,12 @@ sub countryStats {
        return;
     }
 
        return;
     }
 
-    if ($chan eq "") {
+    if ($chan eq '') {
        $chan = $_[0];
     }
 
        $chan = $_[0];
     }
 
-    if ($chan eq "") {
-       &help("countrystats");
+    if ($chan eq '') {
+       &help('countrystats');
        return;
     }
 
        return;
     }
 
@@ -364,7 +367,7 @@ sub do_countrystats {
     }
 
     # TODO: move this into a scheduler
     }
 
     # TODO: move this into a scheduler
-    $msgType   = "private";
+    $msgType   = 'private';
     &performStrictReply( &formListReply(0, "Country Stats ", @list) );
 
     delete $cache{countryStats};
     &performStrictReply( &formListReply(0, "Country Stats ", @list) );
 
     delete $cache{countryStats};
@@ -379,13 +382,13 @@ sub userCommands {
     # conversion: ascii.
     if ($message =~ /^(asci*|chr) (\d+)$/) {
        &DEBUG("ascii/chr called ...");
     # conversion: ascii.
     if ($message =~ /^(asci*|chr) (\d+)$/) {
        &DEBUG("ascii/chr called ...");
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
 
        &DEBUG("ascii/chr called");
 
        $arg    = $2;
        $result = chr($arg);
 
        &DEBUG("ascii/chr called");
 
        $arg    = $2;
        $result = chr($arg);
-       $result = "NULL"        if ($arg == 0);
+       $result = 'NULL'        if ($arg == 0);
 
        &performReply( sprintf("ascii %s is '%s'", $arg, $result) );
 
 
        &performReply( sprintf("ascii %s is '%s'", $arg, $result) );
 
@@ -394,12 +397,12 @@ sub userCommands {
 
     # conversion: ord.
     if ($message =~ /^ord(\s+(.*))$/) {
 
     # conversion: ord.
     if ($message =~ /^ord(\s+(.*))$/) {
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
 
        $arg = $2;
 
        if (!defined $arg or length $arg != 1) {
 
        $arg = $2;
 
        if (!defined $arg or length $arg != 1) {
-           &help("ord");
+           &help('ord');
            return;
        }
 
            return;
        }
 
@@ -418,11 +421,11 @@ sub userCommands {
 
     # hex.
     if ($message =~ /^hex(\s+(.*))?$/i) {
 
     # hex.
     if ($message =~ /^hex(\s+(.*))?$/i) {
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
        my $arg = $2;
 
        if (!defined $arg) {
        my $arg = $2;
 
        if (!defined $arg) {
-           &help("hex");
+           &help('hex');
            return;
        }
 
            return;
        }
 
@@ -442,40 +445,27 @@ sub userCommands {
     }
 
     # crypt.
     }
 
     # crypt.
-    if ($message =~ /^crypt(\s+(.*))?$/i) {
-       my @args        = split /\s+/, $2;
-
-       if (!scalar @args or scalar @args > 2) {
-           &help("crypt");
-           return;
-       }
-
-       if (scalar @args == 2) {
-# disable cause $1$ will use md5
-#          if (length $args[0] != 2) {
-#              &msg($who, "invalid format...");
-#              return;
-#          }
-
-           &performStrictReply( crypt($args[1], $args[0]) );
+    if ($message =~ /^crypt\s+(\S*)?\s*(.*)?$/i) {
+&status("crypt: $1:$2:$3");
+       if ("$2" ne '') {
+           &performStrictReply(crypt($2, $1));
        } else {
        } else {
-           &performStrictReply( &mkcrypt($args[0]) );
+           &performStrictReply(&mkcrypt($1));
        }
        }
-
        return;
     }
 
     # cycle.
     if ($message =~ /^(cycle)(\s+(\S+))?$/i) {
        return;
     }
 
     # cycle.
     if ($message =~ /^(cycle)(\s+(\S+))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $chan = lc $3;
 
        my $chan = lc $3;
 
-       if ($chan eq "") {
+       if ($chan eq '') {
            if ($msgType =~ /public/) {
                $chan = $talkchannel;
                &DEBUG("cycle: setting chan to '$chan'.");
            } else {
            if ($msgType =~ /public/) {
                $chan = $talkchannel;
                &DEBUG("cycle: setting chan to '$chan'.");
            } else {
-               &help("cycle");
+               &help('cycle');
                return;
            }
        }
                return;
            }
        }
@@ -487,7 +477,7 @@ sub userCommands {
 
        &msg($chan, "I'm coming back. (courtesy of $who)");
        &part($chan);
 
        &msg($chan, "I'm coming back. (courtesy of $who)");
        &part($chan);
-###    &ScheduleThis(5, "getNickInUse") if (@_);
+###    &ScheduleThis(5, 'getNickInUse') if (@_);
        &status("Schedule rejoin in 5secs to $chan by $who.");
        $conn->schedule(5, sub { &joinchan($chan); });
 
        &status("Schedule rejoin in 5secs to $chan by $who.");
        $conn->schedule(5, sub { &joinchan($chan); });
 
@@ -496,7 +486,7 @@ sub userCommands {
 
     # reload.
     if ($message =~ /^reload$/i) {
 
     # reload.
     if ($message =~ /^reload$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
@@ -507,21 +497,21 @@ sub userCommands {
 
     # redir.
     if ($message =~ /^redir(\s+(.*))?/i) {
 
     # redir.
     if ($message =~ /^redir(\s+(.*))?/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $factoid = $2;
 
        if (!defined $factoid) {
        my $factoid = $2;
 
        if (!defined $factoid) {
-           &help("redir");
+           &help('redir');
            return;
        }
 
        my $val  = &getFactInfo($factoid, "factoid_value");
            return;
        }
 
        my $val  = &getFactInfo($factoid, "factoid_value");
-       if (!defined $val or $val eq "") {
+       if (!defined $val or $val eq '') {
            &msg($who, "error: '$factoid' does not exist.");
            return;
        }
        &DEBUG("val => '$val'.");
            &msg($who, "error: '$factoid' does not exist.");
            return;
        }
        &DEBUG("val => '$val'.");
-       my @list = &searchTable("factoids", "factoid_key",
+       my @list = &searchTable('factoids', "factoid_key",
                                        "factoid_value", "^$val\$");
 
        if (scalar @list == 1) {
                                        "factoid_value", "^$val\$");
 
        if (scalar @list == 1) {
@@ -562,12 +552,12 @@ sub userCommands {
        my $reply = $3;
 
        if (!defined $reply) {
        my $reply = $3;
 
        if (!defined $reply) {
-           &help("rot13");
+           &help('rot13');
            return;
        }
        my $num = $1 % 26;
            return;
        }
        my $num = $1 % 26;
-       my $upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       my $lower="abcdefghijklmnopqrstuvwxyz";
+       my $upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+       my $lower='abcdefghijklmnopqrstuvwxyz';
        my $to=substr($upper,$num).substr($upper,0,$num).substr($lower,$num).substr($lower,0,$num);
        eval "\$reply =~ tr/$upper$lower/$to/;";
 
        my $to=substr($upper,$num).substr($upper,0,$num).substr($lower,$num).substr($lower,0,$num);
        eval "\$reply =~ tr/$upper$lower/$to/;";
 
@@ -679,7 +669,7 @@ sub userCommands {
        my $startString = scalar(gmtime $^T);
        my $upString    = &Time2String(time() - $^T);
        my ($puser,$psystem,$cuser,$csystem) = times;
        my $startString = scalar(gmtime $^T);
        my $upString    = &Time2String(time() - $^T);
        my ($puser,$psystem,$cuser,$csystem) = times;
-       my $factoids    = &countKeys("factoids");
+       my $factoids    = &countKeys('factoids');
        my $forks = 0;
        foreach (keys %forked) {
            $forks += scalar keys %{ $forked{$_} };
        my $forks = 0;
        foreach (keys %forked) {
            $forks += scalar keys %{ $forked{$_} };
@@ -693,20 +683,20 @@ sub userCommands {
        &performStrictReply(
        "Since $startString, there have been".
          " \002$count{'Update'}\002 ".
        &performStrictReply(
        "Since $startString, there have been".
          " \002$count{'Update'}\002 ".
-               &fixPlural("modification", $count{'Update'}).
+               &fixPlural('modification', $count{'Update'}).
          ", \002$count{'Question'}\002 ".
          ", \002$count{'Question'}\002 ".
-               &fixPlural("question",$count{'Question'}).
+               &fixPlural('question',$count{'Question'}).
          ", \002$count{'Dunno'}\002 ".
          ", \002$count{'Dunno'}\002 ".
-               &fixPlural("dunno",$count{'Dunno'}).
+               &fixPlural('dunno',$count{'Dunno'}).
          ", \002$count{'Moron'}\002 ".
          ", \002$count{'Moron'}\002 ".
-               &fixPlural("moron",$count{'Moron'}).
+               &fixPlural('moron',$count{'Moron'}).
          " and \002$count{'Commands'}\002 ".
          " and \002$count{'Commands'}\002 ".
-               &fixPlural("command",$count{'Commands'}).
+               &fixPlural('command',$count{'Commands'}).
          ".  I have been awake for $upString this session, and ".
          "currently reference \002$factoids\002 factoids.  ".
          "I'm using about \002$memusage\002 ".
          "kB of memory. With \002$forks\002 active ".
          ".  I have been awake for $upString this session, and ".
          "currently reference \002$factoids\002 factoids.  ".
          "I'm using about \002$memusage\002 ".
          "kB of memory. With \002$forks\002 active ".
-               &fixPlural("fork",$forks).
+               &fixPlural('fork',$forks).
          ". Process time user/system $puser/$psystem child $cuser/$csystem"
        );
 
          ". Process time user/system $puser/$psystem child $cuser/$csystem"
        );
 
@@ -714,9 +704,9 @@ sub userCommands {
     }
 
     # wantNick. xk++
     }
 
     # wantNick. xk++
-    # FIXME does not try to get nick "back", just switches nicks
+    # FIXME does not try to get nick 'back', just switches nicks
     if ($message =~ /^wantNick\s(.*)?$/i) {
     if ($message =~ /^wantNick\s(.*)?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $wantnick = lc $1;
        my $mynick = $conn->nick();
 
        my $wantnick = lc $1;
        my $mynick = $conn->nick();
 
@@ -739,7 +729,7 @@ sub userCommands {
            my $str = "someone is using nick $wantnick; GHOSTing";
            &status($str);
            &msg($who, $str);
            my $str = "someone is using nick $wantnick; GHOSTing";
            &status($str);
            &msg($who, $str);
-           &msg("NickServ", "GHOST $wantnick $param{'nickServ_pass'}");
+           &msg('NickServ', "GHOST $wantnick $param{'nickServ_pass'}");
 
            $conn->schedule(5, sub {
                &status("going to change nick from $mynick to $wantnick after GHOST.");
 
            $conn->schedule(5, sub {
                &status("going to change nick from $mynick to $wantnick after GHOST.");
@@ -752,7 +742,9 @@ sub userCommands {
        return;
     }
 
        return;
     }
 
-    return "CONTINUE";
+    return 'CONTINUE';
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ecbcee5f7c9388019e495797b910f66a920bc9fc..936f31cc784ec8aab6fb43951b23f72a67c7cdac 100644 (file)
@@ -47,8 +47,8 @@ $SIG{'__WARN__'} = 'doWarn';
 
 # initialize variables.
 $last{buflen}  = 0;
 
 # initialize variables.
 $last{buflen}  = 0;
-$last{say}     = "";
-$last{msg}     = "";
+$last{say}     = '';
+$last{msg}     = '';
 $userHandle    = "_default";
 $wingaterun    = time();
 $firsttime     = 1;
 $userHandle    = "_default";
 $wingaterun    = time();
 $firsttime     = 1;
@@ -78,23 +78,22 @@ $nottime    = 0;
 $notsize       = 0;
 $notcount      = 0;
 ###
 $notsize       = 0;
 $notcount      = 0;
 ###
-$bot_release   = "1.3.3";
-if ( -d "CVS" ) {
-    use POSIX qw(strftime);
-    $bot_release       .= strftime(" cvs (%Y%m%d)", gmtime( (stat("CVS"))[9] ) );
-}
-$bot_version   = "blootbot $bot_release -- $^O";
-$noreply       = "NOREPLY";
+open(VERSION, '<VERSION');
+$bot_release   = <VERSION> || "(unknown version)";
+chomp($bot_release);
+close(VERSION);
+$bot_version   = "infobot $bot_release -- $^O";
+$noreply       = 'NOREPLY';
 
 ##########
 ### misc commands.
 ###
 
 sub whatInterface {
 
 ##########
 ### misc commands.
 ###
 
 sub whatInterface {
-    if (!&IsParam("Interface") or $param{'Interface'} =~ /IRC/) {
-       return "IRC";
+    if (!&IsParam('Interface') or $param{'Interface'} =~ /IRC/) {
+       return 'IRC';
     } else {
     } else {
-       return "CLI";
+       return 'CLI';
     }
 }
 
     }
 }
 
@@ -113,7 +112,7 @@ sub doExit {
        &status("parent caught SIG$sig (pid $$).") if (defined $sig);
 
        &status("--- Start of quit.");
        &status("parent caught SIG$sig (pid $$).") if (defined $sig);
 
        &status("--- Start of quit.");
-       $ident ||= "blootbot";  # lame hack.
+       $ident ||= 'infobot';   # lame hack.
 
        &status("Memory Usage: $memusage KiB");
 
 
        &status("Memory Usage: $memusage KiB");
 
@@ -131,13 +130,13 @@ sub doExit {
        &sqlCloseDB();
        &closeSHM($shm);
 
        &sqlCloseDB();
        &closeSHM($shm);
 
-       if (&IsParam("dumpvarsAtExit")) {
+       if (&IsParam('dumpvarsAtExit')) {
            &loadMyModule('DumpVars');
            &dumpallvars();
        }
            &loadMyModule('DumpVars');
            &dumpallvars();
        }
-       &symdumpAll()           if (&IsParam("symdumpAtExit"));
+       &symdumpAll()           if (&IsParam('symdumpAtExit'));
        &closeLog();
        &closeLog();
-       &closeSQLDebug()        if (&IsParam("SQLDebug"));
+       &closeSQLDebug()        if (&IsParam('SQLDebug'));
 
        &status("--- QUIT.");
     } else {                                   # child.
 
        &status("--- QUIT.");
     } else {                                   # child.
@@ -158,7 +157,7 @@ sub doWarn {
 }
 
 # Usage: &IsParam($param);
 }
 
 # Usage: &IsParam($param);
-# blootbot.config specific.
+# infobot.config specific.
 sub IsParam {
     my $param = $_[0];
 
 sub IsParam {
     my $param = $_[0];
 
@@ -206,7 +205,7 @@ sub getChanConfList {
            &WARN("multiple items found?");
        }
 
            &WARN("multiple items found?");
        }
 
-       if ($chanconf{$chan}{$param} eq "0") {
+       if ($chanconf{$chan}{$param} eq '0') {
            $chan{$chan}        = -1;
        } else {
            $chan{$chan}        =  1;
            $chan{$chan}        = -1;
        } else {
            $chan{$chan}        =  1;
@@ -224,7 +223,7 @@ sub IsChanConf {
     my($param) = shift;
 
     # knocked tons of bugs with this! :)
     my($param) = shift;
 
     # knocked tons of bugs with this! :)
-    my $debug  = 0; # 1 if ($param eq "whatever");
+    my $debug  = 0; # 1 if ($param eq 'whatever');
 
     if (!defined $param) {
        &WARN("IsChanConf: param == NULL.");
 
     if (!defined $param) {
        &WARN("IsChanConf: param == NULL.");
@@ -251,7 +250,7 @@ sub IsChanConf {
     if (!defined $msgType) {
        $nomatch++;
     } else {
     if (!defined $msgType) {
        $nomatch++;
     } else {
-       $nomatch++ if ($msgType eq "");
+       $nomatch++ if ($msgType eq '');
        $nomatch++ unless ($msgType =~ /^(public|private)$/i);
     }
 
        $nomatch++ unless ($msgType =~ /^(public|private)$/i);
     }
 
@@ -317,7 +316,7 @@ sub getChanConf {
        if (!defined $chanconf{$c[0]}{$param} and ($c ne '_default')) {
            return &getChanConf($param, '_default');
        }
        if (!defined $chanconf{$c[0]}{$param} and ($c ne '_default')) {
            return &getChanConf($param, '_default');
        }
-       #&DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"');
+       &DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"');
        return $chanconf{$c[0]}{$param};
     }
 
        return $chanconf{$c[0]}{$param};
     }
 
@@ -372,9 +371,9 @@ sub findChanConf {
 }
 
 sub showProc {
 }
 
 sub showProc {
-    my ($prefix) = $_[0] || "";
+    my ($prefix) = $_[0] || '';
 
 
-    if ($^O eq "linux") {
+    if ($^O eq 'linux') {
        if (!open(IN, "/proc/$$/status")) {
            &ERROR("cannot open '/proc/$$/status'.");
            return;
        if (!open(IN, "/proc/$$/status")) {
            &ERROR("cannot open '/proc/$$/status'.");
            return;
@@ -385,7 +384,7 @@ sub showProc {
        }
        close IN;
 
        }
        close IN;
 
-    } elsif ($^O eq "netbsd") {
+    } elsif ($^O eq 'netbsd') {
        $memusage = int( (stat "/proc/$$/mem")[7]/1024 );
 
     } elsif ($^O =~ /^(free|open)bsd$/) {
        $memusage = int( (stat "/proc/$$/mem")[7]/1024 );
 
     } elsif ($^O =~ /^(free|open)bsd$/) {
@@ -393,11 +392,11 @@ sub showProc {
        $memusage = $info[20];
 
     } else {
        $memusage = $info[20];
 
     } else {
-       $memusage = "UNKNOWN";
+       $memusage = 'UNKNOWN';
        return;
     }
 
        return;
     }
 
-    if (defined $memusageOld and &IsParam("DEBUG")) {
+    if (defined $memusageOld and &IsParam('DEBUG')) {
        # it's always going to be increase.
        my $delta = $memusage - $memusageOld;
        my $str;
        # it's always going to be increase.
        my $delta = $memusage - $memusageOld;
        my $str;
@@ -428,25 +427,25 @@ sub setup {
     &status("--- Started logging.");
 
     # read.
     &status("--- Started logging.");
 
     # read.
-    &loadLang($bot_data_dir. "/blootbot.lang");
+    &loadLang($bot_data_dir. "/infobot.lang");
     &loadIRCServers();
     &readUserFile();
     &readChanFile();
     &loadMyModulesNow();       # must be after chan file.
 
     $shm = &openSHM();
     &loadIRCServers();
     &readUserFile();
     &readChanFile();
     &loadMyModulesNow();       # must be after chan file.
 
     $shm = &openSHM();
-    &openSQLDebug()    if (&IsParam("SQLDebug"));
+    &openSQLDebug()    if (&IsParam('SQLDebug'));
     &sqlOpenDB($param{'DBName'}, $param{'DBType'}, $param{'SQLUser'},
        $param{'SQLPass'});
     &checkTables();
 
     &sqlOpenDB($param{'DBName'}, $param{'DBType'}, $param{'SQLUser'},
        $param{'SQLPass'});
     &checkTables();
 
-    &status("Setup: ". &countKeys("factoids") ." factoids.");
-    &getChanConfDefault("sendPrivateLimitLines", 3, $chan);
-    &getChanConfDefault("sendPrivateLimitBytes", 1000, $chan);
-    &getChanConfDefault("sendPublicLimitLines", 3, $chan);
-    &getChanConfDefault("sendPublicLimitBytes", 1000, $chan);
-    &getChanConfDefault("sendNoticeLimitLines", 3, $chan);
-    &getChanConfDefault("sendNoticeLimitBytes", 1000, $chan);
+    &status("Setup: ". &countKeys('factoids') ." factoids.");
+    &getChanConfDefault('sendPrivateLimitLines', 3, $chan);
+    &getChanConfDefault('sendPrivateLimitBytes', 1000, $chan);
+    &getChanConfDefault('sendPublicLimitLines', 3, $chan);
+    &getChanConfDefault('sendPublicLimitBytes', 1000, $chan);
+    &getChanConfDefault('sendNoticeLimitLines', 3, $chan);
+    &getChanConfDefault('sendNoticeLimitBytes', 1000, $chan);
 
     $param{tempDir} =~ s#\~/#$ENV{HOME}/#;
 
 
     $param{tempDir} =~ s#\~/#$ENV{HOME}/#;
 
@@ -456,7 +455,7 @@ sub setup {
 
 sub setupConfig {
     $param{'VERBOSITY'} = 1;
 
 sub setupConfig {
     $param{'VERBOSITY'} = 1;
-    &loadConfig($bot_config_dir."/blootbot.config");
+    &loadConfig($bot_config_dir."/infobot.config");
 
     foreach ( qw(ircNick ircUser ircName DBType tempDir) ) {
        next if &IsParam($_);
 
     foreach ( qw(ircNick ircUser ircName DBType tempDir) ) {
        next if &IsParam($_);
@@ -484,7 +483,7 @@ sub setupConfig {
 }
 
 sub startup {
 }
 
 sub startup {
-    if (&IsParam("DEBUG")) {
+    if (&IsParam('DEBUG')) {
        &status("enabling debug diagnostics.");
        # I thought disabling this reduced memory usage by 1000 KiB.
        use diagnostics;
        &status("enabling debug diagnostics.");
        # I thought disabling this reduced memory usage by 1000 KiB.
        use diagnostics;
@@ -502,13 +501,13 @@ sub shutdown {
     &status("--- shutdown called.");
 
     # hack.
     &status("--- shutdown called.");
 
     # hack.
-    $ident ||= "blootbot";
+    $ident ||= 'infobot';
 
 
-    if (!&isFileUpdated("$bot_state_dir/blootbot.users", $wtime_userfile)) {
+    if (!&isFileUpdated("$bot_state_dir/infobot.users", $wtime_userfile)) {
        &writeUserFile()
     }
 
        &writeUserFile()
     }
 
-    if (!&isFileUpdated("$bot_state_dir/blootbot.chan", $wtime_chanfile)) {
+    if (!&isFileUpdated("$bot_state_dir/infobot.chan", $wtime_chanfile)) {
        &writeChanFile();
     }
 
        &writeChanFile();
     }
 
@@ -537,10 +536,10 @@ sub restart {
 
        &ircCheck();    # heh, evil!
 
 
        &ircCheck();    # heh, evil!
 
-       &DCCBroadcast("-HUP called.","m");
+       &DCCBroadcast("-HUP called.",'m');
        &shutdown($sig);
        &shutdown($sig);
-       &loadConfig($bot_config_dir."/blootbot.config");
-       &reloadAllModules() if (&IsParam("DEBUG"));
+       &loadConfig($bot_config_dir."/infobot.config");
+       &reloadAllModules() if (&IsParam('DEBUG'));
        &setup();
 
        &status("--- End of $sig.");
        &setup();
 
        &status("--- End of $sig.");
@@ -566,7 +565,7 @@ sub loadConfig {
        next unless /\S/;
        my ($set,$key,$val) = split(/\s+/, $_, 3);
 
        next unless /\S/;
        my ($set,$key,$val) = split(/\s+/, $_, 3);
 
-       if ($set ne "set") {
+       if ($set ne 'set') {
            &status("loadConfig: invalid line '$_'.");
            next;
        }
            &status("loadConfig: invalid line '$_'.");
            next;
        }
@@ -585,3 +584,5 @@ sub loadConfig {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index c7400b00a7517324eb8ed3e3919032b728242af2..9e1a664eea7fe50b924c30f2bde786bcc4243012 100644 (file)
@@ -72,14 +72,19 @@ sub sqlOpenDB {
        $db = "dbname=$db.sqlite";
     } elsif ($type =~ /^pg/i) {
        $db = "dbname=$db";
        $db = "dbname=$db.sqlite";
     } elsif ($type =~ /^pg/i) {
        $db = "dbname=$db";
-       $type = "Pg";
+       $type = 'Pg';
     }
 
     my $dsn = "DBI:$type:$db";
     }
 
     my $dsn = "DBI:$type:$db";
-    my $hoststr = "";
+    my $hoststr = '';
     # SQLHost should be unset for SQLite
     if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
     # SQLHost should be unset for SQLite
     if (exists $param{'SQLHost'} and $param{'SQLHost'}) {
-       $dsn    .= ":$param{SQLHost}";
+       # PostgreSQL requires ";" and keyword 'host'. See perldoc Pg -- troubled
+       if ($type eq 'Pg') {
+               $dsn    .= ";host=$param{SQLHost}";
+       } else {
+               $dsn    .= ":$param{SQLHost}";
+       }
        $hoststr = " to $param{'SQLHost'}";
     }
     # SQLite ignores $user and $pass
        $hoststr = " to $param{'SQLHost'}";
     }
     # SQLite ignores $user and $pass
@@ -105,7 +110,7 @@ sub sqlCloseDB {
     return 0 unless ($dbh);
 
     my $x = $param{SQLHost};
     return 0 unless ($dbh);
 
     my $x = $param{SQLHost};
-    my $hoststr = ($x) ? " to $x" : "";
+    my $hoststr = ($x) ? " to $x" : '';
 
     &status("Closed DBI connection$hoststr.");
     $dbh->disconnect();
 
     &status("Closed DBI connection$hoststr.");
     $dbh->disconnect();
@@ -276,7 +281,7 @@ sub sqlSet {
        return;
     }
 
        return;
     }
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlSet: data_href == NULL.");
        return;
     }
        &WARN("sqlSet: data_href == NULL.");
        return;
     }
@@ -309,7 +314,7 @@ sub sqlSet {
 sub sqlUpdate {
     my ($table, $data_href, $where_href) = @_;
 
 sub sqlUpdate {
     my ($table, $data_href, $where_href) = @_;
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlSet: data_href == NULL.");
        return 0;
     }
        &WARN("sqlSet: data_href == NULL.");
        return 0;
     }
@@ -317,7 +322,7 @@ sub sqlUpdate {
     my $where  = &hashref2where($where_href) if ($where_href);
     my $update = &hashref2update($data_href) if ($data_href);
 
     my $where  = &hashref2where($where_href) if ($where_href);
     my $update = &hashref2update($data_href) if ($data_href);
 
-    &sqlRaw("Update", "UPDATE $table SET $update WHERE $where");
+    &sqlRaw('Update', "UPDATE $table SET $update WHERE $where");
 
     return 1;
 }
 
     return 1;
 }
@@ -326,9 +331,10 @@ sub sqlUpdate {
 # Usage: &sqlInsert($table, $data_href, $other);
 sub sqlInsert {
     my ($table, $data_href, $other) = @_;
 # Usage: &sqlInsert($table, $data_href, $other);
 sub sqlInsert {
     my ($table, $data_href, $other) = @_;
-    # note: if $other == 1, add "DELAYED" to function instead.
+    # note: if $other == 1, add 'DELAYED' to function instead.
+    # note: ^^^ doesnt actually do anything lol. Need code to s/1/DELAYED/ below -- troubled
 
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlInsert: data_href == NULL.");
        return;
     }
        &WARN("sqlInsert: data_href == NULL.");
        return;
     }
@@ -344,18 +350,18 @@ sub sqlInsert {
 
     &sqlRaw("Insert($table)", sprintf(
        "INSERT %s INTO %s (%s) VALUES (%s)",
 
     &sqlRaw("Insert($table)", sprintf(
        "INSERT %s INTO %s (%s) VALUES (%s)",
-       ($other || ""), $table, join(',',@k), join(',',@v)
+       ($other || ''), $table, join(',',@k), join(',',@v)
     ) );
 
     return 1;
 }
 
 #####
     ) );
 
     return 1;
 }
 
 #####
-# Usage: &sqlReplace($table, $data_href);
+# Usage: &sqlReplace($table, $data_href, [$pkey]);
 sub sqlReplace {
 sub sqlReplace {
-    my ($table, $data_href) = @_;
+    my ($table, $data_href, $pkey) = @_;
 
 
-    if (!defined $data_href or ref($data_href) ne "HASH") {
+    if (!defined $data_href or ref($data_href) ne 'HASH') {
        &WARN("sqlReplace: data_href == NULL.");
        return;
     }
        &WARN("sqlReplace: data_href == NULL.");
        return;
     }
@@ -369,10 +375,29 @@ sub sqlReplace {
        return;
     }
 
        return;
     }
 
-    &sqlRaw("Replace($table)", sprintf(
-       "REPLACE INTO %s (%s) VALUES (%s)",
-       $table, join(',',@k), join(',',@v)
-    ) );
+
+    if ($param{'DBType'} =~ /^pgsql$/i) {
+       # OK, heres the scoop. There is currently no REPLACE INTO in Pgsql.
+       # However, the bot already seems to search for factoids before insert
+       # anyways. Perhaps we could change this to a generic INSERT INTO so
+       # we can skip the seperate sql? -- troubled to: TimRiker
+       # PGSql syntax: UPDATE table SET key = 'value', key2 = 'value2' WHERE key = 'value'
+
+#      &sqlRaw("Replace($table)", sprintf(
+#              "INSERT INTO %s (%s) VALUES (%s)",
+#              $table, join(',',@k), join(',',@v)
+#      ));
+       &WARN("DEBUG: ($pkey = ) " . sprintf(
+                "REPLACE INTO %s (%s) VALUES (%s)",
+                $table, join(',',@k), join(',',@v)
+        ));
+
+    } else {
+       &sqlRaw("Replace($table)", sprintf(
+               "REPLACE INTO %s (%s) VALUES (%s)",
+               $table, join(',',@k), join(',',@v)
+       ));
+    }
 
     return 1;
 }
 
     return 1;
 }
@@ -382,14 +407,14 @@ sub sqlReplace {
 sub sqlDelete {
     my ($table, $where_href) = @_;
 
 sub sqlDelete {
     my ($table, $where_href) = @_;
 
-    if (!defined $where_href or ref($where_href) ne "HASH") {
+    if (!defined $where_href or ref($where_href) ne 'HASH') {
        &WARN("sqlDelete: where_href == NULL.");
        return;
     }
 
     my $where  = &hashref2where($where_href);
 
        &WARN("sqlDelete: where_href == NULL.");
        return;
     }
 
     my $where  = &hashref2where($where_href);
 
-    &sqlRaw("Delete", "DELETE FROM $table WHERE $where");
+    &sqlRaw('Delete', "DELETE FROM $table WHERE $where");
 
     return 1;
 }
 
     return 1;
 }
@@ -469,7 +494,7 @@ sub hashref2where {
        return;
     }
 
        return;
     }
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2where: href is not HASH ref (href => $href)");
        return;
     }
        &WARN("hashref2where: href is not HASH ref (href => $href)");
        return;
     }
@@ -492,7 +517,7 @@ sub hashref2where {
 sub hashref2update {
     my ($href) = @_;
 
 sub hashref2update {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -518,7 +543,7 @@ sub hashref2update {
 sub hashref2array {
     my ($href) = @_;
 
 sub hashref2array {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -546,7 +571,7 @@ sub hashref2array {
 # Usage: &countKeys($table, [$col]);
 sub countKeys {
     my ($table, $col) = @_;
 # Usage: &countKeys($table, [$col]);
 sub countKeys {
     my ($table, $col) = @_;
-    $col ||= "*";
+    $col ||= '*';
 
     return (&sqlRawReturn("SELECT count($col) FROM $table"))[0];
 }
 
     return (&sqlRawReturn("SELECT count($col) FROM $table"))[0];
 }
@@ -627,18 +652,20 @@ sub searchTable {
 }
 
 sub sqlCreateTable {
 }
 
 sub sqlCreateTable {
-    my($table) = @_;
+    my($table, $dbtype)        = @_;
     my(@path)  = ($bot_data_dir, ".","..","../..");
     my $found  = 0;
     my $data;
     my(@path)  = ($bot_data_dir, ".","..","../..");
     my $found  = 0;
     my $data;
+    $dbtype = lc $dbtype;
 
     foreach (@path) {
 
     foreach (@path) {
-       my $file = "$_/setup/$table.sql";
+       my $file = "$_/setup/$dbtype/$table.sql";
        next unless ( -f $file );
 
        open(IN, $file);
        while (<IN>) {
            chop;
        next unless ( -f $file );
 
        open(IN, $file);
        while (<IN>) {
            chop;
+           next if $_ =~ /^--/;
            $data .= $_;
        }
 
            $data .= $_;
        }
 
@@ -686,6 +713,31 @@ sub checkTables {
        }
 
        # create database not needed for SQLite
        }
 
        # create database not needed for SQLite
+
+    } elsif ($param{DBType} =~ /^pgsql$/i) {
+       # $sql_showDB = SQL to select the DB list
+       # $sql_showTBL = SQL to select all tables for the current connection
+
+       my $sql_showDB = "SELECT datname FROM pg_database";
+       my $sql_showTBL = "SELECT tablename FROM pg_tables \
+               WHERE schemaname = 'public'";
+
+       foreach ( &sqlRawReturn($sql_showDB) ) {
+               $database_exists++ if ($_ eq $param{'DBName'});
+       }
+
+       unless ($database_exists) {
+               &status("Creating PostgreSQL database $param{'DBName'}");
+               &status("(actually, not really, please read the INSTALL file)");
+       }
+
+        # retrieve a list of db's from the server. This code is from mysql above, please check -- troubled
+        my @tables = map {s/^\`//; s/\`$//; $_;} &sqlRawReturn($sql_showTBL);
+        if ($#tables == -1){
+            @tables = $dbh->tables;
+        }
+        &status("Tables: ".join(',',@tables));
+        @db{@tables} = (1) x @tables;
     }
 
     foreach ( qw(botmail connections factoids rootwarn seen stats onjoin) ) {
     }
 
     foreach ( qw(botmail connections factoids rootwarn seen stats onjoin) ) {
@@ -698,8 +750,10 @@ sub checkTables {
 
        $cache{create_table}{$_} = 1;
 
 
        $cache{create_table}{$_} = 1;
 
-       &sqlCreateTable($_);
+       &sqlCreateTable($_, $param{DBType});
     }
 }
 
 1;
     }
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 6e80e6c181576ded12197b77327789decaa0c50a..8309a14fa3f6817fb589eebc0c10472debcd88e9 100644 (file)
@@ -16,7 +16,7 @@ use vars qw(%param %file %cache);
 $logtime       = time();
 $logcount      = 0;
 $logrepeat     = 0;
 $logtime       = time();
 $logcount      = 0;
 $logrepeat     = 0;
-$logold                = "";
+$logold                = '';
 
 $param{VEBOSITY} ||= 1;                # lame fix for preload
 
 
 $param{VEBOSITY} ||= 1;                # lame fix for preload
 
@@ -73,7 +73,7 @@ sub cl {
 
 # logging support.
 sub openLog {
 
 # logging support.
 sub openLog {
-    return unless (&IsParam("logfile"));
+    return unless (&IsParam('logfile'));
     $file{log} = $param{'logfile'};
 
     my $error = 0;
     $file{log} = $param{'logfile'};
 
     my $error = 0;
@@ -90,13 +90,14 @@ sub openLog {
        $error++;
     }
 
        $error++;
     }
 
-    if (&IsParam("logType") and $param{'logType'} =~ /DAILY/i) {
+    if (&IsParam('logType') and $param{'logType'} =~ /DAILY/i) {
        my ($day,$month,$year) = (gmtime time())[3,4,5];
        $logDate = sprintf("%04d%02d%02d",$year+1900,$month+1,$day);
        $file{log} .= $logDate;
     }
 
     if (open(LOG, ">>$file{log}")) {
        my ($day,$month,$year) = (gmtime time())[3,4,5];
        $logDate = sprintf("%04d%02d%02d",$year+1900,$month+1,$day);
        $file{log} .= $logDate;
     }
 
     if (open(LOG, ">>$file{log}")) {
+       binmode(LOG, ":encoding(UTF-8)");
        &status("Opened logfile $file{log}.");
        LOG->autoflush(1);
     } else {
        &status("Opened logfile $file{log}.");
        LOG->autoflush(1);
     } else {
@@ -106,7 +107,7 @@ sub openLog {
 
 sub closeLog {
     # lame fix for paramlogfile.
 
 sub closeLog {
     # lame fix for paramlogfile.
-    return unless (&IsParam("logfile"));
+    return unless (&IsParam('logfile'));
     return unless (defined fileno LOG);
 
     close LOG;
     return unless (defined fileno LOG);
 
     close LOG;
@@ -117,7 +118,7 @@ sub closeLog {
 # Usage: &compress($file);
 sub compress {
     my ($file) = @_;
 # Usage: &compress($file);
 sub compress {
     my ($file) = @_;
-    my @compress = ("/usr/bin/bzip2","/bin/gzip");
+    my @compress = ('/usr/bin/bzip2','/bin/bzip2','/bin/gzip');
     my $okay = 0;
 
     if (! -f $file) {
     my $okay = 0;
 
     if (! -f $file) {
@@ -148,7 +149,7 @@ sub compress {
 }
 
 sub DEBUG {
 }
 
 sub DEBUG {
-    return unless (&IsParam("DEBUG"));
+    return unless (&IsParam('DEBUG'));
 
     &status("${b_green}!DEBUG!$ob $_[0]");
 }
 
     &status("${b_green}!DEBUG!$ob $_[0]");
 }
@@ -158,7 +159,7 @@ sub ERROR {
 }
 
 sub WARN {
 }
 
 sub WARN {
-    return unless (&IsParam("WARN"));
+    return unless (&IsParam('WARN'));
 
     return if ($_[0] =~ /^PERL: Subroutine \S+ redefined at/);
 
 
     return if ($_[0] =~ /^PERL: Subroutine \S+ redefined at/);
 
@@ -174,11 +175,11 @@ sub TODO {
 }
 
 sub VERB {
 }
 
 sub VERB {
-    if (!&IsParam("VERBOSITY")) {
+    if (!&IsParam('VERBOSITY')) {
        # NOTHING.
        # NOTHING.
-    } elsif ($param{'VERBOSITY'} eq "1" and $_[1] <= 1) {
+    } elsif ($param{'VERBOSITY'} eq '1' and $_[1] <= 1) {
        &status($_[0]);
        &status($_[0]);
-    } elsif ($param{'VERBOSITY'} eq "2" and $_[1] <= 2) {
+    } elsif ($param{'VERBOSITY'} eq '2' and $_[1] <= 2) {
        &status($_[0]);
     }
 }
        &status($_[0]);
     }
 }
@@ -206,10 +207,10 @@ sub status {
 
     # if it's not a scalar, attempt to warn and fix.
     my $ref = ref $input;
 
     # if it's not a scalar, attempt to warn and fix.
     my $ref = ref $input;
-    if (defined $ref and $ref ne "") {
+    if (defined $ref and $ref ne '') {
        &WARN("status: 'input' is not scalar ($ref).");
 
        &WARN("status: 'input' is not scalar ($ref).");
 
-       if ($ref eq "ARRAY") {
+       if ($ref eq 'ARRAY') {
            foreach (@$input) {
                &WARN("status: '$_'.");
            }
            foreach (@$input) {
                &WARN("status: '$_'.");
            }
@@ -277,12 +278,12 @@ sub status {
        $status = "[$statcount] ".$input;
     }
 
        $status = "[$statcount] ".$input;
     }
 
-    if (&IsParam("backlog")) {
+    if (&IsParam('backlog')) {
        push(@backlog, $status);        # append to end.
        shift(@backlog) if (scalar @backlog > $param{'backlog'});
     }
 
        push(@backlog, $status);        # append to end.
        shift(@backlog) if (scalar @backlog > $param{'backlog'});
     }
 
-    if (&IsParam("VERBOSITY")) {
+    if (&IsParam('VERBOSITY')) {
        if ($statcountfix) {
            printf $_red."!%6d!".$ob." ", $statcount;
        } else {
        if ($statcountfix) {
            printf $_red."!%6d!".$ob." ", $statcount;
        } else {
@@ -337,19 +338,19 @@ sub status {
     }
 
     # log the line into a file.
     }
 
     # log the line into a file.
-    return unless (&IsParam("logfile"));
+    return unless (&IsParam('logfile'));
     return unless (defined fileno LOG);
 
     # remove control characters from logging to LOGFILE.
     for ($input) {
     return unless (defined fileno LOG);
 
     # remove control characters from logging to LOGFILE.
     for ($input) {
-       last if (&IsParam("logColors"));
+       last if (&IsParam('logColors'));
        s/\e\[[0-9;]+m//g;      # escape codes.
        s/[\cA-\c_]//g;         # control chars.
     }
     $input = "FORK($$) ".$input if ($statcountfix);
 
     my $date;
        s/\e\[[0-9;]+m//g;      # escape codes.
        s/[\cA-\c_]//g;         # control chars.
     }
     $input = "FORK($$) ".$input if ($statcountfix);
 
     my $date;
-    if (&IsParam("logType") and $param{'logType'} =~ /DAILY/i) {
+    if (&IsParam('logType') and $param{'logType'} =~ /DAILY/i) {
        $date = sprintf("%02d:%02d.%02d", (gmtime $time)[2,1,0]);
 
        my ($day,$month,$year) = (gmtime $time)[3,4,5];
        $date = sprintf("%02d:%02d.%02d", (gmtime $time)[2,1,0]);
 
        my ($day,$month,$year) = (gmtime $time)[3,4,5];
@@ -375,9 +376,11 @@ sub debug_perl {
        &status("WARN: cannot open $file: $!");
        return;
     }
        &status("WARN: cannot open $file: $!");
        return;
     }
+    binmode(IN, ":encoding(UTF-8)");
 
     # TODO: better filename.
     open(OUT, ">>debug.log");
 
     # TODO: better filename.
     open(OUT, ">>debug.log");
+    binmode(OUT, ":encoding(UTF-8)");
     print OUT "DEBUG: $str\n";
 
     # note: cannot call external functions because SIG{} does not allow us to.
     print OUT "DEBUG: $str\n";
 
     # note: cannot call external functions because SIG{} does not allow us to.
@@ -412,6 +415,7 @@ sub openSQLDebug {
        delete $param{'SQLDebug'};
        return 0;
     }
        delete $param{'SQLDebug'};
        return 0;
     }
+    binmode(SQLDEBUG, ":encoding(UTF-8)");
 
     &status("Opened SQL Debug file: $param{'SQLDebug'}");
     return 1;
 
     &status("Opened SQL Debug file: $param{'SQLDebug'}");
     return 1;
@@ -424,7 +428,7 @@ sub closeSQLDebug {
 }
 
 sub SQLDebug {
 }
 
 sub SQLDebug {
-    return unless (&IsParam("SQLDebug"));
+    return unless (&IsParam('SQLDebug'));
 
     return unless (fileno SQLDEBUG);
 
 
     return unless (fileno SQLDEBUG);
 
@@ -432,3 +436,5 @@ sub SQLDebug {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index bcbd3282a50665e8c1cfd1d80a21d5cc93b22557..3bb2bfa0057bd59d6374379a1aa5976321ff14d0 100644 (file)
@@ -7,7 +7,7 @@
 
 use strict;
 
 
 use strict;
 
-use vars qw($AUTOLOAD $no_timehires);
+use vars qw($AUTOLOAD $no_timehires $bot_version $bot_release);
 
 ###
 ### REQUIRED MODULES.
 
 ###
 ### REQUIRED MODULES.
@@ -44,7 +44,7 @@ sub loadCoreModules {
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
-       &showProc(" ($_)") if (&IsParam("DEBUG"));
+       &showProc(" ($_)") if (&IsParam('DEBUG'));
     }
 }
 
     }
 }
 
@@ -71,7 +71,7 @@ sub loadDBModules {
 }
 
 sub loadFactoidsModules {
 }
 
 sub loadFactoidsModules {
-    if (!&IsParam("factoids")) {
+    if (!&IsParam('factoids')) {
        &status("Factoid support DISABLED.");
        return;
     }
        &status("Factoid support DISABLED.");
        return;
     }
@@ -88,7 +88,7 @@ sub loadFactoidsModules {
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
-       &showProc(" ($_)") if (&IsParam("DEBUG"));
+       &showProc(" ($_)") if (&IsParam('DEBUG'));
     }
 }
 
     }
 }
 
@@ -115,7 +115,7 @@ sub loadIRCModules {
 
        # hrm... use another config option besides DEBUG to display
        # change in memory usage.
 
        # hrm... use another config option besides DEBUG to display
        # change in memory usage.
-       &status("Loading Modules \"$mod\"") if (!&IsParam("DEBUG"));
+       &status("Loading Modules \"$mod\"") if (!&IsParam('DEBUG'));
        eval "require \"$mod\"";
        if ($@) {
            &ERROR("require \"$mod\" => $@");
        eval "require \"$mod\"";
        if ($@) {
            &ERROR("require \"$mod\" => $@");
@@ -124,7 +124,7 @@ sub loadIRCModules {
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
-       &showProc(" ($_)") if (&IsParam("DEBUG"));
+       &showProc(" ($_)") if (&IsParam('DEBUG'));
     }
 }
 
     }
 }
 
@@ -154,10 +154,17 @@ sub loadMyModulesNow {
 
 ### rename to moduleReloadAll?
 sub reloadAllModules {
 
 ### rename to moduleReloadAll?
 sub reloadAllModules {
-    my $retval = "";
+    my $retval = '';
 
     &VERB("Module: reloading all.",2);
 
 
     &VERB("Module: reloading all.",2);
 
+    # Reload version and save
+    open(VERSION,"<VERSION");
+    $bot_release = <VERSION> || "(unknown version)";
+    chomp($bot_release);
+    $bot_version    = "infobot $bot_release -- $^O";
+    close(VERSION);
+
     # obscure usage of map and regex :)
     foreach (map { s/.*?\/?src/src/; $_ } keys %moduleAge) {
        $retval .= &reloadModule($_);
     # obscure usage of map and regex :)
     foreach (map { s/.*?\/?src/src/; $_ } keys %moduleAge) {
        $retval .= &reloadModule($_);
@@ -171,7 +178,7 @@ sub reloadAllModules {
 sub reloadModule {
     my ($mod)  = @_;
     my $file   = (grep /\/$mod/, keys %INC)[0];
 sub reloadModule {
     my ($mod)  = @_;
     my $file   = (grep /\/$mod/, keys %INC)[0];
-    my $retval = "";
+    my $retval = '';
 
     # don't reload if it's not our module.
     if ($mod =~ /::/ or $mod !~ /pl$/) {
 
     # don't reload if it's not our module.
     if ($mod =~ /::/ or $mod !~ /pl$/) {
@@ -347,3 +354,5 @@ sub getPerlFiles {
 }
 
 1;
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80