]> 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)
-       - 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
-       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)
@@ -29,17 +26,20 @@ FEATURES
        * 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.
 
+
 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.
 
+       As of 1.5.0, blootbot was rebranded back to infobot.
+
+
 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
@@ -77,6 +81,7 @@ welcomed.
 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
@@ -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
 
-### UNTESTED:
+
+UNTESTED:
        - 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
-<dms@users.sourceforge.net>
+<infobot-devel@lists.sourceforge.net>
 
 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
+
+
+# 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:
-       - 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
@@ -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 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
@@ -43,7 +44,7 @@ TODO:
 
 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
@@ -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.
 
--- 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/"
-BACKUP_TDIR="blootbot/"
+BACKUP_TDIR="infobot/"
 BACKUP_FILE="/home/a/apt/public_html/tables.tar.bz2"
 
 pwd
@@ -18,3 +18,5 @@ else
 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";
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 7ed1b0d9e8ddf8e4caa3e4c0c130131adf43e730..a93429a1a26988b52f429c21d51491c403011a8f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 BOTDIR=/home/apt/bot
-BOTNICK=blootbot
+BOTNICK=infobot
 PIDFILE=$BOTDIR/$BOTNICK.pid
 
 if [ -f $PIDFILE ]; then       # exists.
@@ -10,10 +10,12 @@ if [ -f $PIDFILE ]; then    # exists.
        exit 0
     fi
 
-    # blootbot removes the pid file.
+    # infobot removes the pid file.
     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...
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 $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);
+
+# 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;
+
+# 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";
 }
+
+# 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;
 
-my $dsn = "DBI:mysql:blootbot:localhost";
+my $dsn = "DBI:mysql:infobot:localhost";
 my $dbh = DBI->connect($dsn, "USERNAME", "PASSWORD");
 
 my @factkey;
@@ -65,3 +65,5 @@ foreach (keys %factval) {
 }
 
 $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";
 
-&loadConfig($bot_config_dir."/blootbot.config");
+&loadConfig($bot_config_dir."/infobot.config");
 &loadDBModules();
 
 unless (@_) {
@@ -34,3 +34,5 @@ foreach (@_) {
 
     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
-# then modified again for blootbot
+# then modified again for infobot
 
 # 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="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;
@@ -317,9 +317,10 @@ sub main {
 
 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);
-# 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);
 }
 
+# vim:ts=4:sw=4:expandtab:tw=80
index 53f3b7763f29247fbdc3f4f057702cb49e6950b8..bc7fad665b48b7358fb50410d1b13aebed7d7ee9 100755 (executable)
@@ -18,7 +18,7 @@ if (!defined $dbname) {
 }
 
 # open the db.
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 &loadDBModules();
 
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
@@ -45,3 +45,5 @@ $sth->finish;
 
 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");
+
+# 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";
 }
+
+# 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
-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";
     }
 }
+
+# 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";
 }
+
+# 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;
 }
+
+# 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.
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
 &loadDBModules();
 &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
 
@@ -55,3 +55,5 @@ close IN;
 
 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";
 }
+
+# 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";
+
+# 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
-# setup_tables: setup MYSQL/PGSQL side of things for blootbot.
+# setup_tables: setup MYSQL/PGSQL side of things for infobot.
 # written by the xk.
 ###
 
@@ -11,8 +11,8 @@ require "src/CLI/Support.pl";
 
 $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'};
@@ -95,3 +95,5 @@ if ($param{'DBType'} =~ /mysql/i) {
 &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";
-    $who = "local";
-    $orig{who} = "local";
+    $who = 'local';
+    $orig{who} = 'local';
     $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;
-    my $term = new Term::ReadLine 'blootbot';
+    my $term = new Term::ReadLine 'infobot';
     my $prompt = "$who> ";
     #$OUT = $term->OUT || STDOUT;
     while ( defined ($_ = $term->readline($prompt)) ) {
@@ -47,7 +47,7 @@ sub msg {
     }
 
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &WARN("msg: msg == $msg.");
        return;
     }
@@ -101,3 +101,5 @@ sub performAddressedReply {
 }
 
 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();
-    my $select = 'nick,time,channel,host,message,messagecount';
+    my $select = 'nick,time,channel,host,message';
     if ($person eq 'random') {
        @seen = &randKey('seen', $select);
     } else {
@@ -363,7 +363,7 @@ sub seen {
 
        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);
@@ -453,7 +453,7 @@ sub convert {
        return;
     }
 
-    &NewUnits::convertUnits($from, $to);
+    &Units::convertUnits($from, $to);
 
     return;
 }
@@ -481,7 +481,7 @@ sub lart {
        $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;
@@ -644,11 +644,6 @@ sub do_text_counters {
        $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;
@@ -657,27 +652,21 @@ sub do_text_counters {
        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*$/) {
-       # this is way ugly.
 
-       # TODO: convert $where to hash
+       # get top 3 stats of $type in $chan
        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;
@@ -702,34 +691,32 @@ sub do_text_counters {
            &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;
        }
 
-       # 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;
        }
-       $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);
@@ -739,101 +726,6 @@ sub do_text_counters {
     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);
@@ -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('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') );
@@ -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('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' ) );
@@ -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('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') );
@@ -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('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') );
@@ -914,3 +808,5 @@ sub nullski {
 &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 {
-    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.");
@@ -64,7 +67,7 @@ sub readUserFile {
        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;
            }
@@ -75,7 +78,7 @@ sub readUserFile {
            }
 
            # nice little hack.
-           if ($what eq "HOSTS") {
+           if ($what eq 'HOSTS') {
                $users{$nick}{$what}{$val} = 1;
            } else {
                $users{$nick}{$what} = $val;
@@ -86,9 +89,9 @@ sub readUserFile {
 
        } 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);
@@ -101,9 +104,9 @@ sub readUserFile {
 
        } 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);
@@ -129,14 +132,14 @@ sub writeUserFile {
        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);
 
-    print OUT "#v1: blootbot -- $ident -- written $time\n\n";
+    print OUT "#v1: infobot -- $ident -- written $time\n\n";
 
     ### USER LIST.
     my $cusers = 0;
@@ -155,7 +158,7 @@ sub writeUserFile {
            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";
                }
@@ -235,7 +238,10 @@ sub writeUserFile {
 #####
 
 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~";
@@ -304,13 +310,13 @@ sub writeChanFile {
        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);
-    print OUT "#v1: blootbot -- $ident -- written $time\n\n";
+    print OUT "#v1: infobot -- $ident -- written $time\n\n";
 
     if ($flag_quit) {
 
@@ -407,7 +413,7 @@ sub writeChanFile {
 # TODO: return all flags for opers
 sub IsFlag {
     my $flags = shift;
-    my ($ret, $f, $o) = "";
+    my ($ret, $f, $o) = '';
 
     &verifyUser($who, $nuh);
 
@@ -432,7 +438,7 @@ sub verifyUser {
        return $userHandle;
     }
 
-    $userHandle = "";
+    $userHandle = '';
 
     foreach $user (keys %users) {
        next if ($user eq "_default");
@@ -453,7 +459,7 @@ sub verifyUser {
            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).");
@@ -472,10 +478,10 @@ sub verifyUser {
 sub ckpasswd {
     # returns true if arg1 encrypts to arg2
     my ($plain, $encrypted) = @_;
-    if ($encrypted eq "") {
+    if ($encrypted eq '') {
        ($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;
@@ -508,8 +514,8 @@ sub hasFlag {
 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;
 
@@ -603,7 +609,7 @@ sub userDel {
 sub banAdd {
     my($mask,$chan,$expire,$reason) = @_;
 
-    $chan      ||= "*";
+    $chan      ||= '*';
     $expire    ||= 0;
 
     if ($expire > 0) {
@@ -615,7 +621,7 @@ sub banAdd {
                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;
@@ -722,7 +728,7 @@ sub chanSet {
        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;
            }
@@ -739,14 +745,16 @@ sub chanSet {
        }
 
        # 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};
+           delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
        } else {
            &performStrictReply("Setting $what for $chan to '$val'$was.");
            $chanconf{$chan}{$what}     = $val;
+           delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
        }
 
        $update++;
@@ -759,10 +767,11 @@ sub chanSet {
            &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;
+       delete $cache{ircTextCounters} if $what eq 'ircTextCounters';
 
        $update++;
 
@@ -826,19 +835,22 @@ sub rehashConfVars {
 
 my @regFlagsUser = (
        # possible chars to include in FLAG
-       "A",    # bot administration over /msg
+       'A',    # bot administration over /msg
                        # 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
-       "r",    # remove factoid.
-       "t",    # teach/add factoid.
+       'r',    # remove factoid.
+       't',    # teach/add factoid.
+       's',    # Bypass +silent on channels
 );
 
 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.
-       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;
@@ -79,7 +79,7 @@ sub validFactoid {
        /\\\%/ 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.
@@ -123,9 +123,9 @@ sub FactoidStuff {
            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';
@@ -140,8 +140,8 @@ sub FactoidStuff {
        return 'forget: no addr' unless ($addressed);
 
        my $faqtoid = $message;
-       if ($faqtoid eq "") {
-           &help("forget");
+       if ($faqtoid eq '') {
+           &help('forget');
            return;
        }
 
@@ -155,22 +155,22 @@ sub FactoidStuff {
        }
 
        # 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);
-       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 $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;
        }
@@ -198,16 +198,16 @@ sub FactoidStuff {
        # 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");
-           @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 $v = &getFactInfo($f, "factoid_value");
+           my $v = &getFactInfo($f, 'factoid_value');
            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) {
-               &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!
 
-       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));
-           ### 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*$/) {
@@ -260,9 +260,9 @@ sub FactoidStuff {
                        &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 {
@@ -289,16 +289,16 @@ sub FactoidStuff {
        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 ($faqtoid eq "") {
-           &help("unforget");
+       if ($faqtoid eq '') {
+           &help('unforget');
            return;
        }
 
@@ -316,9 +316,9 @@ sub FactoidStuff {
            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?
@@ -339,19 +339,19 @@ sub FactoidStuff {
        my $function = lc $1;
        my $faqtoid  = lc $4;
 
-       if ($faqtoid eq "") {
+       if ($faqtoid eq '') {
            &help($function);
            return;
        }
 
-       if (&getFactoid($faqtoid) eq "") {
+       if (&getFactoid($faqtoid) eq '') {
            &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
-           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;
@@ -369,8 +369,8 @@ sub FactoidStuff {
     if ($message =~ s/^rename(\s+|$)//) {
        return 'rename: no addr' unless ($addressed);
 
-       if ($message eq "") {
-           &help("rename");
+       if ($message eq '') {
+           &help('rename');
            return;
        }
 
@@ -384,7 +384,7 @@ sub FactoidStuff {
            }
 
            # 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;
            }
@@ -394,7 +394,7 @@ sub FactoidStuff {
                return;
            }
 
-           &setFactInfo($from,"factoid_key",$to);
+           &setFactInfo($from,'factoid_key',$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;
 
-           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");
@@ -433,17 +433,17 @@ sub FactoidStuff {
                    return;
                }
                # min length.
-               my $faqauth = &getFactInfo($faqtoid, "created_by");
+               my $faqauth = &getFactInfo($faqtoid, 'created_by');
                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.");
                }
 
-               &setFactInfo($faqtoid, "factoid_value", $result);
+               &setFactInfo($faqtoid, 'factoid_value', $result);
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
-               &performReply("OK");
+               &performReply('OK');
            } else {
                &performReply("that doesn't contain '$op'");
            }
@@ -460,7 +460,7 @@ sub FactoidStuff {
        # 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;
@@ -501,7 +501,7 @@ sub FactoidStuff {
        &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");
@@ -540,3 +540,5 @@ sub FactoidStuff {
 }
 
 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 {
-    &sqlSet("factoids",
+    &sqlSet('factoids',
        { factoid_key => $_[0] },
        { $_[1] => $_[2] }
     );
@@ -19,13 +19,13 @@ sub setFactInfo {
 #####
 # 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 {
-    return &getFactInfo($_[0], "factoid_value");
+    return &getFactInfo($_[0], 'factoid_value');
 }
 
 #####
@@ -33,7 +33,7 @@ sub getFactoid {
 sub delFactoid {
     my ($faqtoid) = @_;
 
-    &sqlDelete("factoids", { factoid_key => $faqtoid } );
+    &sqlDelete('factoids', { factoid_key => $faqtoid } );
     &status("DELETED $faqtoid");
 
     return 1;
@@ -43,10 +43,10 @@ sub delFactoid {
 # 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;
        }
@@ -59,7 +59,7 @@ sub IsLocked {
 # 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) {
@@ -83,8 +83,8 @@ sub AddModified {
     }
     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;
 }
@@ -98,28 +98,28 @@ sub AddModified {
 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;
     }
 
-    $thisnuh ||= &getFactInfo($faqtoid,"created_by");
+    $thisnuh ||= &getFactInfo($faqtoid,'created_by');
 
     # 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");
-    &setFactInfo($faqtoid,"locked_by",$nuh);
-    &setFactInfo($faqtoid,"locked_time", time());
+    &setFactInfo($faqtoid,'locked_by',$nuh);
+    &setFactInfo($faqtoid,'locked_time', time());
 
     return 1;
 }
@@ -129,23 +129,25 @@ sub CmdLock {
 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 ($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");
-    &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;
+
+# 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) {
-           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;
@@ -101,3 +101,5 @@ sub switchPerson {
 }
 
 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)      = @_;
-    local($reply)      = "";
+    local($reply)      = '';
     local $finalQMark  = $query =~ s/\?+\s*$//;
     $finalQMark                += $query =~ s/\?\s*$//;
     $query             =~ s/^\s+|\s+$//g;
@@ -29,12 +29,11 @@ sub doQuestion {
        return '';
     }
 
-    my $questionWord   = "";
+    my $questionWord   = '';
 
     if (!$addressed) {
-       return ''; #never respond if we're not addressed
        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?
@@ -42,7 +41,7 @@ sub doQuestion {
 
        # 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;
        }
@@ -88,13 +87,13 @@ sub doQuestion {
        $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);
 
-    if (&IsChanConf("factoidArguments") > 0) {
+    if (&IsChanConf('factoidArguments') > 0) {
        $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);
-       next if (!defined $result or $result eq "");
+       next if (!defined $result or $result eq '');
 
        # 'see also' factoid redirection support.
 
@@ -139,7 +138,7 @@ sub doQuestion {
 
                return;
            }
-           last if (!defined $newr or $newr eq "");
+           last if (!defined $newr or $newr eq '');
            $result  = $newr;
        }
 
@@ -163,13 +162,13 @@ sub doQuestion {
 ###    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 ($addressed and $reply eq "") {
+       if ($addressed and $reply eq '') {
            &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");
@@ -190,9 +189,9 @@ sub factoidArgs {
 #    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[\#\/\:]/;
-    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) );
@@ -239,9 +238,9 @@ sub factoidArgs {
        }
 
        # 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++;
-       &sqlSet("factoids", {'factoid_key' => $q}, {
+       &sqlSet('factoids', {'factoid_key' => $q}, {
                requested_by    => $nuh,
                requested_time  => time(),
                requested_count => $count
@@ -288,8 +287,8 @@ sub factoidArgs {
            $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;
 
@@ -303,3 +302,5 @@ sub factoidArgs {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 0278f32469322c3c83b8e7a5588b5b6f6b1dba64..ec3649bfa1f13ea694e987853bf28a7e02eae846 100644 (file)
@@ -46,7 +46,7 @@ sub getReply {
        } else {
            $factoid = "$search $message";
        }
-       ($count, $fauthor, $result) = &sqlSelect("factoids",
+       ($count, $fauthor, $result) = &sqlSelect('factoids',
            "requested_count,created_by,factoid_value",
            { factoid_key => $factoid }
        );
@@ -55,7 +55,7 @@ sub getReply {
 
     if ($result) {
        $lhs = $message;
-       $mhs = "is";
+       $mhs = 'is';
        $rhs = $result;
 
        return "\"$factoid\" $mhs \"$rhs\"" if ($literal);
@@ -76,7 +76,7 @@ sub getReply {
     $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
 
@@ -84,7 +84,7 @@ sub getReply {
        ### 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
@@ -92,9 +92,9 @@ sub getReply {
 
        # 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 (&IsFlag("n"));
+#      $real++ if (&IsFlag('n'));
        $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 '||'.
-           if ($mhs eq "is") {
+           if ($mhs eq 'is') {
                $reply = &getRandom(keys %{ $lang{'factoid'} });
                $reply =~ s/##KEY/$lhs/;
                $reply =~ s/##VALUE/$result/;
@@ -125,7 +125,13 @@ sub getReply {
                $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/) {
-       my $factoids = &countKeys("factoids");
+       my $factoids = &countKeys('factoids');
        $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 ".
-               &fixPlural("question", $count{'Question'});
+               &fixPlural('question', $count{'Question'});
        $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/;
     }
 
@@ -359,3 +365,5 @@ sub substVars {
 }
 
 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);
 
-    my($urlType) = "";
+    my($urlType) = '';
 
     # 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:/);
@@ -40,12 +40,12 @@ sub doStatement {
     }
 
     # acceptUrl.
-    if (&IsParam("acceptUrl")) {
+    if (&IsParam('acceptUrl')) {
        if ($param{'acceptUrl'} eq 'REQUIRE') {         # require url type.
-           return if ($urlType eq "");
+           return if ($urlType eq '');
        } 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
        }
@@ -56,7 +56,7 @@ sub doStatement {
        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;
@@ -67,7 +67,7 @@ sub doStatement {
        $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";
        }
 
@@ -86,7 +86,7 @@ sub doStatement {
 
        &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;
 
@@ -108,7 +108,9 @@ sub doStatement {
        return if (&update($lhs, $mhs, $rhs));
     }
 
-    return "CONTINUE";
+    return 'CONTINUE';
 }
 
 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.
-    if (&IsParam("profanityCheck") and &hasProfanity($rhs)) {
+    if (&IsParam('profanityCheck') and &hasProfanity($rhs)) {
        &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;
@@ -54,7 +54,7 @@ sub update {
 
     # 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'.");
@@ -87,23 +87,23 @@ sub update {
        # 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'}++;
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
-       &sqlReplace("factoids", {
+       &sqlInsert('factoids', {
                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.");
        }
 
@@ -190,21 +190,20 @@ sub update {
            }
        }
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
        $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,
        } );
 
-       if (!defined $rhs or $rhs eq "") {
+       if (!defined $rhs or $rhs eq '') {
            &ERROR("Update: rhs1 == NULL.");
        }
-    } else {                           # not "also"
+    } else {                           # not 'also'
 
        if (!$correction_plausible) {   # "no, blah is ..."
            if ($addressed) {
@@ -214,28 +213,27 @@ sub update {
            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;
        }
 
-       &performAddressedReply("okay");
+       &performAddressedReply('okay');
 
        $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,
        } );
 
-       if (!defined $rhs or $rhs eq "") {
+       if (!defined $rhs or $rhs eq '') {
            &ERROR("Update: rhs1 == NULL.");
        }
     }
@@ -244,3 +242,5 @@ sub update {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ffd8deaee7057236b55fef7c01f39250c37a6ec2..91610b6bf2e161f0f854321dfbc405d786d5f714 100644 (file)
@@ -26,7 +26,7 @@ sub loadLang {
 
     while (<FILE>) {
        chop;
-       if ($_ eq "" || /^#/) {
+       if ($_ eq '' || /^#/) {
            undef $replyName;
            next;
        }
@@ -53,7 +53,7 @@ sub loadLang {
 
 # File: Irc Servers list.
 sub loadIRCServers {
-    my ($file) = $bot_config_dir."/blootbot.servers";
+    my ($file) = $bot_config_dir."/infobot.servers";
     @ircServers = ();
     %ircPort = ();
 
@@ -81,3 +81,5 @@ sub loadIRCServers {
 }
 
 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;
 
+# Keep track of last time we displayed Chans: to avoid spam in logs
+my $lastChansTime = 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
-    #$irc->addfh(STDIN, \&on_stdin, "r");
+    #$irc->addfh(STDIN, \&on_stdin, 'r');
 
     &status("starting main loop");
 
@@ -193,7 +196,7 @@ sub rawout {
     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;
@@ -208,11 +211,17 @@ sub say {
     my ($msg) = @_;
     my $mynick = $conn->nick();
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &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)) {
@@ -226,7 +235,7 @@ sub say {
 
     return unless (&whatInterface() =~ /IRC/);
 
-    $msg = "zero" if ($msg =~ /^0+$/);
+    $msg = 'zero' if ($msg =~ /^0+$/);
 
     my $t = time();
 
@@ -234,8 +243,8 @@ sub say {
        $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;
@@ -261,11 +270,18 @@ sub msg {
     }
 
     if (!defined $msg) {
-       $msg ||= "NULL";
+       $msg ||= 'NULL';
        &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/);
@@ -275,8 +291,8 @@ sub 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) {
@@ -302,6 +318,12 @@ sub action {
        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);
@@ -327,8 +349,8 @@ sub notice {
        $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;
@@ -464,8 +486,8 @@ sub dcc_close {
 
 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...
@@ -490,7 +512,7 @@ sub part {
     my $chan;
 
     foreach $chan (@_) {
-       next if ($chan eq "");
+       next if ($chan eq '');
        $chan =~ tr/A-Z/a-z/;   # lowercase.
 
        if ($chan !~ /^$mask{chan}$/) {
@@ -526,24 +548,24 @@ sub mode {
 
 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) = @_;
-    my $os = "o" x scalar(@who);
+    my $os = 'o' x scalar(@who);
 
     &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();
 
-    if ($chan ne "" and &validChan($chan) == 0) {
+    if ($chan ne '' and &validChan($chan) == 0) {
        &ERROR("kick: invalid channel $chan.");
        return;
     }
@@ -700,7 +722,7 @@ sub joinNextChan {
     }
 
     # chanserv check: global channels, in case we missed one.
-    foreach ( &ChanConfList("chanServ_ops") ) {
+    foreach ( &ChanConfList('chanServ_ops') ) {
        &chanServCheck($_);
     }
 }
@@ -820,26 +842,35 @@ sub clearIRCVars {
 }
 
 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;
 
+    # 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) {
-       next if ($_ eq "_default");
+       next if ($_ eq '_default');
 
        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;
@@ -861,8 +892,8 @@ sub getJoinChans {
     }
 
     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);
@@ -896,7 +927,7 @@ sub closeDCC {
 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.");
@@ -960,3 +991,5 @@ sub getHostMask {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ad5ec8ba52ae3c42e82fb9d6108dba80113ff4ec..4f64ca41b1e38f3f936eb72852bb7354b75bad79 100644 (file)
 #####
 # 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;
-    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.
-               $skipmessage++ if ($2 ne "" and $2 !~ /^ /);
+               $skipmessage++ if ($2 ne '' and $2 !~ /^ /);
            }
        }
     }
 
     # Determine floodwho.
-    my $c      = "_default";
+    my $c      = '_default';
     if ($msgType =~ /public/i) {
        # public.
        $floodwho = $c = lc $chan;
@@ -141,14 +138,14 @@ sub hookMsg {
        &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;
 
-       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) {
@@ -161,7 +158,7 @@ sub hookMsg {
            return if ($lobotomized);
 
            if (!scalar @who) {
-               push(@who,"Someone");
+               push(@who,'Someone');
            }
            &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");
-       } 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();
-    } 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.
@@ -198,7 +195,7 @@ sub hookMsg {
        @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.
@@ -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;";
+       $sedmsg =~ s/^(.{255}).*$/$1.../; # 255 char max to prevent flood
+
        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'}++;
     }
-    if (&IsChanConf("minVolunteerLength") > 0) {
+    if (&IsChanConf('minVolunteerLength') > 0) {
        # FIXME hack to treat unaddressed as if using addrchar
        $addrchar = 1;
     }
@@ -310,7 +309,7 @@ sub chanLimitVerify {
     $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.");
@@ -324,9 +323,9 @@ sub chanLimitVerify {
     }
 
     # 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 $int   = &getChanConfDefault("chanlimitcheckInterval", 10, $chan);
+    my $int   = &getChanConfDefault('chanlimitcheckInterval', 10, $chan);
 
     my $delta = $count + $plus - $l;
 #   $delta    =~ s/^\-//;
@@ -361,30 +360,26 @@ sub chanServCheck {
        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);
 
-    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()?
-    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)");
-    &rawout("PRIVMSG ChanServ :OP $chan $ident");
+    &msg('ChanServ', "OP $chan");
     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) = @_;
-    my ($nick, @args) = ($event->nick, $event->args);
+    my ($nick, $args) = ($event->nick, $event->args);
     my $chan = ($event->to)[0];
 
-    shift @args;
-
     if ($chan eq $ident) {
-       &status("* [$nick] @args");
+       &status("* [$nick] $args");
     } 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.
-    $userHandle                = "";   # reset.
+    $userHandle                = '';   # reset.
     $who               = lc $nick;
     $message           = $msg;
     $orig{who}         = $nick;
@@ -66,7 +64,7 @@ sub on_chat {
        my $crypto      = $users{$userHandle}{PASS};
        my $success     = 0;
 
-       if ($userHandle eq "_default") {
+       if ($userHandle eq '_default') {
            &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.");
 
-           &dccStatus(2) unless (exists $sched{"dccStatus"}{RUNNING});
+           &dccStatus(2) unless (exists $sched{'dccStatus'}{RUNNING});
 
            $success++;
 
@@ -103,7 +101,7 @@ sub on_chat {
 
            $dcc{'CHATvrfy'}{$nick} = $userHandle;
 
-           return if ($userHandle eq "_default");
+           return if ($userHandle eq '_default');
 
            &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}");
        }
@@ -117,7 +115,7 @@ sub on_chat {
        ### TODO: make use of &Forker(); here?
        &loadMyModule('UserDCC');
 
-       &DCCBroadcast("#$who# $message","m");
+       &DCCBroadcast("#$who# $message",'m');
 
        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.");
-       $users{_default}{FLAGS} = "amrt";
+       $users{_default}{FLAGS} = 'amrt';
        $users{_default}{HOSTS}{"*!*@*"} = 1;
     }
 
@@ -183,11 +181,11 @@ sub on_endofmotd {
     }
 
     if ($firsttime) {
-       &ScheduleThis(1, "setupSchedulers");
+       &ScheduleThis(1, 'setupSchedulers');
        $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 +");
@@ -204,7 +202,7 @@ sub on_endofmotd {
     $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'}");
     }
@@ -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") {
-           &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);
        }
@@ -355,7 +353,7 @@ sub on_dcc_open_chat {
     $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;
@@ -365,7 +363,7 @@ sub on_dcc_open_chat {
        &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();
-    &ScheduleThis(1, "ircCheck");
+    &ScheduleThis(1, 'ircCheck');
 }
 
 sub on_endofnames {
@@ -420,13 +418,13 @@ sub on_endofnames {
 
     my $txt;
     my @array;
-    foreach ("o","v","") {
+    foreach ('o','v','') {
        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");
     }
@@ -477,17 +475,17 @@ sub on_join {
     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;
 
-    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'}++;
-    $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);
@@ -518,7 +516,7 @@ sub on_join {
 
     # 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");
 
@@ -529,7 +527,7 @@ sub on_join {
     ### 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 = $_;
@@ -544,7 +542,7 @@ sub on_join {
        }
 
        my $reason = "no reason";
-       foreach ($chan, "*") {
+       foreach ($chan, '*') {
            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.
-    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");
@@ -670,7 +668,7 @@ sub on_msg {
     $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;
@@ -678,9 +676,9 @@ sub on_msg {
     }
 
     &hookMsg('private', undef, $nick, $msg);
-    $who       = "";
-    $chan      = "";
-    $msgType   = "";
+    $who       = '';
+    $chan      = '';
+    $msgType   = '';
 }
 
 sub on_names {
@@ -739,7 +737,7 @@ sub on_nick_taken {
     $conn = shift(@_);
     my $nick   = $conn->nick();
     #my $newnick = $nick . int(rand 10);
-    my $newnick = $nick . "_";
+    my $newnick = $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 (&IsParam("nickServ_pass")) {
+           if (&IsParam('nickServ_pass')) {
                &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;
 
-           foreach ( &ChanConfList("chanServ_ops") ) {
+           foreach ( &ChanConfList('chanServ_ops') ) {
                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;
-    $msgType   = "public";
+    $msgType   = 'public';
 
     if (!exists $channels{$chan}) {
        &DEBUG("on_part: found out $mynick is on $chan!");
@@ -840,7 +838,7 @@ sub on_part {
        &clearChanVars($chan);
     }
 
-    if (!&IsNickInAnyChan($nick) and &IsChanConf("seenStats") > 0) {
+    if (!&IsNickInAnyChan($nick) and &IsChanConf('seenStats') > 0) {
        delete $userstats{lc $nick};
     }
 
@@ -880,7 +878,7 @@ sub on_public {
     $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;
@@ -894,7 +892,7 @@ sub on_public {
     $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();
     }
@@ -903,7 +901,7 @@ sub on_public {
     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);
     }
@@ -913,11 +911,11 @@ sub on_public {
        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.
-       my ($v,$t) = &sqlSelect("stats", "counter,time", {
+       my ($v,$t) = &sqlSelect('stats', "counter,time", {
                        nick    => $who,
                        type    => $x,
                        channel => $c,
@@ -925,9 +923,8 @@ sub on_public {
        $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,
@@ -938,9 +935,9 @@ sub on_public {
 
     &hookMsg('public', $chan, $nick, $msg);
     $chanstats{$chan}{'PublicMsg'}++;
-    $who       = "";
-    $chan      = "";
-    $msgType   = "";
+    $who       = '';
+    $chan      = '';
+    $msgType   = '';
 }
 
 sub on_quit {
@@ -950,7 +947,7 @@ sub on_quit {
     my $reason = ($event->args)[0];
 
     # hack for ICC.
-    $msgType   = "public";
+    $msgType   = 'public';
     $who       = $nick;
 ###    $chan   = $reason;      # no.
 
@@ -974,7 +971,7 @@ sub on_quit {
 
        # 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.");
@@ -1001,7 +998,7 @@ sub on_quit {
        # 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};
     ###
 
@@ -1280,3 +1277,5 @@ sub on_stdin {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 1327833e457e29ef50dcf9bb45815c2c4d432837..18c649d384eb9a9b7c056181bbe633dc7fa65317 100644 (file)
@@ -18,7 +18,7 @@ use vars qw(%sched %schedule);
 # )
 
 #%schedule = {
-#      uptimeLoop => ("", 60, 1),
+#      uptimeLoop => ('', 60, 1),
 #};
 
 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);
+    &rssFeeds(2);
 
     # 1 for run straight away
     &uptimeLoop(1);
@@ -99,7 +100,8 @@ sub setupSchedulers {
 
 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.");
@@ -124,17 +126,33 @@ sub ScheduleThis {
 #### 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 {
-    my $interval = &getChanConfDefault("randomQuoteInterval", 60, $chan);
+    my $interval = &getChanConfDefault('randomQuoteInterval', 60, $chan);
     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($_));
 
-       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;
@@ -151,18 +169,18 @@ sub randomFactoid {
     my ($key,$val);
     my $error = 0;
 
-    my $interval = &getChanConfDefault("randomFactoidInterval", 60, $chan);
+    my $interval = &getChanConfDefault('randomFactoidInterval', 60, $chan);
     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) {
-           ($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:/));
@@ -181,13 +199,13 @@ sub randomFactoid {
 
 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 (&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'}) {
@@ -250,18 +268,16 @@ sub logLoop {
 
 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?
-    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.
-    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) {
@@ -280,7 +296,7 @@ sub seenFlushOld {
            while (my @row = $sth->fetchrow_array) {
                my ($nick,$time) = @row;
 
-               &sqlDelete("seen", { nick => $nick } );
+               &sqlDelete('seen', { nick => $nick } );
                $delete++;
            }
            $sth->finish;
@@ -294,8 +310,8 @@ sub seenFlushOld {
 
 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')) {
@@ -371,25 +387,25 @@ sub newsFlush {
 }
 
 sub chanlimitCheck {
-    my $interval = &getChanConfDefault("chanlimitcheckInterval", 10, $chan);
+    my $interval = &getChanConfDefault('chanlimitcheckInterval', 10, $chan);
     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));
 
-       if ($chan eq "_default") {
+       if ($chan eq '_default') {
            &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'};
 
@@ -443,8 +459,8 @@ sub netsplitCheck {
     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'}++;
@@ -491,9 +507,10 @@ sub netsplitCheck {
     }
 
     # 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?");
@@ -520,12 +537,12 @@ sub floodLoop {
     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 $interval       = &getChanConfDefault("floodCycle",60, $chan);
+    my $interval       = &getChanConfDefault('floodCycle',60, $chan);
 
     foreach $who (keys %flood) {
        foreach (keys %{ $flood{$who} }) {
@@ -545,29 +562,25 @@ sub floodLoop {
 
 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;
-    $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) {
-           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'},
-                       messagecount => $lastcount+$seencache{$nick}{'msgcount'},
-                                               
            } );
 
            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{'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);
 }
@@ -593,8 +606,8 @@ sub leakCheck {
     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()
@@ -649,8 +662,8 @@ sub leakCheck {
 
 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();
@@ -677,8 +690,8 @@ sub ignoreCheck {
 
 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;
@@ -686,17 +699,13 @@ sub ircCheck {
        $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();
        }
 
-    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?
@@ -708,28 +717,28 @@ sub ircCheck {
            } else {
                &status('ircCheck: possible lost in space; checking.'.
                    scalar(gmtime) );
-               &msg($mynick, "TEST");
+               &msg($mynick, 'TEST');
                $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 (@_) {
-       &ScheduleThis(120, "miscCheck");
-       return if ($_[0] eq "2");       # defer.
+       &ScheduleThis(7200, 'miscCheck'); # every 2 hours
+       return if ($_[0] eq '2');       # defer.
     }
 
     # SHM check.
@@ -763,9 +772,9 @@ sub miscCheck {
     }
 
     # 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} }) {
@@ -796,7 +805,7 @@ sub miscCheck {
            # 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;
        }
 
@@ -807,8 +816,8 @@ sub miscCheck {
 
 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.
@@ -853,8 +862,8 @@ sub getNickInUse {
 #    }
 #
 #    if (@_) {
-#      &ScheduleThis(30, "getNickInUse");
-#      return if ($_[0] eq "2");       # defer.
+#      &ScheduleThis(30, 'getNickInUse');
+#      return if ($_[0] eq '2');       # defer.
 #    }
 #
 #    &nick( $param{'ircNick'} );
@@ -865,7 +874,7 @@ sub uptimeLoop {
 #    return unless &IsParam('Uptime');
 
     if (@_) {
-       &ScheduleThis(60, 'uptimeLoop');
+       &ScheduleThis(3600, 'uptimeLoop'); # once per hour
        return if ($_[0] eq '2');       # defer.
     }
 
@@ -875,8 +884,8 @@ sub uptimeLoop {
 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');
@@ -898,8 +907,8 @@ sub slashdotLoop {
 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');
@@ -920,14 +929,14 @@ sub plugLoop {
 
 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);
 
-    &Forker("Kernel", sub {
+    &Forker('Kernel', sub {
        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");
-       &ban("*!*\@$host", "") if &IsChanConf('wingateBan') > 0;
+       &ban("*!*\@$host", '') if &IsChanConf('wingateBan') > 0;
 
        my $reason      = &getChanConf('wingateKick');
 
        next unless ($reason);
-       &kick($who, "", $reason)
+       &kick($who, '', $reason)
     }
 
     ### RUN CACHE OF TRIED WINGATES.
@@ -978,8 +987,8 @@ sub wingateCheck {
 ### 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);
@@ -1010,21 +1019,21 @@ sub wingateWriteFile {
 
 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) {
-       # disable it since it's "illegal".
+       # disable it since it's 'illegal'.
        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) {
@@ -1055,8 +1064,8 @@ sub dccStatus {
     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()) );
@@ -1117,9 +1126,9 @@ sub mkBackup {
        return;
     }
 
-    my $age    = "New";
+    my $age    = 'New';
     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 {
@@ -1134,3 +1143,5 @@ sub mkBackup {
 }
 
 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;
-    my $file  = $bot_data_dir."/blootbot.help";
+    my $file  = $bot_data_dir."/infobot.help";
     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): $!");
@@ -39,12 +39,12 @@ sub help {
        $val =~ s/__/\037/g;
        $val =~ s/==/        /;
 
-       $help{$key}  = ""                if (!exists $help{$key});
+       $help{$key}  = ''                if (!exists $help{$key});
        $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;
@@ -165,7 +165,7 @@ sub formListReply {
 # Usage: &IJoin(@array);
 sub IJoin {
     if (!scalar @_) {
-       return "NULL";
+       return 'NULL';
     } elsif (scalar @_ == 1) {
        return $_[0];
     } else {
@@ -177,10 +177,10 @@ sub IJoin {
 # Usage: &Time2String(seconds);
 sub Time2String {
     my ($time) = @_;
-    my $prefix = "";
+    my $prefix = '';
     my (@s, @t);
 
-    return "NULL" if (!defined $time);
+    return 'NULL' if (!defined $time);
     return $time  if ($time !~ /\d+/);
 
     if ($time < 0) {
@@ -279,24 +279,24 @@ sub fixPlural {
        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$/) {
-               $str .= "s";    # eg: "money" => "moneys".
+               $str .= 's';    # eg: 'money' => 'moneys'.
            } else {
                $str =~ s/y$/ies/;
            }
        }
     } else {
-       $str .= "s"     if ($int != 1);
+       $str .= 's'     if ($int != 1);
     }
 
     return $str;
@@ -367,36 +367,28 @@ sub getRandom {
     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 {
-    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 {
-           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'.");
-       return 1 if ($thisnuh eq "");
+       return 1 if ($thisnuh eq '');
        return 0;
     }
 
@@ -501,7 +493,7 @@ sub isFileUpdated {
 # 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");
@@ -548,7 +540,7 @@ sub makeRandom {
 
 sub checkMsgType {
     my ($reply) = @_;
-    return unless (&IsParam("minLengthBeforePrivate"));
+    return unless (&IsParam('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);
 
-    if (&IsParam("forking") and $$ == $bot_pid) {
+    if (&IsParam('forking') and $$ == $bot_pid) {
        return unless &addForked($label);
 
        $SIG{CHLD} = 'IGNORE';
@@ -655,13 +647,13 @@ sub mkcrypt {
 }
 
 sub closeStats {
-    return unless (&getChanConfList("ircTextCounters"));
+    return unless (&getChanConfList('ircTextCounters'));
 
     foreach (keys %cmdstats) {
        my $type        = $_;
-       my $i   = &sqlSelect("stats", "counter", {
+       my $i   = &sqlSelect('stats', 'counter', {
                nick    => $type,
-               type    => "cmdstats",
+               type    => 'cmdstats',
        } );
        my $z   = 0;
        $z++ unless ($i);
@@ -669,9 +661,8 @@ sub closeStats {
        $i      += $cmdstats{$type};
 
 
-       &sqlReplace("stats", {
-           nick        => $type,
-           type        => "cmdstats",
+       &sqlSet('stats', {'nick' => $type}, {
+           type        => 'cmdstats',
            'time'      => time(),
            counter     => $i,
        } );
@@ -679,3 +670,5 @@ sub closeStats {
 }
 
 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;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $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) =
-                               unpack("A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2", $flags);
+                               unpack('A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2', $flags);
                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;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(5);
 
@@ -96,7 +96,7 @@ sub list17 {
                                $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;
@@ -120,8 +120,8 @@ sub querytext {
                &::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;
 
@@ -154,26 +154,26 @@ sub querytext {
        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
-       if ($version eq "BZFS0026") {
+       if ($version eq 'BZFS0026') {
                # 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
-               print S1 pack("n2", 0, 0x7167);
+               print S1 pack('n2', 0, 0x7167);
 
                # 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);
-                 ($infolen, $infocode) = unpack("n2", $buffer);
+                 ($infolen, $infocode) = unpack('n2', $buffer);
                }
                $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,
-                       $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
-               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;
-               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;
@@ -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;
-                       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) ";
@@ -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) =
-                                       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;
@@ -227,10 +227,10 @@ sub querytext {
                # 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
-               print S1 pack("n2", 0, 0x7167);
+               print S1 pack('n2', 0, 0x7167);
 
                # 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,
-                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer);
+                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer);
                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;
-               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;
@@ -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;
-                       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) ";
@@ -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) =
-                                       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;
@@ -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;
-               my ($reconnect) = unpack("n", $buffer);
+               my ($reconnect) = unpack('n', $buffer);
                $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
-               print S pack("n2", 0, 0x7167);
+               print S pack('n2', 0, 0x7167);
 
                # 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,
-                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer);
+                       $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer);
                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;
-               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;
-                       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;
@@ -357,4 +357,5 @@ sub query {
 }
 
 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 $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';
+# EDIT THIS (i386, amd64, powerpc, [etc.]):
+my $arch = "i386";
 
 # format: "alias=real".
 my %dists      = (
@@ -42,55 +44,43 @@ my %archived_dists = (
 );
 
 my %archiveurlcontents = (
-       "Contents-##DIST-i386.gz" =>
+       "Contents-##DIST-$arch.gz" =>
                "$protocol://debian.crosslink.net/debian-archive".
-               "/dists/##DIST/Contents-i386.gz",
+               "/dists/##DIST/Contents-$arch.gz",
 );
 
 my %archiveurlpackages = (
-       "Packages-##DIST-main-i386.gz" =>
+       "Packages-##DIST-main-$arch.gz" =>
                "$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".
-               "/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".
-               "/dists/##DIST/non-free/binary-i386/Packages.gz",
+               "/dists/##DIST/non-free/binary-$arch/Packages.gz",
 );
-    
-
 
 
 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".
-               "/debian-non-US/dists/##DIST/non-US/Contents-i386.gz",
+               "/debian-non-US/dists/##DIST/non-US/Contents-$arch.gz",
 );
 
 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;
-    
+
     if (exists $archived_dists{$dist}){
        if ($type eq 'contents'){
            %dist_urls = %archiveurlcontents;
        }
        else {
            %dist_urls = %archiveurlpackages;
-       }  
+       }
     }
     else {
        if ($type eq 'contents'){
@@ -1100,7 +1090,7 @@ sub fixDist {
            %dist_urls = %urlpackages;
        }
     }
-       
+
     while (($key,$val) = each %dist_urls) {
        $key =~ s/##DIST/$dist/;
        $val =~ s/##DIST/$dist/;
@@ -1195,3 +1185,5 @@ sub searchDescFE {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 661247c77f4563894982b3cc120bf8144e5d3989..42a99484436caaf300ec4becd6507a4f72473315 100644 (file)
@@ -121,3 +121,5 @@ sub package_bugs($){
 
 
 __END__
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a9d4d34628a132bc92a3dbc69c088177377ce722..66455964e09cfb5a88f06cdacdad3a378a5a014f 100644 (file)
@@ -179,3 +179,5 @@ sub do_pkg {
 }
 
 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 {
-       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;
@@ -53,16 +53,25 @@ sub Dict {
        if ($query =~ s/^(\d+)\s+//) {
            $num = $1;
        }
+       my $dict = '*';
+       if ($query =~ s/\/(\S+)$//) {
+           $dict = $1;
+       }
 
        # 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;
 
+       my $count=0;
+       foreach (@results) {
+           $count++;
+           &::DEBUG("$count: $_");
+       }
        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 .= " in $dict" if ($dict ne '*');
        }
     }
 
     &::performStrictReply($retval);
 }
 
-sub Dict_Wordnet {
-    my ($socket, $query) = @_;
+sub Define {
+    my ($socket, $query, $dict) = @_;
     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
 
-       &::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;
-       } 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);
-    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;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 2e9fa976c304942ec856b74739e01ba9602dc013..5b36b2248b0eeecd11763462ff1eebf9c1f1649b 100644 (file)
@@ -15,7 +15,7 @@ my $countlines = 0;
 
 sub dumpvarslog {
     my ($line) = @_;
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        print DUMPVARS $line."\n";
     } else {
        &status("DV: ".$line);
@@ -28,7 +28,7 @@ sub DumpNames(\%$) {
     my $line;
 
     if ($packname eq 'main::') {
-       &dumpvarslog("Packages");
+       &dumpvarslog('Packages');
 
        foreach $symname (sort keys %$package) {
            local *sym = $$package{$symname};
@@ -113,7 +113,7 @@ sub DumpNames(\%$) {
 }
 
 sub dumpallvars {
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        my $file = $param{'dumpvarsLogFile'};
        &status("opening fh to dumpvars ($file)");
        if (!open(DUMPVARS,">$file")) {
@@ -124,7 +124,7 @@ sub dumpallvars {
 
     DumpNames(%main::,'main::');
 
-    if (&IsParam("dumpvarsLogFile")) {
+    if (&IsParam('dumpvarsLogFile')) {
        &status("closing fh to dumpvars");
        close DUMPVARS;
     }
@@ -133,3 +133,5 @@ sub dumpallvars {
 }
 
 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;
 
-    if (ref $x eq "HASH") {
+    if (ref $x eq 'HASH') {
        foreach (keys %$x) {
            &symdumpRecur($_);
        }
@@ -64,3 +64,5 @@ sub symdumpAllFile {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ae8470f3e85f2f8cf74796793ab3e01385d1f97a..9c9e320a8e9b658540029288950d332aa1d3b8f9 100644 (file)
@@ -1,6 +1,6 @@
 #!/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>
@@ -30,245 +30,245 @@ sub GetAbb {
 
 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;
 }
@@ -277,7 +277,7 @@ sub 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);
@@ -294,9 +294,9 @@ sub exchange {
 
     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';
@@ -306,7 +306,7 @@ sub exchange {
     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+/,
@@ -373,7 +373,7 @@ sub exchange {
                    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.
@@ -392,7 +392,7 @@ sub query {
   return;
 }
 
-
+#print &exchange('1 usd to eur') . "\n";
 1;
 
 __END__
@@ -422,3 +422,5 @@ currency code is a bit cranky.
 =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;
-    my $string = "";
+    my $string = '';
 
-    if ($faqtoid eq "") {
-       &help("factinfo");
+    if ($faqtoid eq '') {
+       &help('factinfo');
        return;
     }
 
-    my %factinfo = &sqlSelectRowHash("factoids", "*",
+    my %factinfo = &sqlSelectRowHash('factoids', '*',
        { factoid_key => $faqtoid }
     );
 
@@ -47,7 +47,7 @@ sub CmdFactInfo {
     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'};
@@ -57,27 +57,27 @@ sub CmdFactInfo {
                $string .= " at \037". scalar(gmtime $time). "\037" .
                                " ($days days)";
            } else {
-               $string .= " ".&Time2String(time() - $time)." ago";
+               $string .= ' '.&Time2String(time() - $time).' ago';
            }
        }
 
        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'}) {
-       $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 {
-               $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);
     }
@@ -87,12 +87,12 @@ sub CmdFactInfo {
        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 ".
-                       &fixPlural("time", $requested_count);
+                       &fixPlural('time', $requested_count);
            }
 
            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 {
-                   $string .= ", ".&Time2String(time() - $requested_time)." ago";
+                   $string .= ', '.&Time2String(time() - $requested_time).' ago';
                }
            }
        } else {
-           $string  = "has not been requested yet";
+           $string  = 'has not been requested yet';
        }
 
        push(@array, $string);
@@ -128,7 +128,7 @@ sub CmdFactInfo {
        return;
     }
 
-    &performStrictReply("$factinfo{'factoid_key'} -- ". join("; ", @array) .".");
+    &performStrictReply("$factinfo{'factoid_key'} -- ". join('; ', @array) .'.');
     return;
 }
 
@@ -136,9 +136,9 @@ sub CmdFactStats {
     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;
 
@@ -163,24 +163,24 @@ sub CmdFactStats {
        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");
        }
 
-       my $prefix = "factoid statistics by author: ";
+       my $prefix = 'factoid statistics by author: ';
        return &formListReply(0, $prefix, @list);
 
     } elsif ($type =~ /^vandalism$/i) {
-       &status("factstats(vandalism): starting...");
+       &status('factstats(vandalism): starting...');
        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);
-       &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.
@@ -192,7 +192,7 @@ sub CmdFactStats {
        }
 
        $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) {
@@ -200,11 +200,11 @@ sub CmdFactStats {
        }
 
        # parse the results.
-       my $prefix = "Vandalised factoid ";
+       my $prefix = 'Vandalised factoid ';
        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;
@@ -213,50 +213,50 @@ sub CmdFactStats {
 
        ### lets do it.
        # total factoids requests.
-       $i = &sumKey("factoids", "requested_count");
+       $i = &sumKey('factoids', 'requested_count');
        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.
-       $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)
-       $str = sprintf("%.01f", $i/$j);
+       $str = sprintf('%.01f', $i/$j);
        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?)
-       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}++;
        }
-       push(@list, "total unique authors - ".(scalar keys %hash) );
+       push(@list, 'total unique authors - '.(scalar keys %hash) );
        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}++;
        }
-       push(@list, "total unique requesters - ".(scalar keys %hash) );
+       push(@list, 'total unique requesters - '.(scalar keys %hash) );
        undef %hash;
 
-       ### end of "job".
+       ### end of 'job'.
 
        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.
@@ -265,21 +265,21 @@ sub CmdFactStats {
        }
 
        # parse the results.
-       my $prefix = "General factoid statistics ";
+       my $prefix = 'General factoid statistics ';
        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 $val = &getFactInfo($factoid, "factoid_value");
+           my $val = &getFactInfo($factoid, 'factoid_value');
            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);
 
@@ -298,15 +298,15 @@ sub CmdFactStats {
        }
 
        # 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) {
-       &status("factstats(dupe): starting...");
+       &status('factstats(dupe): starting...');
        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;
@@ -324,8 +324,8 @@ sub CmdFactStats {
                }
 
                s/([\,\;]+)/\037$1\037/g;
-               if ($_ eq "") {
-                   &WARN("dupe: _ = NULL. should never happen!.");
+               if ($_ eq '') {
+                   &WARN('dupe: _ = NULL. should never happen!.');
                    next;
                }
                push(@sublist, $_);
@@ -333,20 +333,20 @@ sub CmdFactStats {
 
            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(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) {
-           return "no duplicate factoids... woohoo.";
+           return 'no duplicate factoids... woohoo.';
        }
 
        # parse the results.
-       my $prefix = "dupe factoid ";
+       my $prefix = 'dupe factoid ';
        return &formListReply(1, $prefix, @list);
 
     } elsif ($type =~ /^nullfactoids$/i) {
@@ -356,7 +356,7 @@ sub CmdFactStats {
 
        my @list;
        while (my @row = $sth->fetchrow_array) {
-           if ($row[1] ne "") {
+           if ($row[1] ne '') {
                &DEBUG("row[1] != NULL for $row[0].");
                next;
            }
@@ -367,12 +367,12 @@ sub CmdFactStats {
        $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.
-       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;
 
@@ -394,12 +394,12 @@ sub CmdFactStats {
        $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.
-       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;
 
@@ -414,18 +414,18 @@ sub CmdFactStats {
            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.
-       my $prefix = "Inefficient lists fixed ";
+       my $prefix = 'Inefficient lists fixed ';
        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;
 
@@ -437,9 +437,9 @@ sub CmdFactStats {
        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;
 
@@ -452,24 +452,24 @@ sub CmdFactStats {
        }
 
        if (scalar keys %age == 0) {
-           return "sorry, no new factoids.";
+           return 'sorry, no new factoids.';
        }
 
        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) {
-       ### requires "custom" select statement... oh well...
+       ### requires 'custom' select statement... oh well...
        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;
 
@@ -482,7 +482,7 @@ sub CmdFactStats {
        }
        $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;
@@ -498,53 +498,53 @@ sub CmdFactStats {
                    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) {
-           return "no initial partial duplicate factoids... woohoo.";
+           return 'no initial partial duplicate factoids... woohoo.';
        }
 
        # parse the results.
-       my $prefix = "initial partial dupe factoid ";
+       my $prefix = 'initial partial dupe factoid ';
        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) {
-           push(@list, $_) if (&hasProfanity($_." ".$data{$_}));
+           push(@list, $_) if (&hasProfanity($_.' '.$data{$_}));
        }
 
        # parse the results.
-       my $prefix = "Profanity in factoids ";
+       my $prefix = 'Profanity in factoids ';
        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 $val = &getFactInfo($factoid, "factoid_value");
+           my $val = &getFactInfo($factoid, 'factoid_value');
            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 {
@@ -569,9 +569,9 @@ sub CmdFactStats {
        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) {
@@ -589,7 +589,7 @@ sub CmdFactStats {
            }
            $total      += $count * scalar(@faqtoids);
 
-           push(@list, "$count - ". join(", ", @faqtoids));
+           push(@list, "$count - ". join(', ', @faqtoids));
        }
        unshift(@list, "\037$total - TOTAL\037");
 
@@ -597,9 +597,9 @@ sub CmdFactStats {
        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,
-               "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;
@@ -607,7 +607,7 @@ sub CmdFactStats {
        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);
@@ -617,9 +617,9 @@ sub CmdFactStats {
        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;
 
@@ -646,7 +646,7 @@ sub CmdFactStats {
        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");
@@ -655,12 +655,12 @@ sub CmdFactStats {
        # 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) {
-       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;
@@ -668,12 +668,12 @@ sub CmdFactStats {
 
        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;
-           my $redir   = &getFactInfo($redirf, "factoid_value");
+           my $redir   = &getFactInfo($redirf, 'factoid_value');
 
            if ($redirf =~ /^\Q$factoid\W$/i) {
                &delFactoid($factoid);
@@ -681,7 +681,7 @@ sub CmdFactStats {
            }
 
            if (defined $redir) {       # good.
-               &setFactInfo($factoid,"factoid_value","<REPLY> see $redir");
+               &setFactInfo($factoid,'factoid_value',"<REPLY> see $redir");
                $fixed++;
            } else {
                push(@newlist, $redirf);
@@ -690,8 +690,7 @@ sub CmdFactStats {
 
        # 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);
@@ -719,11 +718,11 @@ sub CmdFactStats {
        $sth->finish;
 
        if (scalar @list == 0) {
-           return "good. no factoids exceed length.";
+           return 'good. no factoids exceed length.';
        }
 
        # 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) {
@@ -739,7 +738,7 @@ sub CmdFactStats {
 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' ";
@@ -747,3 +746,5 @@ sub CmdListAuth {
 }
 
 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);
-       $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";
 
-    &::performStrictReply($line||"Unknown Error Condition");
+    &::performStrictReply($line||'Unknown Error Condition');
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 1a762b886e0176ad6ca1fed03ba32348dd16af77..12ae9d0d6eb53f75aada6ffd213cf42a8837ce94 100644 (file)
@@ -12,7 +12,7 @@ sub kernelGetInfo {
 }
 
 sub Kernel {
-    my $retval = "Linux kernel versions";
+    my $retval = 'Linux kernel versions';
     my @now = &kernelGetInfo();
     if (!scalar @now) {
        &::msg($::who, "failed.");
@@ -20,8 +20,8 @@ sub Kernel {
     }
 
     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) {
@@ -37,7 +37,7 @@ sub Kernel {
        $line =~ s/ for 2.4//;
        $line =~ s/ for 2.2//;
        $line =~ s/ is: */: /;
-       $retval .= ", " . $line;
+       $retval .= ', ' . $line;
     }
     &::performStrictReply($retval);
 }
@@ -48,7 +48,7 @@ sub kernelAnnounce {
     my @old;
 
     if (!scalar @now) {
-       &::DEBUG("kA: failure to retrieve.");
+       &::DEBUG('kA: failure to retrieve.');
        return;
     }
 
@@ -96,3 +96,5 @@ sub kernelAnnounce {
 }
 
 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 = (
-       "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 {
@@ -60,13 +60,13 @@ sub perlMath {
 
     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;
-       my $val = join ("", unpack("B*",$2)) ;
+       my $val = join ('', unpack('B*',$2)) ;
        $locMsg =~ s/$exp/+$val/g;
     }
 
@@ -121,11 +121,11 @@ sub perlMath {
                &FIXME("math: locMsg => '$locMsg'...");
            } else {
                &status("math: could not really compute.");
-               $locMsg = "";
+               $locMsg = '';
            }
        }
     } else {
-       $locMsg = "";
+       $locMsg = '';
     }
 
     if (defined $locMsg and $locMsg ne $message) {
@@ -138,3 +138,5 @@ sub perlMath {
 }
 
 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();
     }
 
-    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*//) {
@@ -123,8 +118,8 @@ sub Parse {
     } 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;
@@ -142,7 +137,7 @@ sub Parse {
        } 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;
@@ -155,7 +150,7 @@ sub Parse {
 }
 
 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;
     }
@@ -203,9 +198,9 @@ sub readNews {
     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.
-    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.");
@@ -249,7 +244,7 @@ sub writeNews {
     }
 
     # 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.
 
@@ -271,7 +266,7 @@ sub add {
     my($str) = @_;
 
     if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
-       &::help("news add");
+       &::help('news add');
        return;
     }
 
@@ -286,7 +281,7 @@ sub add {
     }
 
     $::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!
 
@@ -307,7 +302,7 @@ sub del {
     my $item   = 0;
 
     if (!defined $what) {
-       &::help("news del");
+       &::help('news del');
        return;
     }
 
@@ -355,7 +350,7 @@ sub del {
     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.
@@ -376,7 +371,7 @@ sub list {
        return;
     }
 
-    if (&::IsChanConf("newsKeepRead") > 0) {
+    if (&::IsChanConf('newsKeepRead') > 0) {
        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.");
-    &::msg($who, " \037Num\037  \037Item ".(" "x40)." \037");
+    &::msg($who, " \037Num\037  \037Item ".(' 'x40)." \037");
 
 #    &::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};
-       my $chr         = (exists $::News{$chan}{$subtopic}{Text}) ? "" : "*";
+       my $chr         = (exists $::News{$chan}{$subtopic}{Text}) ? '' : '*';
 
        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*$/) {
-       &::help("news read");
+       &::help('news read');
        return;
     }
 
@@ -471,7 +466,7 @@ sub read {
     }
 
     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;
     }
 
@@ -516,8 +511,8 @@ sub read {
 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;
     }
 
@@ -544,10 +539,10 @@ sub mod {
        # 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/);
-       } 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);
        }
@@ -603,8 +598,8 @@ sub set {
     $what = $1 if ($args =~ s/^(\S+)\s*//);
     $value = $args;
 
-    if ($item eq "") {
-       &::help("news set");
+    if ($item eq '') {
+       &::help('news set');
        return;
     }
 
@@ -622,7 +617,7 @@ sub set {
     }
 
     my $ok = 0;
-    my @elements = ("Expire","Text");
+    my @elements = ('Expire','Text');
     foreach (@elements) {
        next unless ($what =~ /^$_$/i);
        $what = $_;
@@ -646,7 +641,7 @@ sub set {
        return;
     }
 
-    if ($what eq "Expire") {
+    if ($what eq 'Expire') {
        # 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);
-    $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;
@@ -756,7 +751,7 @@ sub latest {
     }
 
     $::chan    = $chan;
-    return if (&::IsChanConf("newsNotifyAll") <= 0);
+    return if (&::IsChanConf('newsNotifyAll') <= 0);
 
     # 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} };
-    if (!$flag && &::IsChanConf("newsTellUnread") <= 0) {
+    if (!$flag && &::IsChanConf('newsTellUnread') <= 0) {
        return;
     }
 
@@ -1033,3 +1028,5 @@ sub stats {
 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;
 
-       # get options 
+       # get options
        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){
-               &performReply("ok");
+               &performReply('ok');
        }
        else{
                &performReply('whoops. database error');
@@ -120,3 +120,5 @@ sub Cmdonjoin {
 }
 
 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 $prefix      = "Plug Headlines ";
+       my $prefix      = 'Plug Headlines ';
        my @list        = &plugParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
@@ -103,3 +103,5 @@ sub plugAnnounce {
 }
 
 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;
-    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");
 
 
@@ -45,7 +45,7 @@ sub Quote {
                "Opened $open, Volume $newvol, Change $change";
     }
 
-    if ($reply eq "") {
+    if ($reply eq '') {
        $reply = "i couldn't get the quote for $stock. sorry. :(";
     }
 
@@ -53,3 +53,5 @@ sub Quote {
 }
 
 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.');
-           &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')) {
@@ -57,7 +57,7 @@ sub rootWarn {
     $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,
@@ -81,8 +81,8 @@ sub CmdrootWarn {
     }
 
     # 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.");
@@ -103,8 +103,8 @@ sub CmdrootWarn {
 
     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.";
     }
 
@@ -112,3 +112,5 @@ sub CmdrootWarn {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a9c39e98df3d1123a785a43be15b600cd4b27519..68df8d408cd1b0414fbb1a4274f0a7140ca2a3ff 100644 (file)
@@ -25,4 +25,5 @@ sub Rss::Rss {
 }
 
 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.
 
-    if ($type eq "value") {
+    if ($type eq 'value') {
        # search by value.
-       @list = &::searchTable("factoids", "factoid_key", "factoid_value", $str);
+       @list = &::searchTable('factoids', 'factoid_key', 'factoid_value', $str);
     } 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);
@@ -35,3 +35,5 @@ sub Search {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 2a07c2ee59b99cfb519d172be22850933a05b2cb..36c1a3f03984fae43c0c5bf1b77ee68425a8a6d9 100644 (file)
@@ -33,7 +33,7 @@ sub topicDecipher {
        }
 
        my $subtopic    = $_;
-       my $owner       = "Unknown";
+       my $owner       = 'Unknown';
 
        if (/(.*)\s+\((.*?)\)$/) {
            $subtopic   = $1;
@@ -60,10 +60,10 @@ sub topicCipher {
     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)");
+       } else {
+           push(@topic, "$subtopic");
        }
     }
 
@@ -101,7 +101,7 @@ sub topicNew {
        return 1;
     }
 
-    if (defined $updateMsg && $updateMsg ne "") {
+    if (defined $updateMsg && $updateMsg ne '') {
        &msg($who, $updateMsg);
     }
 
@@ -113,7 +113,7 @@ sub topicNew {
        $conn->topic($chan, $topic);
        &topicAddHistory($chan, $topic);
     } else {
-       $conn->topic($chan, " ");
+       $conn->topic($chan, ' ');
     }
 
     return 1;
@@ -125,10 +125,10 @@ sub topicAddHistory {
     my ($chan, $topic) = @_;
     my $dupe           = 0;
 
-    return 1 if ($topic eq "");                        # required fix.
+    return 1 if ($topic eq '');                        # required fix.
 
     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.
@@ -153,21 +153,27 @@ sub topicAddHistory {
 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 =~ /\|\|/) {
-       &msg($who, "error: you have an invalid nick, loser!");
+       &msg($who, 'error: you have an invalid nick, loser!');
        return;
     }
 
-    return if ($channels{$chan}{t} and !&hasFlag("T"));
+    return if ($channels{$chan}{t} and !&hasFlag('T'));
 
     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) {
@@ -175,7 +181,7 @@ sub do_add {
        $new = &topicCipher(@prev, $str);
     }
 
-    &topicNew($chan, $new, "");
+    &topicNew($chan, $new, '');
 }
 
 # cmd: delete.
@@ -185,12 +191,12 @@ sub do_delete {
     my $topiccount     = scalar @subtopics;
 
     if ($topiccount == 0) {
-       &msg($who, "No topic set.");
+       &msg($who, 'No topic set.');
        return;
     }
 
-    if ($args eq "") {
-       &help("topic del");
+    if ($args eq '') {
+       &help('topic del');
        return;
     }
 
@@ -209,8 +215,8 @@ sub do_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+)$/) {
@@ -225,7 +231,7 @@ sub do_delete {
            return;
        }
 
-       $topic{$chan}{'What'} = "Deleted ".join("/",@delete);
+       $topic{$chan}{'What'} = 'Deleted '.join("/",@delete);
     }
 
     foreach (@delete) {
@@ -240,7 +246,7 @@ sub do_delete {
 
        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];
@@ -252,7 +258,7 @@ sub do_delete {
        push(@newtopics, $_);
     }
 
-    &topicNew($chan, &topicCipher(@newtopics), "");
+    &topicNew($chan, &topicCipher(@newtopics), '');
 }
 
 # cmd: list
@@ -288,8 +294,8 @@ sub do_list {
 sub do_modify {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic mod");
+    if ($args eq '') {
+       &help('topic mod');
        return;
     }
 
@@ -312,8 +318,8 @@ sub do_modify {
        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/.";
@@ -332,8 +338,8 @@ sub do_modify {
 sub do_move {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic mv");
+    if ($args eq '') {
+       &help('topic mv');
        return;
     }
 
@@ -402,7 +408,7 @@ sub do_move {
 
     undef @subtopics;                  # lets reuse this array.
     foreach (@newtopics) {
-       next if (!defined $_ or $_ eq "");
+       next if (!defined $_ or $_ eq '');
        push(@subtopics, $_);
     }
 
@@ -416,7 +422,7 @@ sub do_shuffle {
     my @subtopics      = &topicDecipher($chan);
     my @newtopics;
 
-    $topic{$chan}{'What'} = "shuffled";
+    $topic{$chan}{'What'} = 'shuffled';
 
     foreach (&makeRandom(scalar @subtopics)) {
        push(@newtopics, $subtopics[$_]);
@@ -451,8 +457,8 @@ sub do_history {
 sub do_restore {
     my ($chan, $args) = @_;
 
-    if ($args eq "") {
-       &help("topic restore");
+    if ($args eq '') {
+       &help('topic restore');
        return;
     }
 
@@ -486,7 +492,7 @@ sub do_rehash {
     my ($chan) = @_;
 
     $_ = "Rehashing topic...";
-    $topic{$chan}{'What'} = "Rehash";
+    $topic{$chan}{'What'} = 'Rehash';
     &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 ".
-               &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);
@@ -553,16 +559,18 @@ sub Topic {
 
     } 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;
        }
 
-       &help("topic");
+       &help('topic');
     }
 
     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
-#       NOTE: Integrated into blootbot by xk.
+#       NOTE: Integrated into infobot by xk.
 
 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) = @_;
 
-  # 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;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ac962f0d03fc2ca0513de9b47a6deb6575c49f12..5c7431613c3f983eb5647f199a3fdc69abd5ab37 100644 (file)
@@ -83,11 +83,9 @@ sub uptimeWriteFile {
   }
 
   close OUT;
-  &status("--- Saved uptime records.");
-
-  return unless defined $conn;
-
-  $conn->schedule(&getRandomInt("1800-3600"), \&uptimeWriteFile, "");
+  &status('--- Saved uptime records.');
 }
 
 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*$/) {
-           &help("tellme");
+           &help('tellme');
            return;
        }
 
@@ -60,12 +60,12 @@ sub userDCC {
 
     # 4op.
     if ($message =~ /^4op(\s+($mask{chan}))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        my $chan = $2;
 
-       if ($chan eq "") {
-           &help("4op");
+       if ($chan eq '') {
+           &help('4op');
            return;
        }
 
@@ -86,13 +86,13 @@ sub userDCC {
 
     # 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;
 
-       if ($chan eq "") {
-           &help("4op");
+       if ($chan eq '') {
+           &help('4op');
            return;
        }
 
@@ -104,13 +104,13 @@ sub userDCC {
 
     # 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) {
-           &help("backlog");
+           &help('backlog');
            return;
        } elsif ($num !~ /^\d+/) {
            &msg($who, "error: argument is not positive integer.");
@@ -132,8 +132,8 @@ sub userDCC {
 
     # 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();
@@ -154,12 +154,12 @@ sub userDCC {
 
     # kick.
     if ($message =~ /^kick(\s+(.*?))$/) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        my $arg = $2;
 
-       if ($arg eq "") {
-           &help("kick");
+       if ($arg eq '') {
+           &help('kick');
            return;
        }
        my @args = split(/\s+/, $arg);
@@ -182,11 +182,11 @@ sub userDCC {
 
     # mode.
     if ($message =~ /^mode(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my ($chan,$mode) = split /\s+/,$2,2;
 
-       if ($chan eq "") {
-           &help("mode");
+       if ($chan eq '') {
+           &help('mode');
            return;
        }
 
@@ -207,12 +207,12 @@ sub userDCC {
 
     # 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.");
-           &help("part");
+           &help('part');
            return;
        }
 
@@ -228,12 +228,12 @@ sub userDCC {
 
     # 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 {
-           &performReply("i have been lobotomized");
+           &performReply('i have been lobotomized');
            $lobotomized = 1;
        }
 
@@ -242,10 +242,10 @@ sub userDCC {
 
     # unlobotomy.
     if ($message =~ /^(unlobotomy|benoisy)$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        if ($lobotomized) {
-           &performReply("i have been unlobotomized, woohoo");
+           &performReply('i have been unlobotomized, woohoo');
            $lobotomized = 0;
            delete $cache{lobotomy};
 #          undef $cache{lobotomy};     # ??
@@ -258,7 +258,7 @@ sub userDCC {
 
     # op.
     if ($message =~ /^op(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
@@ -305,7 +305,7 @@ sub userDCC {
 
     # deop.
     if ($message =~ /^deop(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
@@ -352,41 +352,31 @@ sub userDCC {
 
     # 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'.");
 
-       # 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 unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        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 unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &doExit();
 
@@ -397,7 +387,7 @@ sub userDCC {
     # 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.
@@ -408,8 +398,8 @@ sub userDCC {
 
        ### 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.");
@@ -422,7 +412,7 @@ sub userDCC {
        }
 
        &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) {
@@ -440,7 +430,7 @@ sub userDCC {
                    &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'.");
@@ -453,17 +443,17 @@ sub userDCC {
        }
 
        &performReply("Ok... did s/$op/$np/ for ".
-                               (scalar(@list) - $error)." factoids");
+                               (scalar(@list) - $error).' factoids');
 
        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;
        }
 
@@ -486,7 +476,7 @@ sub userDCC {
 
     # reload.
     if ($message =~ /^reload$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
@@ -498,7 +488,7 @@ sub userDCC {
 
     # reset.
     if ($message =~ /^reset$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"resetting...");
        my @done;
@@ -511,26 +501,26 @@ sub userDCC {
            push(@done, $_);
            sleep 1;
        }
-       &DEBUG("before clearircvars");
+       &DEBUG('before clearircvars');
        &clearIRCVars();
-       &DEBUG("before joinnextchan");
+       &DEBUG('before joinnextchan');
        &joinNextChan();
-       &DEBUG("after joinnextchan");
+       &DEBUG('after joinnextchan');
 
        &status("USER reset $who");
-       &msg($who,"reset complete");
+       &msg($who,'reset complete');
 
        return;
     }
 
     # rehash.
     if ($message =~ /^rehash$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"rehashing...");
-       &restart("REHASH");
+       &restart('REHASH');
        &status("USER rehash $who");
-       &msg($who,"rehashed");
+       &msg($who,'rehashed');
 
        return;
     }
@@ -543,7 +533,7 @@ sub userDCC {
        my @args = split /[\s\t]+/, $2; # hrm.
 
        if (scalar @args != 1) {
-           &help("chaninfo");
+           &help('chaninfo');
            return;
        }
 
@@ -578,14 +568,14 @@ sub userDCC {
        }
 
        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".
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        # READ ONLY.
        if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) {
@@ -612,17 +602,17 @@ sub userDCC {
        }
 
        ### 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') {
-                   &performStrictReply("Default channel settings");
+                   &performStrictReply('Default channel settings');
                } 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?
@@ -652,12 +642,12 @@ sub userDCC {
     }
 
     if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my $args        = $3;
        my $no_chan     = 0;
 
        if (!defined $args) {
-           &help("chanunset");
+           &help('chanunset');
            return;
        }
 
@@ -668,7 +658,7 @@ sub userDCC {
            $delete     = ($1) ? 1 : 0;
        } else {
            &VERB("no chan arg; setting to default.",2);
-           $chan       = "_default";
+           $chan       = '_default';
            $no_chan    = 1;
        }
 
@@ -677,7 +667,7 @@ sub userDCC {
            return;
        }
 
-       if ($args ne "") {
+       if ($args ne '') {
 
            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) );
-           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};
@@ -740,7 +730,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (scalar @args != 1) {
-           &help("newpass");
+           &help('newpass');
            return;
        }
 
@@ -760,7 +750,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chpass");
+           &help('chpass');
            return;
        }
 
@@ -777,7 +767,7 @@ sub userDCC {
 
        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;
            }
@@ -811,7 +801,7 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chattr");
+           &help('chattr');
            return;
        }
 
@@ -842,9 +832,9 @@ sub userDCC {
 
        &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.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        my $state;
@@ -862,7 +852,7 @@ sub userDCC {
                next if ($flags =~ /\Q$_\E/);
                $flags .= $_;
            } else {
-               if (&IsParam("owner")
+               if (&IsParam('owner')
                        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 ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run chnick.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        if (!scalar @args or scalar @args > 2) {
-           &help("chnick");
+           &help('chnick');
            return;
        }
 
@@ -927,9 +917,9 @@ sub userDCC {
            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.");
-           return "REPLY" if ($who eq "_default");
+           return 'REPLY' if ($who eq '_default');
            return;
        }
 
@@ -948,7 +938,7 @@ sub userDCC {
     }
 
     if ($message =~ /^([-+])host(\s+(.*))?$/) {
-       my $cmd         = $1."host";
+       my $cmd         = $1.'host';
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
 
@@ -957,14 +947,14 @@ sub userDCC {
            return;
        }
 
-       if ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run $cmd.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        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>
@@ -979,11 +969,11 @@ sub userDCC {
        }
 
        if (!defined $mask) {
-           &performStrictReply("Hostmasks for $user: " . join(" ", keys %{$users{$user}{HOSTS}}));
+           &performStrictReply("Hostmasks for $user: " . join(' ', keys %{$users{$user}{HOSTS}}));
            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;
        }
@@ -1031,7 +1021,7 @@ sub userDCC {
     }
 
     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;
@@ -1052,7 +1042,7 @@ sub userDCC {
        if ($flatarg =~ s/^($mask{chan})\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";        # _default instead?
+           $chan = '*';        # _default instead?
        }
 
        if ($state == 0) {              # delete.
@@ -1091,7 +1081,7 @@ sub userDCC {
            $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;
        }
@@ -1113,7 +1103,7 @@ sub userDCC {
        my $arg = $2;
 
        if (!defined $arg) {
-           &help("whois");
+           &help('whois');
            return;
        }
 
@@ -1128,7 +1118,7 @@ sub userDCC {
        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} }) {
@@ -1148,7 +1138,7 @@ sub userDCC {
        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;
            }
@@ -1168,7 +1158,7 @@ sub userDCC {
            foreach (keys %{ $bans{$c} }) {
                my $val = $bans{$c}{$_};
 
-               if (ref $val eq "ARRAY") {
+               if (ref $val eq 'ARRAY') {
                    my @array = @{ $val };
                    &performStrictReply("    $_: @array");
                } else {
@@ -1201,11 +1191,11 @@ sub userDCC {
     }
 
     if ($message =~ /^save$/) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        &writeUserFile();
        &writeChanFile();
-       &performStrictReply("saved user and chan files");
+       &performStrictReply('saved user and chan files');
 
        return;
     }
@@ -1216,9 +1206,9 @@ sub userDCC {
 
     # ignore.
     if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $state       = ($1 eq "+") ? 1 : 0;
-       my $str         = $1."ignore";
+       my $str         = $1.'ignore';
        my $args        = $3;
 
        if (!$args) {
@@ -1253,7 +1243,7 @@ sub userDCC {
        if ($args =~ s/^($mask{chan}|\*)\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";
+           $chan = '*';
        }
 
        # time.
@@ -1310,7 +1300,7 @@ sub userDCC {
 
            foreach (keys %{ $ignore{$c} }) {
                my $ref = ref $ignore{$c}{$_};
-               if ($ref eq "ARRAY") {
+               if ($ref eq 'ARRAY') {
                    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;
-       my $strstr      = $1."user";
+       my $strstr      = $1.'user';
        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 $str = join(", ", sort keys %{ $time{$_} });
+           my $str = join(', ', sort keys %{ $time{$_} });
            &DEBUG("time => $_, str => $str");
            push(@time, "$str (".&Time2String($_).")");
        }
@@ -1425,7 +1415,7 @@ sub userDCC {
     }
 
     # 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);
@@ -1436,7 +1426,9 @@ sub userDCC {
        return;
     }
 
-    return "REPLY";
+    return 'REPLY';
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index e35373b04900216dcb8ca53199f63b073a13fcb6..a172d478d209d7338425254e0759b4a551c09eb1 100644 (file)
@@ -9,13 +9,13 @@
 
 use strict;
 
-my $orderOfInfo = "RN,J,C,W,D";
+my $orderOfInfo = 'RN,J,C,W,D';
 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 {
@@ -61,7 +61,7 @@ sub UserInfoGet {
     }
 
     my $result;
-    if ($result = &getFactoid($query." info")) {
+    if ($result = &getFactoid($query.' info')) {
        # good.
     } else { # bad.
        &performReply("No User Information on \002$query\002");
@@ -160,7 +160,7 @@ sub UserInfoSet {
        $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'.");
@@ -170,3 +170,5 @@ sub UserInfoSet {
 }
 
 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
-               Lycos Magellan PLweb SFgate Simple Verity Google);
+               Lycos Magellan PLweb SFgate Simple Verity Google z);
 $W3Search_regex = join '|', @W3Search_engines;
 
 my $maxshow    = 5;
@@ -28,42 +28,37 @@ sub W3Search {
     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 ";
-       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;
-    
+
+# vim:ts=4:sw=4:expandtab:tw=80
index ecf37cf69262f4d64923db09ae748c9d10e91293..d6a2f802e4cdd91e5a59429471863cd4936b4b73 100644 (file)
@@ -51,7 +51,7 @@ sub queryText {
        }
 
        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");
@@ -64,7 +64,7 @@ sub queryText {
                    . " 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.";
            }
        }
@@ -105,7 +105,7 @@ sub queryText {
 
        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";
@@ -132,6 +132,8 @@ if (0) {
 
 1;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __END__
 
 =head1 NAME
index bb93593bf4f7176ad85a7577a31e86f978b40677..ae3e973c415579c48edf2f0a5aab86ab6aa7c014 100644 (file)
@@ -12,7 +12,7 @@ use strict;
 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);
@@ -73,7 +73,7 @@ sub Wingate {
            &::status("Wingate: RUNNING ON $host BY $::who.");
 
            if (&::IsChanConf('wingateBan') > 0) {
-               &::ban("*!*\@$host", "");
+               &::ban("*!*\@$host", '');
            }
 
            my $reason  = &::getChanConf('wingateKick');
@@ -96,3 +96,5 @@ sub Wingate {
 }
 
 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;
-    &::DEBUG("Reading zippy data");
+    &::DEBUG('Reading zippy data');
     while (<DATA>) {
        chomp;
        push @yows, $_;
@@ -31,6 +31,8 @@ sub zippy::get {
 
 1;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 =pod
 
 =head1 NAME
index 850292b172df2d6868cd3f499b7469b16ca55590..fcefe4e484215fc384ebe33e2f45f82797823165 100644 (file)
@@ -63,7 +63,7 @@ sub babelfishParam {
   $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);
@@ -145,3 +145,5 @@ if (0) {
 }
 
 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*$/) {
-       &::help("botmail");
+       &::help('botmail');
        return;
     }
 
@@ -36,8 +36,8 @@ sub parse {
 }
 
 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 %from = &::sqlSelectColHash("botmail", "srcwho,time", {
+    my %from = &::sqlSelectColHash('botmail', "srcwho,time", {
        dstwho => lc $recipient
     } );
     my $t      = keys %from;
@@ -64,7 +64,7 @@ sub check {
 sub next {
     my($recipient) = @_;
 
-    my %hash = &::sqlSelectRowHash("botmail", "*", {
+    my %hash = &::sqlSelectRowHash('botmail', '*', {
        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'});
-       &::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.
-    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) {
@@ -100,7 +101,7 @@ sub add {
        return;
     }
 
-    &::sqlReplace("botmail", {
+    &::sqlInsert('botmail', {
        'dstwho'        => lc $recipient,
        'srcwho'        => lc $::who,
        'srcuh'         => $::nuh,
@@ -112,3 +113,5 @@ sub add {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index c41937cde8f5d29efc9fa0906369552c3fec94d7..0d5c932bb00accde1bd9d7439545bfe4f9fdd09d 100644 (file)
@@ -9,7 +9,8 @@ package case;
 
 sub upper {
     my($message) = @_;
-    &::performStrictReply(uc $message);
+    # make it green like an old terminal
+    &::performStrictReply("\00303" . uc $message);
 }
 
 sub lower {
@@ -18,3 +19,5 @@ sub lower {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 912a463d9109703fd1801aed54b7a993417880c6..60abd6aeea34f81a1aba576ec376da09c1b1af56 100644 (file)
@@ -93,3 +93,5 @@ sub countdown {
 }
 
 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
+
+# vim:ts=4:sw=4:expandtab:tw=80
index 415444d5535a41b78efa213e24fa13a2c688e186..1893b3a050dadadb689f7786aa60ac8534a3e873 100644 (file)
@@ -51,4 +51,5 @@ sub dns::query {
 }
 
 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;
-    &::DEBUG("Reading insult data");
+    &::DEBUG('Reading insult data');
     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);
@@ -32,13 +32,15 @@ sub Insult {
     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;
 
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __DATA__
 #
 # configuration file for colorado insult server
index 440e603566be2645525fba57bdc7a84caa9eccba..d32cf83a6bbbb1908bd404accdd595fa03ac6f0f 100644 (file)
@@ -9,9 +9,11 @@ package md5;
 
 sub md5 {
     my($message) = @_;
-    return unless &::loadPerlModule("Digest::MD5");
+    return unless &::loadPerlModule('Digest::MD5');
 
     &::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) {
-      my $str = join(", ", sort keys %{ $nickometer{$_} });
+      my $str = join(', ', sort keys %{ $nickometer{$_} });
       push(@list, "$str ($_%)");
     }
 
@@ -58,7 +58,7 @@ sub query {
   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/;
@@ -143,7 +143,7 @@ sub nickometer ($) {
         $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),
@@ -267,3 +267,5 @@ sub punish ($$) {
 }
 
 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';
-               # 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!",
-                       'X-Mailer' => "blootbot",
+                       'X-Mailer' => 'infobot',
                );
 
 #              my $logmsg;
@@ -98,5 +98,6 @@ sub pager::page {
        &::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
-  #  y as vowel "style" -> "ylestay"
+  #  y as vowel 'style' -> 'ylestay'
   #  contractions
   for my $word (split /\s+/, $text) {
     my ($pigword, $postfix);
@@ -40,3 +40,5 @@ sub piglatin
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index a6e2fd6018fecd0042279319c38001eaea1f8cf1..5a8231075eae4efb0b2daa5639c0346c9b90d084 100644 (file)
@@ -9,7 +9,9 @@ package reverse;
 
 sub reverse {
     my($message) = @_;
-    &::performStrictReply(join("",reverse(split("",$message))));
+    &::performStrictReply(join('',reverse(split('',$message))));
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index fbe91c500810cf94881c55fdeb690cbcc545462d..96fce80e9ead40cfd9dc29d698e0ab13e54c3574 100644 (file)
@@ -44,7 +44,7 @@ sub scramble
       }
 
       # 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));
 
@@ -56,7 +56,9 @@ sub scramble
   # been included in the original string
   $scrambled =~ s/\s+$//;
 
-  &::performStrictReply($scrambled||"Unknown Error Condition");
+  &::performStrictReply($scrambled||'Unknown Error Condition');
 }
 
 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 $prefix      = "Slashdot Headlines ";
+       my $prefix      = 'Slashdot Headlines ';
        my @list        = &slashdotParse(@results);
        $retval         = &::formListReply(0, $prefix, @list);
     }
@@ -101,3 +101,5 @@ sub slashdotAnnounce {
 }
 
 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:]]/) {
-               return("only one word of alphabetic characters supported");
+               return('only one word of alphabetic characters supported');
        }
 
        my $binary;
@@ -33,11 +33,11 @@ sub spell::spell {
        }
 
        if (!$binary) {
-               return("no binary found.");
+               return('no binary found.');
        }
 
        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'";
@@ -77,4 +77,5 @@ sub spell::query {
 }
 
 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;
@@ -50,7 +50,7 @@ sub wikipedia_lookup {
   &::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);
@@ -137,7 +137,7 @@ sub wikipedia_lookup {
        #$text = substr($text, 0, 330);
        #$text =~ s/(.+)\.([^.]*)$/$1./g;
 
-       return("At " . $url . " (URL), Wikipedia explains: " . $text,
+       return('At ' . $url . " (URL), Wikipedia explains: " . $text,
               1);
       }
     }
@@ -150,7 +150,7 @@ sub wikipedia_get_text {
   &::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);
@@ -174,19 +174,19 @@ sub wikipedia_get_text {
        } 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>/) {
-         $text = $text . " " . $1 . '"';
+         $text = $text . ' ' . $1 . '"';
          last;
        } elsif ($text) {
-         $text = $text . " " . $_;
+         $text = $text . ' ' . $_;
        }
       }
       &::DEBUG("wikipedia returned text: " . $text .
-                  ", redirect " . $redirect. "\n");
+                  ', redirect ' . $redirect. "\n");
 
       if (!$redirect and !$text) {
        return ($res->as_string);
@@ -198,3 +198,5 @@ sub wikipedia_get_text {
 }
 
 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.");
        }
 
-       my $reply ="";
+       my $reply ='';
        foreach (`$binary '$query' 2>&1`){
                $reply .= $_;
        }
@@ -50,4 +50,5 @@ sub wtf::query {
 }
 
 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;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(10);
 
@@ -101,5 +101,6 @@ sub query {
 }
 
 1;
-# vim: shiftwidth=2 tabstop=2
 __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;
-       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy"));
+       $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy'));
 
        $ua->timeout(10);
 
@@ -101,5 +101,7 @@ sub query {
 }
 
 1;
-# vim: shiftwidth=2 tabstop=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
+
 __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 ($rateunit,$rate) = ("B", $size / $delta_time);
+       my ($rateunit,$rate) = ('B', $size / $delta_time);
        if ($rate > 1024) {
            $rate /= 1024;
-           $rateunit = "kB";
+           $rateunit = 'kB';
        }
        &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate));
     }
@@ -153,7 +153,7 @@ sub getURL {
     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);
@@ -189,7 +189,7 @@ sub getURLAsFile {
     }
 
     $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);
@@ -205,3 +205,5 @@ sub getURLAsFile {
 }
 
 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?
-    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");
-       $users{$userHandle}{FLAGS} .= "o";
+       $users{$userHandle}{FLAGS} .= 'o';
     }
 
     # 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();
        }
-       return 'LOBOTOMY' unless IsFlag("A");
+       return 'LOBOTOMY' unless IsFlag('A');
     }
 
     # talkMethod.
@@ -68,8 +68,8 @@ sub process {
        $2 =~ /^($mask{chan})(\s+(\S+))?/;
        my($joinchan, $key) = (lc $1, $3);
 
-       if ($joinchan eq "") {
-           &help("join");
+       if ($joinchan eq '') {
+           &help('join');
            return;
        }
 
@@ -78,7 +78,7 @@ sub process {
            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;
@@ -109,7 +109,7 @@ sub process {
        }
 
        if (!scalar @array or scalar @array > 2) {
-           &help("identify");
+           &help('identify');
            return;
        }
 
@@ -151,7 +151,7 @@ sub process {
        }
 
        if (scalar @array != 1) {
-           &help("pass");
+           &help('pass');
            return;
        }
 
@@ -171,7 +171,7 @@ sub process {
 
        if ($first) {
            &performStrictReply("First time user... adding you as Master.");
-           $users{$who}{FLAGS} = "aemnorst";
+           $users{$who}{FLAGS} = 'aemnorst';
        }
 
        my $crypt = $users{$who}{PASS};
@@ -199,7 +199,7 @@ sub process {
     }
 
     # allowOutsiders.
-    if (&IsParam("disallowOutsiders") and $msgType =~ /private/i) {
+    if (&IsParam('disallowOutsiders') and $msgType =~ /private/i) {
        my $found = 0;
 
        foreach (keys %channels) {
@@ -262,7 +262,7 @@ sub process {
        }
 
        # customized random message.
-       my $tmp = (rand() < 0.5) ? ", $who" : "";
+       my $tmp = (rand() < 0.5) ? ", $who" : '';
        &performStrictReply( &getRandom(keys %{ $lang{'hello'} }) . $tmp );
        return;
     }
@@ -298,7 +298,7 @@ sub process {
 
     # 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);
@@ -308,17 +308,15 @@ sub process {
            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--;
        }
 
-       &sqlReplace("stats", {
-           nick        => $term,
-           type        => "karma",
+       &sqlSet('stats', {'nick' => $term, type => 'karma', channel => 'PRIVATE'}, {
            'time'      => time(),
            counter     => $karma,
        } );
@@ -327,7 +325,7 @@ sub process {
     }
 
     # 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) {
@@ -335,7 +333,7 @@ sub process {
        }
 
        # allow administration of bot via messages (default is DCC CHAT only)
-       if (&IsFlag("A")) {
+       if (&IsFlag('A')) {
            &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.";
@@ -361,3 +359,5 @@ sub process {
 }
 
 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;
 
-    if (&IsParam("noSHM")) {
+    if (&IsParam('noSHM')) {
        &status("Shared memory: Disabled. WARNING: bot may become unreliable");
        return 0;
     }
@@ -51,7 +51,7 @@ sub shmRead {
     my $size = 3*80;
     my $retval = '';
 
-    return '' if (&IsParam("noSHM"));
+    return '' if (&IsParam('noSHM'));
 
     if (shmread($key,$retval,$position,$size)) {
        #&DEBUG("shmRead($key): $retval");
@@ -73,7 +73,7 @@ sub shmWrite {
     my $position = 0;
     my $size = 80*3;
 
-    return if (&IsParam("noSHM"));
+    return if (&IsParam('noSHM'));
 
     $shm_keys{$keys}{accessed} = 1;
 
@@ -93,7 +93,7 @@ sub shmWrite {
 
     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;
@@ -241,8 +241,8 @@ sub shmFlush {
     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;
@@ -284,7 +284,9 @@ sub shmFlush {
        }
     }
 
-    &shmWrite($shm,"") if ($shmmsg ne "");
+    &shmWrite($shm,'') if ($shmmsg ne '');
 }
 
 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 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.
@@ -19,15 +19,16 @@ sub chaninfo {
     my $chan = lc shift(@_);
     my $mode;
 
-    if ($chan eq "") {         # all channels.
+    if ($chan eq '') {         # all 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 %chans;
        my @array;
 
        ### line 1.
-       foreach (sort keys %channels) {
+       foreach (keys %channels) {
            if ( /^\s*$/ or / / ) {
                &status("chanstats: fe channels: chan == NULL.");
                #&ircCheck();
@@ -35,8 +36,10 @@ sub chaninfo {
            }
            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));
 
@@ -57,10 +60,10 @@ sub chaninfo {
 
        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 ".
-           &fixPlural("channel", $chans)."."
+           &fixPlural('channel', $chans)."."
        );
        &ircCheck();
 
@@ -83,7 +86,7 @@ sub chaninfo {
        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.
@@ -107,13 +110,13 @@ sub chaninfo {
     # Step 2:
     undef @array;
     my $type;
-    foreach ("v","o","") {
+    foreach ('v','o','') {
        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");
     }
@@ -167,7 +170,7 @@ sub cmdstats {
 # 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.");
@@ -184,15 +187,15 @@ sub factinfo {
 sub factstats {
     my $type = shift(@_);
 
-    &Forker("Factoids", sub {
+    &Forker('Factoids', sub {
        &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");
@@ -249,7 +252,7 @@ sub tell {
 
     &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;
@@ -271,7 +274,7 @@ sub tell {
     # no such factoid.
     if (!defined $result || $result =~ /^0?$/) {
        $who            = $target;
-       $msgType        = "private";
+       $msgType        = 'private';
 
        # support command redirection.
        # recursive cmdHooks aswell :)
@@ -316,12 +319,12 @@ sub countryStats {
        return;
     }
 
-    if ($chan eq "") {
+    if ($chan eq '') {
        $chan = $_[0];
     }
 
-    if ($chan eq "") {
-       &help("countrystats");
+    if ($chan eq '') {
+       &help('countrystats');
        return;
     }
 
@@ -364,7 +367,7 @@ sub do_countrystats {
     }
 
     # TODO: move this into a scheduler
-    $msgType   = "private";
+    $msgType   = 'private';
     &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 ...");
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
 
        &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) );
 
@@ -394,12 +397,12 @@ sub userCommands {
 
     # conversion: ord.
     if ($message =~ /^ord(\s+(.*))$/) {
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
 
        $arg = $2;
 
        if (!defined $arg or length $arg != 1) {
-           &help("ord");
+           &help('ord');
            return;
        }
 
@@ -418,11 +421,11 @@ sub userCommands {
 
     # hex.
     if ($message =~ /^hex(\s+(.*))?$/i) {
-       return unless (&IsChanConfOrWarn("allowConv"));
+       return unless (&IsChanConfOrWarn('allowConv'));
        my $arg = $2;
 
        if (!defined $arg) {
-           &help("hex");
+           &help('hex');
            return;
        }
 
@@ -442,40 +445,27 @@ sub userCommands {
     }
 
     # 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 {
-           &performStrictReply( &mkcrypt($args[0]) );
+           &performStrictReply(&mkcrypt($1));
        }
-
        return;
     }
 
     # cycle.
     if ($message =~ /^(cycle)(\s+(\S+))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $chan = lc $3;
 
-       if ($chan eq "") {
+       if ($chan eq '') {
            if ($msgType =~ /public/) {
                $chan = $talkchannel;
                &DEBUG("cycle: setting chan to '$chan'.");
            } else {
-               &help("cycle");
+               &help('cycle');
                return;
            }
        }
@@ -487,7 +477,7 @@ sub userCommands {
 
        &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); });
 
@@ -496,7 +486,7 @@ sub userCommands {
 
     # reload.
     if ($message =~ /^reload$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &status("USER reload $who");
        &performStrictReply("reloading...");
@@ -507,21 +497,21 @@ sub userCommands {
 
     # redir.
     if ($message =~ /^redir(\s+(.*))?/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $factoid = $2;
 
        if (!defined $factoid) {
-           &help("redir");
+           &help('redir');
            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'.");
-       my @list = &searchTable("factoids", "factoid_key",
+       my @list = &searchTable('factoids', "factoid_key",
                                        "factoid_value", "^$val\$");
 
        if (scalar @list == 1) {
@@ -562,12 +552,12 @@ sub userCommands {
        my $reply = $3;
 
        if (!defined $reply) {
-           &help("rot13");
+           &help('rot13');
            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/;";
 
@@ -679,7 +669,7 @@ sub userCommands {
        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{$_} };
@@ -693,20 +683,20 @@ sub userCommands {
        &performStrictReply(
        "Since $startString, there have been".
          " \002$count{'Update'}\002 ".
-               &fixPlural("modification", $count{'Update'}).
+               &fixPlural('modification', $count{'Update'}).
          ", \002$count{'Question'}\002 ".
-               &fixPlural("question",$count{'Question'}).
+               &fixPlural('question',$count{'Question'}).
          ", \002$count{'Dunno'}\002 ".
-               &fixPlural("dunno",$count{'Dunno'}).
+               &fixPlural('dunno',$count{'Dunno'}).
          ", \002$count{'Moron'}\002 ".
-               &fixPlural("moron",$count{'Moron'}).
+               &fixPlural('moron',$count{'Moron'}).
          " 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 ".
-               &fixPlural("fork",$forks).
+               &fixPlural('fork',$forks).
          ". Process time user/system $puser/$psystem child $cuser/$csystem"
        );
 
@@ -714,9 +704,9 @@ sub userCommands {
     }
 
     # 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) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        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);
-           &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.");
@@ -752,7 +742,9 @@ sub userCommands {
        return;
     }
 
-    return "CONTINUE";
+    return 'CONTINUE';
 }
 
 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;
-$last{say}     = "";
-$last{msg}     = "";
+$last{say}     = '';
+$last{msg}     = '';
 $userHandle    = "_default";
 $wingaterun    = time();
 $firsttime     = 1;
@@ -78,23 +78,22 @@ $nottime    = 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 {
-    if (!&IsParam("Interface") or $param{'Interface'} =~ /IRC/) {
-       return "IRC";
+    if (!&IsParam('Interface') or $param{'Interface'} =~ /IRC/) {
+       return 'IRC';
     } else {
-       return "CLI";
+       return 'CLI';
     }
 }
 
@@ -113,7 +112,7 @@ sub doExit {
        &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");
 
@@ -131,13 +130,13 @@ sub doExit {
        &sqlCloseDB();
        &closeSHM($shm);
 
-       if (&IsParam("dumpvarsAtExit")) {
+       if (&IsParam('dumpvarsAtExit')) {
            &loadMyModule('DumpVars');
            &dumpallvars();
        }
-       &symdumpAll()           if (&IsParam("symdumpAtExit"));
+       &symdumpAll()           if (&IsParam('symdumpAtExit'));
        &closeLog();
-       &closeSQLDebug()        if (&IsParam("SQLDebug"));
+       &closeSQLDebug()        if (&IsParam('SQLDebug'));
 
        &status("--- QUIT.");
     } else {                                   # child.
@@ -158,7 +157,7 @@ sub doWarn {
 }
 
 # Usage: &IsParam($param);
-# blootbot.config specific.
+# infobot.config specific.
 sub IsParam {
     my $param = $_[0];
 
@@ -206,7 +205,7 @@ sub getChanConfList {
            &WARN("multiple items found?");
        }
 
-       if ($chanconf{$chan}{$param} eq "0") {
+       if ($chanconf{$chan}{$param} eq '0') {
            $chan{$chan}        = -1;
        } else {
            $chan{$chan}        =  1;
@@ -224,7 +223,7 @@ sub IsChanConf {
     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.");
@@ -251,7 +250,7 @@ sub IsChanConf {
     if (!defined $msgType) {
        $nomatch++;
     } else {
-       $nomatch++ if ($msgType eq "");
+       $nomatch++ if ($msgType eq '');
        $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');
        }
-       #&DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"');
+       &DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"');
        return $chanconf{$c[0]}{$param};
     }
 
@@ -372,9 +371,9 @@ sub findChanConf {
 }
 
 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;
@@ -385,7 +384,7 @@ sub showProc {
        }
        close IN;
 
-    } elsif ($^O eq "netbsd") {
+    } elsif ($^O eq 'netbsd') {
        $memusage = int( (stat "/proc/$$/mem")[7]/1024 );
 
     } elsif ($^O =~ /^(free|open)bsd$/) {
@@ -393,11 +392,11 @@ sub showProc {
        $memusage = $info[20];
 
     } else {
-       $memusage = "UNKNOWN";
+       $memusage = 'UNKNOWN';
        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;
@@ -428,25 +427,25 @@ sub setup {
     &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();
-    &openSQLDebug()    if (&IsParam("SQLDebug"));
+    &openSQLDebug()    if (&IsParam('SQLDebug'));
     &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}/#;
 
@@ -456,7 +455,7 @@ sub setup {
 
 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($_);
@@ -484,7 +483,7 @@ sub setupConfig {
 }
 
 sub startup {
-    if (&IsParam("DEBUG")) {
+    if (&IsParam('DEBUG')) {
        &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.
-    $ident ||= "blootbot";
+    $ident ||= 'infobot';
 
-    if (!&isFileUpdated("$bot_state_dir/blootbot.users", $wtime_userfile)) {
+    if (!&isFileUpdated("$bot_state_dir/infobot.users", $wtime_userfile)) {
        &writeUserFile()
     }
 
-    if (!&isFileUpdated("$bot_state_dir/blootbot.chan", $wtime_chanfile)) {
+    if (!&isFileUpdated("$bot_state_dir/infobot.chan", $wtime_chanfile)) {
        &writeChanFile();
     }
 
@@ -537,10 +536,10 @@ sub restart {
 
        &ircCheck();    # heh, evil!
 
-       &DCCBroadcast("-HUP called.","m");
+       &DCCBroadcast("-HUP called.",'m');
        &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.");
@@ -566,7 +565,7 @@ sub loadConfig {
        next unless /\S/;
        my ($set,$key,$val) = split(/\s+/, $_, 3);
 
-       if ($set ne "set") {
+       if ($set ne 'set') {
            &status("loadConfig: invalid line '$_'.");
            next;
        }
@@ -585,3 +584,5 @@ sub loadConfig {
 }
 
 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";
-       $type = "Pg";
+       $type = 'Pg';
     }
 
     my $dsn = "DBI:$type:$db";
-    my $hoststr = "";
+    my $hoststr = '';
     # 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
@@ -105,7 +110,7 @@ sub sqlCloseDB {
     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();
@@ -276,7 +281,7 @@ sub sqlSet {
        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;
     }
@@ -309,7 +314,7 @@ sub sqlSet {
 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;
     }
@@ -317,7 +322,7 @@ sub sqlUpdate {
     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;
 }
@@ -326,9 +331,10 @@ sub sqlUpdate {
 # 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;
     }
@@ -344,18 +350,18 @@ sub sqlInsert {
 
     &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;
 }
 
 #####
-# Usage: &sqlReplace($table, $data_href);
+# Usage: &sqlReplace($table, $data_href, [$pkey]);
 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;
     }
@@ -369,10 +375,29 @@ sub sqlReplace {
        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;
 }
@@ -382,14 +407,14 @@ sub sqlReplace {
 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);
 
-    &sqlRaw("Delete", "DELETE FROM $table WHERE $where");
+    &sqlRaw('Delete', "DELETE FROM $table WHERE $where");
 
     return 1;
 }
@@ -469,7 +494,7 @@ sub hashref2where {
        return;
     }
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2where: href is not HASH ref (href => $href)");
        return;
     }
@@ -492,7 +517,7 @@ sub hashref2where {
 sub hashref2update {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -518,7 +543,7 @@ sub hashref2update {
 sub hashref2array {
     my ($href) = @_;
 
-    if (ref($href) ne "HASH") {
+    if (ref($href) ne 'HASH') {
        &WARN("hashref2update: href is not HASH ref.");
        return;
     }
@@ -546,7 +571,7 @@ sub hashref2array {
 # Usage: &countKeys($table, [$col]);
 sub countKeys {
     my ($table, $col) = @_;
-    $col ||= "*";
+    $col ||= '*';
 
     return (&sqlRawReturn("SELECT count($col) FROM $table"))[0];
 }
@@ -627,18 +652,20 @@ sub searchTable {
 }
 
 sub sqlCreateTable {
-    my($table) = @_;
+    my($table, $dbtype)        = @_;
     my(@path)  = ($bot_data_dir, ".","..","../..");
     my $found  = 0;
     my $data;
+    $dbtype = lc $dbtype;
 
     foreach (@path) {
-       my $file = "$_/setup/$table.sql";
+       my $file = "$_/setup/$dbtype/$table.sql";
        next unless ( -f $file );
 
        open(IN, $file);
        while (<IN>) {
            chop;
+           next if $_ =~ /^--/;
            $data .= $_;
        }
 
@@ -686,6 +713,31 @@ sub checkTables {
        }
 
        # 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) ) {
@@ -698,8 +750,10 @@ sub checkTables {
 
        $cache{create_table}{$_} = 1;
 
-       &sqlCreateTable($_);
+       &sqlCreateTable($_, $param{DBType});
     }
 }
 
 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;
-$logold                = "";
+$logold                = '';
 
 $param{VEBOSITY} ||= 1;                # lame fix for preload
 
@@ -73,7 +73,7 @@ sub cl {
 
 # logging support.
 sub openLog {
-    return unless (&IsParam("logfile"));
+    return unless (&IsParam('logfile'));
     $file{log} = $param{'logfile'};
 
     my $error = 0;
@@ -90,13 +90,14 @@ sub openLog {
        $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}")) {
+       binmode(LOG, ":encoding(UTF-8)");
        &status("Opened logfile $file{log}.");
        LOG->autoflush(1);
     } else {
@@ -106,7 +107,7 @@ sub openLog {
 
 sub closeLog {
     # lame fix for paramlogfile.
-    return unless (&IsParam("logfile"));
+    return unless (&IsParam('logfile'));
     return unless (defined fileno LOG);
 
     close LOG;
@@ -117,7 +118,7 @@ sub closeLog {
 # 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) {
@@ -148,7 +149,7 @@ sub compress {
 }
 
 sub DEBUG {
-    return unless (&IsParam("DEBUG"));
+    return unless (&IsParam('DEBUG'));
 
     &status("${b_green}!DEBUG!$ob $_[0]");
 }
@@ -158,7 +159,7 @@ sub ERROR {
 }
 
 sub WARN {
-    return unless (&IsParam("WARN"));
+    return unless (&IsParam('WARN'));
 
     return if ($_[0] =~ /^PERL: Subroutine \S+ redefined at/);
 
@@ -174,11 +175,11 @@ sub TODO {
 }
 
 sub VERB {
-    if (!&IsParam("VERBOSITY")) {
+    if (!&IsParam('VERBOSITY')) {
        # NOTHING.
-    } elsif ($param{'VERBOSITY'} eq "1" and $_[1] <= 1) {
+    } elsif ($param{'VERBOSITY'} eq '1' and $_[1] <= 1) {
        &status($_[0]);
-    } elsif ($param{'VERBOSITY'} eq "2" and $_[1] <= 2) {
+    } elsif ($param{'VERBOSITY'} eq '2' and $_[1] <= 2) {
        &status($_[0]);
     }
 }
@@ -206,10 +207,10 @@ sub status {
 
     # 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).");
 
-       if ($ref eq "ARRAY") {
+       if ($ref eq 'ARRAY') {
            foreach (@$input) {
                &WARN("status: '$_'.");
            }
@@ -277,12 +278,12 @@ sub status {
        $status = "[$statcount] ".$input;
     }
 
-    if (&IsParam("backlog")) {
+    if (&IsParam('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 {
@@ -337,19 +338,19 @@ sub status {
     }
 
     # 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) {
-       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;
-    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];
@@ -375,9 +376,11 @@ sub debug_perl {
        &status("WARN: cannot open $file: $!");
        return;
     }
+    binmode(IN, ":encoding(UTF-8)");
 
     # 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.
@@ -412,6 +415,7 @@ sub openSQLDebug {
        delete $param{'SQLDebug'};
        return 0;
     }
+    binmode(SQLDEBUG, ":encoding(UTF-8)");
 
     &status("Opened SQL Debug file: $param{'SQLDebug'}");
     return 1;
@@ -424,7 +428,7 @@ sub closeSQLDebug {
 }
 
 sub SQLDebug {
-    return unless (&IsParam("SQLDebug"));
+    return unless (&IsParam('SQLDebug'));
 
     return unless (fileno SQLDEBUG);
 
@@ -432,3 +436,5 @@ sub SQLDebug {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
index bcbd3282a50665e8c1cfd1d80a21d5cc93b22557..3bb2bfa0057bd59d6374379a1aa5976321ff14d0 100644 (file)
@@ -7,7 +7,7 @@
 
 use strict;
 
-use vars qw($AUTOLOAD $no_timehires);
+use vars qw($AUTOLOAD $no_timehires $bot_version $bot_release);
 
 ###
 ### REQUIRED MODULES.
@@ -44,7 +44,7 @@ sub loadCoreModules {
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
-       &showProc(" ($_)") if (&IsParam("DEBUG"));
+       &showProc(" ($_)") if (&IsParam('DEBUG'));
     }
 }
 
@@ -71,7 +71,7 @@ sub loadDBModules {
 }
 
 sub loadFactoidsModules {
-    if (!&IsParam("factoids")) {
+    if (!&IsParam('factoids')) {
        &status("Factoid support DISABLED.");
        return;
     }
@@ -88,7 +88,7 @@ sub loadFactoidsModules {
        }
 
        $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.
-       &status("Loading Modules \"$mod\"") if (!&IsParam("DEBUG"));
+       &status("Loading Modules \"$mod\"") if (!&IsParam('DEBUG'));
        eval "require \"$mod\"";
        if ($@) {
            &ERROR("require \"$mod\" => $@");
@@ -124,7 +124,7 @@ sub loadIRCModules {
        }
 
        $moduleAge{$mod} = (stat $mod)[9];
-       &showProc(" ($_)") if (&IsParam("DEBUG"));
+       &showProc(" ($_)") if (&IsParam('DEBUG'));
     }
 }
 
@@ -154,10 +154,17 @@ sub loadMyModulesNow {
 
 ### rename to moduleReloadAll?
 sub reloadAllModules {
-    my $retval = "";
+    my $retval = '';
 
     &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($_);
@@ -171,7 +178,7 @@ sub reloadAllModules {
 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$/) {
@@ -347,3 +354,5 @@ sub getPerlFiles {
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80