-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
-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
-
-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.
--- /dev/null
+# $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
-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
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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.
+++ /dev/null
-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.
-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)
* 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
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
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
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.
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
for list of configuration options, run:
perl scripts/findparam.pl
+
+
+# vim:ts=4:sw=4:expandtab:tw=80
--- /dev/null
+# $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
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
- 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
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
- 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
+++ /dev/null
-#!/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;
--- /dev/null
+# $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:
+ ...
--- /dev/null
+=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
+
--- /dev/null
+=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
+
+++ /dev/null
-blootbot.chan
-blootbot.config
-blootbot.countdown
-blootbot.servers
-blootbot.uptime
-blootbot.users
-debian
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-
-#
-# 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
+++ /dev/null
-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 ©
-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.
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+
+#
+# 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
--- /dev/null
+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 ©
+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.
+++ /dev/null
-#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
-
+++ /dev/null
-# 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.
-####
+++ /dev/null
-# 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
+++ /dev/null
-###
-# blootbot.servers: line separated list of servers to connect to
-###
-
-irc.freenode.net
-irc.home.org
-irc.linux.com
+++ /dev/null
-#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
-
--- /dev/null
+#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
--- /dev/null
+# 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.
+####
--- /dev/null
+# 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
--- /dev/null
+###
+# infobot.servers: line separated list of servers to connect to
+###
+
+irc.freenode.net
+irc.home.org
+irc.linux.com
--- /dev/null
+#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
+
+++ /dev/null
-#
-# 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
--- /dev/null
+#!/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
--- /dev/null
+--- 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@ @)
+- {
+- $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;
++
--- /dev/null
+--- 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;
+ }
#!/bin/bash
BACKUP_SRCDIR="/var/lib/mysql/"
-BACKUP_TDIR="blootbot/"
+BACKUP_TDIR="infobot/"
BACKUP_FILE="/home/a/apt/public_html/tables.tar.bz2"
pwd
fi
exit 0;
+
+# vim:ts=4:sw=4:expandtab:tw=80
close OUT;
print "Done.\n";
+
+# vim:ts=4:sw=4:expandtab:tw=80
#!/bin/sh
BOTDIR=/home/apt/bot
-BOTNICK=blootbot
+BOTNICK=infobot
PIDFILE=$BOTDIR/$BOTNICK.pid
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
&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'});
print "Done.\n";
&closeDB();
dbmclose(%db);
+
+# vim:ts=4:sw=4:expandtab:tw=80
print "$key => $val\n";
}
dbmclose %db;
+
+# vim:ts=4:sw=4:expandtab:tw=80
foreach (sort keys %conf) {
print " $_\n";
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
use DBI;
-my $dsn = "DBI:mysql:blootbot:localhost";
+my $dsn = "DBI:mysql:infobot:localhost";
my $dbh = DBI->connect($dsn, "USERNAME", "PASSWORD");
my @factkey;
}
$dbh->disconnect();
+
+# vim:ts=4:sw=4:expandtab:tw=80
require "src/modules.pl";
require "src/Factoids/DBCommon.pl";
-&loadConfig($bot_config_dir."/blootbot.config");
+&loadConfig($bot_config_dir."/infobot.config");
&loadDBModules();
unless (@_) {
close IN;
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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
<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;
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
return crypt($what, $salt);
}
+# vim:ts=4:sw=4:expandtab:tw=80
}
# open the db.
-&loadConfig("files/blootbot.config");
+&loadConfig("files/infobot.config");
&loadDBModules();
&openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
print "Done.\n";
&closeDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
%z = (1,2,3,4, 5, 6, \@y);
$z = 300;
DUMPVAR::dumpvar("Test");
+
+# vim:ts=4:sw=4:expandtab:tw=80
$spaces = ": " x $level;
print "${spaces}$_[0]\n";
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
#!/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
print "=> error: could not open file.\n";
}
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
$spaces = ": " x $level;
print "${spaces}$_[0]\n";
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
print $padding."scalars $scalar, size $size\n";
return $size;
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
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'});
print "Done.\n";
&closeDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
print "end.\n";
}
+
+# vim:ts=4:sw=4:expandtab:tw=80
close OUT;
print "Done.\n";
+
+# vim:ts=4:sw=4:expandtab:tw=80
--- /dev/null
+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
+++ /dev/null
-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)
-);
+++ /dev/null
-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)
-);
+++ /dev/null
-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)
-);
+++ /dev/null
-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)
-);
--- /dev/null
+--
+-- 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;
--- /dev/null
+--
+-- 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;
--- /dev/null
+--
+-- 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;
--- /dev/null
+--
+-- 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;
--- /dev/null
+--
+-- 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;
--- /dev/null
+--
+-- 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;
+++ /dev/null
-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)
-);
+++ /dev/null
-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);
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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);
--- /dev/null
+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);
+++ /dev/null
-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)
-);
+++ /dev/null
-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)
-);
#!/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.
###
$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'};
&status("Done.");
&sqlCloseDB();
+
+# vim:ts=4:sw=4:expandtab:tw=80
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
--- /dev/null
+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)
+);
+++ /dev/null
-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)
-);
+++ /dev/null
-CREATE TABLE uptime (
- uptime INT UNSIGNED DEFAULT '0', # start.
- endtime INT UNSIGNED DEFAULT '0', # end.
- string VARCHAR(128) NOT NULL,
- PRIMARY KEY (uptime)
-);
$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)) ) {
}
if (!defined $msg) {
- $msg ||= "NULL";
+ $msg ||= 'NULL';
&WARN("msg: msg == $msg.");
return;
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
&seenFlush(); # very evil hack. oh well, better safe than sorry.
# TODO: convert to &sqlSelectRowHash();
- my $select = 'nick,time,channel,host,message,messagecount';
+ my $select = 'nick,time,channel,host,message';
if ($person eq 'random') {
@seen = &randKey('seen', $select);
} else {
if (&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);
return;
}
- &NewUnits::convertUnits($from, $to);
+ &Units::convertUnits($from, $to);
return;
}
$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;
$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;
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;
&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);
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);
&addCmdHook('bzfquery', ('CODEREF' => 'BZFlag::query', 'Identifier' => 'BZFlag', 'Cmdstats' => 'BZFlag', 'Forker' => 1, 'Module' => 'BZFlag') );
&addCmdHook('chan(stats|info)', ('CODEREF' => 'chaninfo', ) );
&addCmdHook('cmd(stats|info)', ('CODEREF' => 'cmdstats', ) );
-&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'NewUnits', 'Help' => 'convert') );
+&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'Units', 'Help' => 'convert') );
&addCmdHook('(cookie|random)', ('CODEREF' => 'cookie', 'Forker' => 1, 'Identifier' => 'Factoids') );
&addCmdHook('countdown', ('CODEREF' => 'countdown', 'Module' => 'countdown', 'Identifier' => 'countdown', 'Cmdstats' => 'countdown') );
&addCmdHook('countrystats', ('CODEREF' => 'countryStats') );
&addCmdHook('factinfo', ('CODEREF' => 'factinfo', 'Cmdstats' => 'Factoid Info', Module => 'Factoids', ) );
&addCmdHook('factstats?', ('CODEREF' => 'factstats', 'Cmdstats' => 'Factoid Stats', Help => 'factstats', Forker => 1, 'Identifier' => 'Factoids', ) );
&addCmdHook('help', ('CODEREF' => 'help', 'Cmdstats' => 'Help', ) );
+&addCmdHook('hex2ip', ('CODEREF' => 'hex2ip::query', 'Forker' => 1, 'Identifier' => 'hex2ip', 'Cmdstats' => 'hex2ip', 'Help' => 'hex2ip') );
&addCmdHook('HTTPDtype', ('CODEREF' => 'HTTPDtype::HTTPDtype', 'Identifier' => 'HTTPDtype', 'Cmdstats' => 'HTTPDtype', 'Forker' => 1) );
&addCmdHook('[ia]?spell', ('CODEREF' => 'spell::query', 'Identifier' => 'spell', 'Cmdstats' => 'spell', 'Forker' => 1, 'Help' => 'spell') );
&addCmdHook('insult', ('CODEREF' => 'Insult::Insult', 'Forker' => 1, 'Identifier' => 'insult', 'Help' => 'insult' ) );
&addCmdHook('listauth', ('CODEREF' => 'CmdListAuth', 'Identifier' => 'Search', Module => 'Factoids', 'Help' => 'listauth') );
&addCmdHook('md5(sum)?', ('CODEREF' => 'md5::md5', 'Identifier' => 'md5', 'Cmdstats' => 'md5', 'Forker' => 1, 'Module' => 'md5') );
&addCmdHook('metar', ('CODEREF' => 'Weather::Metar', 'Identifier' => 'Weather', 'Help' => 'weather', 'Cmdstats' => 'Weather', 'Forker' => 1) );
-&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News' ) );
+&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News', 'Identifier' => 'News' ) );
&addCmdHook('(?:nick|lame)ometer(?: for)?', ('CODEREF' => 'nickometer::query', 'Identifier' => 'nickometer', 'Cmdstats' => 'nickometer', 'Forker' => 1) );
&addCmdHook('nullski', ('CODEREF' => 'nullski', ) );
&addCmdHook('page', ('CODEREF' => 'pager::page', 'Identifier' => 'pager', 'Cmdstats' => 'pager', 'Forker' => 1, 'Help' => 'page') );
&addCmdHook('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') );
&status('loaded '.scalar(keys %cmdhooks).' command hooks.');
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
#####
sub readUserFile {
- my $f = "$bot_state_dir/blootbot.users";
+ my $f = "$bot_state_dir/infobot.users";
+ if (! -e $f and -e "$bot_state_dir/blootbot.users") {
+ $f = "$bot_state_dir/blootbot.users";
+ }
if (! -f $f) {
&DEBUG("userfile not found; new fresh run detected.");
if (/^--(\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;
}
}
# nice little hack.
- if ($what eq "HOSTS") {
+ if ($what eq 'HOSTS') {
$users{$nick}{$what}{$val} = 1;
} else {
$users{$nick}{$what} = $val;
} 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);
} 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);
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;
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";
}
#####
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~";
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) {
# TODO: return all flags for opers
sub IsFlag {
my $flags = shift;
- my ($ret, $f, $o) = "";
+ my ($ret, $f, $o) = '';
&verifyUser($who, $nuh);
return $userHandle;
}
- $userHandle = "";
+ $userHandle = '';
foreach $user (keys %users) {
next if ($user eq "_default");
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).");
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;
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;
sub banAdd {
my($mask,$chan,$expire,$reason) = @_;
- $chan ||= "*";
+ $chan ||= '*';
$expire ||= 0;
if ($expire > 0) {
exists $bans{'*'}{$mask});
$bans{$chan}{$mask} = [$expire, time(), 0, $who, $reason];
- my @chans = ($chan eq "*") ? keys %channels : $chan;
+ my @chans = ($chan eq '*') ? keys %channels : $chan;
my $m = $mask;
$m =~ s/\?/\\./g;
$m =~ s/\*/\\S*/g;
my $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;
}
}
# 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++;
&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++;
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
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;
/\\\%/ 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.
if ($param{'acceptUrl'} !~ /REQUIRE/ or $rhs =~ /(http|ftp|mailto|telnet|file):/) {
&msg($target, "$who knew: $lhs $mhs $rhs");
- # "are" hack :)
- $rhs = "<REPLY> are" if ($mhs eq "are");
- &setFactInfo($lhs, "factoid_value", $rhs);
+ # 'are' hack :)
+ $rhs = "<REPLY> are" if ($mhs eq 'are');
+ &setFactInfo($lhs, 'factoid_value', $rhs);
}
return 'INFOBOT REPLY';
return 'forget: no addr' unless ($addressed);
my $faqtoid = $message;
- if ($faqtoid eq "") {
- &help("forget");
+ if ($faqtoid eq '') {
+ &help('forget');
return;
}
}
# 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;
}
# 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);
# 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*$/) {
&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 {
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;
}
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?
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;
if ($message =~ s/^rename(\s+|$)//) {
return 'rename: no addr' unless ($addressed);
- if ($message eq "") {
- &help("rename");
+ if ($message eq '') {
+ &help('rename');
return;
}
}
# 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;
}
return;
}
- &setFactInfo($from,"factoid_key",$to);
+ &setFactInfo($from,'factoid_key',$to);
&status("rename: <$who> '$from' is now '$to'");
&performReply("i renamed '$from' to '$to'");
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");
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'");
}
# 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;
&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");
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
#####
# Usage: &setFactInfo($faqtoid, $key, $val);
sub setFactInfo {
- &sqlSet("factoids",
+ &sqlSet('factoids',
{ factoid_key => $_[0] },
{ $_[1] => $_[2] }
);
#####
# 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');
}
#####
sub delFactoid {
my ($faqtoid) = @_;
- &sqlDelete("factoids", { factoid_key => $faqtoid } );
+ &sqlDelete('factoids', { factoid_key => $faqtoid } );
&status("DELETED $faqtoid");
return 1;
# 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;
}
# 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) {
}
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;
}
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;
}
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
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;
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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;
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?
# 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;
}
$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);
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.
return;
}
- last if (!defined $newr or $newr eq "");
+ last if (!defined $newr or $newr eq '');
$result = $newr;
}
### 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");
# 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) );
}
# 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
$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;
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
} else {
$factoid = "$search $message";
}
- ($count, $fauthor, $result) = &sqlSelect("factoids",
+ ($count, $fauthor, $result) = &sqlSelect('factoids',
"requested_count,created_by,factoid_value",
{ factoid_key => $factoid }
);
if ($result) {
$lhs = $message;
- $mhs = "is";
+ $mhs = 'is';
$rhs = $result;
return "\"$factoid\" $mhs \"$rhs\"" if ($literal);
$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
### 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
# 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.
### bot->person reply.
# result is random if separated by '||'.
# rhs is full factoid with '||'.
- if ($mhs eq "is") {
+ if ($mhs eq 'is') {
$reply = &getRandom(keys %{ $lang{'factoid'} });
$reply =~ s/##KEY/$lhs/;
$reply =~ s/##VALUE/$result/;
$reply = "$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);
+ }
+ }
}
}
}
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/;
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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:/);
}
# 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
}
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;
$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";
}
&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;
return if (&update($lhs, $mhs, $rhs));
}
- return "CONTINUE";
+ return 'CONTINUE';
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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;
# 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'.");
# 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.");
}
}
}
- &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) {
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.");
}
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
while (<FILE>) {
chop;
- if ($_ eq "" || /^#/) {
+ if ($_ eq '' || /^#/) {
undef $replyName;
next;
}
# File: Irc Servers list.
sub loadIRCServers {
- my ($file) = $bot_config_dir."/blootbot.servers";
+ my ($file) = $bot_config_dir."/infobot.servers";
@ircServers = ();
%ircPort = ();
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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;
# 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");
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;
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)) {
return unless (&whatInterface() =~ /IRC/);
- $msg = "zero" if ($msg =~ /^0+$/);
+ $msg = 'zero' if ($msg =~ /^0+$/);
my $t = time();
$pubcount++;
$pubsize += length $msg;
- my $i = &getChanConfDefault("sendPublicLimitLines", 3, $chan);
- my $j = &getChanConfDefault("sendPublicLimitBytes", 1000, $chan);
+ my $i = &getChanConfDefault('sendPublicLimitLines', 3, $chan);
+ my $j = &getChanConfDefault('sendPublicLimitBytes', 1000, $chan);
if ( ($pubcount % $i) == 0 and $pubcount) {
sleep 1;
}
if (!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/);
$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) {
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);
$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;
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...
my $chan;
foreach $chan (@_) {
- next if ($chan eq "");
+ next if ($chan eq '');
$chan =~ tr/A-Z/a-z/; # lowercase.
if ($chan !~ /^$mask{chan}$/) {
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;
}
}
# chanserv check: global channels, in case we missed one.
- foreach ( &ChanConfList("chanServ_ops") ) {
+ foreach ( &ChanConfList('chanServ_ops') ) {
&chanServCheck($_);
}
}
}
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;
}
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);
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.");
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
#####
# 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;
+ }
}
}
$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;
&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) {
return if ($lobotomized);
if (!scalar @who) {
- push(@who,"Someone");
+ push(@who,'Someone');
}
&msg($who,join(' ', @who)." already said that ". (time - $time) ." seconds ago" );
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.
@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.
$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. "\"");
$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;
}
$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.");
}
# 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/^\-//;
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
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");
}
}
}
### set vars that would have been set in hookMsg.
- $userHandle = ""; # reset.
+ $userHandle = ''; # reset.
$who = lc $nick;
$message = $msg;
$orig{who} = $nick;
my $crypto = $users{$userHandle}{PASS};
my $success = 0;
- if ($userHandle eq "_default") {
+ if ($userHandle eq '_default') {
&WARN("DCC CHAT: _default/guest not allowed.");
return;
}
$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++;
$dcc{'CHATvrfy'}{$nick} = $userHandle;
- return if ($userHandle eq "_default");
+ return if ($userHandle eq '_default');
&dccsay($nick,"Flags: $users{$userHandle}{FLAGS}");
}
### TODO: make use of &Forker(); here?
&loadMyModule('UserDCC');
- &DCCBroadcast("#$who# $message","m");
+ &DCCBroadcast("#$who# $message",'m');
my $retval = &userDCC();
return unless (defined $retval);
# 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;
}
}
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 +");
$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'}");
}
### 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);
}
$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;
&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.");
}
}
&WARN("scheduling call ircCheck() in 60s");
&clearIRCVars();
- &ScheduleThis(1, "ircCheck");
+ &ScheduleThis(1, 'ircCheck');
}
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");
}
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);
# 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");
### 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 = $_;
}
my $reason = "no reason";
- foreach ($chan, "*") {
+ foreach ($chan, '*') {
next unless (exists $bans{$_});
next unless (exists $bans{$_}{$ban});
$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");
$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;
}
&hookMsg('private', undef, $nick, $msg);
- $who = "";
- $chan = "";
- $msgType = "";
+ $who = '';
+ $chan = '';
+ $msgType = '';
}
sub on_names {
$conn = shift(@_);
my $nick = $conn->nick();
#my $newnick = $nick . int(rand 10);
- my $newnick = $nick . "_";
+ my $newnick = $nick . '_';
&DEBUG("on_nick_taken: nick => $nick");
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;
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.");
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!");
&clearChanVars($chan);
}
- if (!&IsNickInAnyChan($nick) and &IsChanConf("seenStats") > 0) {
+ if (!&IsNickInAnyChan($nick) and &IsChanConf('seenStats') > 0) {
delete $userstats{lc $nick};
}
$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;
$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();
}
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);
}
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,
$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,
&hookMsg('public', $chan, $nick, $msg);
$chanstats{$chan}{'PublicMsg'}++;
- $who = "";
- $chan = "";
- $msgType = "";
+ $who = '';
+ $chan = '';
+ $msgType = '';
}
sub on_quit {
my $reason = ($event->args)[0];
# hack for ICC.
- $msgType = "public";
+ $msgType = 'public';
$who = $nick;
### $chan = $reason; # no.
# 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.");
# 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};
###
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# )
#%schedule = {
-# uptimeLoop => ("", 60, 1),
+# uptimeLoop => ('', 60, 1),
#};
sub setupSchedulersII {
&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);
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.");
#### 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;
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:/));
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'}) {
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) {
while (my @row = $sth->fetchrow_array) {
my ($nick,$time) = @row;
- &sqlDelete("seen", { nick => $nick } );
+ &sqlDelete('seen', { nick => $nick } );
$delete++;
}
$sth->finish;
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')) {
}
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'};
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'}++;
}
# 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?");
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} }) {
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};
$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);
}
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()
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();
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;
$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?
} 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...");
}
}
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.
}
# 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} }) {
# 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;
}
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.
# }
#
# if (@_) {
-# &ScheduleThis(30, "getNickInUse");
-# return if ($_[0] eq "2"); # defer.
+# &ScheduleThis(30, 'getNickInUse');
+# return if ($_[0] eq '2'); # defer.
# }
#
# &nick( $param{'ircNick'} );
# return unless &IsParam('Uptime');
if (@_) {
- &ScheduleThis(60, 'uptimeLoop');
+ &ScheduleThis(3600, 'uptimeLoop'); # once per hour
return if ($_[0] eq '2'); # defer.
}
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');
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');
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) {
### 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.
### 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);
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) {
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()) );
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 {
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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): $!");
$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;
# Usage: &IJoin(@array);
sub IJoin {
if (!scalar @_) {
- return "NULL";
+ return 'NULL';
} elsif (scalar @_ == 1) {
return $_[0];
} else {
# 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) {
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;
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;
+ }
}
##########
$this{'host'} = &makeHostMask(lc $3);
} else {
&WARN("IHM: thisnuh is invalid '$thisnuh'.");
- return 1 if ($thisnuh eq "");
+ return 1 if ($thisnuh eq '');
return 0;
}
# 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");
sub checkMsgType {
my ($reply) = @_;
- return unless (&IsParam("minLengthBeforePrivate"));
+ return unless (&IsParam('minLengthBeforePrivate'));
return if ($force_public_reply);
if (length $reply > $param{'minLengthBeforePrivate'}) {
&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';
}
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);
$i += $cmdstats{$type};
- &sqlReplace("stats", {
- nick => $type,
- type => "cmdstats",
+ &sqlSet('stats', {'nick' => $type}, {
+ type => 'cmdstats',
'time' => time(),
counter => $i,
} );
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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);
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;
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);
$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;
&::status("BZFlag module requires Socket.");
return 'BZFlag module not active';
}
- #my @teamName = ("Rogue", "Red", "Green", "Blue", "Purple", "Observer", "Rabbit");
- my @teamName = ("X", "R", "G", "B", "P", "O", "K");
+ #my @teamName = ('Rogue', 'Red', 'Green', 'Blue', 'Purple', 'Observer', 'Rabbit');
+ my @teamName = ('X', 'R', 'G', 'B', 'P', 'O', 'K');
my ($message, $server, $response);
$port = 5154 unless $port;
my ($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) {
$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;
($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) ";
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;
# 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
$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;
($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) ";
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;
# 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);
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;
$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;
}
1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
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 = (
);
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",
);
#####################
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'){
%dist_urls = %urlpackages;
}
}
-
+
while (($key,$val) = each %dist_urls) {
$key =~ s/##DIST/$dist/;
$val =~ s/##DIST/$dist/;
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
__END__
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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;
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) {
$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
sub dumpvarslog {
my ($line) = @_;
- if (&IsParam("dumpvarsLogFile")) {
+ if (&IsParam('dumpvarsLogFile')) {
print DUMPVARS $line."\n";
} else {
&status("DV: ".$line);
my $line;
if ($packname eq 'main::') {
- &dumpvarslog("Packages");
+ &dumpvarslog('Packages');
foreach $symname (sort keys %$package) {
local *sym = $$package{$symname};
}
sub dumpallvars {
- if (&IsParam("dumpvarsLogFile")) {
+ if (&IsParam('dumpvarsLogFile')) {
my $file = $param{'dumpvarsLogFile'};
&status("opening fh to dumpvars ($file)");
if (!open(DUMPVARS,">$file")) {
DumpNames(%main::,'main::');
- if (&IsParam("dumpvarsLogFile")) {
+ if (&IsParam('dumpvarsLogFile')) {
&status("closing fh to dumpvars");
close DUMPVARS;
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
sub symdumpRecur {
my $x = shift;
- if (ref $x eq "HASH") {
+ if (ref $x eq 'HASH') {
foreach (keys %$x) {
&symdumpRecur($_);
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
#!/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>
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;
}
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);
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';
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+/,
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.
return;
}
-
+#print &exchange('1 usd to eur') . "\n";
1;
__END__
=head1 AUTHORS
Bobby <bobby@bofh.dk>
+
+# vim:ts=4:sw=4:expandtab:tw=80
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 }
);
if ($factinfo{'created_by'}) {
$factinfo{'created_by'} =~ s/\!/ </;
- $factinfo{'created_by'} .= ">";
+ $factinfo{'created_by'} .= '>';
$string = "created by $factinfo{'created_by'}";
my $time = $factinfo{'created_time'};
$string .= " 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 asks: why 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);
}
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'};
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);
return;
}
- &performStrictReply("$factinfo{'factoid_key'} -- ". join("; ", @array) .".");
+ &performStrictReply("$factinfo{'factoid_key'} -- ". join('; ', @array) .'.');
return;
}
my ($type) = @_;
if ($type =~ /^author$/i) {
- my %hash = &sqlSelectColHash("factoids",
- "factoid_key,created_by", undef,
- "WHERE created_by IS NOT NULL"
+ my %hash = &sqlSelectColHash('factoids',
+ 'factoid_key,created_by', undef,
+ 'WHERE created_by IS NOT NULL'
);
my %author;
my $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.
}
$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) {
}
# 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;
### 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.
}
# 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);
}
# 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;
}
s/([\,\;]+)/\037$1\037/g;
- if ($_ eq "") {
- &WARN("dupe: _ = NULL. should never happen!.");
+ if ($_ eq '') {
+ &WARN('dupe: _ = NULL. should never happen!.');
next;
}
push(@sublist, $_);
next 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) {
my @list;
while (my @row = $sth->fetchrow_array) {
- if ($row[1] ne "") {
+ if ($row[1] ne '') {
&DEBUG("row[1] != NULL for $row[0].");
next;
}
$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;
$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;
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;
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;
}
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;
}
$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;
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 {
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) {
}
$total += $count * scalar(@faqtoids);
- push(@list, "$count - ". join(", ", @faqtoids));
+ push(@list, "$count - ". join(', ', @faqtoids));
}
unshift(@list, "\037$total - TOTAL\037");
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;
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);
return &formListReply(0, $prefix, @list);
} elsif ($type =~ /^requesters?$/i) {
- my %hash = &sqlSelectColHash("factoids",
- "factoid_key,requested_by", undef,
- "WHERE requested_by IS NOT NULL"
+ my %hash = &sqlSelectColHash('factoids',
+ 'factoid_key,requested_by', undef,
+ 'WHERE requested_by IS NOT NULL'
);
my %requester;
my $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");
# 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;
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);
}
if (defined $redir) { # good.
- &setFactInfo($factoid,"factoid_value","<REPLY> see $redir");
+ &setFactInfo($factoid,'factoid_value',"<REPLY> see $redir");
$fixed++;
} else {
push(@newlist, $redirf);
# 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);
$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) {
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' ";
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
$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
}
sub Kernel {
- my $retval = "Linux kernel versions";
+ my $retval = 'Linux kernel versions';
my @now = &kernelGetInfo();
if (!scalar @now) {
&::msg($::who, "failed.");
}
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) {
$line =~ s/ for 2.4//;
$line =~ s/ for 2.2//;
$line =~ s/ is: */: /;
- $retval .= ", " . $line;
+ $retval .= ', ' . $line;
}
&::performStrictReply($retval);
}
my @old;
if (!scalar @now) {
- &::DEBUG("kA: failure to retrieve.");
+ &::DEBUG('kA: failure to retrieve.');
return;
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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 {
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;
}
&FIXME("math: locMsg => '$locMsg'...");
} else {
&status("math: could not really compute.");
- $locMsg = "";
+ $locMsg = '';
}
}
} else {
- $locMsg = "";
+ $locMsg = '';
}
if (defined $locMsg and $locMsg ne $message) {
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
+++ /dev/null
-# 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;
&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*//) {
} 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;
} 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;
}
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;
}
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'
);
}
}
# 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.");
}
# 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.
my($str) = @_;
if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
- &::help("news add");
+ &::help('news add');
return;
}
}
$::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!
my $item = 0;
if (!defined $what) {
- &::help("news del");
+ &::help('news del');
return;
}
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.
return;
}
- if (&::IsChanConf("newsKeepRead") > 0) {
+ if (&::IsChanConf('newsKeepRead') > 0) {
my $x = $::newsuser{$chan}{$who};
if (defined $x and ($x == 0 or $x == -1)) {
}
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");
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.");
my($str) = @_;
if (!defined $chan or !defined $str or $str =~ /^\s*$/) {
- &::help("news read");
+ &::help('news read');
return;
}
}
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;
}
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;
}
# 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);
}
$what = $1 if ($args =~ s/^(\S+)\s*//);
$value = $args;
- if ($item eq "") {
- &::help("news set");
+ if ($item eq '') {
+ &::help('news set');
return;
}
}
my $ok = 0;
- my @elements = ("Expire","Text");
+ my @elements = ('Expire','Text');
foreach (@elements) {
next unless ($what =~ /^$_$/i);
$what = $_;
return;
}
- if ($what eq "Expire") {
+ if ($what eq 'Expire') {
# TODO: use do_set().
my $time = 0;
# &::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;
}
$::chan = $chan;
- return if (&::IsChanConf("newsNotifyAll") <= 0);
+ return if (&::IsChanConf('newsNotifyAll') <= 0);
# I don't understand this code ;)
$t = 1 if (!defined $t);
# scalar @new, !$flag
my $unread = scalar @new;
my $total = scalar keys %{ $::news{$chan} };
- if (!$flag && &::IsChanConf("newsTellUnread") <= 0) {
+ if (!$flag && &::IsChanConf('newsTellUnread') <= 0) {
return;
}
sub AUTOLOAD { &::AUTOLOAD(@_); }
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
my $nick = $3;
my $msg = $5;
- # get options
+ # get options
my $strict = &getChanConf('onjoinStrict');
my $ops = &getChanConf('onjoinOpsOnly');
&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');
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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);
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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");
"Opened $open, Volume $newvol, Change $change";
}
- if ($reply eq "") {
+ if ($reply eq '') {
$reply = "i couldn't get the quote for $stock. sorry. :(";
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
--- /dev/null
+#
+# 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
&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')) {
$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,
}
# reply #1.
- $reply = "there ".&fixPlural("has",$count) ." been \002$count\002 ".
- &fixPlural("rooter",$count) ." warned about root.";
+ $reply = 'there '.&fixPlural('has',$count) ." been \002$count\002 ".
+ &fixPlural('rooter',$count) ." warned about root.";
if ($param{'DBType'} !~ /^(pg|my)sql$/i) {
&FIXME("rootwarn does not yet support non-{my,pg}sql.");
if ($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.";
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
$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);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
my $subtopic = $_;
- my $owner = "Unknown";
+ my $owner = 'Unknown';
if (/(.*)\s+\((.*?)\)$/) {
$subtopic = $1;
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");
}
}
return 1;
}
- if (defined $updateMsg && $updateMsg ne "") {
+ if (defined $updateMsg && $updateMsg ne '') {
&msg($who, $updateMsg);
}
$conn->topic($chan, $topic);
&topicAddHistory($chan, $topic);
} else {
- $conn->topic($chan, " ");
+ $conn->topic($chan, ' ');
}
return 1;
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.
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) {
$new = &topicCipher(@prev, $str);
}
- &topicNew($chan, $new, "");
+ &topicNew($chan, $new, '');
}
# cmd: 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;
}
}
my @delete;
- foreach (split ",", $args) {
- next if ($_ eq "");
+ foreach (split ',', $args) {
+ next if ($_ eq '');
# change to hash list instead of array?
if (/^(\d+)-(\d+)$/) {
return;
}
- $topic{$chan}{'What'} = "Deleted ".join("/",@delete);
+ $topic{$chan}{'What'} = 'Deleted '.join("/",@delete);
}
foreach (@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];
push(@newtopics, $_);
}
- &topicNew($chan, &topicCipher(@newtopics), "");
+ &topicNew($chan, &topicCipher(@newtopics), '');
}
# cmd: list
sub do_modify {
my ($chan, $args) = @_;
- if ($args eq "") {
- &help("topic mod");
+ if ($args eq '') {
+ &help('topic mod');
return;
}
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/.";
sub do_move {
my ($chan, $args) = @_;
- if ($args eq "") {
- &help("topic mv");
+ if ($args eq '') {
+ &help('topic mv');
return;
}
undef @subtopics; # lets reuse this array.
foreach (@newtopics) {
- next if (!defined $_ or $_ eq "");
+ next if (!defined $_ or $_ eq '');
push(@subtopics, $_);
}
my @subtopics = &topicDecipher($chan);
my @newtopics;
- $topic{$chan}{'What'} = "shuffled";
+ $topic{$chan}{'What'} = 'shuffled';
foreach (&makeRandom(scalar @subtopics)) {
push(@newtopics, $subtopics[$_]);
sub do_restore {
my ($chan, $args) = @_;
- if ($args eq "") {
- &help("topic restore");
+ if ($args eq '') {
+ &help('topic restore');
return;
}
my ($chan) = @_;
$_ = "Rehashing topic...";
- $topic{$chan}{'What'} = "Rehash";
+ $topic{$chan}{'What'} = 'Rehash';
&topicNew($chan, $topic{$chan}{'Current'}, $_, 1);
}
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);
} 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
# 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
}
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
if ($message =~ /^tellme(\s+(.*))?$/i) {
my $args = $2;
if ($args =~ /^\s*$/) {
- &help("tellme");
+ &help('tellme');
return;
}
# 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;
}
# 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;
}
# 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.");
# 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();
# 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);
# 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;
}
# 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;
}
# 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;
}
# 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}; # ??
# op.
if ($message =~ /^op(\s+(.*))?$/i) {
- return unless (&hasFlag("o"));
+ return unless (&hasFlag('o'));
my ($opee) = lc $2;
my @chans;
# deop.
if ($message =~ /^deop(\s+(.*))?$/i) {
- return unless (&hasFlag("o"));
+ return unless (&hasFlag('o'));
my ($opee) = lc $2;
my @chans;
# 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();
# global factoid substitution.
if ($message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
my ($delim,$op,$np) = ($1, $2, $3);
- return unless (&hasFlag("n"));
+ return unless (&hasFlag('n'));
### TODO: support flags to do full-on global.
# incorrect format.
### TODO: 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.");
}
&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) {
&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'.");
}
&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;
}
# reload.
if ($message =~ /^reload$/i) {
- return unless (&hasFlag("n"));
+ return unless (&hasFlag('n'));
&status("USER reload $who");
&performStrictReply("reloading...");
# reset.
if ($message =~ /^reset$/i) {
- return unless (&hasFlag("n"));
+ return unless (&hasFlag('n'));
&msg($who,"resetting...");
my @done;
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;
}
my @args = split /[\s\t]+/, $2; # hrm.
if (scalar @args != 1) {
- &help("chaninfo");
+ &help('chaninfo');
return;
}
}
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) {
}
### 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?
}
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;
}
$delete = ($1) ? 1 : 0;
} else {
&VERB("no chan arg; setting to default.",2);
- $chan = "_default";
+ $chan = '_default';
$no_chan = 1;
}
return;
}
- if ($args ne "") {
+ if ($args ne '') {
if (!&getChanConf($args,$chan)) {
&performStrictReply("$args does not exist for $chan");
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};
my(@args) = split /[\s\t]+/, $2 || '';
if (scalar @args != 1) {
- &help("newpass");
+ &help('newpass');
return;
}
my(@args) = split /[\s\t]+/, $2 || '';
if (!scalar @args) {
- &help("chpass");
+ &help('chpass');
return;
}
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;
}
my(@args) = split /[\s\t]+/, $2 || '';
if (!scalar @args) {
- &help("chattr");
+ &help('chattr');
return;
}
&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;
next if ($flags =~ /\Q$_\E/);
$flags .= $_;
} else {
- if (&IsParam("owner")
+ if (&IsParam('owner')
and $param{owner} =~ /^\Q$user\E$/i
and $flags =~ /[nmo]/
) {
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;
}
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;
}
}
if ($message =~ /^([-+])host(\s+(.*))?$/) {
- my $cmd = $1."host";
+ my $cmd = $1.'host';
my(@args) = split /[\s\t]+/, $3 || '';
my $state = ($1 eq "+") ? 1 : 0;
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>
}
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;
}
}
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;
if ($flatarg =~ s/^($mask{chan})\s*//) {
$chan = $1;
} else {
- $chan = "*"; # _default instead?
+ $chan = '*'; # _default instead?
}
if ($state == 0) { # delete.
$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;
}
my $arg = $2;
if (!defined $arg) {
- &help("whois");
+ &help('whois');
return;
}
foreach (keys %{ $users{$user} }) {
my $ref = ref $users{$user}{$_};
- if ($ref eq "HASH") {
+ if ($ref eq 'HASH') {
my $type = $_;
### DOES NOT WORK???
foreach (keys %{ $users{$user}{$type} }) {
my $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;
}
foreach (keys %{ $bans{$c} }) {
my $val = $bans{$c}{$_};
- if (ref $val eq "ARRAY") {
+ if (ref $val eq 'ARRAY') {
my @array = @{ $val };
&performStrictReply(" $_: @array");
} else {
}
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;
}
# 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) {
if ($args =~ s/^($mask{chan}|\*)\s*//) {
$chan = $1;
} else {
- $chan = "*";
+ $chan = '*';
}
# time.
foreach (keys %{ $ignore{$c} }) {
my $ref = ref $ignore{$c}{$_};
- if ($ref eq "ARRAY") {
+ if ($ref eq 'ARRAY') {
my @array = @{ $ignore{$c}{$_} };
&performStrictReply(" $_: @array");
} else {
# adduser/deluser.
if ($message =~ /^(add|del)user(\s+(.*))?$/i) {
my $str = $1;
- my $strstr = $1."user";
+ my $strstr = $1.'user';
my @args = split /\s+/, $3 || '';
my $args = $3;
my $state = ($str =~ /^(add)$/) ? 1 : 0;
my @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($_).")");
}
}
# 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);
return;
}
- return "REPLY";
+ return 'REPLY';
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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 {
}
my $result;
- if ($result = &getFactoid($query." info")) {
+ if ($result = &getFactoid($query.' info')) {
# good.
} else { # bad.
&performReply("No User Information on \002$query\002");
$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'.");
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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;
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
}
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");
. " 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.";
}
}
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";
1;
+# vim:ts=4:sw=4:expandtab:tw=80
+
__END__
=head1 NAME
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);
&::status("Wingate: RUNNING ON $host BY $::who.");
if (&::IsChanConf('wingateBan') > 0) {
- &::ban("*!*\@$host", "");
+ &::ban("*!*\@$host", '');
}
my $reason = &::getChanConf('wingateKick');
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
sub zippy::get {
my @yows;
- &::DEBUG("Reading zippy data");
+ &::DEBUG('Reading zippy data');
while (<DATA>) {
chomp;
push @yows, $_;
1;
+# vim:ts=4:sw=4:expandtab:tw=80
+
=pod
=head1 NAME
$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);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
my($what) = @_;
if (!defined $what or $what =~ /^\s*$/) {
- &::help("botmail");
+ &::help('botmail');
return;
}
}
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). ".");
}
#####
my($recipient, $always) = @_;
$recipient ||= $::who;
- my %from = &::sqlSelectColHash("botmail", "srcwho,time", {
+ my %from = &::sqlSelectColHash('botmail', "srcwho,time", {
dstwho => lc $recipient
} );
my $t = keys %from;
sub next {
my($recipient) = @_;
- my %hash = &::sqlSelectRowHash("botmail", "*", {
+ my %hash = &::sqlSelectRowHash('botmail', '*', {
dstwho => lc $recipient
} );
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}});
}
}
# 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) {
return;
}
- &::sqlReplace("botmail", {
+ &::sqlInsert('botmail', {
'dstwho' => lc $recipient,
'srcwho' => lc $::who,
'srcuh' => $::nuh,
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
sub upper {
my($message) = @_;
- &::performStrictReply(uc $message);
+ # make it green like an old terminal
+ &::performStrictReply("\00303" . uc $message);
}
sub lower {
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
POSSIBILITY OF SUCH DAMAGE.
=cut
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
--- /dev/null
+#
+# 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
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);
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
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
### 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 ($_%)");
}
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/;
$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),
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
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;
&::performStrictReply($retval);
}
-"pager";
-# vim: ts=2 sw=2
+'pager';
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
sub reverse {
my($message) = @_;
- &::performStrictReply(join("",reverse(split("",$message))));
+ &::performStrictReply(join('',reverse(split('',$message))));
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
}
# 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));
# 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
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);
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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;
}
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'";
}
1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
-# This program is distributed under the same terms as blootbot.
+# This program is distributed under the same terms as infobot.
package wikipedia;
use strict;
&::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);
#$text = substr($text, 0, 330);
#$text =~ s/(.+)\.([^.]*)$/$1./g;
- return("At " . $url . " (URL), Wikipedia explains: " . $text,
+ return('At ' . $url . " (URL), Wikipedia explains: " . $text,
1);
}
}
&::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);
} 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);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
return("argument appears to be fuzzy.");
}
- my $reply ="";
+ my $reply ='';
foreach (`$binary '$query' 2>&1`){
$reply .= $_;
}
}
1;
-# vim: ts=2 sw=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
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);
}
1;
-# vim: shiftwidth=2 tabstop=2
__END__
+
+# vim:ts=4:sw=4:expandtab:tw=80
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);
}
1;
-# vim: shiftwidth=2 tabstop=2
+
+# vim:ts=4:sw=4:expandtab:tw=80
+
__END__
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));
}
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);
}
$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);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# 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.
$2 =~ /^($mask{chan})(\s+(\S+))?/;
my($joinchan, $key) = (lc $1, $3);
- if ($joinchan eq "") {
- &help("join");
+ if ($joinchan eq '') {
+ &help('join');
return;
}
return;
}
- if (&IsFlag("o") ne "o") {
+ if (&IsFlag('o') ne 'o') {
if (!exists $chanconf{$joinchan}) {
&msg($who, "I am not allowed to join $joinchan.");
return;
}
if (!scalar @array or scalar @array > 2) {
- &help("identify");
+ &help('identify');
return;
}
}
if (scalar @array != 1) {
- &help("pass");
+ &help('pass');
return;
}
if ($first) {
&performStrictReply("First time user... adding you as Master.");
- $users{$who}{FLAGS} = "aemnorst";
+ $users{$who}{FLAGS} = 'aemnorst';
}
my $crypt = $users{$who}{PASS};
}
# allowOutsiders.
- if (&IsParam("disallowOutsiders") and $msgType =~ /private/i) {
+ if (&IsParam('disallowOutsiders') and $msgType =~ /private/i) {
my $found = 0;
foreach (keys %channels) {
}
# customized random message.
- my $tmp = (rand() < 0.5) ? ", $who" : "";
+ my $tmp = (rand() < 0.5) ? ", $who" : '';
&performStrictReply( &getRandom(keys %{ $lang{'hello'} }) . $tmp );
return;
}
# 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);
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,
} );
}
# 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) {
}
# allow administration of bot via messages (default is DCC CHAT only)
- if (&IsFlag("A")) {
+ if (&IsFlag('A')) {
&loadMyModule('UserDCC');
$er = &userDCC();
if (!defined $er) {
}
}
- 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.";
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
my $IPC_PRIVATE = 0;
my $size = 2000;
- if (&IsParam("noSHM")) {
+ if (&IsParam('noSHM')) {
&status("Shared memory: Disabled. WARNING: bot may become unreliable");
return 0;
}
my $size = 3*80;
my $retval = '';
- return '' if (&IsParam("noSHM"));
+ return '' if (&IsParam('noSHM'));
if (shmread($key,$retval,$position,$size)) {
#&DEBUG("shmRead($key): $retval");
my $position = 0;
my $size = 80*3;
- return if (&IsParam("noSHM"));
+ return if (&IsParam('noSHM'));
$shm_keys{$keys}{accessed} = 1;
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;
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;
}
}
- &shmWrite($shm,"") if ($shmmsg ne "");
+ &shmWrite($shm,'') if ($shmmsg ne '');
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
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.
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();
}
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));
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();
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.
# 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");
}
# 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.");
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");
&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;
# no such factoid.
if (!defined $result || $result =~ /^0?$/) {
$who = $target;
- $msgType = "private";
+ $msgType = 'private';
# support command redirection.
# recursive cmdHooks aswell :)
return;
}
- if ($chan eq "") {
+ if ($chan eq '') {
$chan = $_[0];
}
- if ($chan eq "") {
- &help("countrystats");
+ if ($chan eq '') {
+ &help('countrystats');
return;
}
}
# TODO: move this into a scheduler
- $msgType = "private";
+ $msgType = 'private';
&performStrictReply( &formListReply(0, "Country Stats ", @list) );
delete $cache{countryStats};
# 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) );
# 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;
}
# 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;
}
}
# 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;
}
}
&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); });
# reload.
if ($message =~ /^reload$/i) {
- return unless (&hasFlag("n"));
+ return unless (&hasFlag('n'));
&status("USER reload $who");
&performStrictReply("reloading...");
# 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) {
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/;";
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{$_} };
&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"
);
}
# 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();
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.");
return;
}
- return "CONTINUE";
+ return 'CONTINUE';
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
# initialize variables.
$last{buflen} = 0;
-$last{say} = "";
-$last{msg} = "";
+$last{say} = '';
+$last{msg} = '';
$userHandle = "_default";
$wingaterun = time();
$firsttime = 1;
$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';
}
}
&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");
&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.
}
# Usage: &IsParam($param);
-# blootbot.config specific.
+# infobot.config specific.
sub IsParam {
my $param = $_[0];
&WARN("multiple items found?");
}
- if ($chanconf{$chan}{$param} eq "0") {
+ if ($chanconf{$chan}{$param} eq '0') {
$chan{$chan} = -1;
} else {
$chan{$chan} = 1;
my($param) = shift;
# knocked tons of bugs with this! :)
- my $debug = 0; # 1 if ($param eq "whatever");
+ my $debug = 0; # 1 if ($param eq 'whatever');
if (!defined $param) {
&WARN("IsChanConf: param == NULL.");
if (!defined $msgType) {
$nomatch++;
} else {
- $nomatch++ if ($msgType eq "");
+ $nomatch++ if ($msgType eq '');
$nomatch++ unless ($msgType =~ /^(public|private)$/i);
}
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};
}
}
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;
}
close IN;
- } elsif ($^O eq "netbsd") {
+ } elsif ($^O eq 'netbsd') {
$memusage = int( (stat "/proc/$$/mem")[7]/1024 );
} elsif ($^O =~ /^(free|open)bsd$/) {
$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;
&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}/#;
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($_);
}
sub startup {
- if (&IsParam("DEBUG")) {
+ if (&IsParam('DEBUG')) {
&status("enabling debug diagnostics.");
# I thought disabling this reduced memory usage by 1000 KiB.
use diagnostics;
&status("--- 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();
}
&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.");
next unless /\S/;
my ($set,$key,$val) = split(/\s+/, $_, 3);
- if ($set ne "set") {
+ if ($set ne 'set') {
&status("loadConfig: invalid line '$_'.");
next;
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
$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
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();
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;
}
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;
}
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;
}
# 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;
}
&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;
}
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;
}
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;
}
return;
}
- if (ref($href) ne "HASH") {
+ if (ref($href) ne 'HASH') {
&WARN("hashref2where: href is not HASH ref (href => $href)");
return;
}
sub hashref2update {
my ($href) = @_;
- if (ref($href) ne "HASH") {
+ if (ref($href) ne 'HASH') {
&WARN("hashref2update: href is not HASH ref.");
return;
}
sub hashref2array {
my ($href) = @_;
- if (ref($href) ne "HASH") {
+ if (ref($href) ne 'HASH') {
&WARN("hashref2update: href is not HASH ref.");
return;
}
# Usage: &countKeys($table, [$col]);
sub countKeys {
my ($table, $col) = @_;
- $col ||= "*";
+ $col ||= '*';
return (&sqlRawReturn("SELECT count($col) FROM $table"))[0];
}
}
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 .= $_;
}
}
# 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) ) {
$cache{create_table}{$_} = 1;
- &sqlCreateTable($_);
+ &sqlCreateTable($_, $param{DBType});
}
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
$logtime = time();
$logcount = 0;
$logrepeat = 0;
-$logold = "";
+$logold = '';
$param{VEBOSITY} ||= 1; # lame fix for preload
# logging support.
sub openLog {
- return unless (&IsParam("logfile"));
+ return unless (&IsParam('logfile'));
$file{log} = $param{'logfile'};
my $error = 0;
$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 {
sub closeLog {
# lame fix for paramlogfile.
- return unless (&IsParam("logfile"));
+ return unless (&IsParam('logfile'));
return unless (defined fileno LOG);
close LOG;
# 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) {
}
sub DEBUG {
- return unless (&IsParam("DEBUG"));
+ return unless (&IsParam('DEBUG'));
&status("${b_green}!DEBUG!$ob $_[0]");
}
}
sub WARN {
- return unless (&IsParam("WARN"));
+ return unless (&IsParam('WARN'));
return if ($_[0] =~ /^PERL: Subroutine \S+ redefined at/);
}
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]);
}
}
# 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: '$_'.");
}
$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 {
}
# 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];
&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.
delete $param{'SQLDebug'};
return 0;
}
+ binmode(SQLDEBUG, ":encoding(UTF-8)");
&status("Opened SQL Debug file: $param{'SQLDebug'}");
return 1;
}
sub SQLDebug {
- return unless (&IsParam("SQLDebug"));
+ return unless (&IsParam('SQLDebug'));
return unless (fileno SQLDEBUG);
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80
use strict;
-use vars qw($AUTOLOAD $no_timehires);
+use vars qw($AUTOLOAD $no_timehires $bot_version $bot_release);
###
### REQUIRED MODULES.
}
$moduleAge{$mod} = (stat $mod)[9];
- &showProc(" ($_)") if (&IsParam("DEBUG"));
+ &showProc(" ($_)") if (&IsParam('DEBUG'));
}
}
}
sub loadFactoidsModules {
- if (!&IsParam("factoids")) {
+ if (!&IsParam('factoids')) {
&status("Factoid support DISABLED.");
return;
}
}
$moduleAge{$mod} = (stat $mod)[9];
- &showProc(" ($_)") if (&IsParam("DEBUG"));
+ &showProc(" ($_)") if (&IsParam('DEBUG'));
}
}
# 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\" => $@");
}
$moduleAge{$mod} = (stat $mod)[9];
- &showProc(" ($_)") if (&IsParam("DEBUG"));
+ &showProc(" ($_)") if (&IsParam('DEBUG'));
}
}
### 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($_);
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$/) {
}
1;
+
+# vim:ts=4:sw=4:expandtab:tw=80