From ccc02c22796957aa2f2951c1146d58645261ad0f Mon Sep 17 00:00:00 2001 From: dondelelcaro Date: Sat, 26 Apr 2008 07:40:45 +0000 Subject: [PATCH] * Merge changes from prposed changes * Add back in a few custom patches git-svn-id: https://svn.code.sf.net/p/infobot/code/branches/don/dpkg@1811 c11ca15a-4712-0410-83d8-924469b57eb5 --- AUTHORS | 65 +- BUGS | 21 +- ChangeLog | 3282 ----------------- FAQ | 36 + INSTALL | 213 +- INSTALL.mysql | 39 - INSTALL.patches | 16 - INSTALL.pgsql | 8 - INSTALL.sqlite | 29 - README | 58 +- README.quick | 3 + THANKS | 32 + TODO | 32 +- VERSION | 1 + doc/USAGE | 782 ++++ doc/infobot.config.pod | 455 +++ doc/infobot.users.pod | 158 + files/.cvsignore | 7 - files/{blootbot.help => infobot.help} | 65 +- files/{blootbot.lang => infobot.lang} | 2 +- files/{blootbot.lart => infobot.lart} | 0 files/{blootbot.randtext => infobot.randtext} | 0 files/sample/blootbot.servers | 7 - files/sample/{blootbot.chan => infobot.chan} | 12 +- .../{blootbot.config => infobot.config} | 37 +- .../{blootbot.countdown => infobot.countdown} | 0 files/sample/infobot.servers | 7 + .../sample/{blootbot.users => infobot.users} | 5 +- files/unittab | 668 ---- blootbot => infobot | 10 +- log/.cvsignore | 1 - patches/WWW_Search.patch | 444 +++ patches/WWW_Search.patch.old | 31 + scripts/backup_table-master.sh | 4 +- scripts/backup_table-slave.pl | 2 + scripts/botchk.sh | 8 +- scripts/dbm2mysql.pl | 4 +- scripts/dbm2txt.pl | 2 + scripts/findparam.pl | 2 + scripts/fixbadchars.pl | 4 +- scripts/insertDB.pl | 4 +- scripts/irclog2html.pl | 9 +- scripts/makepasswd | 1 + scripts/mysql2txt.pl | 4 +- scripts/oreilly_dumpvar.pl | 2 + scripts/oreilly_prettyp.pl | 2 + scripts/output_stats.sh | 14 +- scripts/parse_warn.pl | 2 + scripts/showvars.pl | 2 + scripts/symname.pl | 2 + scripts/txt2mysql.pl | 4 +- scripts/vartree.pl | 2 + scripts/webbackup.pl | 2 + setup/README | 24 + setup/connections.sql | 9 - setup/factoids.sql | 14 - setup/freshmeat.sql | 8 - setup/mysql/botmail.sql | 12 + setup/mysql/factoids.sql | 18 + setup/mysql/onjoin.sql | 12 + setup/mysql/rootwarn.sql | 12 + setup/mysql/seen.sql | 12 + setup/mysql/stats.sql | 12 + setup/news.sql | 7 - setup/pgsql/botmail.sql | 12 + setup/pgsql/factoids.sql | 18 + setup/pgsql/onjoin.sql | 12 + setup/pgsql/rootwarn.sql | 12 + setup/pgsql/seen.sql | 12 + setup/pgsql/stats.sql | 12 + setup/setup.pl | 8 +- setup/{ => sqlite}/botmail.sql | 0 setup/sqlite/factoids.sql | 14 + setup/{ => sqlite}/onjoin.sql | 2 +- setup/{ => sqlite}/rootwarn.sql | 2 +- setup/{ => sqlite}/seen.sql | 4 +- setup/{ => sqlite}/stats.sql | 2 +- setup/sqlite2/botmail.sql | 8 + setup/sqlite2/factoids.sql | 14 + setup/sqlite2/onjoin.sql | 14 + setup/sqlite2/rootwarn.sql | 8 + setup/sqlite2/seen.sql | 8 + setup/sqlite2/stats.sql | 8 + setup/uptime.sql | 6 - src/CLI/Support.pl | 12 +- src/CommandStubs.pl | 178 +- src/DynaConfig.pl | 86 +- src/Factoids/Core.pl | 90 +- src/Factoids/DBCommon.pl | 44 +- src/Factoids/Norm.pl | 4 +- src/Factoids/Question.pl | 39 +- src/Factoids/Reply.pl | 32 +- src/Factoids/Statement.pl | 22 +- src/Factoids/Update.pl | 36 +- src/Files.pl | 6 +- src/IRC/Irc.pl | 85 +- src/IRC/IrcHelpers.pl | 147 +- src/IRC/IrcHooks.pl | 103 +- src/IRC/Schedulers.pl | 239 +- src/Misc.pl | 97 +- src/Modules/BZFlag.pl | 63 +- src/Modules/Debian.pl | 70 +- src/Modules/DebianBugs.pm | 2 + src/Modules/DebianExtra.pl | 2 + src/Modules/Dict.pl | 188 +- src/Modules/DumpVars.pl | 10 +- src/Modules/DumpVars2.pl | 4 +- src/Modules/Exchange.pl | 496 +-- src/Modules/Factoids.pl | 227 +- src/Modules/HTTPDtype.pl | 6 +- src/Modules/Kernel.pl | 12 +- src/Modules/Math.pl | 50 +- src/Modules/NewUnits.pl | 31 - src/Modules/News.pl | 69 +- src/Modules/OnJoin.pl | 6 +- src/Modules/Plug.pl | 4 +- src/Modules/Quote.pl | 6 +- src/Modules/RSSFeeds.pl | 163 + src/Modules/RootWarn.pl | 14 +- src/Modules/Rss.pl | 3 +- src/Modules/Search.pl | 8 +- src/Modules/Topic.pl | 80 +- src/Modules/Units.pl | 553 +-- src/Modules/Uptime.pl | 8 +- src/Modules/UserDCC.pl | 204 +- src/Modules/UserInfo.pl | 18 +- src/Modules/W3Search.pl | 65 +- src/Modules/Weather.pl | 8 +- src/Modules/Wingate.pl | 6 +- src/Modules/Zippy.pl | 4 +- src/Modules/babelfish.pl | 4 +- src/Modules/botmail.pl | 23 +- src/Modules/case.pl | 5 +- src/Modules/countdown.pl | 2 + src/Modules/dice.pl | 2 + src/Modules/dns.pl | 3 +- src/Modules/hex2ip.pl | 44 + src/Modules/insult.pl | 12 +- src/Modules/md5.pl | 4 +- src/Modules/nickometer.pl | 8 +- src/Modules/pager.pl | 9 +- src/Modules/piglatin.pl | 4 +- src/Modules/reverse.pl | 4 +- src/Modules/scramble.pl | 6 +- src/Modules/slashdot.pl | 4 +- src/Modules/spell.pl | 9 +- src/Modules/wikipedia.pl | 18 +- src/Modules/wtf.pl | 5 +- src/Modules/zfi.pl | 5 +- src/Modules/zsi.pl | 6 +- src/Net.pl | 10 +- src/Process.pl | 42 +- src/Shm.pl | 16 +- src/UserExtra.pl | 134 +- src/core.pl | 89 +- src/dbi.pl | 106 +- src/logger.pl | 42 +- src/modules.pl | 25 +- 158 files changed, 4615 insertions(+), 6544 deletions(-) create mode 100644 FAQ delete mode 100644 INSTALL.mysql delete mode 100644 INSTALL.patches delete mode 100644 INSTALL.pgsql delete mode 100644 INSTALL.sqlite create mode 100644 THANKS create mode 100644 VERSION create mode 100644 doc/USAGE create mode 100644 doc/infobot.config.pod create mode 100644 doc/infobot.users.pod delete mode 100644 files/.cvsignore rename files/{blootbot.help => infobot.help} (88%) rename files/{blootbot.lang => infobot.lang} (97%) rename files/{blootbot.lart => infobot.lart} (100%) rename files/{blootbot.randtext => infobot.randtext} (100%) delete mode 100644 files/sample/blootbot.servers rename files/sample/{blootbot.chan => infobot.chan} (92%) rename files/sample/{blootbot.config => infobot.config} (85%) rename files/sample/{blootbot.countdown => infobot.countdown} (100%) create mode 100644 files/sample/infobot.servers rename files/sample/{blootbot.users => infobot.users} (65%) delete mode 100644 files/unittab rename blootbot => infobot (92%) delete mode 100644 log/.cvsignore create mode 100644 patches/WWW_Search.patch create mode 100644 patches/WWW_Search.patch.old mode change 100644 => 100755 scripts/findparam.pl mode change 100644 => 100755 scripts/fixbadchars.pl mode change 100644 => 100755 scripts/insertDB.pl mode change 100644 => 100755 scripts/oreilly_dumpvar.pl mode change 100644 => 100755 scripts/oreilly_prettyp.pl mode change 100644 => 100755 scripts/output_stats.sh mode change 100644 => 100755 scripts/showvars.pl mode change 100644 => 100755 scripts/vartree.pl create mode 100644 setup/README delete mode 100644 setup/connections.sql delete mode 100644 setup/factoids.sql delete mode 100644 setup/freshmeat.sql create mode 100644 setup/mysql/botmail.sql create mode 100644 setup/mysql/factoids.sql create mode 100644 setup/mysql/onjoin.sql create mode 100644 setup/mysql/rootwarn.sql create mode 100644 setup/mysql/seen.sql create mode 100644 setup/mysql/stats.sql delete mode 100644 setup/news.sql create mode 100644 setup/pgsql/botmail.sql create mode 100644 setup/pgsql/factoids.sql create mode 100644 setup/pgsql/onjoin.sql create mode 100644 setup/pgsql/rootwarn.sql create mode 100644 setup/pgsql/seen.sql create mode 100644 setup/pgsql/stats.sql rename setup/{ => sqlite}/botmail.sql (100%) create mode 100644 setup/sqlite/factoids.sql rename setup/{ => sqlite}/onjoin.sql (93%) rename setup/{ => sqlite}/rootwarn.sql (82%) rename setup/{ => sqlite}/seen.sql (68%) rename setup/{ => sqlite}/stats.sql (80%) create mode 100644 setup/sqlite2/botmail.sql create mode 100644 setup/sqlite2/factoids.sql create mode 100644 setup/sqlite2/onjoin.sql create mode 100644 setup/sqlite2/rootwarn.sql create mode 100644 setup/sqlite2/seen.sql create mode 100644 setup/sqlite2/stats.sql delete mode 100644 setup/uptime.sql delete mode 100644 src/Modules/NewUnits.pl create mode 100644 src/Modules/RSSFeeds.pl create mode 100644 src/Modules/hex2ip.pl diff --git a/AUTHORS b/AUTHORS index 5efe778..ec8e1cc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,30 +1,49 @@ -Blootbot: - License: Artistic - Main Author: - - Tim Riker - Other Contributors: - - David Sobon - - Danny Jabbour [GmLB] +# $Id$ -Module-Reload: (idea taken) - License: Artistic - - Doug MacEachern - - Joshua Pritikin + ------------- + -- AUTHORS -- + ------------- -Module-Units: - License: GPL - - M-J. Dominus +Infobot original: -Infobot: License: As perl (GPL & Artistic) - - Kevin A. Lenzo [oznoid] - - Patrick Cole [ltd] + - Kevin A. Lenzo [oznoid] + - Patrick Cold [ltd] + +Later forked as Blootbot (and now remerged back): + + License: Artistic + Tim Riker [TimRiker] + +Is currently maintained by: + + - Tim Riker [TimRiker] + - Don Armstrong [dondelelcaro] + - Dan McGrath [troubled] + - Simon Cote [simonrvn] + +and has previously been maintained by: + + - Adam Kennedy + - Corey Edwards + - Danny Jabbour [GmLB] + - Dave Brown + - Dave Paris + - David Sobon + - Doug MacEachern + - Joshua Pritikin + - Kevin Meltzer + - M-J. Dominus + - Martijin van Beers + - Masque + - Peter Sergeant + - Rich Lafferty + - Richard Harman + - Roderick Schertler + - Tony -OnJoin: - - Corey Edwards -Patches: - - ... +Countless other people have contributed to Infobot (see THANKS), provided code +and/or helped troubleshoot problems. Many thanks to all of them. -Quotes file (files/blootbot.randtext): - - ??? Ask netgod/larne/is for dpkg's tcl +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/BUGS b/BUGS index 684c8c4..48d079c 100644 --- a/BUGS +++ b/BUGS @@ -1 +1,20 @@ -allows adding a "cmd:foo (.*)" factoid but not removing it +Known bugs that should be dealt with soon as possible: + + * Older CMD: foo's cannot be used or removed. Must be removed manually from + the database with SQL + + * !+topic list gives and incorrect error Failed. "You (#botpark) are not in + #botpark, hey?" + + * Bot tries to ask chanserv for OP's on any channel. Should be a chanset + setting on a per channel basis + + * News is currently stored in a file rather than the SQL table created for it + + * !help has size issues. Add's extra lines with only 1 or 2 help commands + instead of one maximum size IRC msg + + * Bot can be flooded offline with a crash if !+factstats help and /msg nick + factstats help, are used at the same time + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/ChangeLog b/ChangeLog index baed181..e69de29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3282 +0,0 @@ - -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 :)" -- 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 " - -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 [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 [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 [#channel] [time] " WORKS - - ".-ignore " WORKS - - ".ignore [chan]" WORKS, - - ".adduser " DONE,TODO - - ".deluser " DONE,TODO - - ".+user " WORKS - - ".-user " WORKS - - ".chatset [channel] " 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 -- are also ' 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 ' - => 'uinfo set ' - => 'uinfo unset ' - - 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 ' 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 about ' 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 see erp'). if - 'blah' is asked, the reply from 'erp' is given. - - OPN allows part messages -- fixed in /PART/ for $chan. - -v0.11.3 (19991008): - - Uptime.pl appears to be fixed after rewrite of getUptimeInfo. - - Fixed up Freshmeat.pl for updating the index. Proxy is now - optional. - - Moved rootWarn to RootWarn.pl. Added hall-of-fame of losers. - - Cleaned up bugs/typo here and there which may have caused the - bot to behave in a weird manner. - -v0.11.2 (19991006): - - ChanInfo now displays "statistics" just like our little friend - BitchX. - - Minor change in determining args on commands [myRoutines]. - - Added "cmdstats". - - Added rootWarn checking on checks. Repeat offenders will be - punished. Requested by larne. [update: we aren't so harsh now] - - Added lc $chan where appropriate. damn uppercase channames. - -v0.11.1 (19991005): - - all instances of undef on hash lists changed to delete which - _now_ works. found minor bugs/typos related to DUI. - - Now skip internic whois intro (13 lines) to fix bad output. - - Forgot to subtract $i from $counter in chaninfo when full. - [update: whole function changed, see above] - - Now backup (and gzip) freshmeat index file. - -v0.11 (19991004): looks like a bug fix release :) - - Fixed typo in reply of Topic.pl/&NewTopic(). - - Decreased max topic length allowed; now print it, too, for - debugging. - - Altered repeat code to only work on public. Flooders should be - taken care of by the (allowOutsiders == 0) code. if not, there's - 'lobotomy' :) - - Added excess flood protection around &rawout(); - - Don't bother about outsiders if we haven't joined any channels. - - Changed email address to one throughout modifications. - New files have neato headers. - - Uptime.pl fixed, didn't need to check against ($pid == $$) - - Repeat-prevention code kind-of looks what it was before but this - one, at least, works :). any problems, just bitch at me. - - Added debugging code for chaninfo to diagnose "problem". - -v0.10 (19991001): - - Added Uptime module. - - Added Freshmeat module. - - Dict now returns definition without suggestions (syn's) by - default. Also cleaned up. - - NickServ/ChanServ major clean up. - - Join upon reconnect fix: set $joinchans = 0. - - Fixed up Help.pl, added more help entries. - -v0.9b (19990925): - - Did repeat-prevention code from scratch -- now works. - [19991001 update]: multiplier is now 2 instead of 10. - - Made reaction to "hello" more strict. the same should be done to - "thanks", don't you think? - - Converted remaining modules to use forking. should be no more - bot lockups... - - Changed maxhits to 20 for Search. - -v0.9 (19990924): +16K added to patch size. - - More, more and more major changes. - - Fixed up inappropriate usage of performReply. - - Added lobotomy command to (un)silence the bot. - - Added allowOutsiders toggle to prevent usage of the bot - _outside_ the channels the bot is in. - - Added $fullyaddressed, enabled if $addressed == 1 and - $param{addressing} == REQUIRE. - - Readded auto-continuity code. it is disable if not fully - addressed. otherwise works as per normal. - - Moved join-on-start-of-motd code to end-of-motd. If nickserv && - chanserv is enabled, IDENTIFY is done first. If okay, then we - proceed to join channels. - - When bot joins channel, summary of nicks (ops|voice|total) is - given instead of NAMES list. - - Chanserv support moved to "end of names". - - Detection of nickserv (no such nick). - - join channel if channel is on our joins list and if we're not on - it (hrm, providing their client prevents it). - - ... - -v0.8 (19990919): +50K patch from last version. - - Major changes, particularly cleanups and fixed a few bugs: - - Found 2 or so instances of $params{}. Either deleted or - renamed to $param where appropriate. - - Shortened foreach statements where possible. - - Replaced duplicate code involving &say and &msg with - &performReply($text,[0=rand,1=strict]). -- major shortcut and - cleanup. - - Added tracking of all users on channel(s). Users are - deleted if they disappear for whatever reason with - &DeleteUserInfo. - - Tracking of channels now works; they are deleted if we disappear - from any channel for whatever reason (hopefully). - - 'forget' command _SHOULD_ be wrapped with $addressed. - - Moved 'modes' from User.pl to myRoutines.pl as 'chaninfo'. - - Added stock quote support by using mu's script. Thanks. - - Added param{*} around stuff in myRoutines.pl for flexibility. - - Added auto-join on invite if not on specific "join_channels" - - Renamed &Timetostring to &Time2String and made use of it not - only for status but for seen. - - If $param{*} == false, it is now not defined. - - Removed Auto-continuity code -- very evil for any bot commands - other than non-intentionally requesting a factoid. - - crypt command required "(" before passwd??? - - Removed stupid commands which just generate URLs for you to cut - and paste. - - repeatIgnoreInterval code _NOW_ works unlike before. - - Added support for Topic.pl not to update topics if commands are - prepended by '-'. Topics can be "rehashed" when either a) the - next command is used without '-' or b) "rehash" is the next - command. - - &NewTopic takes two more args to prevent repetition and now does - topic checking. Check code for details. - -v0.7 (19990914): - - Major clean up: Search.pl now only uses the "is" dbm; final - pair of parens in commands removed for legibility; Removed - debugging for NickServ, ChanServ to go. - - Added multiple subtopic delete ability. requested by Mercury. - - Moved responses/replies to [files/infobot.lang]. Modified - related functions to conform, including mine. - - Fixed up Kernel.pl to use different type of sockets. Previous - code somehow broke itself. - - Added, but disabled, semi-working timer support. Need to ask - lenzo some questions on how to implement it the best way. - - Added channel (and offender's) notification if someone joins the - channel with root. requested by #debian. - - Added dict.org support. For now, it uses wordnet and returns a - random definition. Could change in the future. - -v0.6 (19990903): - - Added support for nickserv and chanserv, requested by is. - - Updated README to describe new features and modifications. Do we - need to elaborate on the modifications to the depth where it - would exceed the size of the patch? - - Minor clean up. - - Removed assumed-continuity of messages -- should be used if - addressing is in optional mode but would be bad in any situation - if more than one infobot existed in the channel. - - Added parsing of g flag to factoid sar. - -v0.5 (19990827): - - Better way to confirm if bot is on channel now for topic - management. Also added check for +o+t or -t. &DoModes() on - server stuff, too? - - Patch updated to work for infobot-0.44.2 only. - - Found a bug in Irc.pl under "NAMES" where $u was used initially - but trashed afterwards. => replaced $u w/ $_. - - Lost track of a bug found by Mercury. Seems to be fixed now, - somehow, heh. - -v0.4c (19990822): - - Worked on random-cookie -- random responses can now be added - (internally) with ease. - - Noticed joeyh changing his nick to/from '||' which reminded me - of something bad ;) hint: topic management. - - One line patch to allow '|' in factoids; delimiter is now '||'. - -v0.4b (19990818): - - Implemented patch from mu. Now it is possible to use the topic - command through private messages to the bot instead of the - channel. - - Replaced SAR of \| with \|\| so we can still use the single - pipes. Double pipes will be either removed or promote an error - message. Found by Robot101. Added el-cheapo work-around if the - last char of subtopic is |, kill it. - -v0.4a (19990816): - - Added cheap fix (sleep 1, heh) to excess floods of 'topic - history'. Is sleep 1 enough? - - Added 'random' for random value{key} from database. - Requested by jCommons. - -v0.4 (19990815): - - Fixed topic history by replacing push with unshift. Now the - history list is reversed and cycled properly. - - Reversed Changes list. request by mu. - - Totally fixed up topic history since it would break if - 'topic add' was induced quickly. Now we only record topics set - by us (for reasons) and onjoin topics (set by anyone). - - Removed 'topic last/reset' because how do you know which topic - is last? Better control with 'topic restore'. - -v0.3c (19990813): - - Fixed 'topic mv 2 before 1' bug. Forgot to store 'move' topic - before doing the foreach loop. - - Touched up Kernel.pl in preparation for auto-notify feature. - -v0.3b (19990812): - - Added version string to new files so we know which version - of patch we're using (or used). There you go, Mercury ;) - - Fixed up DecipherTopic to reject null subtopics. This would, if - unchanged, (theoretically but not tried, luckily) produce a - domino-effect of problems if the topic was to be changed. - Update: check if the supposed null topic contains spaces - within the nick component. If so, then it's not - nick, therefore treat like ownerless subtopic. - - Worked on README. - -v0.3a (19990810): - - Changed back to use topic{chan} (now topicnow{chan}) since - @topiclist{chan} (now @topichist{chan}) does not deal with dupes - or blanks. - - Renamed 'topic last' in preference to 'topic reset'. Original - command can be used but is vague in meaning. - - Fixed several typos made in Irc.pl. - - Replaced 'defined' with 'length' in if statements. - -v0.3 (19990809): - - Applied patch from mu for Irc.pl | Topic.pl. - - Replaced %topic hash and $topiclast with @{$topiclist{chan}}. - Much cleaner implementation. Thanks to mu for this. Fully - implemented by xk. - - Reworked on topicbyme (was topiclast), should work now. - -v0.2 (19990808): - - Changed name of patch to funkystuph. - - Added history/last/restore to Topic.pl by request of mu and is. - - Reorganised help and order of commands in Topic.pl - - Bot must be addressed to use commands. - - Fixed bug if multiple infobots were in the channel. - - One occurrence where Cipher was called instead of CipherTopic. - - Fixed up Slashdot.pl. Problems: a) borked completely b) missed - first headline. el-cheapo fix but it works. - -v0.1c (19990729): - - Fixed long list{keys|values} bug, hopefully. - - Now randomize key results from search. - - If keys contain ',', underline to differentiate it. - - Fixed possible DoS against Kernel.pl. - - Bug fixed with Kernel.pl repeating itself. - - Typo of @results [one occurrance of @result] - -v0.1b (19990723): - - Fixed bug with &CipherTopic where, if no owner was found, it - would just use NULL. [like "Topic ()"] - - Added kernel feature. - - Moved error messages to public/private, depending on behaviour. - Help-related stuff is private(msg) only for convenience. - -v0.1a (19990721): - - Misc cleanup, removed repeated code. - -v0.1 (19990720): - - Initial release. diff --git a/FAQ b/FAQ new file mode 100644 index 0000000..f7a8dcc --- /dev/null +++ b/FAQ @@ -0,0 +1,36 @@ +# $Id$ + +Q: The bot exits after I run 'factstats testing' or 'kernel' or anything + that uses fork(). Is this a bug in the bot? + +A: No, this is not a bug in the bot but rather Net::IRC. A cheap hack is + to edit /usr/lib/perl5/Net/IRC/Connection.pm, search for DESTROY, and + comment out '$self->quit();' +A: Apply the patches in the patches/ directory. + + +Q: I notice that, in the bot logs, the bot attempts to close all current + DCC CHAT connections whenever a forked process ends. Why is this? + +A: Yet another bug in Net::IRC. Currently, DCC CHAT connections are not + closed because there is an endless-loop bug when it is done. + + +Q: I executed 'scripts/setup_user.pl' but it said 'connection refused to + localhost' + +A: Looks like a bug in the installation of mysqld. You need to reload or + restart the daemon. + reload => 'mysqladmin -u root -p reload' + restart => '/etc/init.d/mysql stop; /etc/init.d/mysql start' + +Q: How do I get my bot to automatically ask for OP's from chanserv? + +A: By default, the "chanServCheck" option is off in _default. You can + set it on a per channel basis or as default. For example, the following + commands will enable asking for OP by default, except on #notmychannel + + chanset _default chanServCheck 1 + chanset #notmychannel chanServCheck 0 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/INSTALL b/INSTALL index aed3621..12f1b3e 100644 --- a/INSTALL +++ b/INSTALL @@ -1,28 +1,185 @@ -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 + > createdb --owner= [] + +Dont forget to replace 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 . 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 ' + Where 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 .sqlite and populate the tables for +you if they do not already exist. + +- Install SQLite libraries and DBI Perl modules. + - Debian: (apt-get install libsqlite0 libdbd-sqlite-perl) + +other distros might need to build from sources. + +You may use either DBD::SQLite or DBD::SQLite2 + +SQLite sources: + + http://www.hwaci.com/sw/sqlite/ + +DBD::SQLite sources: + + http://search.cpan.org/author/MSERGEANT/DBD-SQLite/ + +You will also need the normal Perl DBD stuff which should be included in your +Perl distribution. + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/INSTALL.mysql b/INSTALL.mysql deleted file mode 100644 index 5de7a16..0000000 --- a/INSTALL.mysql +++ /dev/null @@ -1,39 +0,0 @@ -INSTALL.mysql ----------------- - -- Install a MySQL server and the DBI Perl modules. - - Debian: (apt-get install mysql-server libdbd-mysql-perl) - -- Run 'mysqladmin -u root -p create ' - Where is the same as specified in blootbot.config. - -- Run 'setup/setup.pl' - -= Possible problems - - if connection to localhost is (short) refused, run - '/etc/init.d/mysql stop' - '/etc/init.d/mysql start' - - if connection for user is refused, reload grant tables with - 'mysqladmin -u root -p reload' - -* [OPTIONAL] - - run 'scripts/dbm2mysql.pl old-db' to convert dbm database file - to mysql. - -ADDITIONAL NOTES: ------------------ -You can add a new user manually by connecting to MySQL and performing these -commands: - - $ mysql -u root -p - - mysql> CREATE DATABASE blootbot; - mysql> GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY 'yourpassword'; - mysql> GRANT ALL PRIVILEGES ON blootbot.* TO 'user'@'localhost'; - -FULL FACTOID DATABASE: ----------------------- -You can get the data from the MySQL database that the apt bot uses on -#debian at freenode (irc.freenode.net), at: - - http://lain.cheme.cmu.edu/~apt/blootbot/apt.sql.bz2 diff --git a/INSTALL.patches b/INSTALL.patches deleted file mode 100644 index c72294c..0000000 --- a/INSTALL.patches +++ /dev/null @@ -1,16 +0,0 @@ -INSTALL.patches -------------------- - -- apply *.patch patches inside patches/ - - cd /usr/lib/perl5/WWW/Search - patch -p0 < WWW::Search::Google.patch - -- alternatively, move the files from patches/ - - mv patches/Google.pm /usr/lib/perl5/WWW/Search/ - -Net::IRC DCC CHAT ----------------------- -Unfortunately, Net::IRC 0.70 has buggy code that does not detect DCC CHAT -properly. to patch: - cd /usr/share/perl5/Net/IRC/ - cat ~bot/patches/Net_IRC_Connection_pm.patch | patch -p0 diff --git a/INSTALL.pgsql b/INSTALL.pgsql deleted file mode 100644 index 1810d5f..0000000 --- a/INSTALL.pgsql +++ /dev/null @@ -1,8 +0,0 @@ -Method of installation. ------------------------ - -- Debian: (apt-get install postgresql) -- Debian: (apt-get install libpgperl) - -SUPPORT FOR PGSQL IS CURRENTLY BROKEN! You'll have to use one of the other -databases instead. diff --git a/INSTALL.sqlite b/INSTALL.sqlite deleted file mode 100644 index 35c6b7b..0000000 --- a/INSTALL.sqlite +++ /dev/null @@ -1,29 +0,0 @@ -INSTALL.sqlite ----------------- - -SQLite is a C library that implements an embeddable SQL database engine. -Programs that link with the SQLite library can have SQL database access without -running a separate RDBMS process. The distribution comes with a standalone -command-line access program (sqlite) that can be used to administer an SQLite -database and which serves as an example of how to use the SQLite library. - -blootbot will create a file called .sqlite and populate the tables for -you if they do not already exist. - -- Install SQLite libraries and DBI Perl modules. - - Debian: (apt-get install libsqlite0 libdbd-sqlite-perl) - -other distros might need to build from sources. - -You may use either DBD::SQLite or DBD::SQLite2 - -SQLite sources: - -http://www.hwaci.com/sw/sqlite/ - -DBD::SQLite sources: - -http://search.cpan.org/author/MSERGEANT/DBD-SQLite/ - -You will also need the normal Perl DBD stuff which should be included in your -Perl distribution. diff --git a/README b/README index 92fc7e6..32197d3 100644 --- a/README +++ b/README @@ -1,20 +1,17 @@ -This is out of date. +# $Id$ - - - - - -blootbot v1.0.0 (20000729) -------------------------- + ------------- + -- Infobot -- + ------------- INTRODUCTION - This bot is based upon infobot-0.44.2 by kevin lenzo -. 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 , which is now officially rebranded back to +infobot! The basis of infobot is still there but _many_ wild features have +been added. Along the way, many issues were spotted in the original +infobot source and fixed in this version. Many new bugs have been added as well +Thanks to kevin for bringing infobot in the first place. + FEATURES * Additional information stored with factoids. (factinfo) @@ -29,17 +26,20 @@ FEATURES * Slashdot, Kernel and Freshmeat auto-update announcements. * Units conversion (provided by external module, Units-Module) - DESIGN - - Modularity. Ability to disable IRC or Factoid support. - - Funky pseudo Module autoloader support - - Eleet Forker() function -Improvements include: +DESIGN + - Modularity. Ability to disable IRC or Factoid support. + - Funky pseudo Module autoloader support + - Eleet Forker() function + + +IMPROVEMENTS * log file is not opened and closed for each line of data => unblocked logging is used. * seen data is not flushed for each public message on IRC => caching and flushing over an interval is used. + HISTORY As of 0.99pre1, blootbot supports mysql database in the hope to increase performance and to avoid borked over dbm's which occurred when @@ -56,9 +56,13 @@ back. It should work in all but 3 specific (countdown, factstats unreq) cases. preliminary pgsql support has been added but someone with pgperl knowledge needs to fix it up or at least unify the module with mysql. + As of 1.5.0, blootbot was rebranded back to infobot. + + INSTALLATION - Read the included INSTALL file + NOTICE Be warned that this bot consumes quite a lot of memory upon start up and during usage. Right now, 7.4megs is used for old'ish perl, 8.3megs @@ -77,6 +81,7 @@ welcomed. blootbot, not based on the above source base. Core factoid code and mysql support works - but that is it. + MODIFICATIONS All modifications are that of the blootbot author unless otherwise specified, like none. See 'ChangeLog' for details. A list of future @@ -119,7 +124,8 @@ NOTES through DCC CHAT. /chat . All commands must be prepended by '.' otherwise it is sent to the bot chat net -### UNTESTED: + +UNTESTED: - user statistics shown by 'seen'. bug in this? - User Information Services. - new wingate caching/file-read code. @@ -145,7 +151,15 @@ hope to get that same guy to re-send me the patch... CONTACT Contributions of a patch, or anything, can be sent to - + 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 diff --git a/README.quick b/README.quick index c17c34d..6ffa1a2 100644 --- a/README.quick +++ b/README.quick @@ -12,3 +12,6 @@ DCC CHAT: for list of configuration options, run: perl scripts/findparam.pl + + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..20cb949 --- /dev/null +++ b/THANKS @@ -0,0 +1,32 @@ +# $Id$ + + ------------ + -- THANKS -- + ------------ + +Over time, many people have helped us out with the project. Some have helped on +IRC with suggestions, ideas, bug fixes. Some still with bug reports, complaints +and feedback. Below is a list of those people that have contributed in one way +other another, or people who we feel we owe thanks to in one way or another. + +If we missed you from this list, drop us a line and we will be sure to give +credit where it is due. + + +#perl@freenode.net +------------------ +Somni +apeiron +sili +f00li5h +Caelum +anno- +mst +dngor +PerlJam +Limbic_Region +mmap__ +jagerman + + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/TODO b/TODO index b3ddccc..579c6c3 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,6 @@ TODO: - - let's get a release out! + - Normalize the SQL tables a little better to reduce size and increase speed + - Keep the Changelog, TODO and BUGS files up to date. Clean things up a bit - rename ^[+-] commands - remind - like this and others: http://jibble.org/reminderbot/ - kill SHM and and move to a pipe @@ -8,8 +9,8 @@ TODO: - move nicks/server into sql table - make channel flags be server/channel flags - move channel flags to sql table, include initial state - - move praise from blootbot.lang to "praise:" in factoids? - - move lart from blootbot.lang to "lart:" in factoids? + - move praise from infobot.lang to "praise:" in factoids? + - move lart from infobot.lang to "lart:" in factoids? - debian BTS frontend "bugs" - !country - !dinstall @@ -43,7 +44,7 @@ TODO: Other TODO items may be listed on sourceforge. Please access it from the website or this link: -http://sourceforge.net/pm/task.php?group_id=8794&group_project_id=3207&func=browse&set=open +http://sourceforge.net/pm/task.php?group_id=2241 ---------------------------------------------------- ------------ FUTURE, NON-IMPORTANT @@ -72,26 +73,5 @@ http://sourceforge.net/pm/task.php?group_id=8794&group_project_id=3207&func=brow - do some test cases to confirm code actually works as proposed. --- useless statistics -- 20010420: -DEBUG: 373 -WARN: 129 -FIXME: 35 -status: 386 -TODO: 145 -20031111: scripts/output_stats.sh -DEBUG: 384 -WARN: 167 -FIXME: 33 -status: 424 -ERROR: 123 -TODO: 91 - -20050217: scripts/output_stats.sh -DEBUG: 388 -WARN: 164 -FIXME: 43 -status: 436 -ERROR: 125 -TODO: 158 +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..bc80560 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.5.0 diff --git a/doc/USAGE b/doc/USAGE new file mode 100644 index 0000000..23786fe --- /dev/null +++ b/doc/USAGE @@ -0,0 +1,782 @@ +# $Id$ + +############ +# EXAMPLES # +############ + +DCC CHAT: +.+chan #chan +.chanset #chan +autojoin +.chanset +autojoin +.chanunset -autojoin +.chanset -autojoin + +for list of configuration options, run: + ./scripts/findparam.pl + + +===== + infobot: hex2ip aaBBcD12 + me: AABBCD12 = 170.187.205.18 + + infobot: test is testing + me: okay + infobot: testing? + testing is testing + + infobot: tests is testing + me: okay + infobot: tests? + testing + + infobot: cough is coughs + me: okay + infobot: cough +* infobot/#infobot coughs + + infobot: test is What's (one|two|three|four|five|six) + times (seven|eight|nine|ten|eleven|twelve)? + okay, me + infobot: test + What's four times nine? + infobot: test? + What's six times ten? + + infobot: op me is Mode change "+o $nick" on channel + $channel by $ident + me: okay + infobot: op me +* infobot/#debian-bots Mode change "+o me" on channel #infobot by + infobot + + infobot: no who am i is You are $nick!$user@$host on + $channel. + okay, me + infobot: who am i + You are me!me@home.org on #infobot. + + infobot: who last spoke is To my knowledge, $lastspeaker + was the last to say something worthwhile. + me: okay + infobot: who last spoke + To my knowledge, me was the last to say something worthwhile. + + infobot: percentage is you are $randpercentage% lame + me: okay + infobot: percentage + you are 79% lame + + infobot: slap $1 is slaps $1 + me: okay, me + infobot: slap Bob + * infobot slaps Bob + infobot: forget cmd: slap (.*?) + 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 + i am on 2 channels: #infobot #debian + i've cached 5 users distributed over 2 channels. + + > infobot: chanstats #infobot + On #infobot, there have been 1 Join, 1 Op and 20 + PublicMsgs. + 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 about + +Example: + ... diff --git a/doc/infobot.config.pod b/doc/infobot.config.pod new file mode 100644 index 0000000..584bba7 --- /dev/null +++ b/doc/infobot.config.pod @@ -0,0 +1,455 @@ +=pod + +=head1 NAME + +infobot.config - Main infobot configuration file + +=head1 SYNOPSIS + +B EBE EBE + +=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> to the +S> 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 EBE + +The name that you want your infobot to appear as on B. + +=item B EBE + +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 EBE + +This sets the name that appears as "Real Name" when someone does a C on +your infobot's nick on B. + +=item B EBE + +If this variable is set, then the server will send it when connecting to the +B server. Most networks only use this for server administrators to gain +their operator status. However, B (B) uses +this server password to identify you automatically to nickserv on connect. + +=item B EB<+>|B<->EEBE[EB<+>|B<->EEBE...] + +This is a list of user modes that the infobot should attempt to set after it +has established a connection with the B server. + +=item B EB|BE + +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 or B of the +interface that you want it to use when connecting to B. + +=item B EBE + +Set this to the nick that matches the name of the account that you set in the +F file for yourself. + +I + +=item B EBE + +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 EBE + +When your bot intentionally disconnects from a server, it will display the +following quit reason to users who see it quit. + +I + +=item B EBE + +This sets a path to a temporary directory which infobot can use. Most people +find this best set to F. + +=back + +=head2 Factoid database configuration + +=over + +=item B EB|B|B|B|BE + +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 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 type actually work without breaking non factoid related> +I + +=item B EB|BE + +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 + +=item B EB|BE + +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 + +=item B EBE + +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 + +=item B EBE + +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 + +=item B EBE + +If you are using a database, this specifies the filename that you wish to log +all B commands to. On some platforms, you may be able to use a "-" to +specify B 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 EB|BE + +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 + +=item B EB|B + +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 + +=item B EBE + +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 + +=back + +=head2 Factoid-related configuration + +These settings govern how factoids are managed. + +=over + +=item B EB|BE + +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 EBE + +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 EBE + +If you have factoid support enabled, this value determines the maximum length +of the factoid key. + +=item B EBE + +If you have factoid support enabled, this value determines the maximum length +of the value for a factoid key. + +=item B EB|BE + +If you have factoid support enabled, this value determines how the bot reacts +to public chatter. + +In B mode, the bot will only learn the factoid if you address it +specifically by name S<(eg: Botname: ...)>, or by B. This is the +recommended mode. + +In B 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 EB|B|BE + +The bot has the ability to recognize B's. This setting will control what +it accepts as a B. + +In B mode, the bot will need the protocol to be specifically mentioned +for it to be considered (eg: file://, http://). + +In B mode, the bot will accept just about anything. + +In B mode, the bot will not accept any B's. This makes it easy to +run with different nicks and styles. + +I + +=item B EB|BE + +This determines if the bot should accept or reject factoids which contain foul +language. + +=item B EB|BE + +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 [B [B ... B]] + +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 +I + +=back + +=head2 Factoid related and unrelated features, mainly Extras. + +These settings are basically stuff that doesn't fit anywhere else. + +=over + +=item B EB|BE + +This setting controls how your bot responds (not related to learning factoids) +to people saying stuff in a channel. With B, the bot will only say +something if it is addressed (via nick or trigger). With B, the bot +will respong (not learn) irrelevent of addressing. + +=item B EB|BE + +This setting controls how the bot should send messages. With B, the +bot will reply to private messages only, rejecting public messags. With +B, the bot will reply to publid and private queries. + +=item B EBE + +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 EB|BE + +This setting, if enabled, will allow people outside and channels that your bot +is on to use the bot. + +=item B EBE + +This setting controls the amount of time for auto-ignore (flooding) to expire. + +=item B EBE + +This controls the amount of time for forced-online ignore to expire in minutes. + +=back + +=head2 Internal (simple) bot commands + +=over + +=item B EB|BE + +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 EBE + +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 EBE + +This proxy is used for any module in the bot which requires LWP + http proxy. + +=item B EB|BE + +This determines if the bot should use the countdown file to remember and +announce special dates. + +=item B EB|BE + +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 EB|BE + +The bot has the ability to search B for packages. This setting +controls if that is enabled or not. + +=item B EBE + +If the B search is enabled, this setting will control how often +the bot should update the index in hours. + +=item B EB|BE + +If B is enabled as well as this setting, the bot will search +freshmeat for factoids which do not exist. + +=item B EB|BE + +This controls if the bot should store uptime records or not. + +=item BminutesE> + +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 EB<0>|B<1>|B<2>E + +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 EB|BE + +This setting controls if the bot console will display warning messages or not. + +=item B EB|BE + +If the bot console should display debugging messages or not. + +=item B EB|BE + +If the bot should activate work in progress (experimental) features. + +I + +=item B EB|BE + +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 EB|BE + +This controls the interface that the bot should use. Most people will want to +use B which connects the bot to an IRC server. Optionally, you can setup a +standalone bot by setting this to B. In B 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 EB|BE + +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 EB|BE + +If the bot should dump its variables or not. + +=item B EB|BE + +If the bot should dump its variables when it shuts down. + +=item B EBE + +If the dumped variables should go to a sepcific log file. + +=item B EB|BE + +If the bot should dump extra variables. + +=item B EBE + +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 +or B may not work for certain variables. This is considered a B, +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>. If you would +rather a more realtime conversation with us, we can be found in the B<#infobot> +channel on the B network (B). + +=cut + diff --git a/doc/infobot.users.pod b/doc/infobot.users.pod new file mode 100644 index 0000000..264196a --- /dev/null +++ b/doc/infobot.users.pod @@ -0,0 +1,158 @@ +=pod + +=head1 NAME + +infobot.users - User accounts database for infobot + +=head1 SYNOPSIS + + # Please edit to your needs. + # "local" is used for CLI mode + # Passwords can be generated with mkpasswd in linux + + _default + --FLAGS amrt + --HOSTS *!*@* + + local + --FLAGS Aemnorst + --HOSTS local!local@local + --PASS xxfxfIfoJHdYg + + timriker + --FLAGS Aemnorst + --HOSTS *!~timr@TimRiker.active.supporter.pdpc + --PASS xxfxfIfoJHdYg + + xk + --FLAGS emnorst + --HOSTS *!xk@example.com + --HOSTS *!xk@superbox.home.org + --PASS 5K/rmJPzwxJhU + +=head1 DESCRIPTION + +This file controls who has access to use your infobot. + +=head1 FIELDS + +There are various fields allowed in your file. Whitespace is ignored, and as +usual, any line starting with a C<#> is treated as a comment. + +The first non whitespace/comment line in your file, is the user name for the +account you are about to define. Take note that a special username called +C<_default>, is meant to define what everyone who doesnt have an account in this +file should use for permissions. + +Also, the special user name C, is used when you run the bot in B +mode (console only, no B connection). As well, the C user requires a +special hostmask of S>. + +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 + +=over + +=item * + +B - bot administration over /msg (default is only via DCC CHAT) + +=item * + +B - dynamic ops (as on channel). (automatic +o) + +=item * + +B - add topics. + +=item * + +B - ask/request factoid. + +=item * + +B - modify factoid. (includes renaming) + +=item * + +B - bot owner, can "reload" + +=item * + +B - 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 - remove factoid. + +=item * + +B - teach/add factoid. + +=item * + +B - 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 + +I + +=item B<--PASS> + +This field used a C formated password, that is used for B 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 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 +command on B. + +=back + +=head1 BUGS + +At some point, it is likely that the C account will be removed and +implied to have full access. + +=cut + diff --git a/files/.cvsignore b/files/.cvsignore deleted file mode 100644 index cb7dd24..0000000 --- a/files/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -blootbot.chan -blootbot.config -blootbot.countdown -blootbot.servers -blootbot.uptime -blootbot.users -debian diff --git a/files/blootbot.help b/files/infobot.help similarity index 88% rename from files/blootbot.help rename to files/infobot.help index 2044d08..c0370ee 100644 --- a/files/blootbot.help +++ b/files/infobot.help @@ -1,12 +1,12 @@ -# Revised: 20050224 +# Revised: 20071016 # Author: Tim Riker ### 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 does the hokey-pokey". When asked about x, the bot does this "* blootbot does the hokey-pokey" +action: This is used to override the usual response. "x is 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 blootbot to choose one of the replies at random. "X is Y||Z" will produce "X is Y" or "X is Z" randomly. +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. @@ -106,7 +106,7 @@ chanunset: U: ## <#chan> [what] chanunset: E: ## #c chanunset: E: ## #c test -chattr: D: Change flags on a user (see @regFlagsUser in source) +chattr: D: Change flags on a user (see "help flags") chattr: U: ## [flags] chattr: E: ## bloot +nmo chattr: E: ## bloot -ot @@ -212,7 +212,7 @@ forget: If I have an old/redundant factoid x, "forget x" will cause me to erase freshmeat: D: Frontend to www.freshmeat.net freshmeat: U: ## -freshmeat: E: ## blootbot +freshmeat: E: ## infobot hex: D: Convert ascii to hex hex: U: ## @@ -249,7 +249,7 @@ lart: E: ## #perl everyone perl \=\= lamerville lc: D: lower case a given string lc: U: ## -lc: E: ## When will blootbot achieve world domination? +lc: E: ## When will infobot achieve world domination? listauth: D: Search the factoid extension db by creator listauth: U: ## @@ -257,15 +257,15 @@ listauth: E: ## xk listkeys: D: Search the factoid database by key (factoid) listkeys: U: ## -listkeys: E: ## blootbot +listkeys: E: ## infobot listvalues: D: Search the factoid database by value (description) listvalues: U: ## -listvalues: E: ## blootbot +listvalues: E: ## infobot literal: used to get a raw factoid contents. Use _default to ignore factoidSearch path. literal: U: ## [_default|prefix] -literal: E: ## blootbot +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 @@ -277,7 +277,7 @@ lock: N: Requires factoid extension (extra) support enabled. md5: D: calculates the md5sum of a given string md5: U: ## -md5: E: ## When will blootbot achieve world domination? +md5: E: ## When will infobot achieve world domination? mode: set modes for a channel mode: U: ## <#chan> @@ -325,7 +325,7 @@ nickometer: E: ## #botpark onjoin: D: get/set OnJoin message (needs chan option +OnJoin) onjoin: U: ## [#chan|_default] [-] [message] -onjoin: E: ## blootbot Hey! It's another blootbot! +onjoin: E: ## infobot Hey! It's another infobot! ord: D: Convert ascii to decimal ord: U: ## @@ -343,7 +343,7 @@ part: NOTE: /kick is an alternative piglatin: D: translates english text into piglatin piglatin: U: ## -piglatin: E: ## When will blootbot achieve world domination? +piglatin: E: ## When will infobot achieve world domination? quote: D: Frontend to yahoo's online stock market share listing quote: U: ## @@ -351,11 +351,11 @@ quote: E: ## RHAT,MSFT rename: D: Factoid renaming rename: U: ## 'from' 'to' -rename: E: ## 'infobot' 'blootbot' +rename: E: ## 'infobot' 'infobot' reverse: D: reverses a given string reverse: U: ## -reverse: E: ## When will blootbot achieve world domination? +reverse: E: ## When will infobot achieve world domination? rot13: D: ROT13's a given string rot13: U: ## @@ -366,14 +366,14 @@ say: U: ## scramble: D: scrambles a given string scramble: U: ## -scramble: E: ## When will blootbot achieve world domination? +scramble: E: ## When will infobot achieve world domination? search: U: ## for -search: E: ## google for blootbot +search: E: ## google for infobot seen: D: Report last seen time for somebody seen: U: ## -seen: E: ## blootbot +seen: E: ## infobot slashdot: D: News for nerds, Stuff that matters. [tm] (shows the headlines) slashdot: U: ## @@ -384,7 +384,7 @@ status: status dumps general status information tell: D: Tell someone about a factoid or command tell: U: ## -?about -tell: E: ## me about blootbot +tell: E: ## me about infobot tell: E: ## someone -about testing topic add: D: Add your own topic @@ -434,7 +434,7 @@ topic: End of help. uc: D: upper case a given string uc: U: ## -uc: E: ## When will blootbot achieve world domination? +uc: E: ## When will infobot achieve world domination? unforget: If a factoid has been forgotten, "unforget x" will cause me to unerase it. @@ -468,3 +468,30 @@ wtf: E: ## iirc +host: E: ## owner +host: E: ## *!*@owns.org +host: E: ## owner leet!leet@*.heh.org + +flags: D: Flags for chattr command +flags: D: "A" - bot administration over /msg (default is only via DCC CHAT) +flags: D: "O" - dynamic ops (as on channel). (automatic +o) +flags: D: "T" - add topics. +flags: D: "a" - ask/request factoid. +flags: D: "m" - modify factoid. (includes renaming) +flags: D: "n" - bot owner, can "reload" +flags: D: "o" - master of bot (automatic +amrt) +flags: D: - can search on factoid strings shorter than 2 chars +flags: D: - can tell bot to join new channels +flags: D: - can [un]lock factoids +flags: D: "r" - remove factoid. +flags: D: "t" - teach/add factoid. +flags: D: "s" - Bypass +silent on channels + +rssfeeds: D: rssfeeds is used to control the RSS Feed tracking module +rssfeeds: U: rssfeeds [command] +rssfeeds: E: rssfeeds flush +rssfeeds: D: flush - Will erase the cache file. (Must be chattr +o) +rssfeeds: D: update - Force a manual update of the feeds. (Must be chattr +o) + +hex2ip: D: Convert Hex idents for some gateways to an IP address +hex2ip: U: ## <8 char hex value> +hex2ip: E: ## AabBcC12 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/files/blootbot.lang b/files/infobot.lang similarity index 97% rename from files/blootbot.lang rename to files/infobot.lang index 527ea1f..242378b 100644 --- a/files/blootbot.lang +++ b/files/infobot.lang @@ -1,4 +1,4 @@ -# blootbot.lang: configurable responses. +# infobot.lang: configurable responses. # by the xk. ### diff --git a/files/blootbot.lart b/files/infobot.lart similarity index 100% rename from files/blootbot.lart rename to files/infobot.lart diff --git a/files/blootbot.randtext b/files/infobot.randtext similarity index 100% rename from files/blootbot.randtext rename to files/infobot.randtext diff --git a/files/sample/blootbot.servers b/files/sample/blootbot.servers deleted file mode 100644 index 648b010..0000000 --- a/files/sample/blootbot.servers +++ /dev/null @@ -1,7 +0,0 @@ -### -# blootbot.servers: line separated list of servers to connect to -### - -irc.freenode.net -irc.home.org -irc.linux.com diff --git a/files/sample/blootbot.chan b/files/sample/infobot.chan similarity index 92% rename from files/sample/blootbot.chan rename to files/sample/infobot.chan index b0fe8b6..c721138 100644 --- a/files/sample/blootbot.chan +++ b/files/sample/infobot.chan @@ -1,4 +1,4 @@ -#v1: blootbot -- infobot -- written Sat Jan 21 06:17:24 2006 +#v1.5.0: infobot #botpark -OnJoin @@ -7,6 +7,7 @@ #debian-bots +News + -OnJoin +RootWarn +chanlimitcheck chanlimitcheckInterval 10 @@ -21,8 +22,16 @@ +newsNotifyAll rootWarnMode aggressive +#infobot + -OnJoin + +RootWarn + +autojoin + _default + +hex2ip + +News +BZFlag + +chanServCheck +Debian +DebianExtra +Dict @@ -93,4 +102,3 @@ _default +wtf +zfi +zsi - diff --git a/files/sample/blootbot.config b/files/sample/infobot.config similarity index 85% rename from files/sample/blootbot.config rename to files/sample/infobot.config index 246ed2e..073a81e 100644 --- a/files/sample/blootbot.config +++ b/files/sample/infobot.config @@ -1,12 +1,12 @@ -# blootbot configuration file, modify it to your own taste. blootbot reads -# this file from files/blootbot.config so it should be moved there. +# 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 blootbot -set ircUser blootbot -set ircName blootbot experimental bot +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 @@ -18,15 +18,14 @@ set ircHost 0.0.0.0 set owner OWNER -# nickserv/chanserv support. +# nickserv 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 +# path to a temporary directory which infobot can use. +set tempDir /tmp ##### # Factoid database configuration @@ -37,20 +36,20 @@ set tempDir temp # mysql -- ... # SQLite -- SQLite (libdbd-sqlite-perl) (might be version 2 or 3) # SQLite2 -- SQLite (libdbd-sqlite-perl) (force version 2) -# pgsql -- postgresql (NOT SUPPORTED) +# pgsql -- postgresql (SUPPORTED and TESTED!!!) ### 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 +# 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 blootbot +set SQLUser infobot # [str] SQL password. (unset for SQLite) set SQLPass PASSWORD @@ -180,6 +179,9 @@ set freshmeatForFactoid false # [0/1] Uptime logs set Uptime true +# [minutes] RSS Feeds refresh interval +set rssFeedTime 30 + ##### # Miscellaneous configuration options ##### @@ -216,7 +218,12 @@ set useStrict 1 # 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 blootbot.chan for per-channel specific configuration see +# Now modify infobot.chan for per-channel specific configuration see # sample.chans for info. #### diff --git a/files/sample/blootbot.countdown b/files/sample/infobot.countdown similarity index 100% rename from files/sample/blootbot.countdown rename to files/sample/infobot.countdown diff --git a/files/sample/infobot.servers b/files/sample/infobot.servers new file mode 100644 index 0000000..93767ca --- /dev/null +++ b/files/sample/infobot.servers @@ -0,0 +1,7 @@ +### +# infobot.servers: line separated list of servers to connect to +### + +irc.freenode.net +irc.home.org +irc.linux.com diff --git a/files/sample/blootbot.users b/files/sample/infobot.users similarity index 65% rename from files/sample/blootbot.users rename to files/sample/infobot.users index 59f7b1e..9f30e78 100644 --- a/files/sample/blootbot.users +++ b/files/sample/infobot.users @@ -1,4 +1,7 @@ -#v1: blootbot -- blootbot -- written Mon Feb 28 23:46:48 2005 +#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 diff --git a/files/unittab b/files/unittab deleted file mode 100644 index d4f7a0e..0000000 --- a/files/unittab +++ /dev/null @@ -1,668 +0,0 @@ -# -# Unit defintions -# 18 May 2001 M-J. Dominus . -# 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 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 -short 100|112 # Convert long tons, cwts, and quarters to short. -shortton short longton -ton short longton # the american ton, see metriton and longton -stone 14 lb -cental 100 lb -wey 252 lb -# Obscure apothecaries' measures -scruple 20 grains -dram 3 scruples -apothounce 480 grains -apothoz apothounce -apothpound 12 apothoz -apothlb apothpound -# Troy measures (for gold and precious stones) -pennyweight 24 grains -troyoz 480 grains # We can't define `troy' as a constant, - # because there are 16 oz in a lb, but only - # 12 troyoz in a troylb, so at least one of - # `troy oz' or `troy lb' would be wrong. -troylb 12 troyoz -carat 3.08647 grain # Metric version. Is this useful? -atomicmassunit 1.6605402e-27 kg # NIST 19990301 (+/- 0.10e-33 kg) -amu atomicmassunit -quintal 100kg # Metric quintal. Wasn't there another quintal? -elvis 255lb # At the time of his death, the King weighed 255 lb. - -# TIME -sec second -s second -minute 60 sec -min minute -hour 60 min -hr hour -day 24 hrs -dy day # This will denote mean solar days -siderealday 0.99726957 dys -week 7 days -wk week -month 30 days -lunarmonth 29.530588 days # Mean solar days -meanmonth 730 hours -mo month -tropicalyear 365.24219 dys # Mean solar days -siderealyear 365.25636 dys # Mean solar days -leapyear 366 dys # Mean solar days -calendaryear 365 dys # Mean solar days -gregorianyear 365.2425 dys -year tropicalyear # Correct on average for most calculations -yr years -fortnight two weeks -decade 10 years -century 100 years -millennium 1000 years -millennia millennium -centuries century -beat 1|1000 day # Swatch Internet Time (``Fuck the Sun'') -# Velocity -knot 1 nautical mi/hour -mph 1 mi/hr - -# SCIENTIFIC -# -# Electromagnetic items, work, force, energy. -# -# Velocity -c 299792458 m/s # NIST 19990301 EXACT -light c # Implies `light year' - - -# Absolute temperature -kelvin Kelvin -K Kelvin -Rankine 5|9 K # This is a very funny unit -Ra Rankine - -# Amount of substance -mol mole -Avogadro 6.0221367e23 -avogadro Avogadro -molecule 1 mole per Avogadro # 1 mole is an Avogagro-number of molecules - -# Current -# The Ampere is fundamental here, defined as the constant current -# which, if maintained in two straight parallel conductors of infinite -# length, of negligible circular cross-section, and placed 1m apart in -# vacuum, would produce between these conductors a force equal to 2e-7 -# newtons per meter of length. -Ampere ampere -amp ampere -abampere 10 amps -abamp abampere -statampere 3.335635e-11 abamperes -statamp statampere - -# What is this called? Is it capitalized? Is there an abbreviation? -gilbert 0.79577472 ampere turns - -# Electrostatic charge -Coulomb ampere sec -coulomb Coulomb -coul Coulomb -C Coulomb -electron 1.60217733e-19 C # Charge on the electron; implies electron-volts -e electron -abcoulomb 10C -statcoulomb 3.335635e-11 abcoulomb - - -# Force -Newton kg m/s2 -newton Newton -N newton -dyne g cm/s2 -grav 9.8 m/s2 # Acceleration due to gravity -gee grav -# Actually the accleration varies with altitude and latitude, -# from 9.78039 m/s2 at the equator to 9.83217 m/s2 at the poles. -# This mean value corresponds to a latitude of about 38 degrees. -lbf lb grav - -# Pressure -Pascal N/m2 -pascal Pascal -Pa pascal -atmosphere 101325 N/m2 # NIST 20010518 EXACT -atm atmosphere -bar megadyne/cm2 # Implies `millibars' -mercury 1|760 atm/mm # Implies `mm mercury' and `inches mercury' -hg mercury -torricelli mm hg -torr torricelli -water .0295 atm/ft # Implies `feet water' -barye dyne/cm2 -air 6.6083e-5 atm/foot # At 60 deg.F; Implies `feet air' - -# Work and energy -Joule newton-meter -joule Joule -J joule -footpound ft-lbf # foot-pound won't work, because `pound' is a mass -calorie 4.186 J -cal calorie -kcal kilocalorie -britishthermalunit 1054.8 J -btu britishthermalunit -erg dyne-cm -# Kilowatt-hour (kWh) will be implied by `Watt'. - - -# Power -Watt J/sec -watt Watt -W Watt -horsepower 550 ft-lbf/s - -# Electric potential -Volt W/amp -volt Volt -V Volt -abvolt 1|100 microvolt -statvolt 2.997930e10 V - -# Frequency -cycle 1 # For `cycles per second' -Hertz cycles per second -Hz Hertz -hz Hz - -# Inductance -Henry volt s/amp -henry Henry -H Henry -abhenry 1.0e-9 henry -Henries Henry # For plural -henries Henry -stathenry 8.987584e11 henries -stathenries stathenry - -# Etc. -Weber volt s -weber Weber -Wb weber -Tesla Wb/m2 -tesla Tesla -T tesla -Oersted 1|4 pi kiloamp/m -oersted Oersted -Oe oersted -Maxwell 1.0e-8 Wb -maxwell Maxwell -Mx Maxwell -Gauss 1.0e-4 T -gauss Gauss -# We won't use G for Gauss because it is more important to -# use it for the universal gravitational constant - -# Capacitance -# `farad' is *not* an abbreviation for `Faraday' as far as I can tell. -farad amp sec / volt -F farad -abfarad 1.0e9 farad -statfarad 1.112646e-13 farad - -# Resistance -Ohm volt/amp -ohm Ohm -abohm 1.0e-9 ohm -statohm 8.987584e11 Ohms - -# Conductance -mho 1/ohm -abmho 1/abohm -Siemens mho -siemens Siemens - -# Misc -Angstrom 1.0e-10 m -angstrom Angstrom -G 6.67259e-11 N m2/kg2 # Newton gravitational constant NIST19990301 -lightyear light year # Common abbreviation -eV e V # Electron volts -ev eV -kev kiloeV -Mev megaeV -Gev gigaeV -Tev teraeV -energy c2 # You can ask for `1 gram energy' and get - # the amount of energy equivalent to - # 1 gram according to e=mc2. - # Check: 1amu energy == 931.16 Mev? -Franklin (10/c) C cm/sec -Fr Franklin -franklin Franklin -Biot 10 amp -Bi Biot -biot Biot - -# Viscosity - Maybe someone who understands this better can check. -poise g/(cm s) # Named after M. Poiseuille -rhe 1/poise -reyn (lbf s)/in2 -# Kinematic viscosity = viscosity per unit density -stoke cm2/s - -# Refrigeration - Maybe someone who understands this better can check. -refrigeration 288000 btu/ton -ice tons refrigeration / 2009.1 lb - -# Light -# The candela is fundamental here. Prior to 1979, it was defined as -# the luminous intensity of a black body at the temperature of -# solidification of platinum, whose radiating surface is 1/60 cm2. It -# is now the luminous intensity, in a given direction, of a source -# that emits monochromatic radiation of frequency 540e12 Hz and that -# has a radiant intensity in that direction of 1|683 W/sr -cd candela -sr steradian -lumen candela sr -lm lumen -lux lm/m2 -lx lux -candlepower 12.566370 lumens -candle candela # ``International standard candle'' -Hefner 0.90 candles # This was the German standard in early C20. -hefner Hefner -Lambert lm/cm2 -lambert Lambert -footcandle lm/ft2 # NOT the same as foot-candle. -phot 1.0e4 lx -stilb candle/m2 # Same as a pi lambert - -# Various important physical constants -# I got this stuff from physics.nist.gov on 19990301. -h 6.6260755e-27 erg-sec # Planck's constant -hbar h/(2 pi) -plancklength 1.61605e-35 m -planckmass 2.17671e-8 kg -plancktime 5.39056e-44 sec -# Let's reserve `Planck' for a while longer until I can decide if -# they'd be useful in `planck time' etc. -permeability 4*pi*1.0e-7 H/m # Magnetic permeability of vacuum constant -permittivity 8.854187817e-12 F/m # Electric permittivity of vacuum constant -protonmass 1.6726231e-27 kg -neutronmass 1.6749286e-27 kg -electronmass 9.1093897e-31 kg -finestructure 7.29735308e-3 # Rl -# Electron charge is up above under `electrostatic'. -# There's no reason to get too obscure here because if someone wants -# they can make up an `obscure physical constants' file that -# physiscists could load in if they wanted to. So I've omitted stuff -# like the magnetic moment of the muon. - -# ANGULAR -rad radian -circle 2 pi radians -revolution circle # For revolutions / sec -rev revolution -rpm revolutions per minute -quadrant 1|4 circle -degree 1|360 circle -arcminute 1|60 degree -arcsecond 1|60 arcminute -arcmin arcminute -arcsec arcsecond -sphere 4 pi steradians -grade 1|100 quadrant -grad grade - -# PAPER -quire 50 sheets -ream 10 quires - -# INFORMATION -byte 8 bits -nybble half byte -kbyte 1024 bytes # `kilobyte' means 1000 bytes -# Don't use `K'; that's for Kelvins. -kb kbyte -Kb kbyte -KB kbyte -mbyte 1024 kbytes # `megabyte' means 1000000 bytes -meg mbyte -kbit 1024 bits -Kbit kbit -mbit 1024 kbits -Mbit mbit -baud bit/sec # Not strictly correct - -# MONEY -# -# Conversions accurate only as of 25 November 1996. -# -$ dollar -usdollar $ -usd $ -us$ $ -$us $ -US$ $ -$US $ -cent 1|100 $ -Australia.dollar 0.8123$ -AUS$ Australia.dollar -Austria.schilling 0.09438$ -Belgium.franc 0.03223$ -Brazil.real 0.9709$ -British.pound 1.681$ -pound.sterling British.pound -sterling British.pound -Canada.dollar 0.7468$ -Can$ Canada.dollar -Cayman.currency 1.22$ -Denmark.krone 0.173$ -krone Denmark.krone -EuropeanCommunityUnit.ECU 1.278$ -ECU EuropeanCommunityUnit.ECU -ecu ECU -Finland.markka 0.2203$ -markka Finland.markka -France.franc 0.1963$ -franc France.franc -Germany.mark 0.6647$ -DM Germany.mark -Deutschmark DM -mark DM -Greece.drachma 0.004216$ -drachma Greece.drachma -HongKong.dollar 0.1294$ -HK$ HongKong.dollar -India.rupee 0.02797$ -rupee India.rupee -Ireland.punt 1.684$ -punt Ireland.punt -Israel.shekel 0.3623$ -shekel Israel.shekel -Italy.lira 0.0006655$ -Japan.yen 0.008976$ -yen Japan.yen -Kenya.shilling 0.02376$ -Malaysia.dollar 0.397$ -Mexico.peso 0.1269$ -peso Mexico.peso -Morocco.dirham 0.1248$ -dirham Morocco.dirham -Netherlands.guilder 0.5924$ -guilder Netherlands.guilder -NewZealand.dollar 0.7153$ -NZ$ NewZealand.dollar -Norway.krone 0.1576$ -krone Norway.krone -Portugal.escudo 0.006577$ -escudo Portugal.escudo -Senegal.CFAfranc 0.002019$ -SouthAfrica.rand 0.2169$ -rand SouthAfrica.rand -Spain.peseta 0.007896$ -peseta Spain.peseta -Sweden.krona 0.1513$ -krona Sweden.krona -Switzerland.franc 0.788$ -swissfranc Switzerland.franc -Swissfranc Switzerland.franc -Turkey.lira 1.3e-05$ -# Old-style Brit money. Did I omit anything interesting? -sovereign sterling -shilling 1|20 sterling -penny 1|12 shilling -pence penny -farthing 1|4 penny -hapenny half penny -twopence two pence -tuppence two pence -thruppence 3 pence -threepence 3 pence -sixpence 6 pence -crown 5 shillings # Implies `half crown' -guinea 21 shillings -florin 2 shillings - - -# 18th century French coinage. References: -# http://home.nordnet.fr/~jlmorel/mesures.html and reverse-engineered -# from The Three Musketeers -# 20011227 Thomas R Wyant III -livre franc ### 3 Musketeers has francs! - ### Now, you too can convert Louis d'Or to U.S. Dollars! -sou 1|20 livre -crown 3 livres # It's ecu in French, not to be confused with ECU. -pistole 10 livres -double 2 # 3 Musketeers refers to double pistoles, so ... -louis 24 livres -### Now if only I had good definitions for reals and doubloons ... - - -# For `register tons' -register 100 ft3/ton -registerton register ton - -# What's missing? -# bequerel (nucleotide radioactivity): Bq = k/s k=1?? -# gray (absorbed dose): Gy = k J/kg k=1?? -# sievert (dose equivalent): Sv = k J/kg k=1?? -# curie: Ci = 3.3e10 Bq -# roentgen: R = 2.58e-4 C/kg -# rad: rad = centigray -# rem: rem = centisievert diff --git a/blootbot b/infobot similarity index 92% rename from blootbot rename to infobot index a888ed2..f20af53 100755 --- a/blootbot +++ b/infobot @@ -1,7 +1,9 @@ #!/usr/bin/perl -# infobot -- copyright kevin lenzo (c) 1997-1999 -# blootbot -- copyright david sobon (c) 1999-infinity +# infobot +# copyright kevin lenzo (c) 1997-1999 +# copyright david sobon (c) 1999-infinity +# Copyright (c) 2001-2008 Tim Riker use strict; use vars qw($bot_base_dir $bot_src_dir $bot_misc_dir $bot_state_dir @@ -27,8 +29,6 @@ BEGIN { $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"; @@ -99,3 +99,5 @@ sub duperuncheck { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/log/.cvsignore b/log/.cvsignore deleted file mode 100644 index 72e8ffc..0000000 --- a/log/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/patches/WWW_Search.patch b/patches/WWW_Search.patch new file mode 100644 index 0000000..a276101 --- /dev/null +++ b/patches/WWW_Search.patch @@ -0,0 +1,444 @@ +--- Google.pm.orig Wed May 24 16:55:47 2000 ++++ Google.pm Wed Jan 16 22:02:53 2002 +@@ -2,7 +2,7 @@ + # Google.pm + # by Jim Smyser + # Copyright (C) 1996-1999 by Jim Smyser & USC/ISI +-# $Id$ ++# $Id$ + ########################################################## + + +@@ -30,8 +30,6 @@ + It handles making and interpreting Google searches. + F. + +-Googles returns 100 Hits per page. Custom Linux Only search capable. +- + This class exports no public interface; all interaction should + be done through L objects. + +@@ -70,33 +68,41 @@ + + This module adheres to the C 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. + + + =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 '; + $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|(\d+) 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@^

(.*)
(.*)@i || ++ m@^

(.*).*?(.*)@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 . '
' if not $mDesc =~ m@
@; ++ $hit->description($mDesc) if (defined $hit); ++ $state = $HITS; ++ ++# description parsing ++ } elsif ($state == $HITS && m@(\.\.(.+)) @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@

@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|.*?|i ++ ) { ++ my($relative_url) = $1; ++ print STDERR "**Fetching >>Next<< Page**\n" if ($self->{_debug}); ++ $self->{_next_url} = 'http://www.google.com' . $relative_url; ++ $state = $POST_NEXT; ++ } ++ } ++ ++ if ($state != $POST_NEXT) { ++ # No "Next" Tag ++ $self->{_next_url} = undef; ++ $self->begin_new_hit($hit, $raw) if ($state == $HITS); ++ $self->{_next_url} = undef; ++ } ++ ++ # ZZZzzzzZZZZzzzzzzZZZZZZzzz ++ $self->user_agent_delay if (defined($self->{_next_url})); ++ return $hits_found; ++} ++ ++1; ++ diff --git a/patches/WWW_Search.patch.old b/patches/WWW_Search.patch.old new file mode 100644 index 0000000..eec3ce3 --- /dev/null +++ b/patches/WWW_Search.patch.old @@ -0,0 +1,31 @@ +--- WWW/Search/Google.pm.orig Wed May 24 16:55:47 2000 ++++ WWW/Search/Google.pm Wed May 24 16:56:19 2000 +@@ -240,7 +240,7 @@ + if ($state eq $HITS) { + print "\n**state == HITS**\n" if 2 <= $self->{_debug}; + } +- if ($state eq $HITS && m@^

(.*)$@i) ++ if ($state eq $HITS && m@^

(.*)@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; + } diff --git a/scripts/backup_table-master.sh b/scripts/backup_table-master.sh index a98bba7..31c1c24 100755 --- a/scripts/backup_table-master.sh +++ b/scripts/backup_table-master.sh @@ -1,7 +1,7 @@ #!/bin/bash BACKUP_SRCDIR="/var/lib/mysql/" -BACKUP_TDIR="blootbot/" +BACKUP_TDIR="infobot/" BACKUP_FILE="/home/a/apt/public_html/tables.tar.bz2" pwd @@ -18,3 +18,5 @@ else fi exit 0; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/backup_table-slave.pl b/scripts/backup_table-slave.pl index bc7cbc7..c743d48 100755 --- a/scripts/backup_table-slave.pl +++ b/scripts/backup_table-slave.pl @@ -101,3 +101,5 @@ for(my $i=0; $i $val\n"; } dbmclose %db; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/findparam.pl b/scripts/findparam.pl old mode 100644 new mode 100755 index 900920f..0a559d1 --- a/scripts/findparam.pl +++ b/scripts/findparam.pl @@ -70,3 +70,5 @@ print "Conf:\n"; foreach (sort keys %conf) { print " $_\n"; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/fixbadchars.pl b/scripts/fixbadchars.pl old mode 100644 new mode 100755 index 8f9d072..2662993 --- a/scripts/fixbadchars.pl +++ b/scripts/fixbadchars.pl @@ -2,7 +2,7 @@ use DBI; -my $dsn = "DBI:mysql:blootbot:localhost"; +my $dsn = "DBI:mysql:infobot:localhost"; my $dbh = DBI->connect($dsn, "USERNAME", "PASSWORD"); my @factkey; @@ -65,3 +65,5 @@ foreach (keys %factval) { } $dbh->disconnect(); + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/insertDB.pl b/scripts/insertDB.pl old mode 100644 new mode 100755 index d11cd09..802149b --- a/scripts/insertDB.pl +++ b/scripts/insertDB.pl @@ -9,7 +9,7 @@ require "src/logger.pl"; require "src/modules.pl"; require "src/Factoids/DBCommon.pl"; -&loadConfig($bot_config_dir."/blootbot.config"); +&loadConfig($bot_config_dir."/infobot.config"); &loadDBModules(); unless (@_) { @@ -34,3 +34,5 @@ foreach (@_) { close IN; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/irclog2html.pl b/scripts/irclog2html.pl index 9cef018..40e4ed2 100755 --- a/scripts/irclog2html.pl +++ b/scripts/irclog2html.pl @@ -15,7 +15,7 @@ # Modified by Tim Riker # to work with infobot logs -# then modified again for blootbot +# then modified again for infobot # Usage: irclog2html < logfile @@ -90,7 +90,7 @@ sub footer { Jeff Waugh - find it at freshmeat.net! Modified by Tim Riker to work with -blootbot logs, split per channel, etc. +infobot logs, split per channel, etc. }; return $return; @@ -317,9 +317,10 @@ sub main { if (!scalar @ARGV) { print "Usage: irclog2html.pl < 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 diff --git a/scripts/makepasswd b/scripts/makepasswd index b76617c..7b9d47c 100755 --- a/scripts/makepasswd +++ b/scripts/makepasswd @@ -18,3 +18,4 @@ sub mkpasswd { return crypt($what, $salt); } +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/mysql2txt.pl b/scripts/mysql2txt.pl index 53f3b77..bc7fad6 100755 --- a/scripts/mysql2txt.pl +++ b/scripts/mysql2txt.pl @@ -18,7 +18,7 @@ if (!defined $dbname) { } # open the db. -&loadConfig("files/blootbot.config"); +&loadConfig("files/infobot.config"); &loadDBModules(); &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'}); @@ -45,3 +45,5 @@ $sth->finish; print "Done.\n"; &closeDB(); + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/oreilly_dumpvar.pl b/scripts/oreilly_dumpvar.pl old mode 100644 new mode 100755 index 3efe8b6..70410d8 --- a/scripts/oreilly_dumpvar.pl +++ b/scripts/oreilly_dumpvar.pl @@ -25,3 +25,5 @@ $x = 10; %z = (1,2,3,4, 5, 6, \@y); $z = 300; DUMPVAR::dumpvar("Test"); + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/oreilly_prettyp.pl b/scripts/oreilly_prettyp.pl old mode 100644 new mode 100755 index db58d78..3d25165 --- a/scripts/oreilly_prettyp.pl +++ b/scripts/oreilly_prettyp.pl @@ -85,3 +85,5 @@ sub print_indented { $spaces = ": " x $level; print "${spaces}$_[0]\n"; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/output_stats.sh b/scripts/output_stats.sh old mode 100644 new mode 100755 index 0b877bd..a731473 --- a/scripts/output_stats.sh +++ b/scripts/output_stats.sh @@ -1,7 +1,9 @@ #!/bin/sh -echo -n "DEBUG: "; grep DEBUG `find blootbot src -type f`| wc -l -echo -n "WARN: "; grep WARN `find blootbot src -type f` | wc -l -echo -n "FIXME: "; grep FIXME `find blootbot src -type f` | wc -l -echo -n "status: "; grep status `find blootbot src -type f` | wc -l -echo -n "ERROR: "; grep ERROR `find blootbot src -type f` | wc -l -echo -n "TODO: "; grep TODO `find blootbot src -type f` | wc -l +echo -n "DEBUG: "; grep DEBUG `find infobot src -type f`| wc -l +echo -n "WARN: "; grep WARN `find infobot src -type f` | wc -l +echo -n "FIXME: "; grep FIXME `find infobot src -type f` | wc -l +echo -n "status: "; grep status `find infobot src -type f` | wc -l +echo -n "ERROR: "; grep ERROR `find infobot src -type f` | wc -l +echo -n "TODO: "; grep TODO `find infobot src -type f` | wc -l + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/parse_warn.pl b/scripts/parse_warn.pl index 53a224c..e22e024 100755 --- a/scripts/parse_warn.pl +++ b/scripts/parse_warn.pl @@ -89,3 +89,5 @@ foreach $file (keys %done) { print "=> error: could not open file.\n"; } } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/showvars.pl b/scripts/showvars.pl old mode 100644 new mode 100755 index 22c55ac..80b9c35 --- a/scripts/showvars.pl +++ b/scripts/showvars.pl @@ -108,3 +108,5 @@ sub print_indented { $spaces = ": " x $level; print "${spaces}$_[0]\n"; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/symname.pl b/scripts/symname.pl index dfa71c7..86e2649 100755 --- a/scripts/symname.pl +++ b/scripts/symname.pl @@ -102,3 +102,5 @@ sub DumpPackage { print $padding."scalars $scalar, size $size\n"; return $size; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/txt2mysql.pl b/scripts/txt2mysql.pl index 47a70b7..68b134d 100755 --- a/scripts/txt2mysql.pl +++ b/scripts/txt2mysql.pl @@ -19,7 +19,7 @@ my $txtfile = shift; open(IN,$txtfile) or die "error: cannot open txtfile '$txtfile'.\n"; # read the bot config file. -&loadConfig("files/blootbot.config"); +&loadConfig("files/infobot.config"); &loadDBModules(); &openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'}); @@ -55,3 +55,5 @@ close IN; print "Done.\n"; &closeDB(); + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/vartree.pl b/scripts/vartree.pl old mode 100644 new mode 100755 index d96fcc1..1b53de8 --- a/scripts/vartree.pl +++ b/scripts/vartree.pl @@ -78,3 +78,5 @@ sub vartree { print "end.\n"; } + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/scripts/webbackup.pl b/scripts/webbackup.pl index ce6412e..41e43c7 100755 --- a/scripts/webbackup.pl +++ b/scripts/webbackup.pl @@ -93,3 +93,5 @@ for(my $i=0; $i v.3 +-- ALTER TABLE onjoin ADD COLUMN modified_by VARCHAR(20) NOT NULL DEFAULT 'nobody'; +-- ALTER TABLE onjoin ADD COLUMN modified_time INT NOT NULL DEFAULT '0'; +-- ** the following doesn't work for sqlite ** +-- ALTER TABLE onjoin ADD PRIMARY KEY (nick, channel); diff --git a/setup/sqlite2/rootwarn.sql b/setup/sqlite2/rootwarn.sql new file mode 100644 index 0000000..d3ea912 --- /dev/null +++ b/setup/sqlite2/rootwarn.sql @@ -0,0 +1,8 @@ +CREATE TABLE rootwarn ( + nick VARCHAR(20) NOT NULL, + attempt SMALLINT UNSIGNED, + time INT NOT NULL, + host VARCHAR(80) NOT NULL, + channel VARCHAR(30) NOT NULL, + PRIMARY KEY (nick) +); diff --git a/setup/sqlite2/seen.sql b/setup/sqlite2/seen.sql new file mode 100644 index 0000000..75c7639 --- /dev/null +++ b/setup/sqlite2/seen.sql @@ -0,0 +1,8 @@ +CREATE TABLE seen ( + nick VARCHAR(20) NOT NULL, + time INT NOT NULL, + channel VARCHAR(30) NOT NULL, + host VARCHAR(80) NOT NULL, + message TINYTEXT NOT NULL, + PRIMARY KEY(nick) +); diff --git a/setup/sqlite2/stats.sql b/setup/sqlite2/stats.sql new file mode 100644 index 0000000..d738dc0 --- /dev/null +++ b/setup/sqlite2/stats.sql @@ -0,0 +1,8 @@ +CREATE TABLE stats ( + nick VARCHAR(20) NOT NULL, + type VARCHAR(8) NOT NULL, + channel VARCHAR(30) NOT NULL DEFAULT "PRIVATE", + time INT UNSIGNED DEFAULT 'UNIX_TIMESTAMP()', + counter SMALLINT UNSIGNED DEFAULT '0', + PRIMARY KEY (nick,type,channel) +); diff --git a/setup/uptime.sql b/setup/uptime.sql deleted file mode 100644 index 373902a..0000000 --- a/setup/uptime.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE uptime ( - uptime INT UNSIGNED DEFAULT '0', # start. - endtime INT UNSIGNED DEFAULT '0', # end. - string VARCHAR(128) NOT NULL, - PRIMARY KEY (uptime) -); diff --git a/src/CLI/Support.pl b/src/CLI/Support.pl index d3c5a3d..33034a3 100644 --- a/src/CLI/Support.pl +++ b/src/CLI/Support.pl @@ -16,17 +16,17 @@ sub cliloop { $nuh = "local!local\@local"; $uh = "local\@local"; - $who = "local"; - $orig{who} = "local"; + $who = 'local'; + $orig{who} = 'local'; $ident = $param{'ircUser'}; $chan = $talkchannel = "_local"; $addressed = 1; $msgType = 'private'; - $host = "local"; + $host = 'local'; # install libterm-readline-gnu-perl to get history support use Term::ReadLine; - my $term = new Term::ReadLine 'blootbot'; + my $term = new Term::ReadLine 'infobot'; my $prompt = "$who> "; #$OUT = $term->OUT || STDOUT; while ( defined ($_ = $term->readline($prompt)) ) { @@ -47,7 +47,7 @@ sub msg { } if (!defined $msg) { - $msg ||= "NULL"; + $msg ||= 'NULL'; &WARN("msg: msg == $msg."); return; } @@ -101,3 +101,5 @@ sub performAddressedReply { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/CommandStubs.pl b/src/CommandStubs.pl index ef2e014..4a3fb57 100644 --- a/src/CommandStubs.pl +++ b/src/CommandStubs.pl @@ -331,7 +331,7 @@ sub seen { &seenFlush(); # very evil hack. oh well, better safe than sorry. # TODO: convert to &sqlSelectRowHash(); - my $select = 'nick,time,channel,host,message,messagecount'; + my $select = 'nick,time,channel,host,message'; if ($person eq 'random') { @seen = &randKey('seen', $select); } else { @@ -363,7 +363,7 @@ sub seen { if (&IsChanConf('seenStats') > 0) { my $i; - $i = $seen[6] || $userstats{lc $seen[0]}{'Count'}; + $i = $userstats{lc $seen[0]}{'Count'}; $reply .= ". Has said a total of \002$i\002 messages" if (defined $i); $i = $userstats{lc $seen[0]}{'Time'}; $reply .= '. Is idling for '.&Time2String(time() - $i) if (defined $i); @@ -453,7 +453,7 @@ sub convert { return; } - &NewUnits::convertUnits($from, $to); + &Units::convertUnits($from, $to); return; } @@ -481,7 +481,7 @@ sub lart { $for = $2; } - my $line = &getRandomLineFromFile($bot_data_dir. '/blootbot.lart'); + my $line = &getRandomLineFromFile($bot_data_dir. '/infobot.lart'); if (defined $line) { if ($target =~ /^(me|you|itself|\Q$mynick\E)$/i) { $line =~ s/WHO/$who/g; @@ -644,11 +644,6 @@ sub do_text_counters { $chan = $1; } - if ($message =~ /^_stats(\s+(\S+))$/i) { - &textstats_main($2); - return 1; - } - my ($type,$arg); if ($message =~ /^($z)stats(\s+(\S+))?$/i) { $type = $1; @@ -657,27 +652,21 @@ sub do_text_counters { return 0; } - # even more uglier with channel/time arguments. - my $c = $chan; -# my $c = $chan || 'PRIVATE'; - my $where = 'type='.&sqlQuote($type); - if (defined $c) { - &DEBUG("c => $c"); - $where .= ' AND channel='.&sqlQuote($c) if (defined $c); - } else { - &DEBUG('not using chan arg'); - } + my $c = $chan || 'PRIVATE'; - my $sum = (&sqlRawReturn('SELECT SUM(counter) FROM stats' - .' WHERE '.$where ))[0]; + # Define various types of stats in one place. + # Note: sqlSelectColHash has built in sqlQuote + my $where_chan_type = { channel => $c, type => $type }; + my $where_chan_type_nick = { channel => $c, type => $type, nick => $arg}; + + my $sum = (&sqlSelect('stats', 'SUM(counter)', $where_chan_type))[0]; if (!defined $arg or $arg =~ /^\s*$/) { - # this is way ugly. - # TODO: convert $where to hash + # get top 3 stats of $type in $chan my %hash = &sqlSelectColHash('stats', 'nick,counter', - { }, - $where.' ORDER BY counter DESC LIMIT 3', 1 + $where_chan_type, + 'ORDER BY counter DESC LIMIT 3', 1 ); my $i; my @top; @@ -702,34 +691,32 @@ sub do_text_counters { &performStrictReply("zero counter for \037$type\037."); } } else { - # TODO: convert $where to hash and use a sqlSelect - my $x = (&sqlRawReturn('SELECT SUM(counter) FROM stats'. - " WHERE $where AND nick=".&sqlQuote($arg) ))[0]; + my $x = (&sqlSelect('stats', 'SUM(counter)', $where_chan_type_nick))[0]; - if (!defined $x) { # !defined. + if (!defined $x) { # If no stats were found &performStrictReply("$arg has not said $type yet."); return 1; } - # defined. - # TODO: convert $where to hash - my @array = &sqlSelect('stats', 'nick', undef, - $where.' ORDER BY counter', 1 + # Get list of all nicks for channel $c and $type + my @array = &sqlSelectColArray('stats', 'nick', + $where_chan_type, + 'ORDER BY counter DESC' ); - my $good = 0; - my $i = 0; - for ($i=0; $i $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 $i, good => $good, total => $total"); - $x .= ' '.$total.'blah blah'; - } - -# return; - - if (!defined $x) { # !defined. - &performStrictReply("$arg has not said $type yet."); - return; - } - - my $xtra = ''; - if ($total and $good) { - my $pct = sprintf("%.01f", 100*(1+$total-$ii)/$total); - $xtra = ", ranked $ii\002/\002$total (percentile: \002$pct\002 %)"; - } - - my $pct1 = sprintf("%.01f", 100*$x/$sum); - &performStrictReply("\002$arg\002 has said \037$type\037 \002$x\002 times (\002$pct1\002 %)$xtra"); -} - sub nullski { my ($arg) = @_; return unless (defined $arg); @@ -852,7 +744,7 @@ sub nullski { &addCmdHook('bzfquery', ('CODEREF' => 'BZFlag::query', 'Identifier' => 'BZFlag', 'Cmdstats' => 'BZFlag', 'Forker' => 1, 'Module' => 'BZFlag') ); &addCmdHook('chan(stats|info)', ('CODEREF' => 'chaninfo', ) ); &addCmdHook('cmd(stats|info)', ('CODEREF' => 'cmdstats', ) ); -&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'NewUnits', 'Help' => 'convert') ); +&addCmdHook('convert', ('CODEREF' => 'convert', 'Forker' => 1, 'Identifier' => 'Units', 'Help' => 'convert') ); &addCmdHook('(cookie|random)', ('CODEREF' => 'cookie', 'Forker' => 1, 'Identifier' => 'Factoids') ); &addCmdHook('countdown', ('CODEREF' => 'countdown', 'Module' => 'countdown', 'Identifier' => 'countdown', 'Cmdstats' => 'countdown') ); &addCmdHook('countrystats', ('CODEREF' => 'countryStats') ); @@ -871,6 +763,7 @@ sub nullski { &addCmdHook('factinfo', ('CODEREF' => 'factinfo', 'Cmdstats' => 'Factoid Info', Module => 'Factoids', ) ); &addCmdHook('factstats?', ('CODEREF' => 'factstats', 'Cmdstats' => 'Factoid Stats', Help => 'factstats', Forker => 1, 'Identifier' => 'Factoids', ) ); &addCmdHook('help', ('CODEREF' => 'help', 'Cmdstats' => 'Help', ) ); +&addCmdHook('hex2ip', ('CODEREF' => 'hex2ip::query', 'Forker' => 1, 'Identifier' => 'hex2ip', 'Cmdstats' => 'hex2ip', 'Help' => 'hex2ip') ); &addCmdHook('HTTPDtype', ('CODEREF' => 'HTTPDtype::HTTPDtype', 'Identifier' => 'HTTPDtype', 'Cmdstats' => 'HTTPDtype', 'Forker' => 1) ); &addCmdHook('[ia]?spell', ('CODEREF' => 'spell::query', 'Identifier' => 'spell', 'Cmdstats' => 'spell', 'Forker' => 1, 'Help' => 'spell') ); &addCmdHook('insult', ('CODEREF' => 'Insult::Insult', 'Forker' => 1, 'Identifier' => 'insult', 'Help' => 'insult' ) ); @@ -881,7 +774,7 @@ sub nullski { &addCmdHook('listauth', ('CODEREF' => 'CmdListAuth', 'Identifier' => 'Search', Module => 'Factoids', 'Help' => 'listauth') ); &addCmdHook('md5(sum)?', ('CODEREF' => 'md5::md5', 'Identifier' => 'md5', 'Cmdstats' => 'md5', 'Forker' => 1, 'Module' => 'md5') ); &addCmdHook('metar', ('CODEREF' => 'Weather::Metar', 'Identifier' => 'Weather', 'Help' => 'weather', 'Cmdstats' => 'Weather', 'Forker' => 1) ); -&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News' ) ); +&addCmdHook('News', ('CODEREF' => 'News::Parse', Module => 'News', 'Cmdstats' => 'News', 'Identifier' => 'News' ) ); &addCmdHook('(?:nick|lame)ometer(?: for)?', ('CODEREF' => 'nickometer::query', 'Identifier' => 'nickometer', 'Cmdstats' => 'nickometer', 'Forker' => 1) ); &addCmdHook('nullski', ('CODEREF' => 'nullski', ) ); &addCmdHook('page', ('CODEREF' => 'pager::page', 'Identifier' => 'pager', 'Cmdstats' => 'pager', 'Forker' => 1, 'Help' => 'page') ); @@ -892,6 +785,7 @@ sub nullski { &addCmdHook('RootWarn', ('CODEREF' => 'CmdrootWarn', 'Identifier' => 'RootWarn', 'Module' => 'RootWarn') ); &addCmdHook('OnJoin', ('CODEREF' => 'Cmdonjoin', 'Identifier' => 'OnJoin', 'Module' => 'OnJoin') ); &addCmdHook('Rss', ('CODEREF' => 'Rss::Rss', 'Identifier' => 'Rss', 'Cmdstats' => 'Rss', 'Forker' => 1, 'Help' => 'rss') ); +&addCmdHook('RSSFeeds',('CODEREF' => 'RSSFeeds::RSS', 'Identifier' => 'RSSFeeds', 'Forker' => 1, 'Help' => 'rssfeeds', 'Cmdstats' => 'RSSFeeds', 'Module' => 'RSSFeeds') ); &addCmdHook('sched(stats|info)', ('CODEREF' => 'scheduleList', ) ); &addCmdHook('scramble', ('CODEREF' => 'scramble::scramble', 'Identifier' => 'scramble', 'Cmdstats' => 'scramble', 'Forker' => 1, 'Module' => 'scramble') ); &addCmdHook('seen', ('CODEREF' => 'seen', 'Identifier' => 'seen') ); @@ -914,3 +808,5 @@ sub nullski { &status('loaded '.scalar(keys %cmdhooks).' command hooks.'); 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/DynaConfig.pl b/src/DynaConfig.pl index f4ba9c3..4bdcf99 100644 --- a/src/DynaConfig.pl +++ b/src/DynaConfig.pl @@ -20,7 +20,10 @@ use vars qw($utime_userfile $ucount_userfile $utime_chanfile $who ##### sub readUserFile { - my $f = "$bot_state_dir/blootbot.users"; + my $f = "$bot_state_dir/infobot.users"; + if (! -e $f and -e "$bot_state_dir/blootbot.users") { + $f = "$bot_state_dir/blootbot.users"; + } if (! -f $f) { &DEBUG("userfile not found; new fresh run detected."); @@ -64,7 +67,7 @@ sub readUserFile { if (/^--(\S+)[\s\t]+(.*)$/) { # user: middle entry. my ($what,$val) = ($1,$2); - if (!defined $val or $val eq "") { + if (!defined $val or $val eq '') { &WARN("$what: val == NULL."); next; } @@ -75,7 +78,7 @@ sub readUserFile { } # nice little hack. - if ($what eq "HOSTS") { + if ($what eq 'HOSTS') { $users{$nick}{$what}{$val} = 1; } else { $users{$nick}{$what} = $val; @@ -86,9 +89,9 @@ sub readUserFile { } elsif (/^::(\S+) ignore$/) { # ignore: start entry. $chan = $1; - $type = "ignore"; + $type = 'ignore'; - } elsif (/^- (\S+):\+(\d+):\+(\d+):(\S+):(.*)$/ and $type eq "ignore") { + } elsif (/^- (\S+):\+(\d+):\+(\d+):(\S+):(.*)$/ and $type eq 'ignore') { ### ignore: middle entry. my $mask = $1; my(@array) = ($2,$3,$4,$5); @@ -101,9 +104,9 @@ sub readUserFile { } elsif (/^::(\S+) bans$/) { # bans: start entry. $chan = $1; - $type = "bans"; + $type = 'bans'; - } elsif (/^- (\S+):\+(\d+):\+(\d+):(\d+):(\S+):(.*)$/ and $type eq "bans") { + } elsif (/^- (\S+):\+(\d+):\+(\d+):(\d+):(\S+):(.*)$/ and $type eq 'bans') { ### bans: middle entry. # $btime, $atime, $count, $whoby, $reason. my(@array) = ($2,$3,$4,$5,$6); @@ -129,14 +132,14 @@ sub writeUserFile { return; } - if (!open OUT,">$bot_state_dir/blootbot.users") { - &ERROR("Cannot write userfile ($bot_state_dir/blootbot.users): $!"); + if (!open OUT,">$bot_state_dir/infobot.users") { + &ERROR("Cannot write userfile ($bot_state_dir/infobot.users): $!"); return; } my $time = scalar(gmtime); - print OUT "#v1: blootbot -- $ident -- written $time\n\n"; + print OUT "#v1: infobot -- $ident -- written $time\n\n"; ### USER LIST. my $cusers = 0; @@ -155,7 +158,7 @@ sub writeUserFile { my $what = $_; my $val = $users{$user}{$_}; - if (ref($val) eq "HASH") { + if (ref($val) eq 'HASH') { foreach (sort keys %{ $users{$user}{$_} }) { print OUT "--$what\t\t$_\n"; } @@ -235,7 +238,10 @@ sub writeUserFile { ##### sub readChanFile { - my $f = "$bot_state_dir/blootbot.chan"; + my $f = "$bot_state_dir/infobot.chan"; + if (-e "$bot_state_dir/infobot.chan" and -e "$bot_state_dir/blootbot.chan") { + $f = "$bot_state_dir/blootbot.chan"; + } if ( -f $f and -f "$f~") { my $s1 = -s $f; my $s2 = -s "$f~"; @@ -304,13 +310,13 @@ sub writeChanFile { return; } - if (!open OUT,">$bot_state_dir/blootbot.chan") { - &ERROR("Cannot write chanfile ($bot_state_dir/blootbot.chan): $!"); + if (!open OUT,">$bot_state_dir/infobot.chan") { + &ERROR("Cannot write chanfile ($bot_state_dir/infobot.chan): $!"); return; } my $time = scalar(gmtime); - print OUT "#v1: blootbot -- $ident -- written $time\n\n"; + print OUT "#v1: infobot -- $ident -- written $time\n\n"; if ($flag_quit) { @@ -407,7 +413,7 @@ sub writeChanFile { # TODO: return all flags for opers sub IsFlag { my $flags = shift; - my ($ret, $f, $o) = ""; + my ($ret, $f, $o) = ''; &verifyUser($who, $nuh); @@ -432,7 +438,7 @@ sub verifyUser { return $userHandle; } - $userHandle = ""; + $userHandle = ''; foreach $user (keys %users) { next if ($user eq "_default"); @@ -453,7 +459,7 @@ sub verifyUser { last; } - last if ($userHandle ne ""); + last if ($userHandle ne ''); if ($user =~ /^\Q$nick\E$/i and !exists $cache{VUSERWARN}{$user}) { &status("vU: nick matched but host is not in list ($lnuh)."); @@ -472,10 +478,10 @@ sub verifyUser { sub ckpasswd { # returns true if arg1 encrypts to arg2 my ($plain, $encrypted) = @_; - if ($encrypted eq "") { + if ($encrypted eq '') { ($plain, $encrypted) = split(/\s+/, $plain, 2); } - return 0 unless ($plain ne "" and $encrypted ne ""); + return 0 unless ($plain ne '' and $encrypted ne ''); # MD5 // DES. Bobby Billingsley++. my $salt; @@ -508,8 +514,8 @@ sub hasFlag { sub ignoreAdd { my($mask,$chan,$expire,$comment) = @_; - $chan ||= "*"; # global if undefined. - $comment ||= ""; # optional. + $chan ||= '*'; # global if undefined. + $comment ||= ''; # optional. $expire ||= 0; # permament. my $count ||= 0; @@ -603,7 +609,7 @@ sub userDel { sub banAdd { my($mask,$chan,$expire,$reason) = @_; - $chan ||= "*"; + $chan ||= '*'; $expire ||= 0; if ($expire > 0) { @@ -615,7 +621,7 @@ sub banAdd { exists $bans{'*'}{$mask}); $bans{$chan}{$mask} = [$expire, time(), 0, $who, $reason]; - my @chans = ($chan eq "*") ? keys %channels : $chan; + my @chans = ($chan eq '*') ? keys %channels : $chan; my $m = $mask; $m =~ s/\?/\\./g; $m =~ s/\*/\\S*/g; @@ -722,7 +728,7 @@ sub chanSet { my $was = $chanconf{$chan}{$what}; if ($set) { # add/set. - if (defined $was and $was eq "1") { + if (defined $was and $was eq '1') { &performStrictReply("setting $what for $chan already 1."); return; } @@ -739,14 +745,16 @@ sub chanSet { } # alter for cosmetic (print out) reasons only. - $was = (defined $was) ? "; was '$was'" : ""; + $was = (defined $was) ? "; was '$was'" : ''; - if ($val eq "0") { + if ($val eq '0') { &performStrictReply("Unsetting $what for $chan$was."); delete $chanconf{$chan}{$what}; + delete $cache{ircTextCounters} if $what eq 'ircTextCounters'; } else { &performStrictReply("Setting $what for $chan to '$val'$was."); $chanconf{$chan}{$what} = $val; + delete $cache{ircTextCounters} if $what eq 'ircTextCounters'; } $update++; @@ -759,10 +767,11 @@ sub chanSet { &performStrictReply("setting $what for $chan already '$val'."); return; } - $was = ($was) ? "; was '$was'" : ""; + $was = ($was) ? "; was '$was'" : ''; &performStrictReply("Setting $what for $chan to '$val'$was."); $chanconf{$chan}{$what} = $val; + delete $cache{ircTextCounters} if $what eq 'ircTextCounters'; $update++; @@ -826,19 +835,22 @@ sub rehashConfVars { my @regFlagsUser = ( # possible chars to include in FLAG - "A", # bot administration over /msg + 'A', # bot administration over /msg # default is only via DCC CHAT - "O", # dynamic ops (as on channel). (automatic +o) - "T", # add topics. - "a", # ask/request factoid. - "m", # modify factoid. (includes renaming) - "n", # bot owner, can "reload" - "o", # master of bot (automatic +amrt) + 'O', # dynamic ops (as on channel). (automatic +o) + 'T', # add topics. + 'a', # ask/request factoid. + 'm', # modify factoid. (includes renaming) + 'n', # bot owner, can 'reload' + 'o', # master of bot (automatic +amrt) # can search on factoid strings shorter than 2 chars # can tell bot to join new channels # can [un]lock factoids - "r", # remove factoid. - "t", # teach/add factoid. + 'r', # remove factoid. + 't', # teach/add factoid. + 's', # Bypass +silent on channels ); 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Core.pl b/src/Factoids/Core.pl index e33685c..4898008 100644 --- a/src/Factoids/Core.pl +++ b/src/Factoids/Core.pl @@ -18,7 +18,7 @@ sub validFactoid { for (lc $lhs) { # allow the following only if they have been made on purpose. - if ($rhs ne "" and $rhs !~ /^ are" if ($mhs eq "are"); - &setFactInfo($lhs, "factoid_value", $rhs); + # 'are' hack :) + $rhs = " are" if ($mhs eq 'are'); + &setFactInfo($lhs, 'factoid_value', $rhs); } return 'INFOBOT REPLY'; @@ -140,8 +140,8 @@ sub FactoidStuff { return 'forget: no addr' unless ($addressed); my $faqtoid = $message; - if ($faqtoid eq "") { - &help("forget"); + if ($faqtoid eq '') { + &help('forget'); return; } @@ -155,22 +155,22 @@ sub FactoidStuff { } # TODO: squeeze 3 getFactInfo calls into one? - my $author = &getFactInfo($faqtoid, "created_by"); - my $count = &getFactInfo($faqtoid, "requested_count") || 0; + my $author = &getFactInfo($faqtoid, 'created_by'); + my $count = &getFactInfo($faqtoid, 'requested_count') || 0; # don't delete if requested $limit times my $limit = &getChanConfDefault('factoidPreventForgetLimit', 100, $chan); # don't delete if older than $limitage seconds (modified by requests below) my $limitage = &getChanConfDefault('factoidPreventForgetLimitTime', 7 * 24 * 60 * 60, $chan); - my $t = &getFactInfo($faqtoid, "created_time") || 0; + my $t = &getFactInfo($faqtoid, 'created_time') || 0; my $age = time() - $t; # lets scale limitage from 1 (nearly 0) to $limit (full time). $limitage = $limitage*($count+1)/$limit if ($count < $limit); # isauthor and isop. my $isau = (defined $author and &IsHostMatch($author) == 2) ? 1 : 0; - my $isop = (&IsFlag("o") eq "o") ? 1 : 0; + my $isop = (&IsFlag('o') eq 'o') ? 1 : 0; - if (IsFlag("r") ne "r" && !$isop) { + if (IsFlag('r') ne 'r' && !$isop) { &msg($who, "you don't have access to remove factoids"); return; } @@ -198,16 +198,16 @@ sub FactoidStuff { # prevent deletion if other factoids redirect to it. # TODO: use hash instead of array. my @list; - if (&getChanConf("factoidPreventForgetRedirect")) { + if (&getChanConf('factoidPreventForgetRedirect')) { &status("Factoids/Core: forget: checking for redirect factoids"); - @list = &searchTable("factoids", "factoid_key", - "factoid_value", "^ see "); + @list = &searchTable('factoids', 'factoid_key', + 'factoid_value', "^ 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 =~ /^ ?see( also)? $fsafe\.?$/i); @@ -234,21 +234,21 @@ sub FactoidStuff { # TODO: make forget limit configurable. # TODO: make forget ignore time configurable. if ($cache{forget}{$h} > 5) { - &ignoreAdd(&makeHostMask($nuh), "*", 3*24*60, "abuse of forget"); + &ignoreAdd(&makeHostMask($nuh), '*', 3*24*60, "abuse of forget"); &msg($who, "forget: Ignoring you for abuse!"); } } # lets do it! - if (&IsParam("factoidDeleteDelay") or &IsChanConf("factoidDeleteDelay") > 0) { + if (&IsParam('factoidDeleteDelay') or &IsChanConf('factoidDeleteDelay') > 0) { if (!($isop or $isau) and $faqtoid =~ / #DEL#$/) { &msg($who, "cannot delete it ($faqtoid)."); return; } &status("forgot (safe delete): '$faqtoid' - ". scalar(gmtime)); - ### TODO: check if the "backup" exists and overwrite it + ### TODO: check if the 'backup' exists and overwrite it my $check = &getFactoid("$faqtoid #DEL#"); if (!defined $check or $check =~ /^\s*$/) { @@ -260,9 +260,9 @@ sub FactoidStuff { &DEBUG("forget: not overwriting backup: $faqtoid"); } else { &status("forget: backing up '$faqtoid'"); - &setFactInfo($faqtoid, "factoid_key", $new); - &setFactInfo($new, "modified_by", $who); - &setFactInfo($new, "modified_time", time()); + &setFactInfo($faqtoid, 'factoid_key', $new); + &setFactInfo($new, 'modified_by', $who); + &setFactInfo($new, 'modified_time', time()); } } else { @@ -289,16 +289,16 @@ sub FactoidStuff { return 'unforget: no addr' unless ($addressed); my $i = 0; - $i++ if (&IsParam("factoidDeleteDelay")); - $i++ if (&IsChanConf("factoidDeleteDelay") > 0); + $i++ if (&IsParam('factoidDeleteDelay')); + $i++ if (&IsChanConf('factoidDeleteDelay') > 0); if (!$i) { &performReply("safe delete has been disable so what is there to undelete?"); return; } my $faqtoid = $message; - if ($faqtoid eq "") { - &help("unforget"); + if ($faqtoid eq '') { + &help('unforget'); return; } @@ -316,9 +316,9 @@ sub FactoidStuff { return; } - &setFactInfo($faqtoid." #DEL#", "factoid_key", $faqtoid); -# &setFactInfo($faqtoid, "modified_by", ""); -# &setFactInfo($faqtoid, "modified_time", 0); + &setFactInfo($faqtoid." #DEL#", 'factoid_key', $faqtoid); +# &setFactInfo($faqtoid, 'modified_by', ''); +# &setFactInfo($faqtoid, 'modified_time', 0); $check = &getFactoid($faqtoid); # TODO: check if $faqtoid." #DEL#" exists? @@ -339,19 +339,19 @@ sub FactoidStuff { my $function = lc $1; my $faqtoid = lc $4; - if ($faqtoid eq "") { + if ($faqtoid eq '') { &help($function); return; } - if (&getFactoid($faqtoid) eq "") { + if (&getFactoid($faqtoid) eq '') { &msg($who, "factoid \002$faqtoid\002 does not exist"); return; } - if ($function eq "lock") { + if ($function eq 'lock') { # strongly requested by #debian on 19991028. -xk - if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag("o") ne "o") { + if (1 and $faqtoid !~ /^\Q$who\E$/i and &IsFlag('o') ne 'o') { &msg($who,"sorry, locking cannot be used since it can be abused unneccesarily."); &status("Replace 1 with 0 in Process.pl#~324 for locking support."); return; @@ -369,8 +369,8 @@ sub FactoidStuff { if ($message =~ s/^rename(\s+|$)//) { return 'rename: no addr' unless ($addressed); - if ($message eq "") { - &help("rename"); + if ($message eq '') { + &help('rename'); return; } @@ -384,7 +384,7 @@ sub FactoidStuff { } # who == nick!user@host. - if (&IsFlag("m") ne "m" and $author !~ /^\Q$who\E\!/i) { + if (&IsFlag('m') ne 'm' and $author !~ /^\Q$who\E\!/i) { &msg($who, "factoid '$from' is not yours to modify."); return; } @@ -394,7 +394,7 @@ sub FactoidStuff { return; } - &setFactInfo($from,"factoid_key",$to); + &setFactInfo($from,'factoid_key',$to); &status("rename: <$who> '$from' is now '$to'"); &performReply("i renamed '$from' to '$to'"); @@ -421,7 +421,7 @@ sub FactoidStuff { return 'subst: locked' if (&IsLocked($faqtoid) == 1); my $was = $result; - if (($flags eq "g" && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) { + if (($flags eq 'g' && $result =~ s/\Q$op/$np/gi) || $result =~ s/\Q$op/$np/i) { # excessive length. if (length $result > $param{'maxDataSize'}) { &performReply("that's too long"); @@ -433,17 +433,17 @@ sub FactoidStuff { return; } # min length. - my $faqauth = &getFactInfo($faqtoid, "created_by"); + my $faqauth = &getFactInfo($faqtoid, 'created_by'); if ((length $result)*2 < length $was and - &IsFlag("o") ne "o" and + &IsFlag('o') ne 'o' and &IsHostMatch($faqauth) != 2 ) { &performReply("too drastic change of factoid."); } - &setFactInfo($faqtoid, "factoid_value", $result); + &setFactInfo($faqtoid, 'factoid_value', $result); &status("update: '$faqtoid' =is=> '$result'; was '$was'"); - &performReply("OK"); + &performReply('OK'); } else { &performReply("that doesn't contain '$op'"); } @@ -460,7 +460,7 @@ sub FactoidStuff { # fix the string. s/^hey([, ]+)where/where/i; s/\s+\?$/?/; - s/whois/who is/ig; + s/^whois /who is /i; # Must match ^, else factoids with "whois" anywhere break s/where can i find/where is/i; s/how about/where is/i; s/ da / the /ig; @@ -501,7 +501,7 @@ sub FactoidStuff { &loadMyModule('Math'); my $newresult = &perlMath(); - if (defined $newresult and $newresult ne "") { + if (defined $newresult and $newresult ne '') { $cmdstats{'Maths'}++; $result = $newresult; &status("math: <$who> $message => $result"); @@ -540,3 +540,5 @@ sub FactoidStuff { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/DBCommon.pl b/src/Factoids/DBCommon.pl index 1d869ab..ab37eeb 100644 --- a/src/Factoids/DBCommon.pl +++ b/src/Factoids/DBCommon.pl @@ -10,7 +10,7 @@ ##### # Usage: &setFactInfo($faqtoid, $key, $val); sub setFactInfo { - &sqlSet("factoids", + &sqlSet('factoids', { factoid_key => $_[0] }, { $_[1] => $_[2] } ); @@ -19,13 +19,13 @@ sub setFactInfo { ##### # Usage: &getFactInfo($faqtoid, [$what]); sub getFactInfo { - return &sqlSelect("factoids", $_[1], { factoid_key => $_[0] } ); + return &sqlSelect('factoids', $_[1], { factoid_key => $_[0] } ); } ##### # Usage: &getFactoid($faqtoid); sub getFactoid { - return &getFactInfo($_[0], "factoid_value"); + return &getFactInfo($_[0], 'factoid_value'); } ##### @@ -33,7 +33,7 @@ sub getFactoid { sub delFactoid { my ($faqtoid) = @_; - &sqlDelete("factoids", { factoid_key => $faqtoid } ); + &sqlDelete('factoids', { factoid_key => $faqtoid } ); &status("DELETED $faqtoid"); return 1; @@ -43,10 +43,10 @@ sub delFactoid { # Usage: &IsLocked($faqtoid); sub IsLocked { my ($faqtoid) = @_; - my $thisnuh = &getFactInfo($faqtoid, "locked_by"); + my $thisnuh = &getFactInfo($faqtoid, 'locked_by'); - if (defined $thisnuh and $thisnuh ne "") { - if (!&IsHostMatch($thisnuh) and &IsFlag("o") ne "o") { + if (defined $thisnuh and $thisnuh ne '') { + if (!&IsHostMatch($thisnuh) and &IsFlag('o') ne 'o') { &performReply("cannot alter locked factoids"); return 1; } @@ -59,7 +59,7 @@ sub IsLocked { # Usage: &AddModified($faqtoid,$nuh); sub AddModified { my ($faqtoid,$nuh) = @_; - my $modified_by = &getFactInfo($faqtoid, "modified_by"); + my $modified_by = &getFactInfo($faqtoid, 'modified_by'); my (@modifiedlist, @modified, %modified); if (defined $modified_by) { @@ -83,8 +83,8 @@ sub AddModified { } shift(@modifiedlist) while (scalar @modifiedlist > 3); - &setFactInfo($faqtoid, "modified_by", join(",",@modifiedlist)); - &setFactInfo($faqtoid, "modified_time", time()); + &setFactInfo($faqtoid, 'modified_by', join(",",@modifiedlist)); + &setFactInfo($faqtoid, 'modified_time', time()); return 1; } @@ -98,28 +98,28 @@ sub AddModified { sub CmdLock { my ($faqtoid) = @_; - my $thisnuh = &getFactInfo($faqtoid,"locked_by"); + my $thisnuh = &getFactInfo($faqtoid,'locked_by'); - if (defined $thisnuh and $thisnuh ne "") { + if (defined $thisnuh and $thisnuh ne '') { my $locked_by = (split(/\!/,$thisnuh))[0]; &msg($who,"factoid \002$faqtoid\002 has already been locked by $locked_by."); return 0; } - $thisnuh ||= &getFactInfo($faqtoid,"created_by"); + $thisnuh ||= &getFactInfo($faqtoid,'created_by'); # fixes bug found on 19991103. # code needs to be reorganised though. - if ($thisnuh ne "") { - if (!&IsHostMatch($thisnuh) && IsFlag("o") ne "o") { + if ($thisnuh ne '') { + if (!&IsHostMatch($thisnuh) && IsFlag('o') ne 'o') { &msg($who, "sorry, you are not allowed to lock '$faqtoid'."); return 0; } } &performReply("locking factoid \002$faqtoid\002"); - &setFactInfo($faqtoid,"locked_by",$nuh); - &setFactInfo($faqtoid,"locked_time", time()); + &setFactInfo($faqtoid,'locked_by',$nuh); + &setFactInfo($faqtoid,'locked_time', time()); return 1; } @@ -129,23 +129,25 @@ sub CmdLock { sub CmdUnLock { my ($faqtoid) = @_; - my $thisnuh = &getFactInfo($faqtoid,"locked_by"); + my $thisnuh = &getFactInfo($faqtoid,'locked_by'); if (!defined $thisnuh) { &msg($who, "factoid \002$faqtoid\002 is not locked."); return 0; } - if ($thisnuh ne "" and !&IsHostMatch($thisnuh) and &IsFlag("o") ne "o") { + if ($thisnuh ne '' and !&IsHostMatch($thisnuh) and &IsFlag('o') ne 'o') { &msg($who, "sorry, you are not allowed to unlock factoid '$faqtoid'."); return 0; } &performReply("unlocking factoid \002$faqtoid\002"); - &setFactInfo($faqtoid,"locked_by", ""); - &setFactInfo($faqtoid,"locked_time", ""); + &setFactInfo($faqtoid,'locked_by', ''); + &setFactInfo($faqtoid,'locked_time', '0'); # pgsql complains if NOT NULL set. So set 0 which is the default return 1; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Norm.pl b/src/Factoids/Norm.pl index 0d853a9..ba97e7d 100644 --- a/src/Factoids/Norm.pl +++ b/src/Factoids/Norm.pl @@ -86,7 +86,7 @@ sub switchPerson { s/(^|\W)you\'?re(\W|$)/$1you are$2/ig; if ($addressed) { - my $mynick = "UNDEF"; + my $mynick = 'UNDEF'; $mynick = $conn->nick() if ($conn); # is it safe to remove $in from here, too? $in =~ s/yourself/$mynick/i; @@ -101,3 +101,5 @@ sub switchPerson { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Question.pl b/src/Factoids/Question.pl index 2c2506f..7a99e6b 100644 --- a/src/Factoids/Question.pl +++ b/src/Factoids/Question.pl @@ -20,7 +20,7 @@ sub doQuestion { # my doesn't allow variables to be inherinted, local does. # following is used in math()... local($query) = @_; - local($reply) = ""; + local($reply) = ''; local $finalQMark = $query =~ s/\?+\s*$//; $finalQMark += $query =~ s/\?\s*$//; $query =~ s/^\s+|\s+$//g; @@ -29,12 +29,11 @@ sub doQuestion { return ''; } - my $questionWord = ""; + my $questionWord = ''; if (!$addressed) { - return ''; #never respond if we're not addressed return '' unless ($finalQMark); - return '' unless &IsChanConf("minVolunteerLength") > 0; + return '' unless &IsChanConf('minVolunteerLength') > 0; return '' if (length $query < &::getChanConf('minVolunteerLength')); } else { ### TODO: this should be caught in Process.pl? @@ -42,7 +41,7 @@ sub doQuestion { # there is no flag to disable/enable asking factoids... # so it was added... thanks zyxep! :) - if (&IsFlag("a") ne "a" && &IsFlag("o") ne "o") { + if (&IsFlag('a') ne 'a' && &IsFlag('o') ne 'o') { &status("$who tried to ask us when not allowed."); return; } @@ -88,13 +87,13 @@ sub doQuestion { $questionWord = lc($1); } - if ($questionWord eq "" and $finalQMark and $addressed) { - $questionWord = "where"; + if ($questionWord eq '' and $finalQMark and $addressed) { + $questionWord = 'where'; } $query =~ s/^\s+|\s+$//g; # bleh. hacked. push(@query, $query) if ($query ne $x); - if (&IsChanConf("factoidArguments") > 0) { + if (&IsChanConf('factoidArguments') > 0) { $result = &factoidArgs($query[0]); return $result if (defined $result); @@ -104,7 +103,7 @@ sub doQuestion { for (my$i=0; $i ".join(' :: ', @query)) if ($finalQMark); - return '' unless (&IsParam("friendlyBots")); + return '' unless (&IsParam('friendlyBots')); foreach (split /\s+/, $param{'friendlyBots'}) { &msg($_, ":INFOBOT:QUERY <$who> $query"); @@ -190,9 +189,9 @@ sub factoidArgs { # my $t = &timeget(); my ($first) = split(/\s+/, $str); - # ignore split to commands [dumb commands vs. factoids] + # ignore split to commands [dumb commands vs. factoids] (editing commands?) return undef if $str =~ /\s+\=\~\s+s[\#\/\:]/; - my @list = &searchTable("factoids", "factoid_key", "factoid_key", "^CMD: $first "); + my @list = &searchTable('factoids', 'factoid_key', 'factoid_key', "^cmd: $first "); # my $delta_time = &timedelta($t); # &DEBUG("factArgs: delta_time = $delta_time s"); # &DEBUG("factArgs: list => ".scalar(@list) ); @@ -239,9 +238,9 @@ sub factoidArgs { } # update stats. old mysql/sqlite don't do +1 - my ($count) = &sqlSelect("factoids", "requested_count", { factoid_key => $q }); + my ($count) = &sqlSelect('factoids', 'requested_count', { factoid_key => $q }); $count++; - &sqlSet("factoids", {'factoid_key' => $q}, { + &sqlSet('factoids', {'factoid_key' => $q}, { requested_by => $nuh, requested_time => time(), requested_count => $count @@ -288,8 +287,8 @@ sub factoidArgs { $i++; } - # nasty hack to get partial &getReply() functionality. - $result = &SARit($result); + $result = &SARit($result); + # rest of nasty hack to get partial &getReply() functionality. $result =~ s/^\s*\s*(.*)/\cAACTION $1\cA/i; $result =~ s/^\s*\s*//i; @@ -303,3 +302,5 @@ sub factoidArgs { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Reply.pl b/src/Factoids/Reply.pl index 0278f32..ec3649b 100644 --- a/src/Factoids/Reply.pl +++ b/src/Factoids/Reply.pl @@ -46,7 +46,7 @@ sub getReply { } else { $factoid = "$search $message"; } - ($count, $fauthor, $result) = &sqlSelect("factoids", + ($count, $fauthor, $result) = &sqlSelect('factoids', "requested_count,created_by,factoid_value", { factoid_key => $factoid } ); @@ -55,7 +55,7 @@ sub getReply { if ($result) { $lhs = $message; - $mhs = "is"; + $mhs = 'is'; $rhs = $result; return "\"$factoid\" $mhs \"$rhs\"" if ($literal); @@ -76,7 +76,7 @@ sub getReply { $result = &SARit($result); $reply = $result; - if ($result ne "") { + if ($result ne '') { ### AT LAST, REPEAT PREVENTION CODE REMOVED IN FAVOUR OF GLOBAL ### FLOOD REPETION AND PROTECTION. -20000124 @@ -84,7 +84,7 @@ sub getReply { ### FIXME: old mysql/sqlite doesn't support ### "requested_count=requested_count+1". $count++; - &sqlSet("factoids", {'factoid_key' => $factoid}, { + &sqlSet('factoids', {'factoid_key' => $factoid}, { requested_by => $nuh, requested_time => time(), requested_count => $count @@ -92,9 +92,9 @@ sub getReply { # TODO: rename $real to something else! my $real = 0; -# my $author = &getFactInfo($lhs,"created_by") || ''; +# my $author = &getFactInfo($lhs,'created_by') || ''; # $real++ if ($author =~ /^\Q$who\E\!/); -# $real++ if (&IsFlag("n")); +# $real++ if (&IsFlag('n')); $real = 0 if ($msgType =~ /public/); ### fix up the reply. @@ -117,7 +117,7 @@ sub getReply { ### bot->person reply. # result is random if separated by '||'. # rhs is full factoid with '||'. - if ($mhs eq "is") { + if ($mhs eq 'is') { $reply = &getRandom(keys %{ $lang{'factoid'} }); $reply =~ s/##KEY/$lhs/; $reply =~ s/##VALUE/$result/; @@ -125,7 +125,13 @@ sub getReply { $reply = "$lhs $mhs $result"; } - $reply =~ s/^\Q$who\E is/you are/i; + if ($reply =~ s/^\Q$who\E is/you are/i) { + # fix the person. + } else { + if ($reply =~ /^you are / or $reply =~ / you are /) { + return if ($addressed); + } + } } } @@ -331,25 +337,25 @@ sub substVars { } if ($reply =~ /\$factoids/) { - my $factoids = &countKeys("factoids"); + my $factoids = &countKeys('factoids'); $reply =~ s/\$factoids/$factoids/; } if ($reply =~ /\$Fupdate/) { my $x = "\002$count{'Update'}\002 ". - &fixPlural("modification", $count{'Update'}); + &fixPlural('modification', $count{'Update'}); $reply =~ s/\$Fupdate/$x/; } if ($reply =~ /\$Fquestion/) { my $x = "\002$count{'Question'}\002 ". - &fixPlural("question", $count{'Question'}); + &fixPlural('question', $count{'Question'}); $reply =~ s/\$Fquestion/$x/; } if ($reply =~ /\$Fdunno/) { my $x = "\002$count{'Dunno'}\002 ". - &fixPlural("dunno", $count{'Dunno'}); + &fixPlural('dunno', $count{'Dunno'}); $reply =~ s/\$Fdunno/$x/; } @@ -359,3 +365,5 @@ sub substVars { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Statement.pl b/src/Factoids/Statement.pl index 6617dd6..0df4918 100644 --- a/src/Factoids/Statement.pl +++ b/src/Factoids/Statement.pl @@ -24,13 +24,13 @@ sub doStatement { # check if we need to be addressed and if we are return unless ($learnok); - my($urlType) = ""; + my($urlType) = ''; # prefix www with http:// and ftp with ftp:// $in =~ s/ www\./ http:\/\/www\./ig; $in =~ s/ ftp\./ ftp:\/\/ftp\./ig; - $urlType = "about" if ($in =~ /\babout:/i); + $urlType = 'about' if ($in =~ /\babout:/i); $urlType = 'afp' if ($in =~ /\bafp:/); $urlType = 'file' if ($in =~ /\bfile:/); $urlType = 'palace' if ($in =~ /\bpalace:/); @@ -40,12 +40,12 @@ sub doStatement { } # acceptUrl. - if (&IsParam("acceptUrl")) { + if (&IsParam('acceptUrl')) { if ($param{'acceptUrl'} eq 'REQUIRE') { # require url type. - return if ($urlType eq ""); + return if ($urlType eq ''); } elsif ($param{'acceptUrl'} eq 'REJECT') { - &status("REJECTED URL entry") if (&IsParam("VERBOSITY")); - return unless ($urlType eq ""); + &status("REJECTED URL entry") if (&IsParam('VERBOSITY')); + return unless ($urlType eq ''); } else { # OPTIONAL } @@ -56,7 +56,7 @@ sub doStatement { my($lhs, $mhs, $rhs) = ($`, $&, $'); # allows factoid arguments to be updated. -lear. - $lhs =~ s/^(cmd: )?(.*)/$1||"" . lc $2/e; + $lhs =~ s/^(cmd: )?(.*)/$1||'' . lc $2/e; # discard article. $lhs =~ s/^(the|da|an?)\s+//i; @@ -67,7 +67,7 @@ sub doStatement { $rhs =~ s/^\s+|\s+$//g; # break if either lhs or rhs is NULL. - if ($lhs eq "" or $rhs eq "") { + if ($lhs eq '' or $rhs eq '') { return "NOT-A-STATEMENT"; } @@ -86,7 +86,7 @@ sub doStatement { &status("statement: <$who> $message"); - # change "#*#" back to "*" because of '\' sar to '#blah#'. + # change "#*#" back to '*' because of '\' sar to '#blah#'. $lhs =~ s/\#(\S+)\#/$1/g; $rhs =~ s/\#(\S+)\#/$1/g; @@ -108,7 +108,9 @@ sub doStatement { return if (&update($lhs, $mhs, $rhs)); } - return "CONTINUE"; + return 'CONTINUE'; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Factoids/Update.pl b/src/Factoids/Update.pl index 475e0d9..9ee8e22 100644 --- a/src/Factoids/Update.pl +++ b/src/Factoids/Update.pl @@ -21,13 +21,13 @@ sub update { return if (&IsLocked($lhs) == 1); # profanity. - if (&IsParam("profanityCheck") and &hasProfanity($rhs)) { + if (&IsParam('profanityCheck') and &hasProfanity($rhs)) { &performReply("please, watch your language."); return 1; } # teaching. - if (&IsFlag("t") ne "t" && &IsFlag("o") ne "o") { + if (&IsFlag('t') ne 't' && &IsFlag('o') ne 'o') { &msg($who, "permission denied."); &status("alert: $who wanted to teach me."); return 1; @@ -54,7 +54,7 @@ sub update { # factoid arguments handler. # must start with a non-variable - if (&IsChanConf("factoidArguments") > 0 and $lhs =~ /^[^\$]+.*\$/) { + if (&IsChanConf('factoidArguments') > 0 and $lhs =~ /^[^\$]+.*\$/) { &status("Update: Factoid Arguments found."); &status("Update: orig lhs => '$lhs'."); &status("Update: orig rhs => '$rhs'."); @@ -87,23 +87,23 @@ sub update { # nice 'are' hack (or work-around). if ($mhs =~ /^are$/i and $rhs !~ /<\S+>/) { &status("Update: 'are' hack detected."); - $mhs = "is"; + $mhs = 'is'; $rhs = " are ". $rhs; } &status("enter: <$who> \'$lhs\' =$mhs=> \'$rhs\'"); $count{'Update'}++; - &performAddressedReply("okay"); + &performAddressedReply('okay'); - &sqlReplace("factoids", { + &sqlInsert('factoids', { created_by => $nuh, created_time => time(), # modified time. factoid_key => $lhs, factoid_value => $rhs, } ); - if (!defined $rhs or $rhs eq "") { + if (!defined $rhs or $rhs eq '') { &ERROR("Update: rhs1 == NULL."); } @@ -190,21 +190,20 @@ sub update { } } - &performAddressedReply("okay"); + &performAddressedReply('okay'); $count{'Update'}++; &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'"); - &sqlReplace("factoids", { - factoid_key => $lhs, + &sqlSet('factoids', {'factoid_key' => $lhs}, { modified_by => $nuh, modified_time => time(), factoid_value => $rhs, } ); - if (!defined $rhs or $rhs eq "") { + if (!defined $rhs or $rhs eq '') { &ERROR("Update: rhs1 == NULL."); } - } else { # not "also" + } else { # not 'also' if (!$correction_plausible) { # "no, blah is ..." if ($addressed) { @@ -214,28 +213,27 @@ sub update { return 1; } - my $author = &getFactInfo($lhs, "created_by") || ""; + my $author = &getFactInfo($lhs, 'created_by') || ''; - if (IsFlag("m") ne "m" && IsFlag("o") ne "o" && + if (IsFlag('m') ne 'm' && IsFlag('o') ne 'o' && $author !~ /^\Q$who\E\!/i ) { &msg($who, "you can't change that factoid."); return 1; } - &performAddressedReply("okay"); + &performAddressedReply('okay'); $count{'Update'}++; &status("update: <$who> \'$lhs\' =$mhs=> \'$rhs\'; was \'$exists\'"); - &sqlReplace("factoids", { - factoid_key => $lhs, + &sqlSet('factoids', {'factoid_key' => $lhs}, { modified_by => $nuh, modified_time => time(), factoid_value => $rhs, } ); - if (!defined $rhs or $rhs eq "") { + if (!defined $rhs or $rhs eq '') { &ERROR("Update: rhs1 == NULL."); } } @@ -244,3 +242,5 @@ sub update { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Files.pl b/src/Files.pl index ffd8dea..91610b6 100644 --- a/src/Files.pl +++ b/src/Files.pl @@ -26,7 +26,7 @@ sub loadLang { while () { chop; - if ($_ eq "" || /^#/) { + if ($_ eq '' || /^#/) { undef $replyName; next; } @@ -53,7 +53,7 @@ sub loadLang { # File: Irc Servers list. sub loadIRCServers { - my ($file) = $bot_config_dir."/blootbot.servers"; + my ($file) = $bot_config_dir."/infobot.servers"; @ircServers = (); %ircPort = (); @@ -81,3 +81,5 @@ sub loadIRCServers { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/IRC/Irc.pl b/src/IRC/Irc.pl index 4ce64f6..c89c0db 100644 --- a/src/IRC/Irc.pl +++ b/src/IRC/Irc.pl @@ -26,6 +26,9 @@ $nickserv = 0; # It's probably closer to 510, but let's be cautious until we calculate it extensively. my $maxlinelen = 490; +# Keep track of last time we displayed Chans: to avoid spam in logs +my $lastChansTime = 0; + sub ircloop { my $error = 0; my $lastrun = 0; @@ -178,7 +181,7 @@ sub irc { # works? needs to actually do something # should likely listen on a tcp port instead - #$irc->addfh(STDIN, \&on_stdin, "r"); + #$irc->addfh(STDIN, \&on_stdin, 'r'); &status("starting main loop"); @@ -193,7 +196,7 @@ sub rawout { my ($buf) = @_; $buf =~ s/\n//gi; - # slow down a bit if traffic is "high". + # slow down a bit if traffic is 'high'. # need to take into account time of last message sent. if ($last{buflen} > 256 and length($buf) > 256) { sleep 1; @@ -208,11 +211,17 @@ sub say { my ($msg) = @_; my $mynick = $conn->nick(); if (!defined $msg) { - $msg ||= "NULL"; + $msg ||= 'NULL'; &WARN("say: msg == $msg."); return; } + if (&getChanConf('silent', $talkchannel) and not + (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) { + &DEBUG("say: silent in $talkchannel, not saying $msg"); + return; + } + if ( $postprocess ) { undef $postprocess; } elsif ($postprocess = &getChanConf('postprocess', $talkchannel)) { @@ -226,7 +235,7 @@ sub say { return unless (&whatInterface() =~ /IRC/); - $msg = "zero" if ($msg =~ /^0+$/); + $msg = 'zero' if ($msg =~ /^0+$/); my $t = time(); @@ -234,8 +243,8 @@ sub say { $pubcount++; $pubsize += length $msg; - my $i = &getChanConfDefault("sendPublicLimitLines", 3, $chan); - my $j = &getChanConfDefault("sendPublicLimitBytes", 1000, $chan); + my $i = &getChanConfDefault('sendPublicLimitLines', 3, $chan); + my $j = &getChanConfDefault('sendPublicLimitBytes', 1000, $chan); if ( ($pubcount % $i) == 0 and $pubcount) { sleep 1; @@ -261,11 +270,18 @@ sub msg { } if (!defined $msg) { - $msg ||= "NULL"; + $msg ||= 'NULL'; &WARN("msg: msg == $msg."); return; } + # some say() end up here (eg +help) + if (&getChanConf('silent', $nick) and not + (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) { + &DEBUG("msg: silent in $nick, not saying $msg"); + return; + } + &status(">$nick< $msg"); return unless (&whatInterface() =~ /IRC/); @@ -275,8 +291,8 @@ sub msg { $msgcount++; $msgsize += length $msg; - my $i = &getChanConfDefault("sendPrivateLimitLines", 3, $chan); - my $j = &getChanConfDefault("sendPrivateLimitBytes", 1000, $chan); + my $i = &getChanConfDefault('sendPrivateLimitLines', 3, $chan); + my $j = &getChanConfDefault('sendPrivateLimitBytes', 1000, $chan); if ( ($msgcount % $i) == 0 and $msgcount) { sleep 1; } elsif ($msgsize > $j) { @@ -302,6 +318,12 @@ sub action { return; } + if (&getChanConf('silent', $target) and not + (&IsFlag("s") and &verifyUser($who,$nuh{lc $who}))) { + &DEBUG("action: silent in $target, not doing $txt"); + return; + } + if (length $txt > 480) { &status("action: txt too long; truncating."); chop($txt) while (length $txt > 480); @@ -327,8 +349,8 @@ sub notice { $notcount++; $notsize += length $txt; - my $i = &getChanConfDefault("sendNoticeLimitLines", 3, $chan); - my $j = &getChanConfDefault("sendNoticeLimitBytes", 1000, $chan); + my $i = &getChanConfDefault('sendNoticeLimitLines', 3, $chan); + my $j = &getChanConfDefault('sendNoticeLimitBytes', 1000, $chan); if ( ($notcount % $i) == 0 and $notcount) { sleep 1; @@ -464,8 +486,8 @@ sub dcc_close { sub joinchan { my ($chan, $key) = @_; - $key ||= &getChanConf("chankey", $chan); - $key ||= ""; + $key ||= &getChanConf('chankey', $chan); + $key ||= ''; # forgot for about 2 years to implement channel keys when moving # over to Net::IRC... @@ -490,7 +512,7 @@ sub part { my $chan; foreach $chan (@_) { - next if ($chan eq ""); + next if ($chan eq ''); $chan =~ tr/A-Z/a-z/; # lowercase. if ($chan !~ /^$mask{chan}$/) { @@ -526,24 +548,24 @@ sub mode { sub op { my ($chan, @who) = @_; - my $os = "o" x scalar(@who); + my $os = 'o' x scalar(@who); &mode($chan, "+$os @who"); } sub deop { my ($chan, @who) = @_; - my $os = "o" x scalar(@who); + my $os = 'o' x scalar(@who); &mode($chan, "-$os ".@who); } sub kick { my ($nick,$chan,$msg) = @_; - my (@chans) = ($chan eq "") ? (keys %channels) : lc($chan); + my (@chans) = ($chan eq '') ? (keys %channels) : lc($chan); my $mynick = $conn->nick(); - if ($chan ne "" and &validChan($chan) == 0) { + if ($chan ne '' and &validChan($chan) == 0) { &ERROR("kick: invalid channel $chan."); return; } @@ -700,7 +722,7 @@ sub joinNextChan { } # chanserv check: global channels, in case we missed one. - foreach ( &ChanConfList("chanServ_ops") ) { + foreach ( &ChanConfList('chanServ_ops') ) { &chanServCheck($_); } } @@ -820,26 +842,35 @@ sub clearIRCVars { } sub getJoinChans { - my($show) = @_; + # $show should contain the min number of seconds between display + # of the Chans: status line. Use 0 to disable + my $show = shift; my @in; my @skip; my @join; + # Display "Chans:" only if more than $show seconds since last display + if (time() - $lastChansTime > $show) { + $lastChansTime = time(); + } else { + $show = 0; # Don't display since < 15min since last + } + # can't join any if not connected return @join if (!$conn); my $nick = $conn->nick(); foreach (keys %chanconf) { - next if ($_ eq "_default"); + next if ($_ eq '_default'); my $skip = 0; my $val = $chanconf{$_}{autojoin}; if (defined $val) { - $skip++ if ($val eq "0"); - if ($val eq "1") { + $skip++ if ($val eq '0'); + if ($val eq '1') { # convert old +autojoin to autojoin $val = lc $nick; $chanconf{$_}{autojoin} = $val; @@ -861,8 +892,8 @@ sub getJoinChans { } my $str; - #$str .= ' in:' . join(',', sort @in) if scalar @in; - #$str .= ' skip:' . join(',', sort @skip) if scalar @skip; + $str .= ' in:' . join(',', sort @in) if scalar @in; + $str .= ' skip:' . join(',', sort @skip) if scalar @skip; $str .= ' join:' . join(',', sort @join) if scalar @join; &status("Chans: ($nick)$str") if ($show); @@ -896,7 +927,7 @@ sub closeDCC { sub joinfloodCheck { my($who,$chan,$userhost) = @_; - return unless (&IsChanConf("joinfloodCheck") > 0); + return unless (&IsChanConf('joinfloodCheck') > 0); if (exists $netsplit{lc $who}) { # netsplit join. &DEBUG("joinfloodCheck: $who was in netsplit; not checking."); @@ -960,3 +991,5 @@ sub getHostMask { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/IRC/IrcHelpers.pl b/src/IRC/IrcHelpers.pl index ad5ec8b..4f64ca4 100644 --- a/src/IRC/IrcHelpers.pl +++ b/src/IRC/IrcHelpers.pl @@ -13,61 +13,58 @@ ##### # Usage: &hookMode($nick, $modes, @targets); sub hookMode { - my ($nick, $modes, @targets) = @_; - my $parity = 0; - - if ($chan =~ tr/A-Z/a-z/) { - &VERB("hookMode: cased $chan.",2); - } + my ( $nick, $modes, @targets ) = @_; + my $parity = 0; my $mode; - foreach $mode (split(//, $modes)) { - # sign. - if ($mode =~ /[-+]/) { - $parity = 1 if ($mode eq "+"); - $parity = 0 if ($mode eq "-"); - next; - } - - # mode with target. - if ($mode =~ /[bklov]/) { - my $target = shift @targets; - - if ($parity) { - $chanstats{$chan}{'Op'}++ if ($mode eq "o"); - $chanstats{$chan}{'Ban'}++ if ($mode eq "b"); - } else { - $chanstats{$chan}{'Deop'}++ if ($mode eq "o"); - $chanstats{$chan}{'Unban'}++ if ($mode eq "b"); - } - - # modes w/ target affecting nick => cache it. - if ($mode =~ /[bov]/) { - $channels{$chan}{$mode}{$target}++ if $parity; - delete $channels{$chan}{$mode}{$target} if !$parity; - - # lets do some custom stuff. - if ($mode eq "o" and $parity) { - if ($nick eq "ChanServ" and $target =~ /^\Q$ident\E$/i) { - &VERB("hookmode: chanserv deopped us! asking",2); - &chanServCheck($chan); - } - - &chanLimitVerify($chan); - } - } - - if ($mode =~ /[l]/) { - $channels{$chan}{$mode} = $target if $parity; - delete $channels{$chan}{$mode} if !$parity; - } - } - - # important channel modes, targetless. - if ($mode =~ /[mt]/) { - $channels{$chan}{$mode}++ if $parity; - delete $channels{$chan}{$mode} if !$parity; - } + foreach $mode ( split( //, $modes ) ) { + + # sign. tmp parity needed to store current state + if ( $mode =~ /[-+]/ ) { + $parity = 1 if ( $mode eq "+" ); + $parity = 0 if ( $mode eq "-" ); + next; + } + + # mode with target. + if ( $mode =~ /[bklov]/ ) { + my $target = shift @targets; + + if ($parity) { + $chanstats{ lc $chan }{'Op'}++ if ( $mode eq 'o' ); + $chanstats{ lc $chan }{'Ban'}++ if ( $mode eq 'b' ); + } else { + $chanstats{ lc $chan }{'Deop'}++ if ( $mode eq 'o' ); + $chanstats{ lc $chan }{'Unban'}++ if ( $mode eq 'b' ); + } + + # modes w/ target affecting nick => cache it. + if ( $mode =~ /[bov]/ ) { + $channels{ lc $chan }{$mode}{$target}++ if $parity; + delete $channels{ lc $chan }{$mode}{$target} if !$parity; + + # lets do some custom stuff. + if ( $mode =~ /o/ and not $parity ) { + if ( $target =~ /^\Q$ident\E$/i ) { + &VERB( "hookmode: someone deopped us!", 2 ); + &chanServCheck($chan); + } + + &chanLimitVerify($chan); + } + } + + if ( $mode =~ /[l]/ ) { + $channels{ lc $chan }{$mode} = $target if $parity; + delete $channels{ lc $chan }{$mode} if !$parity; + } + } + + # important channel modes, targetless. + if ( $mode =~ /[mt]/ ) { + $channels{ lc $chan }{$mode}++ if $parity; + delete $channels{ lc $chan }{$mode} if !$parity; + } } } @@ -123,13 +120,13 @@ sub hookMsg { $addressed = 1; } else { # ignore messages addressed to other people or unaddressed. - $skipmessage++ if ($2 ne "" and $2 !~ /^ /); + $skipmessage++ if ($2 ne '' and $2 !~ /^ /); } } } # Determine floodwho. - my $c = "_default"; + my $c = '_default'; if ($msgType =~ /public/i) { # public. $floodwho = $c = lc $chan; @@ -141,14 +138,14 @@ sub hookMsg { &FIXME("floodwho = ???"); } - my $val = &getChanConfDefault("floodRepeat", "2:5", $c); + my $val = &getChanConfDefault('floodRepeat', "2:5", $c); my ($count, $interval) = split /:/, $val; # flood repeat protection. if ($addressed) { my $time = $flood{$floodwho}{$message} || 0; - if (!&IsFlag('o') and $msgType eq "public" and (time() - $time < $interval)) { + if (!&IsFlag('o') and $msgType eq 'public' and (time() - $time < $interval)) { ### public != personal who so the below is kind of pointless. my @who; foreach (keys %flood) { @@ -161,7 +158,7 @@ sub hookMsg { return if ($lobotomized); if (!scalar @who) { - push(@who,"Someone"); + push(@who,'Someone'); } &msg($who,join(' ', @who)." already said that ". (time - $time) ." seconds ago" ); @@ -183,14 +180,14 @@ sub hookMsg { if ($addrchar) { &status("$b_cyan$who$ob is short-addressing $mynick"); - } elsif ($msgType eq "private") { # private. + } elsif ($msgType eq 'private') { # private. &status("$b_cyan$who$ob is /msg'ing $mynick"); } else { # public? &status("$b_cyan$who$ob is addressing $mynick"); } $flood{$floodwho}{$message} = time(); - } elsif ($msgType eq "public" and &IsChanConf("kickOnRepeat") > 0) { + } elsif ($msgType eq 'public' and &IsChanConf('kickOnRepeat') > 0) { # unaddressed, public only. ### TODO: use a separate "short-time" hash. @@ -198,7 +195,7 @@ sub hookMsg { @data = keys %{ $flood{$floodwho} } if (exists $flood{$floodwho}); } - $val = &getChanConfDefault("floodMessages", "5:30", $c); + $val = &getChanConfDefault('floodMessages', "5:30", $c); ($count, $interval) = split /:/, $val; # flood overflow protection. @@ -243,6 +240,8 @@ sub hookMsg { $orig{message} =~ /^s\/([^;\/]*)\/([^;\/]*)\/([g]*)$/) { my $sedmsg = $seencache{$who}{'msg'}; eval "\$sedmsg =~ s/\Q$1\E/\Q$2\E/$3;"; + $sedmsg =~ s/^(.{255}).*$/$1.../; # 255 char max to prevent flood + if ($sedmsg ne $seencache{$who}{'msg'}) { &DEBUG("sed \"" . $orig{message} . "\" \"" . $seencache{$who}{'msg'} . "\" \"" . $sedmsg. "\""); @@ -257,7 +256,7 @@ sub hookMsg { $seencache{$who}{'msg'} = $orig{message}; $seencache{$who}{'msgcount'}++; } - if (&IsChanConf("minVolunteerLength") > 0) { + if (&IsChanConf('minVolunteerLength') > 0) { # FIXME hack to treat unaddressed as if using addrchar $addrchar = 1; } @@ -310,7 +309,7 @@ sub chanLimitVerify { $chan = $c; my $l = $channels{$chan}{'l'}; - return unless (&IsChanConf("chanlimitcheck") > 0); + return unless (&IsChanConf('chanlimitcheck') > 0); if (scalar keys %netsplit) { &WARN("clV: netsplit active (1, chan = $chan); skipping."); @@ -324,9 +323,9 @@ sub chanLimitVerify { } # only change it if it's not set. - my $plus = &getChanConfDefault("chanlimitcheckPlus", 5, $chan); + my $plus = &getChanConfDefault('chanlimitcheckPlus', 5, $chan); my $count = scalar(keys %{ $channels{$chan}{''} }); - my $int = &getChanConfDefault("chanlimitcheckInterval", 10, $chan); + my $int = &getChanConfDefault('chanlimitcheckInterval', 10, $chan); my $delta = $count + $plus - $l; # $delta =~ s/^\-//; @@ -361,30 +360,26 @@ sub chanServCheck { return 0; } - if ($chan =~ tr/A-Z/a-z/) { - &DEBUG("chanServCheck: lowercased chan ($chan)"); - } - - if (! &IsChanConf("chanServ_ops") > 0) { - return 0; - } + return unless (&IsChanConf('chanServCheck') > 0); &VERB("chanServCheck($chan) called.",2); - if ( &IsParam("nickServ_pass") and !$nickserv) { - $conn->who("NickServ"); + if ( &IsParam('nickServ_pass') and !$nickserv) { + $conn->who('NickServ'); return 0; } # check for first hash then for next hash. # TODO: a function for &ischanop()? &isvoice()? - if (exists $channels{$chan} and exists $channels{$chan}{'o'}{$ident}) { + if (exists $channels{lc $chan} and exists $channels{lc $chan}{'o'}{$ident}) { return 0; } &status("ChanServ ==> Requesting ops for $chan. (chanServCheck)"); - &rawout("PRIVMSG ChanServ :OP $chan $ident"); + &msg('ChanServ', "OP $chan"); return 1; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/IRC/IrcHooks.pl b/src/IRC/IrcHooks.pl index d105d8e..07adbb2 100644 --- a/src/IRC/IrcHooks.pl +++ b/src/IRC/IrcHooks.pl @@ -24,15 +24,13 @@ sub on_generic { sub on_action { $conn = shift(@_); my ($event) = @_; - my ($nick, @args) = ($event->nick, $event->args); + my ($nick, $args) = ($event->nick, $event->args); my $chan = ($event->to)[0]; - shift @args; - if ($chan eq $ident) { - &status("* [$nick] @args"); + &status("* [$nick] $args"); } else { - &status("* $nick/$chan @args"); + &status("* $nick/$chan $args"); } } @@ -50,7 +48,7 @@ sub on_chat { } ### set vars that would have been set in hookMsg. - $userHandle = ""; # reset. + $userHandle = ''; # reset. $who = lc $nick; $message = $msg; $orig{who} = $nick; @@ -66,7 +64,7 @@ sub on_chat { my $crypto = $users{$userHandle}{PASS}; my $success = 0; - if ($userHandle eq "_default") { + if ($userHandle eq '_default') { &WARN("DCC CHAT: _default/guest not allowed."); return; } @@ -84,7 +82,7 @@ sub on_chat { $conn->privmsg($sock, "Commands start with '.' (like '.quit' or '.help')"); $conn->privmsg($sock, "Everything else goes out to the party line."); - &dccStatus(2) unless (exists $sched{"dccStatus"}{RUNNING}); + &dccStatus(2) unless (exists $sched{'dccStatus'}{RUNNING}); $success++; @@ -103,7 +101,7 @@ sub on_chat { $dcc{'CHATvrfy'}{$nick} = $userHandle; - return if ($userHandle eq "_default"); + return if ($userHandle eq '_default'); &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}"); } @@ -117,7 +115,7 @@ sub on_chat { ### TODO: make use of &Forker(); here? &loadMyModule('UserDCC'); - &DCCBroadcast("#$who# $message","m"); + &DCCBroadcast("#$who# $message",'m'); my $retval = &userDCC(); return unless (defined $retval); @@ -160,7 +158,7 @@ sub on_endofmotd { # first time run. if (!exists $users{_default}) { &status("!!! First time run... adding _default user."); - $users{_default}{FLAGS} = "amrt"; + $users{_default}{FLAGS} = 'amrt'; $users{_default}{HOSTS}{"*!*@*"} = 1; } @@ -183,11 +181,11 @@ sub on_endofmotd { } if ($firsttime) { - &ScheduleThis(1, "setupSchedulers"); + &ScheduleThis(1, 'setupSchedulers'); $firsttime = 0; } - if (&IsParam("ircUMode")) { + if (&IsParam('ircUMode')) { &VERB("Attempting change of user modes to $param{'ircUMode'}.", 2); if ($param{'ircUMode'} !~ /^[-+]/) { &WARN("ircUMode had no +- prefix; adding +"); @@ -204,7 +202,7 @@ sub on_endofmotd { $conn->ison($conn->nick()); # Q, as on quakenet.org. - if (&IsParam("Q_pass")) { + if (&IsParam('Q_pass')) { &status("Authing to Q..."); &rawout("PRIVMSG Q\@CServe.quakenet.org :AUTH $param{'Q_user'} $param{'Q_pass'}"); } @@ -315,7 +313,7 @@ sub on_dcc_open { ### TODO: run ScheduleThis inside on_dcc_open_chat recursively ### 1,3,5,10 seconds then fail. if ($nuh{$nick} eq "GETTING-NOW") { - &ScheduleThis(3/60, "on_dcc_open_chat", $nick, $sock); + &ScheduleThis(3/60, 'on_dcc_open_chat', $nick, $sock); } else { on_dcc_open_chat(undef, $nick, $sock); } @@ -355,7 +353,7 @@ sub on_dcc_open_chat { $dcc{'CHAT'}{$nick} = $sock; # TODO: don't make DCC CHAT established in the first place. - if ($userHandle eq "_default") { + if ($userHandle eq '_default') { &dccsay($nick, "_default/guest not allowed"); $sock->close(); return; @@ -365,7 +363,7 @@ sub on_dcc_open_chat { &status("DCC CHAT: going to use ".$nick."'s crypt."); &dccsay($nick,"Enter your password."); } else { -# &dccsay($nick,"Welcome to blootbot DCC CHAT interface, $userHandle."); +# &dccsay($nick,"Welcome to infobot DCC CHAT interface, $userHandle."); } } @@ -397,7 +395,7 @@ sub on_disconnect { &WARN("scheduling call ircCheck() in 60s"); &clearIRCVars(); - &ScheduleThis(1, "ircCheck"); + &ScheduleThis(1, 'ircCheck'); } sub on_endofnames { @@ -420,13 +418,13 @@ sub on_endofnames { my $txt; my @array; - foreach ("o","v","") { + foreach ('o','v','') { my $count = scalar(keys %{ $channels{$chan}{$_} }); next unless ($count); - $txt = "total" if ($_ eq ""); - $txt = "voice" if ($_ eq "v"); - $txt = "ops" if ($_ eq "o"); + $txt = 'total' if ($_ eq ''); + $txt = 'voice' if ($_ eq 'v'); + $txt = 'ops' if ($_ eq 'o'); push(@array, "$count $txt"); } @@ -477,17 +475,17 @@ sub on_join { my ($user,$host) = split(/\@/, $event->userhost); $chan = lc( ($event->to)[0] ); # CASING!!!! $who = $event->nick(); - $msgType = "public"; + $msgType = 'public'; my $i = scalar(keys %{ $channels{$chan} }); my $j = $cache{maxpeeps}{$chan} || 0; - if (!&IsParam("noSHM") && time() > ($sched{shmFlush}{TIME} || time()) + 3600) { + if (!&IsParam('noSHM') && time() > ($sched{shmFlush}{TIME} || time()) + 3600) { &DEBUG("looks like schedulers died somewhere... restarting..."); &setupSchedulers(); } $chanstats{$chan}{'Join'}++; - $userstats{lc $who}{'Join'} = time() if (&IsChanConf("seenStats") > 0); + $userstats{lc $who}{'Join'} = time() if (&IsChanConf('seenStats') > 0); $cache{maxpeeps}{$chan} = $i if ($i > $j); &joinfloodCheck($who, $chan, $event->userhost); @@ -518,7 +516,7 @@ sub on_join { # how to tell if there's a netjoin??? - my $netsplitstr = ""; + my $netsplitstr = ''; $netsplitstr = " $b_yellow\[${ob}NETSPLIT VICTIM$b_yellow]$ob" if ($netsplit); &status(">>> join/$b_blue$chan$ob $b_cyan$who$ob $b_yellow($ob$user\@$host$b_yellow)$ob$netsplitstr"); @@ -529,7 +527,7 @@ sub on_join { ### on-join bans. my @bans; push(@bans, keys %{ $bans{$chan} }) if (exists $bans{$chan}); - push(@bans, keys %{ $bans{"*"} }) if (exists $bans{"*"}); + push(@bans, keys %{ $bans{'*'} }) if (exists $bans{'*'}); foreach (@bans) { my $ban = $_; @@ -544,7 +542,7 @@ sub on_join { } my $reason = "no reason"; - foreach ($chan, "*") { + foreach ($chan, '*') { next unless (exists $bans{$_}); next unless (exists $bans{$_}{$ban}); @@ -637,7 +635,7 @@ sub on_mode { $chan = ($event->to)[0]; # last element is empty... so nuke it. - pop @args while ($args[$#args] eq ""); + pop @args while ($args[$#args] eq ''); if ($nick eq $chan) { # UMODE &status(">>> mode $b_yellow\[$ob$b@args$b_yellow\]$ob by $b_cyan$nick$ob"); @@ -670,7 +668,7 @@ sub on_msg { $h = $host; if ($nick eq $ident) { # hopefully ourselves. - if ($msg eq "TEST") { + if ($msg eq 'TEST') { &status("IRCTEST: Yes, we're alive."); delete $cache{connect}; return; @@ -678,9 +676,9 @@ sub on_msg { } &hookMsg('private', undef, $nick, $msg); - $who = ""; - $chan = ""; - $msgType = ""; + $who = ''; + $chan = ''; + $msgType = ''; } sub on_names { @@ -739,7 +737,7 @@ sub on_nick_taken { $conn = shift(@_); my $nick = $conn->nick(); #my $newnick = $nick . int(rand 10); - my $newnick = $nick . "_"; + my $newnick = $nick . '_'; &DEBUG("on_nick_taken: nick => $nick"); @@ -769,7 +767,7 @@ sub on_notice { if ($check) { &status("nickserv told us to register; doing it."); - if (&IsParam("nickServ_pass")) { + if (&IsParam('nickServ_pass')) { &status("NickServ: ==> Identifying."); &rawout("PRIVMSG NickServ :IDENTIFY $param{'nickServ_pass'}"); return; @@ -782,7 +780,7 @@ sub on_notice { if ($args =~ /^Password a/i) { my $done = 0; - foreach ( &ChanConfList("chanServ_ops") ) { + foreach ( &ChanConfList('chanServ_ops') ) { next unless &chanServCheck($_); next if ($done); &DEBUG("nickserv activated or restarted; doing chanserv check."); @@ -823,7 +821,7 @@ sub on_part { my $nick = $event->nick; my $userhost = $event->userhost; $who = $nick; - $msgType = "public"; + $msgType = 'public'; if (!exists $channels{$chan}) { &DEBUG("on_part: found out $mynick is on $chan!"); @@ -840,7 +838,7 @@ sub on_part { &clearChanVars($chan); } - if (!&IsNickInAnyChan($nick) and &IsChanConf("seenStats") > 0) { + if (!&IsNickInAnyChan($nick) and &IsChanConf('seenStats') > 0) { delete $userstats{lc $nick}; } @@ -880,7 +878,7 @@ sub on_public { $who = $nick; $uh = $event->userhost(); $nuh = $nick."!".$uh; - $msgType = "public"; + $msgType = 'public'; # TODO: move this out of hookMsg to here? ($user,$host) = split(/\@/, $uh); $h = $host; @@ -894,7 +892,7 @@ sub on_public { $msgtime = time(); $lastWho{$chan} = $nick; ### TODO: use $nick or lc $nick? - if (&IsChanConf("seenStats") > 0) { + if (&IsChanConf('seenStats') > 0) { $userstats{lc $nick}{'Count'}++; $userstats{lc $nick}{'Time'} = time(); } @@ -903,7 +901,7 @@ sub on_public { my $time = time(); if (!$cache{ircTextCounters}) { &DEBUG("caching ircTextCounters for first time."); - my @str = split(/\s+/, &getChanConf("ircTextCounters")); + my @str = split(/\s+/, &getChanConf('ircTextCounters')); for (@str) { $_ = quotemeta($_); } $cache{ircTextCounters} = join('|', @str); } @@ -913,11 +911,11 @@ sub on_public { my $x = $1; &VERB("textcounters: $x matched for $who",2); - my $c = $chan || "PRIVATE"; + my $c = $chan || 'PRIVATE'; # better to do "counter=counter+1". # but that will avoid time check. - my ($v,$t) = &sqlSelect("stats", "counter,time", { + my ($v,$t) = &sqlSelect('stats', "counter,time", { nick => $who, type => $x, channel => $c, @@ -925,9 +923,8 @@ sub on_public { $v++; # don't allow ppl to cheat the stats :-) - if (defined $t && $time - $t > 60) { - &sqlReplace("stats", { - nick => $who, + if ((defined $t && $time - $t > 60) or (!defined $t)) { + &sqlSet('stats', {'nick' => $who}, { type => $x, channel => $c, time => $time, @@ -938,9 +935,9 @@ sub on_public { &hookMsg('public', $chan, $nick, $msg); $chanstats{$chan}{'PublicMsg'}++; - $who = ""; - $chan = ""; - $msgType = ""; + $who = ''; + $chan = ''; + $msgType = ''; } sub on_quit { @@ -950,7 +947,7 @@ sub on_quit { my $reason = ($event->args)[0]; # hack for ICC. - $msgType = "public"; + $msgType = 'public'; $who = $nick; ### $chan = $reason; # no. @@ -974,7 +971,7 @@ sub on_quit { # chanlimit code. foreach $chan ( &getNickInChans($nick) ) { - next unless ( &IsChanConf("chanlimitcheck") > 0); + next unless ( &IsChanConf('chanlimitcheck') > 0); next unless ( exists $channels{$_}{'l'} ); &DEBUG("on_quit: netsplit detected on $_; disabling chan limit."); @@ -1001,7 +998,7 @@ sub on_quit { # well.. it's good but weird that this has happened - lets just # be quiet about it. } - delete $userstats{lc $nick} if (&IsChanConf("seenStats") > 0); + delete $userstats{lc $nick} if (&IsChanConf('seenStats') > 0); delete $chanstats{lc $nick}; ### @@ -1280,3 +1277,5 @@ sub on_stdin { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/IRC/Schedulers.pl b/src/IRC/Schedulers.pl index 1327833..18c649d 100644 --- a/src/IRC/Schedulers.pl +++ b/src/IRC/Schedulers.pl @@ -18,7 +18,7 @@ use vars qw(%sched %schedule); # ) #%schedule = { -# uptimeLoop => ("", 60, 1), +# uptimeLoop => ('', 60, 1), #}; sub setupSchedulersII { @@ -70,6 +70,7 @@ sub setupSchedulers { &factoidCheck(2); # takes a couple of seconds on a 486. defer it # TODO: convert to new format... or nuke altogether. &newsFlush(2); + &rssFeeds(2); # 1 for run straight away &uptimeLoop(1); @@ -99,7 +100,8 @@ sub setupSchedulers { sub ScheduleThis { my ($interval, $codename, @args) = @_; - my $waittime = &getRandomInt($interval); + # Set to supllied value plus a random 0-60 seconds to avoid simultaneous runs + my $waittime = &getRandomInt("$interval-" . ($interval+&getRandomInt(60) ) ); if (!defined $waittime) { &WARN("interval == waittime == UNDEF for $codename."); @@ -124,17 +126,33 @@ sub ScheduleThis { #### LET THE FUN BEGIN. #### +sub rssFeeds { + my $interval = $param{'rssFeedTime'} || 30; + if (@_) { + &ScheduleThis( $interval*60, 'rssFeeds' ); # minutes + return if ( $_[0] eq '2' ); # defer. + } + &Forker( + 'RSSFeeds', + sub { + my $line = &RSSFeeds::RSS(); + return unless ( defined $line ); + + } + ); +} + sub randomQuote { - my $interval = &getChanConfDefault("randomQuoteInterval", 60, $chan); + my $interval = &getChanConfDefault('randomQuoteInterval', 60, $chan); if (@_) { - &ScheduleThis($interval, "randomQuote"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis($interval*60, 'randomQuote'); # every hour + return if ($_[0] eq '2'); # defer. } - foreach ( &ChanConfList("randomQuote") ) { + foreach ( &ChanConfList('randomQuote') ) { next unless (&validChan($_)); - my $line = &getRandomLineFromFile($bot_data_dir. "/blootbot.randtext"); + my $line = &getRandomLineFromFile($bot_data_dir. "/infobot.randtext"); if (!defined $line) { &ERROR("random Quote: weird error?"); return; @@ -151,18 +169,18 @@ sub randomFactoid { my ($key,$val); my $error = 0; - my $interval = &getChanConfDefault("randomFactoidInterval", 60, $chan); + my $interval = &getChanConfDefault('randomFactoidInterval', 60, $chan); if (@_) { - &ScheduleThis($interval, "randomFactoid"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis($interval*60, 'randomFactoid'); # minutes + return if ($_[0] eq '2'); # defer. } - foreach ( &ChanConfList("randomFactoid") ) { + foreach ( &ChanConfList('randomFactoid') ) { next unless (&validChan($_)); &status("sending random Factoid to $_."); while (1) { - ($key,$val) = &randKey("factoids","factoid_key,factoid_value"); + ($key,$val) = &randKey('factoids',"factoid_key,factoid_value"); &DEBUG("rF: $key, $val"); ### $val =~ tr/^[A-Z]/[a-z]/; # blah is Good => blah is good. last if ((defined $val) and ($val !~ /^ $param{'maxLogSize'}) { @@ -250,18 +268,16 @@ sub logLoop { sub seenFlushOld { if (@_) { - &ScheduleThis(1440, "seenFlushOld"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(86400, 'seenFlushOld'); # 1 day + return if ($_[0] eq '2'); # defer. } - # NO SEEN FLUSHING!!! - return; # is this global-only? - return unless (&IsChanConf("seen") > 0); - return unless (&IsChanConf("seenFlushInterval") > 0); + return unless (&IsChanConf('seen') > 0); + return unless (&IsChanConf('seenFlushInterval') > 0); # global setting. does not make sense for per-channel. - my $max_time = &getChanConfDefault("seenMaxDays", 30, $chan) *60*60*24; + my $max_time = &getChanConfDefault('seenMaxDays', 30, $chan) *60*60*24; my $delete = 0; if ($param{'DBType'} =~ /^(pgsql|mysql|sqlite(2)?)$/i) { @@ -280,7 +296,7 @@ sub seenFlushOld { while (my @row = $sth->fetchrow_array) { my ($nick,$time) = @row; - &sqlDelete("seen", { nick => $nick } ); + &sqlDelete('seen', { nick => $nick } ); $delete++; } $sth->finish; @@ -294,8 +310,8 @@ sub seenFlushOld { sub newsFlush { if (@_) { - &ScheduleThis(60, "newsFlush"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(3600, 'newsFlush'); # 1 hour + return if ($_[0] eq '2'); # defer. } if (!&ChanConfList('News')) { @@ -371,25 +387,25 @@ sub newsFlush { } sub chanlimitCheck { - my $interval = &getChanConfDefault("chanlimitcheckInterval", 10, $chan); + my $interval = &getChanConfDefault('chanlimitcheckInterval', 10, $chan); my $mynick=$conn->nick(); if (@_) { - &ScheduleThis($interval, "chanlimitCheck"); - return if ($_[0] eq "2"); + &ScheduleThis($interval*60, 'chanlimitCheck'); # default 10 minutes + return if ($_[0] eq '2'); } - my $str = join(' ', &ChanConfList("chanlimitcheck") ); + my $str = join(' ', &ChanConfList('chanlimitcheck') ); - foreach $chan ( &ChanConfList("chanlimitcheck") ) { + foreach $chan ( &ChanConfList('chanlimitcheck') ) { next unless (&validChan($chan)); - if ($chan eq "_default") { + if ($chan eq '_default') { &WARN("chanlimit: we're doing $chan!! HELP ME!"); next; } - my $limitplus = &getChanConfDefault("chanlimitcheckPlus", 5, $chan); + my $limitplus = &getChanConfDefault('chanlimitcheckPlus', 5, $chan); my $newlimit = scalar(keys %{ $channels{$chan}{''} }) + $limitplus; my $limit = $channels{$chan}{'l'}; @@ -443,8 +459,8 @@ sub netsplitCheck { my ($s1,$s2); if (@_) { - &ScheduleThis(15, "netsplitCheck"); - return if ($_[0] eq "2"); + &ScheduleThis(300, 'netsplitCheck'); # every 5 minutes + return if ($_[0] eq '2'); } $cache{'netsplitCache'}++; @@ -491,9 +507,10 @@ sub netsplitCheck { } # yet another hack. - foreach (keys %channels) { - my $i = $cache{maxpeeps}{$chan} || 0; - my $j = scalar(keys %{ $channels{$chan} }); + # FIXED: $ch should be used rather than $chan since it creates NULL channels in the hash + foreach my $ch (keys %channels) { + my $i = $cache{maxpeeps}{$ch} || 0; + my $j = scalar(keys %{ $channels{$ch} }); next unless ($i > 10 and 0.25*$i > $j); &DEBUG("netsplit: 0.25*max($i) > current($j); possible netsplit?"); @@ -520,12 +537,12 @@ sub floodLoop { my $who; if (@_) { - &ScheduleThis(60, "floodLoop"); # minutes. - return if ($_[0] eq "2"); + &ScheduleThis(60, 'floodLoop'); # 1 minute + return if ($_[0] eq '2'); } my $time = time(); - my $interval = &getChanConfDefault("floodCycle",60, $chan); + my $interval = &getChanConfDefault('floodCycle',60, $chan); foreach $who (keys %flood) { foreach (keys %{ $flood{$who} }) { @@ -545,29 +562,25 @@ sub floodLoop { sub seenFlush { if (@_) { - my $interval = &getChanConfDefault("seenFlushInterval", 60, $chan); - &ScheduleThis($interval, "seenFlush"); - return if ($_[0] eq "2"); + my $interval = &getChanConfDefault('seenFlushInterval', 60, $chan); + &ScheduleThis($interval*60, 'seenFlush'); # minutes + return if ($_[0] eq '2'); } my %stats; my $nick; my $flushed = 0; - $stats{'count_old'} = &countKeys("seen") || 0; + $stats{'count_old'} = &countKeys('seen') || 0; $stats{'new'} = 0; $stats{'old'} = 0; if ($param{'DBType'} =~ /^(mysql|pgsql|sqlite(2)?)$/i) { foreach $nick (keys %seencache) { - my $lastcount = &sqlSelect('seen','messagecount',{nick=>lc $seencache{$nick}{'nick'}}) || 0; - my $retval = &sqlReplace("seen", { - nick => lc $seencache{$nick}{'nick'}, + my $retval = &sqlSet('seen', {'nick' => lc $seencache{$nick}{'nick'}}, { time => $seencache{$nick}{'time'}, host => $seencache{$nick}{'host'}, channel => $seencache{$nick}{'chan'}, message => $seencache{$nick}{'msg'}, - messagecount => $lastcount+$seencache{$nick}{'msgcount'}, - } ); delete $seencache{$nick}; @@ -582,8 +595,8 @@ sub seenFlush { $stats{'new'}*100/($stats{'count_old'} || 1), $stats{'new'}, ( $stats{'count_old'} || 1) ), 2) if ($stats{'new'}); &VERB(sprintf(" now seen: %3.1f%% (%d/%d)", - $stats{'old'}*100 / ( &countKeys("seen") || 1), - $stats{'old'}, &countKeys("seen") ), 2) if ($stats{'old'}); + $stats{'old'}*100 / ( &countKeys('seen') || 1), + $stats{'old'}, &countKeys('seen') ), 2) if ($stats{'old'}); &WARN("scalar keys seenflush != 0!") if (scalar keys %seenflush); } @@ -593,8 +606,8 @@ sub leakCheck { my $count = 0; if (@_) { - &ScheduleThis(240, "leakCheck"); - return if ($_[0] eq "2"); + &ScheduleThis(14400, 'leakCheck'); # every 4 hours + return if ($_[0] eq '2'); } # flood. this is dealt with in floodLoop() @@ -649,8 +662,8 @@ sub leakCheck { sub ignoreCheck { if (@_) { - &ScheduleThis(60, "ignoreCheck"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(60, 'ignoreCheck'); # once every minute + return if ($_[0] eq '2'); # defer. } my $time = time(); @@ -677,8 +690,8 @@ sub ignoreCheck { sub ircCheck { if (@_) { - &ScheduleThis(15, "ircCheck"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(300, 'ircCheck'); # every 5 minutes + return if ($_[0] eq '2'); # defer. } $cache{statusSafe} = 1; @@ -686,17 +699,13 @@ sub ircCheck { $conn=$conns{$_}; my $mynick=$conn->nick(); &DEBUG("ircCheck for $_"); - my @join = &getJoinChans(1); + my @join = &getJoinChans(900); # Display with min of 900sec delay between redisplay if (scalar @join) { &FIXME('ircCheck: found channels to join! ' . join(',',@join)); &joinNextChan(); } - my @join = &getJoinChans(1); - if (scalar @join) { - &FIXME('ircCheck: found channels to join! ' . join(',',@join)); - &joinNextChan(); - } + # TODO: fix on_disconnect() if (time() - $msgtime > 3600) { # TODO: shouldn't we use cache{connect} somewhere? @@ -708,28 +717,28 @@ sub ircCheck { } else { &status('ircCheck: possible lost in space; checking.'. scalar(gmtime) ); - &msg($mynick, "TEST"); + &msg($mynick, 'TEST'); $cache{connect} = time(); } } } - if (grep /^\s*$/, keys %channels) { - &WARN('ircCheck: we have a NULL chan in hash channels? removing!'); - if (!exists $channels{''}) { - &DEBUG('ircCheck: this should never happen!'); - } - } - if ($ident !~ /^\Q$param{ircNick}\E$/) { - # this does not work unfortunately. - &WARN("ircCheck: ident($ident) != param{ircNick}($param{ircNick})."); - - # this check is misleading... perhaps we should do a notify. - if (! &IsNickInAnyChan( $param{ircNick} ) ) { - &DEBUG("$param{ircNick} not in use... changing!"); - &nick( $param{ircNick} ); - } else { - &WARN("$param{ircNick} is still in use..."); + if (grep /^\s*$/, keys %channels) { + &WARN('ircCheck: we have a NULL chan in hash channels? removing!'); + if (!exists $channels{''}) { + &DEBUG('ircCheck: this should never happen!'); + } + } + if ($ident !~ /^\Q$param{ircNick}\E$/) { + # this does not work unfortunately. + &WARN("ircCheck: ident($ident) != param{ircNick}($param{ircNick})."); + + # this check is misleading... perhaps we should do a notify. + if (! &IsNickInAnyChan( $param{ircNick} ) ) { + &DEBUG("$param{ircNick} not in use... changing!"); + &nick( $param{ircNick} ); + } else { + &WARN("$param{ircNick} is still in use..."); } } @@ -749,8 +758,8 @@ sub ircCheck { sub miscCheck { if (@_) { - &ScheduleThis(120, "miscCheck"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(7200, 'miscCheck'); # every 2 hours + return if ($_[0] eq '2'); # defer. } # SHM check. @@ -763,9 +772,9 @@ sub miscCheck { } # make backup of important files. - &mkBackup( $bot_state_dir."/blootbot.chan", 60*60*24*3); - &mkBackup( $bot_state_dir."/blootbot.users", 60*60*24*3); - &mkBackup( $bot_base_dir."/blootbot-news.txt", 60*60*24*1); + &mkBackup( $bot_state_dir."/infobot.chan", 60*60*24*3); + &mkBackup( $bot_state_dir."/infobot.users", 60*60*24*3); + &mkBackup( $bot_base_dir."/infobot-news.txt", 60*60*24*1); # flush cache{lobotomy} foreach (keys %{ $cache{lobotomy} }) { @@ -796,7 +805,7 @@ sub miscCheck { # don't touch other bots, if they're running. next unless ($param{ircUser} =~ /^\Q$n\E$/); } else { - &DEBUG("shm: $shmid is not ours or old blootbot => ($z)"); + &DEBUG("shm: $shmid is not ours or old infobot => ($z)"); next; } @@ -807,8 +816,8 @@ sub miscCheck { sub miscCheck2 { if (@_) { - &ScheduleThis(240, "miscCheck2"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(14400, 'miscCheck2'); # every 4 hours + return if ($_[0] eq '2'); # defer. } # debian check. @@ -853,8 +862,8 @@ sub getNickInUse { # } # # if (@_) { -# &ScheduleThis(30, "getNickInUse"); -# return if ($_[0] eq "2"); # defer. +# &ScheduleThis(30, 'getNickInUse'); +# return if ($_[0] eq '2'); # defer. # } # # &nick( $param{'ircNick'} ); @@ -865,7 +874,7 @@ sub uptimeLoop { # return unless &IsParam('Uptime'); if (@_) { - &ScheduleThis(60, 'uptimeLoop'); + &ScheduleThis(3600, 'uptimeLoop'); # once per hour return if ($_[0] eq '2'); # defer. } @@ -875,8 +884,8 @@ sub uptimeLoop { sub slashdotLoop { if (@_) { - &ScheduleThis(60, 'slashdotLoop'); - return if ($_[0] eq "2"); + &ScheduleThis(3600, 'slashdotLoop'); # once per hour + return if ($_[0] eq '2'); } my @chans = &ChanConfList('slashdotAnnounce'); @@ -898,8 +907,8 @@ sub slashdotLoop { sub plugLoop { if (@_) { - &ScheduleThis(60, 'plugLoop'); - return if ($_[0] eq "2"); + &ScheduleThis(3600, 'plugLoop'); # once per hour + return if ($_[0] eq '2'); } my @chans = &ChanConfList('plugAnnounce'); @@ -920,14 +929,14 @@ sub plugLoop { sub kernelLoop { if (@_) { - &ScheduleThis(240, "kernelLoop"); - return if ($_[0] eq "2"); + &ScheduleThis(14400, 'kernelLoop'); # once every 4 hours + return if ($_[0] eq '2'); } - my @chans = &ChanConfList("kernelAnnounce"); + my @chans = &ChanConfList('kernelAnnounce'); return unless (scalar @chans); - &Forker("Kernel", sub { + &Forker('Kernel', sub { my @data = &Kernel::kernelAnnounce(); foreach (@chans) { @@ -948,12 +957,12 @@ sub wingateCheck { ### FILE CACHE OF OFFENDING WINGATES. foreach (grep /^$host$/, @wingateBad) { &status("Wingate: RUNNING ON $host BY $who"); - &ban("*!*\@$host", "") if &IsChanConf('wingateBan') > 0; + &ban("*!*\@$host", '') if &IsChanConf('wingateBan') > 0; my $reason = &getChanConf('wingateKick'); next unless ($reason); - &kick($who, "", $reason) + &kick($who, '', $reason) } ### RUN CACHE OF TRIED WINGATES. @@ -978,8 +987,8 @@ sub wingateCheck { ### TODO: ?? sub wingateWriteFile { if (@_) { - &ScheduleThis(60, 'wingateWriteFile'); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(3600, 'wingateWriteFile'); # once per hour + return if ($_[0] eq '2'); # defer. } return unless (scalar @wingateCache); @@ -1010,21 +1019,21 @@ sub wingateWriteFile { sub factoidCheck { if (@_) { - &ScheduleThis(720, "factoidCheck"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(43200, 'factoidCheck'); # ever 12 hours + return if ($_[0] eq '2'); # defer. } - my @list = &searchTable("factoids", "factoid_key", "factoid_key", " #DEL#"); - my $stale = &getChanConfDefault("factoidDeleteDelay", 14, $chan) *60*60*24; + my @list = &searchTable('factoids', 'factoid_key', 'factoid_key', " #DEL#"); + my $stale = &getChanConfDefault('factoidDeleteDelay', 14, $chan) *60*60*24; if ($stale < 1) { - # disable it since it's "illegal". + # disable it since it's 'illegal'. return; } my $time = time(); foreach (@list) { - my $age = &getFactInfo($_, "modified_time"); + my $age = &getFactInfo($_, 'modified_time'); if (!defined $age or $age !~ /^\d+$/) { if (scalar @list > 50) { @@ -1055,8 +1064,8 @@ sub dccStatus { return unless (scalar keys %{ $dcc{CHAT} }); if (@_) { - &ScheduleThis(10, "dccStatus"); - return if ($_[0] eq "2"); # defer. + &ScheduleThis(600, 'dccStatus'); # every 10 minutes + return if ($_[0] eq '2'); # defer. } my $time = strftime("%H:%M", gmtime(time()) ); @@ -1117,9 +1126,9 @@ sub mkBackup { return; } - my $age = "New"; + my $age = 'New'; if ( -e "$file~" ) { - $backup++ if ((stat $file)[9] - (stat "$file~")[9] > $time); + $backup++ if ((stat $file)[9] - (stat "$file~")[9] > $time); my $delta = time() - (stat "$file~")[9]; $age = &Time2String($delta); } else { @@ -1134,3 +1143,5 @@ sub mkBackup { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Misc.pl b/src/Misc.pl index bf95b60..db0c523 100644 --- a/src/Misc.pl +++ b/src/Misc.pl @@ -13,11 +13,11 @@ use vars qw($msgType $who $bot_pid $nuh $shm $force_public_reply sub help { my $topic = shift; - my $file = $bot_data_dir."/blootbot.help"; + my $file = $bot_data_dir."/infobot.help"; my %help = (); # crude hack for performStrictReply() to work as expected. - $msgType = "private" if ($msgType eq "public"); + $msgType = 'private' if ($msgType eq 'public'); if (!open(FILE, $file)) { &ERROR("Failed reading help file ($file): $!"); @@ -39,12 +39,12 @@ sub help { $val =~ s/__/\037/g; $val =~ s/==/ /; - $help{$key} = "" if (!exists $help{$key}); + $help{$key} = '' if (!exists $help{$key}); $help{$key} .= $val."\n"; } close FILE; - if (!defined $topic or $topic eq "") { + if (!defined $topic or $topic eq '') { &msg($who, $help{'main'}); my $i = 0; @@ -165,7 +165,7 @@ sub formListReply { # Usage: &IJoin(@array); sub IJoin { if (!scalar @_) { - return "NULL"; + return 'NULL'; } elsif (scalar @_ == 1) { return $_[0]; } else { @@ -177,10 +177,10 @@ sub IJoin { # Usage: &Time2String(seconds); sub Time2String { my ($time) = @_; - my $prefix = ""; + my $prefix = ''; my (@s, @t); - return "NULL" if (!defined $time); + return 'NULL' if (!defined $time); return $time if ($time !~ /\d+/); if ($time < 0) { @@ -279,24 +279,24 @@ sub fixPlural { return $str; } - if ($str eq "has") { - $str = "have" if ($int > 1); - } elsif ($str eq "is") { - $str = "are" if ($int > 1); - } elsif ($str eq "was") { - $str = "were" if ($int > 1); - } elsif ($str eq "this") { - $str = "these" if ($int > 1); + if ($str eq 'has') { + $str = 'have' if ($int > 1); + } elsif ($str eq 'is') { + $str = 'are' if ($int > 1); + } elsif ($str eq 'was') { + $str = 'were' if ($int > 1); + } elsif ($str eq 'this') { + $str = 'these' if ($int > 1); } elsif ($str =~ /y$/) { if ($int > 1) { if ($str =~ /ey$/) { - $str .= "s"; # eg: "money" => "moneys". + $str .= 's'; # eg: 'money' => 'moneys'. } else { $str =~ s/y$/ies/; } } } else { - $str .= "s" if ($int != 1); + $str .= 's' if ($int != 1); } return $str; @@ -367,36 +367,28 @@ sub getRandom { return $array[int(rand(scalar @array))]; } -# Usage: &getRandomInt("30-60"); +# Usage: &getRandomInt("30-60"); &getRandomInt(5); +# Desc : Returns a randomn integer between "X-Y" or 1 and the value passed sub getRandomInt { - my $str = $_[0]; + my $str = shift; - if (!defined $str) { - &WARN("gRI: str == NULL."); - return; - } - - srand(); - - if ($str =~ /^(\d+(\.\d+)?)$/) { - my $i = $1; - my $fuzzy = int(rand 5); - if ($i < 10) { - return $i; + if ( !defined $str ) { + &WARN("getRandomInt: str == NULL."); + return undef; } - if (rand > 0.5) { - return ($i - $fuzzy)*60; + + if ( $str =~ /^(\d+(\.\d+)?)$/ ) { + return int( rand $str ) + 1; + } elsif ( $str =~ /^(\d+)-(\d+)$/ ) { + return $1 if $1 == $2; + my $min = $1 < $2 ? $1 : $2; # Swap is backwords + my $max = $2 > $1 ? $2 : $1; + return int( rand( $max - $min + 1 ) ) + $min; } else { - return ($i + $fuzzy)*60; - } - } elsif ($str =~ /^(\d+)-(\d+)$/) { - return ($2 - $1)*int(rand $1)*60; - } else { - return $str; # hope we're safe. - } - &ERROR("getRandomInt: invalid arg '$str'."); - return 1800; + # &ERROR("getRandomInt: invalid arg '$str'."); + return undef; + } } ########## @@ -436,7 +428,7 @@ sub IsHostMatch { $this{'host'} = &makeHostMask(lc $3); } else { &WARN("IHM: thisnuh is invalid '$thisnuh'."); - return 1 if ($thisnuh eq ""); + return 1 if ($thisnuh eq ''); return 0; } @@ -501,7 +493,7 @@ sub isFileUpdated { # Usage: &makeHostMask($host); sub makeHostMask { my ($host) = @_; - my $nu = ""; + my $nu = ''; if ($host =~ s/^(\S+!\S+\@)//) { &DEBUG("mHM: detected nick!user\@ for host arg; fixing"); @@ -548,7 +540,7 @@ sub makeRandom { sub checkMsgType { my ($reply) = @_; - return unless (&IsParam("minLengthBeforePrivate")); + return unless (&IsParam('minLengthBeforePrivate')); return if ($force_public_reply); if (length $reply > $param{'minLengthBeforePrivate'}) { @@ -609,7 +601,7 @@ sub Forker { &shmFlush(); &VERB("double fork detected; not forking.",2) if ($$ != $bot_pid); - if (&IsParam("forking") and $$ == $bot_pid) { + if (&IsParam('forking') and $$ == $bot_pid) { return unless &addForked($label); $SIG{CHLD} = 'IGNORE'; @@ -655,13 +647,13 @@ sub mkcrypt { } sub closeStats { - return unless (&getChanConfList("ircTextCounters")); + return unless (&getChanConfList('ircTextCounters')); foreach (keys %cmdstats) { my $type = $_; - my $i = &sqlSelect("stats", "counter", { + my $i = &sqlSelect('stats', 'counter', { nick => $type, - type => "cmdstats", + type => 'cmdstats', } ); my $z = 0; $z++ unless ($i); @@ -669,9 +661,8 @@ sub closeStats { $i += $cmdstats{$type}; - &sqlReplace("stats", { - nick => $type, - type => "cmdstats", + &sqlSet('stats', {'nick' => $type}, { + type => 'cmdstats', 'time' => time(), counter => $i, } ); @@ -679,3 +670,5 @@ sub closeStats { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/BZFlag.pl b/src/Modules/BZFlag.pl index 518efbe..ef988c4 100755 --- a/src/Modules/BZFlag.pl +++ b/src/Modules/BZFlag.pl @@ -44,7 +44,7 @@ sub BZFlag { sub list { my ($response); my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(5); @@ -58,7 +58,7 @@ sub list { my ($style, $maxShots, $shakeWins, $shakeTimeout, $maxPlayerScore, $maxTeamScore, $maxTime, $maxPlayers, $rogueSize, $rogueMax, $redSize, $redMax, $greenSize, $greenMax, $blueSize, $blueMax, $purpleSize, $purpleMax, $observerSize, $observerMax) = - unpack("A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2", $flags); + unpack('A4A4A4A4A4A4A4A2A2A2A2A2A2A2A2A2A2A2A2A2', $flags); my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize) + hex($blueSize) + hex($purpleSize) + hex($observerSize); $servers{$serverport} = $playerSize; @@ -79,7 +79,7 @@ sub list { sub list17 { my ($response); my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(5); @@ -96,7 +96,7 @@ sub list17 { $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax, $shakeWins,$shakeTimeout, $maxPlayerScore,$maxTeamScore,$maxTime) = - unpack("A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4", $flags); + unpack('A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4A4', $flags); my $playerSize = hex($rogueSize) + hex($redSize) + hex($greenSize) + hex($blueSize) + hex($purpleSize); $servers{$serverport} = $playerSize; @@ -120,8 +120,8 @@ sub querytext { &::status("BZFlag module requires Socket."); return 'BZFlag module not active'; } - #my @teamName = ("Rogue", "Red", "Green", "Blue", "Purple", "Observer", "Rabbit"); - my @teamName = ("X", "R", "G", "B", "P", "O", "K"); + #my @teamName = ('Rogue', 'Red', 'Green', 'Blue', 'Purple', 'Observer', 'Rabbit'); + my @teamName = ('X', 'R', 'G', 'B', 'P', 'O', 'K'); my ($message, $server, $response); $port = 5154 unless $port; @@ -154,26 +154,26 @@ sub querytext { my ($version) = $magic . $major . $minor . $something . $revision; # quit if version isn't valid - return 'not a bzflag server' if ($magic ne "BZFS"); + return 'not a bzflag server' if ($magic ne 'BZFS'); $response .= "$major$minor$something$revision "; # check version - if ($version eq "BZFS0026") { + if ($version eq 'BZFS0026') { # 1.11.x handled here return 'read error' unless read(S1, $buffer, 1) == 1; - my ($id) = unpack("C", $buffer); + my ($id) = unpack('C', $buffer); return "rejected by server" if ($id == 255); # send game request - print S1 pack("n2", 0, 0x7167); + print S1 pack('n2', 0, 0x7167); # get reply my $nbytes = read(S1, $buffer, 4); - my ($infolen, $infocode) = unpack("n2", $buffer); + my ($infolen, $infocode) = unpack('n2', $buffer); if ($infocode == 0x6774) { # read and ignore MsgGameTime from new servers $nbytes = read(S1, $buffer, 8); $nbytes = read(S1, $buffer, 4); - ($infolen, $infocode) = unpack("n2", $buffer); + ($infolen, $infocode) = unpack('n2', $buffer); } $nbytes = read(S1, $buffer, 42); if ($nbytes != 42) { @@ -184,15 +184,15 @@ sub querytext { $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize,$observerSize, $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax,$observerMax, $shakeWins,$shakeTimeout, - $maxPlayerScore,$maxTeamScore,$maxTime,$timeElapsed) = unpack("n23", $buffer); + $maxPlayerScore,$maxTeamScore,$maxTime,$timeElapsed) = unpack('n23', $buffer); return "bad server data $infocode" unless $infocode == 0x7167; # send players request - print S1 pack("n2", 0, 0x7170); + print S1 pack('n2', 0, 0x7170); # get number of teams and players we'll be receiving return 'count read error' unless read(S1, $buffer, 8) == 8; - my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer); + my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer); # get the teams return 'bad count data' unless $countcode == 0x7170; @@ -200,7 +200,7 @@ sub querytext { ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer); for (1..$numTeams) { return 'team read error' unless read(S1, $buffer, 8) == 8; - my ($team,$size,$won,$lost) = unpack("n4", $buffer); + my ($team,$size,$won,$lost) = unpack('n4', $buffer); if ($size > 0) { my $score = $won - $lost; $response .= "$teamName[$team]:$score($won-$lost) "; @@ -211,7 +211,7 @@ sub querytext { for (1..$numPlayers) { last unless read(S1, $buffer, 175) == 175; my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) = - unpack("n2Cn5A32A128", $buffer); + unpack('n2Cn5A32A128', $buffer); #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) = # unpack("n2Nn2 n4A32A128", $buffer); return 'bad player data' unless $playercode == 0x6170; @@ -227,10 +227,10 @@ sub querytext { # 1.10.x handled here $revision = $something * 10 + $revision; return 'read error' unless read(S1, $buffer, 1) == 1; - my ($id) = unpack("C", $buffer); + my ($id) = unpack('C', $buffer); # send game request - print S1 pack("n2", 0, 0x7167); + print S1 pack('n2', 0, 0x7167); # FIXME the packets are wrong from here down # get reply @@ -239,15 +239,15 @@ sub querytext { $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize, $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax, $shakeWins,$shakeTimeout, - $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer); + $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer); return 'bad server data' unless $infocode == 0x7167; # send players request - print S1 pack("n2", 0, 0x7170); + print S1 pack('n2', 0, 0x7170); # get number of teams and players we'll be receiving return 'count read error' unless read(S1, $buffer, 8) == 8; - my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer); + my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer); # get the teams return 'bad count data' unless $countcode == 0x7170; @@ -255,7 +255,7 @@ sub querytext { ($countlen,$countcode,$numTeams) = unpack("n n C", $buffer); for (1..$numTeams) { return 'team read error' unless read(S1, $buffer, 8) == 8; - my ($team,$size,$won,$lost) = unpack("n4", $buffer); + my ($team,$size,$won,$lost) = unpack('n4', $buffer); if ($size > 0) { my $score = $won - $lost; $response .= "$teamName[$team]:$score($won-$lost) "; @@ -266,7 +266,7 @@ sub querytext { for (1..$numPlayers) { last unless read(S1, $buffer, 175) == 175; my ($playerlen,$playercode,$pID,$type,$team,$won,$lost,$tks,$sign,$email) = - unpack("n2Cn5A32A128", $buffer); + unpack('n2Cn5A32A128', $buffer); #my ($playerlen,$playercode,$pAddr,$pPort,$pNum,$type,$team,$won,$lost,$sign,$email) = # unpack("n2Nn2 n4A32A128", $buffer); return 'bad player data' unless $playercode == 0x6170; @@ -283,7 +283,7 @@ sub querytext { # 1.7* versions handled here # old servers send a reconnect port number return 'read error' unless read(S1, $buffer, 2) == 2; - my ($reconnect) = unpack("n", $buffer); + my ($reconnect) = unpack('n', $buffer); $minor = $minor * 10 + $something; # quit if rejected return 'rejected by server' if ($reconnect == 0); @@ -298,7 +298,7 @@ sub querytext { close(S1); # send game request - print S pack("n2", 0, 0x7167); + print S pack('n2', 0, 0x7167); # get reply return 'server read error' unless read(S, $buffer, 40) == 40; @@ -306,21 +306,21 @@ sub querytext { $rogueSize,$redSize,$greenSize,$blueSize,$purpleSize, $rogueMax,$redMax,$greenMax,$blueMax,$purpleMax, $shakeWins,$shakeTimeout, - $maxPlayerScore,$maxTeamScore,$maxTime) = unpack("n20", $buffer); + $maxPlayerScore,$maxTeamScore,$maxTime) = unpack('n20', $buffer); return 'bad server data' unless $infocode == 0x7167; # send players request - print S pack("n2", 0, 0x7170); + print S pack('n2', 0, 0x7170); # get number of teams and players we'll be receiving return 'count read error' unless read(S, $buffer, 8) == 8; - my ($countlen,$countcode,$numTeams,$numPlayers) = unpack("n4", $buffer); + my ($countlen,$countcode,$numTeams,$numPlayers) = unpack('n4', $buffer); return 'bad count data' unless $countcode == 0x7170; # get the teams for (1..$numTeams) { return 'team read error' unless read(S, $buffer, 14) == 14; - my ($teamlen,$teamcode,$team,$size,$aSize,$won,$lost) = unpack("n7", $buffer); + my ($teamlen,$teamcode,$team,$size,$aSize,$won,$lost) = unpack('n7', $buffer); return 'bad team data' unless $teamcode == 0x7475; if ($size > 0) { my $score = $won - $lost; @@ -357,4 +357,5 @@ sub query { } 1; -# vim: ts=2 sw=2 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Debian.pl b/src/Modules/Debian.pl index 4dfadfb..8ec592b 100644 --- a/src/Modules/Debian.pl +++ b/src/Modules/Debian.pl @@ -17,9 +17,11 @@ my $announce = 0; my $defaultdist = 'sid'; my $refresh = &::getChanConfDefault('debianRefreshInterval', 7, $::chan) * 60 * 60 * 24; my $debug = 0; -my $debian_dir = $::bot_state_dir . 'debian'; -my $country = 'us'; # well .config it yourself then. ;-) +my $debian_dir = $::bot_state_dir . '/debian'; +my $country = 'nl'; # well .config it yourself then. ;-) my $protocol = 'http'; +# EDIT THIS (i386, amd64, powerpc, [etc.]): +my $arch = "i386"; # format: "alias=real". my %dists = ( @@ -42,55 +44,43 @@ my %archived_dists = ( ); my %archiveurlcontents = ( - "Contents-##DIST-i386.gz" => + "Contents-##DIST-$arch.gz" => "$protocol://debian.crosslink.net/debian-archive". - "/dists/##DIST/Contents-i386.gz", + "/dists/##DIST/Contents-$arch.gz", ); my %archiveurlpackages = ( - "Packages-##DIST-main-i386.gz" => + "Packages-##DIST-main-$arch.gz" => "$protocol://debian.crosslink.net/debian-archive". - "/dists/##DIST/main/binary-i386/Packages.gz", - "Packages-##DIST-contrib-i386.gz" => + "/dists/##DIST/main/binary-$arch/Packages.gz", + "Packages-##DIST-contrib-$arch.gz" => "$protocol://debian.crosslink.net/debian-archive". - "/dists/##DIST/contrib/binary-i386/Packages.gz", - "Packages-##DIST-non-free-i386.gz" => + "/dists/##DIST/contrib/binary-$arch/Packages.gz", + "Packages-##DIST-non-free-$arch.gz" => "$protocol://debian.crosslink.net/debian-archive". - "/dists/##DIST/non-free/binary-i386/Packages.gz", + "/dists/##DIST/non-free/binary-$arch/Packages.gz", ); - - my %urlcontents = ( - "Contents-##DIST-i386.gz" => - "$protocol://debian.usc.edu". - "/dists/##DIST/Contents-i386.gz", - "Contents-##DIST-i386-non-US.gz" => + "Contents-##DIST-$arch.gz" => + "$protocol://ftp.$country.debian.org". + "/debian/dists/##DIST/Contents-$arch.gz", + "Contents-##DIST-$arch-non-US.gz" => "$protocol://non-us.debian.org". - "/debian-non-US/dists/##DIST/non-US/Contents-i386.gz", + "/debian-non-US/dists/##DIST/non-US/Contents-$arch.gz", ); my %urlpackages = ( - "Packages-##DIST-main-i386.gz" => - "$protocol://debian.usc.edu". - "/dists/##DIST/main/binary-i386/Packages.gz", - "Packages-##DIST-contrib-i386.gz" => - "$protocol://debian.usc.edu". - "/dists/##DIST/contrib/binary-i386/Packages.gz", - "Packages-##DIST-non-free-i386.gz" => - "$protocol://debian.usc.edu". - "/dists/##DIST/non-free/binary-i386/Packages.gz", - -# "Packages-##DIST-non-US-main-i386.gz" => -# "$protocol://non-us.debian.org". -# "/debian-non-US/dists/##DIST/non-US/main/binary-i386/Packages.gz", -# "Packages-##DIST-non-US-contrib-i386.gz" => -# "$protocol://non-us.debian.org". -# "/debian-non-US/dists/##DIST/non-US/contrib/binary-i386/Packages.gz", -# "Packages-##DIST-non-US-non-free-i386.gz" => -# "$protocol://non-us.debian.org". -# "/debian-non-US/dists/##DIST/non-US/non-free/binary-i386/Packages.gz", + "Packages-##DIST-main-$arch.gz" => + "$protocol://ftp.$country.debian.org". + "/debian/dists/##DIST/main/binary-$arch/Packages.gz", + "Packages-##DIST-contrib-$arch.gz" => + "$protocol://ftp.$country.debian.org". + "/debian/dists/##DIST/contrib/binary-$arch/Packages.gz", + "Packages-##DIST-non-free-$arch.gz" => + "$protocol://ftp.$country.debian.org". + "/debian/dists/##DIST/non-free/binary-$arch/Packages.gz", ); ##################### @@ -1083,14 +1073,14 @@ sub fixDist { my %new; my ($key,$val); my %dist_urls; - + if (exists $archived_dists{$dist}){ if ($type eq 'contents'){ %dist_urls = %archiveurlcontents; } else { %dist_urls = %archiveurlpackages; - } + } } else { if ($type eq 'contents'){ @@ -1100,7 +1090,7 @@ sub fixDist { %dist_urls = %urlpackages; } } - + while (($key,$val) = each %dist_urls) { $key =~ s/##DIST/$dist/; $val =~ s/##DIST/$dist/; @@ -1195,3 +1185,5 @@ sub searchDescFE { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/DebianBugs.pm b/src/Modules/DebianBugs.pm index 661247c..42a9948 100644 --- a/src/Modules/DebianBugs.pm +++ b/src/Modules/DebianBugs.pm @@ -121,3 +121,5 @@ sub package_bugs($){ __END__ + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/DebianExtra.pl b/src/Modules/DebianExtra.pl index a9d4d34..6645596 100644 --- a/src/Modules/DebianExtra.pl +++ b/src/Modules/DebianExtra.pl @@ -179,3 +179,5 @@ sub do_pkg { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Dict.pl b/src/Modules/Dict.pl index 288b06e..2522a1c 100644 --- a/src/Modules/Dict.pl +++ b/src/Modules/Dict.pl @@ -37,7 +37,7 @@ sub Dict { my $socket = new IO::Socket; socket($socket, PF_INET, SOCK_STREAM, $proto) or return "error: socket: $!"; eval { - local $SIG{ALRM} = sub { die "alarm" }; + local $SIG{ALRM} = sub { die 'alarm' }; alarm 10; connect($socket, sockaddr_in($port, inet_aton($server))) or die "error: connect: $!"; alarm 0; @@ -53,16 +53,25 @@ sub Dict { if ($query =~ s/^(\d+)\s+//) { $num = $1; } + my $dict = '*'; + if ($query =~ s/\/(\S+)$//) { + $dict = $1; + } # body. - push(@results, &Dict_Wordnet($socket,$query)); - push(@results, &Dict_Foldoc($socket,$query)); - push(@results, &Dict_web1913($socket,$query)); + push(@results, &Define($socket,$query,$dict)); + #push(@results, &Define($socket,$query,'foldoc')); + #push(@results, &Define($socket,$query,'web1913')); # end. print $socket "QUIT\n"; close $socket; + my $count=0; + foreach (@results) { + $count++; + &::DEBUG("$count: $_"); + } my $total = scalar @results; if ($total == 0) { @@ -87,138 +96,91 @@ sub Dict { $retval = "Dictionary '$query' ".$results[0]; } else { $retval = "could not find definition for \002$query\002"; + $retval .= " in $dict" if ($dict ne '*'); } } &::performStrictReply($retval); } -sub Dict_Wordnet { - my ($socket, $query) = @_; +sub Define { + my ($socket, $query, $dict) = @_; my @results; - &::status("Dict: asking Wordnet."); - print $socket "DEFINE wn \"$query\"\n"; + &::DEBUG("Dict: asking $dict."); + print $socket "DEFINE $dict \"$query\"\n"; - my $def = ""; - my $wordtype = ""; + my $def = ''; + my $term = $query; while (<$socket>) { chop; # remove \n chop; # remove \r - &::DEBUG("got '$_'"); - if ($_ eq ".") { # end of def. - push(@results, $def); - } elsif (/^250 /) { # stats. - last; - } elsif (/^552 no match/) { # no match. + &::DEBUG("$term/$dict '$_'"); + if (/^552 /) { + # no match. return; - } elsif (/^\s+(\S+ )?(\d+)?: (.*)/) { # start of sub def. - my $text = $3; - $def =~ s/\s+$//; -### &::DEBUG("def => '$def'."); - push(@results, $def) if ($def ne ""); - $def = $text; - - if (0) { # old non-fLR format. - $def = "$query $wordtype: $text" if (defined $text); - $wordtype = substr($1,0,-1) if (defined $1); -### &::DEBUG("_ => '$_'.") if (!defined $text); + } elsif (/^250 /) { + # end w/ optional stats + last; + } elsif (/^151 "([^"]*)" (\S+) .*/) { + # 151 "Good Thing" jargon "Jargon File (4.3.0, 30 APR 2001)" + $term=$1; + $dict=$2; + $def = ''; + &::DEBUG("term=$term dict=$dict"); + } else { + my $line = $_; + # some dicts put part of the definition on the same line ie: jargon + $line =~ s/^$term//i; + $line =~ s/^\s+/ /; + if ($dict eq 'wn') { + # special processing for sub defs in wordnet + if ($line eq '.') { + # end of def. + $def =~ s/\s+$//; + $def =~ s/\[[^\]]*\]//g; + push(@results, $def); + } elsif ($line =~ m/^\s+(\S+ )?(\d+)?: (.*)/) { + # start of sub def. + my $text = $3; + $def =~ s/\s+$//; + #&::DEBUG("def => '$def'."); + $def =~ s/\[[^\]]*\]//g; + push(@results, $def) if ($def ne ''); + $def = $text; + } elsif (/^\s+(.*)/) { + $def .= $line; + } else { + &::DEBUG("ignored '$line'"); + } + } else { + # would be nice to divide other dicts + # but many are not always in a parsable format + if ($line eq '.') { + # end of def. + next if ($def eq ''); + push(@results, $def); + $def = ''; + } elsif ($line =~ m/^\s+(\S.*\S)\s*$/) { + #&::DEBUG("got '$1'"); + $def .= ' ' if ($def ne ''); + $def .= $1; + } else { + &::DEBUG("ignored '$line'"); + } } - - } elsif (/^\s+(.*)/) { - s/^\s{2,}/ /; - $def .= $_; - $def =~ s/\[.*?\]$//g; - } - } - - &::status("Dict: wordnet: found ". scalar(@results) ." defs."); - - return if (!scalar @results); - - return @results; -} - -sub Dict_Foldoc { - my ($socket,$query) = @_; - my @results; - - &::status("Dict: asking Foldoc."); - print $socket "DEFINE foldoc \"$query\"\n"; - - my $firsttime = 1; - my $string; - while (<$socket>) { - chomp; # remove \r\n - - &::DEBUG("got '$_'"); - return if /^552 /; # no match. - - last if (/^250/ or /^\.$/); # stats; end of def. - - s/^\s+|\s+$//g; # each line. - - if ($_ eq "") { # sub def separator. - $string =~ s/^\s+|\s+$//g; # sub def. - $string =~ s/[{}]//g; - - next if ($string eq ""); - - push(@results, $string); - $string = ""; } - - $string .= $_." "; } - &::status("Dict: foldoc: found ". scalar(@results) ." defs."); + &::DEBUG("Dict: $dict: found ". scalar(@results) ." defs."); return if (!scalar @results); - pop @results; # last def is date of entry. - - return @results; -} - -sub Dict_web1913 { - my ($socket,$query) = @_; - my @results; - - &::status("Dict: asking web1913."); - print $socket "DEFINE web1913 \"$query\"\n"; - - my $string; - while (<$socket>) { - chop; # remove \n - chop; # remove \r - - return if /^552/; # no match. - - last if (/^250/); # stats; end of def. - next if (/^151/ or /^150/); # definition and/or retrieval - - s/^\s+|\s+$//g; # each line. - - if ($_ eq "" or $_ =~ /^\.$/) { # sub def separator. - $string =~ s/^\s+|\s+$//g; # sub def. - $string =~ s/[{}]//g; - - next if ($string eq ""); - - push(@results, $string); - $string = ""; - } - - $string .= $_." "; - } - - &::status("Dict: web1913: found ". scalar(@results) ." defs."); - - return if (!scalar @results); - pop @results; # last def is date of entry. return @results; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/DumpVars.pl b/src/Modules/DumpVars.pl index 2e9fa97..5b36b22 100644 --- a/src/Modules/DumpVars.pl +++ b/src/Modules/DumpVars.pl @@ -15,7 +15,7 @@ my $countlines = 0; sub dumpvarslog { my ($line) = @_; - if (&IsParam("dumpvarsLogFile")) { + if (&IsParam('dumpvarsLogFile')) { print DUMPVARS $line."\n"; } else { &status("DV: ".$line); @@ -28,7 +28,7 @@ sub DumpNames(\%$) { my $line; if ($packname eq 'main::') { - &dumpvarslog("Packages"); + &dumpvarslog('Packages'); foreach $symname (sort keys %$package) { local *sym = $$package{$symname}; @@ -113,7 +113,7 @@ sub DumpNames(\%$) { } sub dumpallvars { - if (&IsParam("dumpvarsLogFile")) { + if (&IsParam('dumpvarsLogFile')) { my $file = $param{'dumpvarsLogFile'}; &status("opening fh to dumpvars ($file)"); if (!open(DUMPVARS,">$file")) { @@ -124,7 +124,7 @@ sub dumpallvars { DumpNames(%main::,'main::'); - if (&IsParam("dumpvarsLogFile")) { + if (&IsParam('dumpvarsLogFile')) { &status("closing fh to dumpvars"); close DUMPVARS; } @@ -133,3 +133,5 @@ sub dumpallvars { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/DumpVars2.pl b/src/Modules/DumpVars2.pl index ddff6fa..a6e70e5 100644 --- a/src/Modules/DumpVars2.pl +++ b/src/Modules/DumpVars2.pl @@ -32,7 +32,7 @@ sub symdumpAll { sub symdumpRecur { my $x = shift; - if (ref $x eq "HASH") { + if (ref $x eq 'HASH') { foreach (keys %$x) { &symdumpRecur($_); } @@ -64,3 +64,5 @@ sub symdumpAllFile { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Exchange.pl b/src/Modules/Exchange.pl index ae8470f..9c9e320 100644 --- a/src/Modules/Exchange.pl +++ b/src/Modules/Exchange.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Exchange.pl - currency exchange "module" +# Exchange.pl - currency exchange 'module' # # Last update: 990818 08:30:10, bobby@bofh.dk # 20021111 Tim Riker @@ -30,245 +30,245 @@ sub GetAbb { sub GetTlds { my %Hash = ( - "AF", "AFGHANISTAN", - "AL", "ALBANIA", - "DZ", "ALGERIA", - "AS", "AMERICAN SAMOA", - "AD", "ANDORRA", - "AO", "ANGOLA", - "AI", "ANGUILLA", - "AQ", "ANTARCTICA", - "AG", "ANTIGUA AND BARBUDA", - "AR", "ARGENTINA", - "AM", "ARMENIA", - "AW", "ARUBA", - "AU", "AUSTRALIA", - "AT", "AUSTRIA", - "AZ", "AZERBAIJAN", - "BS", "BAHAMAS", - "BH", "BAHRAIN", - "BD", "BANGLADESH", - "BB", "BARBADOS", - "BY", "BELARUS", - "BE", "BELGIUM", - "BZ", "BELIZE", - "BJ", "BENIN", - "BM", "BERMUDA", - "BT", "BHUTAN", - "BO", "BOLIVIA", - "BA", "BOSNIA AND HERZEGOWINA", - "BW", "BOTSWANA", - "BV", "BOUVET ISLAND", - "BR", "BRAZIL", - "IO", "BRITISH INDIAN OCEAN TERRITORY", - "BN", "BRUNEI DARUSSALAM", - "BG", "BULGARIA", - "BF", "BURKINA FASO", - "BI", "BURUNDI", - "KH", "CAMBODIA", - "CM", "CAMEROON", - "CA", "CANADA", - "CV", "CAPE VERDE", - "KY", "CAYMAN ISLANDS", - "CF", "CENTRAL AFRICAN REPUBLIC", - "TD", "CHAD", - "CL", "CHILE", - "CN", "CHINA", - "CX", "CHRISTMAS ISLAND", - "CC", "COCOS (KEELING) ISLANDS", - "CO", "COLOMBIA", - "KM", "COMOROS", - "CG", "CONGO", - "CD", "CONGO, THE DEMOCRATIC REPUBLIC OF THE", - "CK", "COOK ISLANDS", - "CR", "COSTA RICA", - "CI", "COTE D'IVOIRE", - "HR", "CROATIA (local name: Hrvatska)", - "CU", "CUBA", - "CY", "CYPRUS", - "CZ", "CZECH REPUBLIC", - "DK", "DENMARK", - "DJ", "DJIBOUTI", - "DM", "DOMINICA", - "DO", "DOMINICAN REPUBLIC", - "TP", "EAST TIMOR", - "EC", "ECUADOR", - "EG", "EGYPT", - "SV", "EL SALVADOR", - "GQ", "EQUATORIAL GUINEA", - "ER", "ERITREA", - "EE", "ESTONIA", - "ET", "ETHIOPIA", - "FK", "FALKLAND ISLANDS (MALVINAS)", - "FO", "FAROE ISLANDS", - "FJ", "FIJI", - "FI", "FINLAND", - "FR", "FRANCE", - "FX", "FRANCE, METROPOLITAN", - "GF", "FRENCH GUIANA", - "PF", "FRENCH POLYNESIA", - "TF", "FRENCH SOUTHERN TERRITORIES", - "GA", "GABON", - "GM", "GAMBIA", - "GE", "GEORGIA", - "DE", "GERMANY", - "GH", "GHANA", - "GI", "GIBRALTAR", - "GR", "GREECE", - "GL", "GREENLAND", - "GD", "GRENADA", - "GP", "GUADELOUPE", - "GU", "GUAM", - "GT", "GUATEMALA", - "GN", "GUINEA", - "GW", "GUINEA-BISSAU", - "GY", "GUYANA", - "HT", "HAITI", - "HM", "HEARD AND MC DONALD ISLANDS", - "VA", "HOLY SEE (VATICAN CITY STATE)", - "HN", "HONDURAS", - "HK", "HONG KONG", - "HU", "HUNGARY", - "IS", "ICELAND", - "IN", "INDIA", - "ID", "INDONESIA", - "IR", "IRAN (ISLAMIC REPUBLIC OF)", - "IQ", "IRAQ", - "IE", "IRELAND", - "IL", "ISRAEL", - "IT", "ITALY", - "JM", "JAMAICA", - "JP", "JAPAN", - "JO", "JORDAN", - "KZ", "KAZAKHSTAN", - "KE", "KENYA", - "KI", "KIRIBATI", - "KP", "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", - "KR", "KOREA, REPUBLIC OF", - "KW", "KUWAIT", - "KG", "KYRGYZSTAN", - "LA", "LAO PEOPLE'S DEMOCRATIC REPUBLIC", - "LV", "LATVIA", - "LB", "LEBANON", - "LS", "LESOTHO", - "LR", "LIBERIA", - "LY", "LIBYAN ARAB JAMAHIRIYA", - "LI", "LIECHTENSTEIN", - "LT", "LITHUANIA", - "LU", "LUXEMBOURG", - "MO", "MACAU", - "MK", "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF", - "MG", "MADAGASCAR", - "MW", "MALAWI", - "MY", "MALAYSIA", - "MV", "MALDIVES", - "ML", "MALI", - "MT", "MALTA", - "MH", "MARSHALL ISLANDS", - "MQ", "MARTINIQUE", - "MR", "MAURITANIA", - "MU", "MAURITIUS", - "YT", "MAYOTTE", - "MX", "MEXICO", - "FM", "MICRONESIA, FEDERATED STATES OF", - "MD", "MOLDOVA, REPUBLIC OF", - "MC", "MONACO", - "MN", "MONGOLIA", - "MS", "MONTSERRAT", - "MA", "MOROCCO", - "MZ", "MOZAMBIQUE", - "MM", "MYANMAR", - "NA", "NAMIBIA", - "NR", "NAURU", - "NP", "NEPAL", - "NL", "NETHERLANDS", - "AN", "NETHERLANDS ANTILLES", - "NC", "NEW CALEDONIA", - "NZ", "NEW ZEALAND", - "NI", "NICARAGUA", - "NE", "NIGER", - "NG", "NIGERIA", - "NU", "NIUE", - "NF", "NORFOLK ISLAND", - "MP", "NORTHERN MARIANA ISLANDS", - "NO", "NORWAY", - "OM", "OMAN", - "PK", "PAKISTAN", - "PW", "PALAU", - "PA", "PANAMA", - "PG", "PAPUA NEW GUINEA", - "PY", "PARAGUAY", - "PE", "PERU", - "PH", "PHILIPPINES", - "PN", "PITCAIRN", - "PL", "POLAND", - "PT", "PORTUGAL", - "PR", "PUERTO RICO", - "QA", "QATAR", - "RE", "REUNION", - "RO", "ROMANIA", - "RU", "RUSSIAN FEDERATION", - "RW", "RWANDA", - "KN", "SAINT KITTS AND NEVIS", - "LC", "SAINT LUCIA", - "VC", "SAINT VINCENT AND THE GRENADINES", - "WS", "SAMOA", - "SM", "SAN MARINO", - "ST", "SAO TOME AND PRINCIPE", - "SA", "SAUDI ARABIA", - "SN", "SENEGAL", - "SC", "SEYCHELLES", - "SL", "SIERRA LEONE", - "SG", "SINGAPORE", - "SK", "SLOVAKIA (Slovak Republic)", - "SI", "SLOVENIA", - "SB", "SOLOMON ISLANDS", - "SO", "SOMALIA", - "ZA", "SOUTH AFRICA", - "GS", "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", - "ES", "SPAIN", - "LK", "SRI LANKA", - "SH", "ST. HELENA", - "PM", "ST. PIERRE AND MIQUELON", - "SD", "SUDAN", - "SR", "SURINAME", - "SJ", "SVALBARD AND JAN MAYEN ISLANDS", - "SZ", "SWAZILAND", - "SE", "SWEDEN", - "CH", "SWITZERLAND", - "SY", "SYRIAN ARAB REPUBLIC", - "TW", "TAIWAN, PROVINCE OF CHINA", - "TJ", "TAJIKISTAN", - "TZ", "TANZANIA, UNITED REPUBLIC OF", - "TH", "THAILAND", - "TG", "TOGO", - "TK", "TOKELAU", - "TO", "TONGA", - "TT", "TRINIDAD AND TOBAGO", - "TN", "TUNISIA", - "TR", "TURKEY", - "TM", "TURKMENISTAN", - "TC", "TURKS AND CAICOS ISLANDS", - "TV", "TUVALU", - "UG", "UGANDA", - "UA", "UKRAINE", - "AE", "UNITED ARAB EMIRATES", - "GB", "UNITED KINGDOM", - "US", "UNITED STATES", - "UM", "UNITED STATES MINOR OUTLYING ISLANDS", - "UY", "URUGUAY", - "UZ", "UZBEKISTAN", - "VU", "VANUATU", - "VE", "VENEZUELA", - "VN", "VIET NAM", - "VG", "VIRGIN ISLANDS (BRITISH)", - "VI", "VIRGIN ISLANDS (U.S.)", - "WF", "WALLIS AND FUTUNA ISLANDS", - "EH", "WESTERN SAHARA", - "YE", "YEMEN", - "YU", "YUGOSLAVIA", - "ZM", "ZAMBIA", - "ZW", "ZIMBABWE", + 'AF', 'AFGHANISTAN', + 'AL', 'ALBANIA', + 'DZ', 'ALGERIA', + 'AS', 'AMERICAN SAMOA', + 'AD', 'ANDORRA', + 'AO', 'ANGOLA', + 'AI', 'ANGUILLA', + 'AQ', 'ANTARCTICA', + 'AG', 'ANTIGUA AND BARBUDA', + 'AR', 'ARGENTINA', + 'AM', 'ARMENIA', + 'AW', 'ARUBA', + 'AU', 'AUSTRALIA', + 'AT', 'AUSTRIA', + 'AZ', 'AZERBAIJAN', + 'BS', 'BAHAMAS', + 'BH', 'BAHRAIN', + 'BD', 'BANGLADESH', + 'BB', 'BARBADOS', + 'BY', 'BELARUS', + 'BE', 'BELGIUM', + 'BZ', 'BELIZE', + 'BJ', 'BENIN', + 'BM', 'BERMUDA', + 'BT', 'BHUTAN', + 'BO', 'BOLIVIA', + 'BA', 'BOSNIA AND HERZEGOWINA', + 'BW', 'BOTSWANA', + 'BV', 'BOUVET ISLAND', + 'BR', 'BRAZIL', + 'IO', 'BRITISH INDIAN OCEAN TERRITORY', + 'BN', 'BRUNEI DARUSSALAM', + 'BG', 'BULGARIA', + 'BF', 'BURKINA FASO', + 'BI', 'BURUNDI', + 'KH', 'CAMBODIA', + 'CM', 'CAMEROON', + 'CA', 'CANADA', + 'CV', 'CAPE VERDE', + 'KY', 'CAYMAN ISLANDS', + 'CF', 'CENTRAL AFRICAN REPUBLIC', + 'TD', 'CHAD', + 'CL', 'CHILE', + 'CN', 'CHINA', + 'CX', 'CHRISTMAS ISLAND', + 'CC', 'COCOS (KEELING) ISLANDS', + 'CO', 'COLOMBIA', + 'KM', 'COMOROS', + 'CG', 'CONGO', + 'CD', 'CONGO, THE DEMOCRATIC REPUBLIC OF THE', + 'CK', 'COOK ISLANDS', + 'CR', 'COSTA RICA', + 'CI', "COTE D'IVOIRE", + 'HR', 'CROATIA (local name: Hrvatska)', + 'CU', 'CUBA', + 'CY', 'CYPRUS', + 'CZ', 'CZECH REPUBLIC', + 'DK', 'DENMARK', + 'DJ', 'DJIBOUTI', + 'DM', 'DOMINICA', + 'DO', 'DOMINICAN REPUBLIC', + 'TP', 'EAST TIMOR', + 'EC', 'ECUADOR', + 'EG', 'EGYPT', + 'SV', 'EL SALVADOR', + 'GQ', 'EQUATORIAL GUINEA', + 'ER', 'ERITREA', + 'EE', 'ESTONIA', + 'ET', 'ETHIOPIA', + 'FK', 'FALKLAND ISLANDS (MALVINAS)', + 'FO', 'FAROE ISLANDS', + 'FJ', 'FIJI', + 'FI', 'FINLAND', + 'FR', 'FRANCE', + 'FX', 'FRANCE, METROPOLITAN', + 'GF', 'FRENCH GUIANA', + 'PF', 'FRENCH POLYNESIA', + 'TF', 'FRENCH SOUTHERN TERRITORIES', + 'GA', 'GABON', + 'GM', 'GAMBIA', + 'GE', 'GEORGIA', + 'DE', 'GERMANY', + 'GH', 'GHANA', + 'GI', 'GIBRALTAR', + 'GR', 'GREECE', + 'GL', 'GREENLAND', + 'GD', 'GRENADA', + 'GP', 'GUADELOUPE', + 'GU', 'GUAM', + 'GT', 'GUATEMALA', + 'GN', 'GUINEA', + 'GW', 'GUINEA-BISSAU', + 'GY', 'GUYANA', + 'HT', 'HAITI', + 'HM', 'HEARD AND MC DONALD ISLANDS', + 'VA', 'HOLY SEE (VATICAN CITY STATE)', + 'HN', 'HONDURAS', + 'HK', 'HONG KONG', + 'HU', 'HUNGARY', + 'IS', 'ICELAND', + 'IN', 'INDIA', + 'ID', 'INDONESIA', + 'IR', 'IRAN (ISLAMIC REPUBLIC OF)', + 'IQ', 'IRAQ', + 'IE', 'IRELAND', + 'IL', 'ISRAEL', + 'IT', 'ITALY', + 'JM', 'JAMAICA', + 'JP', 'JAPAN', + 'JO', 'JORDAN', + 'KZ', 'KAZAKHSTAN', + 'KE', 'KENYA', + 'KI', 'KIRIBATI', + 'KP', "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", + 'KR', 'KOREA, REPUBLIC OF', + 'KW', 'KUWAIT', + 'KG', 'KYRGYZSTAN', + 'LA', "LAO PEOPLE'S DEMOCRATIC REPUBLIC", + 'LV', 'LATVIA', + 'LB', 'LEBANON', + 'LS', 'LESOTHO', + 'LR', 'LIBERIA', + 'LY', 'LIBYAN ARAB JAMAHIRIYA', + 'LI', 'LIECHTENSTEIN', + 'LT', 'LITHUANIA', + 'LU', 'LUXEMBOURG', + 'MO', 'MACAU', + 'MK', 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF', + 'MG', 'MADAGASCAR', + 'MW', 'MALAWI', + 'MY', 'MALAYSIA', + 'MV', 'MALDIVES', + 'ML', 'MALI', + 'MT', 'MALTA', + 'MH', 'MARSHALL ISLANDS', + 'MQ', 'MARTINIQUE', + 'MR', 'MAURITANIA', + 'MU', 'MAURITIUS', + 'YT', 'MAYOTTE', + 'MX', 'MEXICO', + 'FM', 'MICRONESIA, FEDERATED STATES OF', + 'MD', 'MOLDOVA, REPUBLIC OF', + 'MC', 'MONACO', + 'MN', 'MONGOLIA', + 'MS', 'MONTSERRAT', + 'MA', 'MOROCCO', + 'MZ', 'MOZAMBIQUE', + 'MM', 'MYANMAR', + 'NA', 'NAMIBIA', + 'NR', 'NAURU', + 'NP', 'NEPAL', + 'NL', 'NETHERLANDS', + 'AN', 'NETHERLANDS ANTILLES', + 'NC', 'NEW CALEDONIA', + 'NZ', 'NEW ZEALAND', + 'NI', 'NICARAGUA', + 'NE', 'NIGER', + 'NG', 'NIGERIA', + 'NU', 'NIUE', + 'NF', 'NORFOLK ISLAND', + 'MP', 'NORTHERN MARIANA ISLANDS', + 'NO', 'NORWAY', + 'OM', 'OMAN', + 'PK', 'PAKISTAN', + 'PW', 'PALAU', + 'PA', 'PANAMA', + 'PG', 'PAPUA NEW GUINEA', + 'PY', 'PARAGUAY', + 'PE', 'PERU', + 'PH', 'PHILIPPINES', + 'PN', 'PITCAIRN', + 'PL', 'POLAND', + 'PT', 'PORTUGAL', + 'PR', 'PUERTO RICO', + 'QA', 'QATAR', + 'RE', 'REUNION', + 'RO', 'ROMANIA', + 'RU', 'RUSSIAN FEDERATION', + 'RW', 'RWANDA', + 'KN', 'SAINT KITTS AND NEVIS', + 'LC', 'SAINT LUCIA', + 'VC', 'SAINT VINCENT AND THE GRENADINES', + 'WS', 'SAMOA', + 'SM', 'SAN MARINO', + 'ST', 'SAO TOME AND PRINCIPE', + 'SA', 'SAUDI ARABIA', + 'SN', 'SENEGAL', + 'SC', 'SEYCHELLES', + 'SL', 'SIERRA LEONE', + 'SG', 'SINGAPORE', + 'SK', 'SLOVAKIA (Slovak Republic)', + 'SI', 'SLOVENIA', + 'SB', 'SOLOMON ISLANDS', + 'SO', 'SOMALIA', + 'ZA', 'SOUTH AFRICA', + 'GS', 'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS', + 'ES', 'SPAIN', + 'LK', 'SRI LANKA', + 'SH', 'ST. HELENA', + 'PM', 'ST. PIERRE AND MIQUELON', + 'SD', 'SUDAN', + 'SR', 'SURINAME', + 'SJ', 'SVALBARD AND JAN MAYEN ISLANDS', + 'SZ', 'SWAZILAND', + 'SE', 'SWEDEN', + 'CH', 'SWITZERLAND', + 'SY', 'SYRIAN ARAB REPUBLIC', + 'TW', 'TAIWAN, PROVINCE OF CHINA', + 'TJ', 'TAJIKISTAN', + 'TZ', 'TANZANIA, UNITED REPUBLIC OF', + 'TH', 'THAILAND', + 'TG', 'TOGO', + 'TK', 'TOKELAU', + 'TO', 'TONGA', + 'TT', 'TRINIDAD AND TOBAGO', + 'TN', 'TUNISIA', + 'TR', 'TURKEY', + 'TM', 'TURKMENISTAN', + 'TC', 'TURKS AND CAICOS ISLANDS', + 'TV', 'TUVALU', + 'UG', 'UGANDA', + 'UA', 'UKRAINE', + 'AE', 'UNITED ARAB EMIRATES', + 'GB', 'UNITED KINGDOM', + 'US', 'UNITED STATES', + 'UM', 'UNITED STATES MINOR OUTLYING ISLANDS', + 'UY', 'URUGUAY', + 'UZ', 'UZBEKISTAN', + 'VU', 'VANUATU', + 'VE', 'VENEZUELA', + 'VN', 'VIET NAM', + 'VG', 'VIRGIN ISLANDS (BRITISH)', + 'VI', 'VIRGIN ISLANDS (U.S.)', + 'WF', 'WALLIS AND FUTUNA ISLANDS', + 'EH', 'WESTERN SAHARA', + 'YE', 'YEMEN', + 'YU', 'YUGOSLAVIA', + 'ZM', 'ZAMBIA', + 'ZW', 'ZIMBABWE', ); return %Hash; } @@ -277,7 +277,7 @@ sub exchange { my ($message) = @_; &::DEBUG("exchange(@_)"); - return "Exchange.pl needs LWP::UserAgent and HTTP::Request::Common" + return 'Exchange.pl needs LWP::UserAgent and HTTP::Request::Common' if ($no_exchange); my ($From, $To, $Amount, $Country); @@ -294,9 +294,9 @@ sub exchange { my $ua = new LWP::UserAgent; # Let's pretend - #$ua->agent("Mozilla/5.0 " . $ua->agent); - $ua->agent("Mozilla/5.0"); - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + #$ua->agent('Mozilla/5.0 ' . $ua->agent); + $ua->agent('Mozilla/5.0'); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(10); my $Referer = 'http://www.xe.net/ucc/full.shtml'; @@ -306,7 +306,7 @@ sub exchange { my $grab = GET $Referer; my $reply = $ua->request($grab); if (!$reply->is_success) { - return "EXCHANGE: ".$reply->status_line; + return 'EXCHANGE: '.$reply->status_line; } my $html = $reply->as_string; my %Currencies = (grep /\S+/, @@ -373,7 +373,7 @@ sub exchange { return "$Cfrom $Currencies{$From} makes ". "$Cto $Currencies{$To} (from http://www.xe.com/)"; # ." ($When)\n"; } else { - return "i got some error trying that"; + return 'i got some error trying that'; } } else { # Oh dear. @@ -392,7 +392,7 @@ sub query { return; } - +#print &exchange('1 usd to eur') . "\n"; 1; __END__ @@ -422,3 +422,5 @@ currency code is a bit cranky. =head1 AUTHORS Bobby + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Factoids.pl b/src/Modules/Factoids.pl index 9a2a859..12e6495 100644 --- a/src/Modules/Factoids.pl +++ b/src/Modules/Factoids.pl @@ -15,14 +15,14 @@ use vars qw(%param); sub CmdFactInfo { my ($faqtoid, $query) = (lc $_[0], $_[1]); my @array; - my $string = ""; + my $string = ''; - if ($faqtoid eq "") { - &help("factinfo"); + if ($faqtoid eq '') { + &help('factinfo'); return; } - my %factinfo = &sqlSelectRowHash("factoids", "*", + my %factinfo = &sqlSelectRowHash('factoids', '*', { factoid_key => $faqtoid } ); @@ -47,7 +47,7 @@ sub CmdFactInfo { if ($factinfo{'created_by'}) { $factinfo{'created_by'} =~ s/\!/ "; + $factinfo{'created_by'} .= '>'; $string = "created by $factinfo{'created_by'}"; my $time = $factinfo{'created_time'}; @@ -57,27 +57,27 @@ sub CmdFactInfo { $string .= " at \037". scalar(gmtime $time). "\037" . " ($days days)"; } else { - $string .= " ".&Time2String(time() - $time)." ago"; + $string .= ' '.&Time2String(time() - $time).' ago'; } } push(@array,$string); } - # modified: (TimRiker asks "why do you keep turning this off?) + # modified: (TimRiker 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); } @@ -87,12 +87,12 @@ sub CmdFactInfo { my $requested_count = $factinfo{'requested_count'}; if ($requested_count) { - $string = "it has been requested "; + $string = 'it has been requested '; if ($requested_count == 1) { $string .= "\002once\002"; } else { $string .= "\002". $requested_count. "\002 ". - &fixPlural("time", $requested_count); + &fixPlural('time', $requested_count); } my $requested_by = $factinfo{'requested_by'}; @@ -104,11 +104,11 @@ sub CmdFactInfo { if (time() - $requested_time > 60*60*24*7) { $string .= " at \037". scalar(localtime $requested_time). "\037"; } else { - $string .= ", ".&Time2String(time() - $requested_time)." ago"; + $string .= ', '.&Time2String(time() - $requested_time).' ago'; } } } else { - $string = "has not been requested yet"; + $string = 'has not been requested yet'; } push(@array, $string); @@ -128,7 +128,7 @@ sub CmdFactInfo { return; } - &performStrictReply("$factinfo{'factoid_key'} -- ". join("; ", @array) ."."); + &performStrictReply("$factinfo{'factoid_key'} -- ". join('; ', @array) .'.'); return; } @@ -136,9 +136,9 @@ sub CmdFactStats { my ($type) = @_; if ($type =~ /^author$/i) { - my %hash = &sqlSelectColHash("factoids", - "factoid_key,created_by", undef, - "WHERE created_by IS NOT NULL" + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,created_by', undef, + 'WHERE created_by IS NOT NULL' ); my %author; @@ -163,24 +163,24 @@ sub CmdFactStats { my $count; my @list; foreach $count (sort { $b <=> $a } keys %count) { - my $author = join(", ", sort keys %{ $count{$count} }); + my $author = join(', ', sort keys %{ $count{$count} }); push(@list, "$count by $author"); } - my $prefix = "factoid statistics by author: "; + my $prefix = 'factoid statistics by author: '; return &formListReply(0, $prefix, @list); } elsif ($type =~ /^vandalism$/i) { - &status("factstats(vandalism): starting..."); + &status('factstats(vandalism): starting...'); my $start_time = &timeget(); - my %data = &sqlSelectColHash("factoids", - "factoid_key,factoid_value", undef, - "WHERE factoid_value IS NOT NULL" + my %data = &sqlSelectColHash('factoids', + 'factoid_key,factoid_value', undef, + 'WHERE factoid_value IS NOT NULL' ); my @list; my $delta_time = &timedelta($start_time); - &status(sprintf("factstats(vandalism): %.02f sec to retreive all factoids.", $delta_time)) if ($delta_time > 0); + &status(sprintf('factstats(vandalism): %.02f sec to retreive all factoids.', $delta_time)) if ($delta_time > 0); $start_time = &timeget(); # parse the factoids. @@ -192,7 +192,7 @@ sub CmdFactStats { } $delta_time = &timedelta($start_time); - &status(sprintf("factstats(vandalism): %.02f sec to complete.", $delta_time)) if ($delta_time > 0); + &status(sprintf('factstats(vandalism): %.02f sec to complete.', $delta_time)) if ($delta_time > 0); # bail out on no results. if (scalar @list == 0) { @@ -200,11 +200,11 @@ sub CmdFactStats { } # parse the results. - my $prefix = "Vandalised factoid "; + my $prefix = 'Vandalised factoid '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^total$/i) { - &status("factstats(total): starting..."); + &status('factstats(total): starting...'); my $start_time = &timeget(); my @list; my $str; @@ -213,50 +213,50 @@ sub CmdFactStats { ### lets do it. # total factoids requests. - $i = &sumKey("factoids", "requested_count"); + $i = &sumKey('factoids', 'requested_count'); push(@list, "total requests - $i"); # total factoids modified. - $str = &countKeys("factoids", "modified_by"); + $str = &countKeys('factoids', 'modified_by'); push(@list, "total modified - $str"); # total factoids modified. - $j = &countKeys("factoids", "requested_count"); - $str = &countKeys("factoids", "factoid_key"); - push(@list, "total non-requested - ".($str - $i)); + $j = &countKeys('factoids', 'requested_count'); + $str = &countKeys('factoids', 'factoid_key'); + push(@list, 'total non-requested - '.($str - $i)); # average request/factoid. # i/j == total(requested_count)/count(requested_count) - $str = sprintf("%.01f", $i/$j); + $str = sprintf('%.01f', $i/$j); push(@list, "average requested per factoid - $str"); # total prepared for deletion. - $str = scalar( &searchTable("factoids", "factoid_key", "factoid_value", " #DEL") ); + $str = scalar( &searchTable('factoids', 'factoid_key', 'factoid_value', ' #DEL') ); push(@list, "total prepared for deletion - $str"); # total unique authors. # TODO: convert to sqlSelectColHash ? (or ColArray?) - foreach ( &sqlRawReturn("SELECT created_by FROM factoids WHERE created_by IS NOT NULL") ) { + foreach ( &sqlRawReturn('SELECT created_by FROM factoids WHERE created_by IS NOT NULL') ) { /^(\S+)!/; my $nick = lc $1; $hash{$nick}++; } - push(@list, "total unique authors - ".(scalar keys %hash) ); + push(@list, 'total unique authors - '.(scalar keys %hash) ); undef %hash; # total unique requesters. - foreach ( &sqlRawReturn("SELECT requested_by FROM factoids WHERE requested_by IS NOT NULL") ) { + foreach ( &sqlRawReturn('SELECT requested_by FROM factoids WHERE requested_by IS NOT NULL') ) { /^(\S+)!/; my $nick = lc $1; $hash{$nick}++; } - push(@list, "total unique requesters - ".(scalar keys %hash) ); + push(@list, 'total unique requesters - '.(scalar keys %hash) ); undef %hash; - ### end of "job". + ### end of 'job'. my $delta_time = &timedelta($start_time); - &status(sprintf("factstats(broken): %.02f sec to retreive all factoids.", $delta_time)) if ($delta_time > 0); + &status(sprintf('factstats(broken): %.02f sec to retreive all factoids.', $delta_time)) if ($delta_time > 0); $start_time = &timeget(); # bail out on no results. @@ -265,21 +265,21 @@ sub CmdFactStats { } # parse the results. - my $prefix = "General factoid statistics "; + my $prefix = 'General factoid statistics '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^deadredir$/i) { - my @list = &searchTable("factoids", "factoid_key", - "factoid_value", "^ see "); + my @list = &searchTable('factoids', 'factoid_key', + 'factoid_value', '^ see '); my %redir; my $f; for (@list) { my $factoid = $_; - my $val = &getFactInfo($factoid, "factoid_value"); + my $val = &getFactInfo($factoid, 'factoid_value'); if ($val =~ /^ ?see( also)? (.*?)\.?$/i) { my $redirf = lc $2; - my $redir = &getFactInfo($redirf, "factoid_value"); + my $redir = &getFactInfo($redirf, 'factoid_value'); next if (defined $redir); next if (length $val > 50); @@ -298,15 +298,15 @@ sub CmdFactStats { } # parse the results. - my $prefix = "Loose link (dead) redirections in factoids "; + my $prefix = 'Loose link (dead) redirections in factoids '; return &formListReply(1, $prefix, @newlist); } elsif ($type =~ /^dup(licate|e)$/i) { - &status("factstats(dupe): starting..."); + &status('factstats(dupe): starting...'); my $start_time = &timeget(); - my %hash = &sqlSelectColHash("factoids", - "factoid_key,factoid_value", undef, - "WHERE factoid_value IS NOT NULL", 1 + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,factoid_value', undef, + 'WHERE factoid_value IS NOT NULL', 1 ); my $refs = 0; my @list; @@ -324,8 +324,8 @@ sub CmdFactStats { } s/([\,\;]+)/\037$1\037/g; - if ($_ eq "") { - &WARN("dupe: _ = NULL. should never happen!."); + if ($_ eq '') { + &WARN('dupe: _ = NULL. should never happen!.'); next; } push(@sublist, $_); @@ -333,20 +333,20 @@ sub CmdFactStats { next unless (scalar @sublist); - push(@list, join(", ", @sublist)); + push(@list, join(', ', @sublist)); } &status("factstats(dupe): (good) dupe refs: $refs."); my $delta_time = &timedelta($start_time); - &status(sprintf("factstats(dupe): %.02f sec to complete", $delta_time)) if ($delta_time > 0); + &status(sprintf('factstats(dupe): %.02f sec to complete', $delta_time)) if ($delta_time > 0); # bail out on no results. if (scalar @list == 0) { - return "no duplicate factoids... woohoo."; + return 'no duplicate factoids... woohoo.'; } # parse the results. - my $prefix = "dupe factoid "; + my $prefix = 'dupe factoid '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^nullfactoids$/i) { @@ -356,7 +356,7 @@ sub CmdFactStats { my @list; while (my @row = $sth->fetchrow_array) { - if ($row[1] ne "") { + if ($row[1] ne '') { &DEBUG("row[1] != NULL for $row[0]."); next; } @@ -367,12 +367,12 @@ sub CmdFactStats { $sth->finish; # parse the results. - my $prefix = "NULL factoids (not deleted yet) "; + my $prefix = 'NULL factoids (not deleted yet) '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^(2|too)short$/i) { # Custom select statement. - my $query = "SELECT factoid_key,factoid_value FROM factoids WHERE length(factoid_value) <= 40"; + my $query = 'SELECT factoid_key,factoid_value FROM factoids WHERE length(factoid_value) <= 40'; my $sth = $dbh->prepare($query); &ERROR("factstats(lame): => '$query'.") unless $sth->execute; @@ -394,12 +394,12 @@ sub CmdFactStats { $sth->finish; # parse the results. - my $prefix = "Lame factoids "; + my $prefix = 'Lame factoids '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^listfix$/i) { # Custom select statement. - my $query = "SELECT factoid_key,factoid_value FROM factoids"; + my $query = 'SELECT factoid_key,factoid_value FROM factoids'; my $sth = $dbh->prepare($query); &ERROR("factstats(listfix): => '$query'.") unless $sth->execute; @@ -414,18 +414,18 @@ sub CmdFactStats { push(@list, $key); $val =~ s/,? or /, /g; &DEBUG("fixed: => $val."); - &setFactInfo($key,"factoid_value", $val); + &setFactInfo($key,'factoid_value', $val); } $sth->finish; # parse the results. - my $prefix = "Inefficient lists fixed "; + my $prefix = 'Inefficient lists fixed '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^locked$/i) { - my %hash = &sqlSelectColhash("factoids", - "factoid_key,locked_by", undef, - "WHERE locked_by IS NOT NULL" + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,locked_by', undef, + 'WHERE locked_by IS NOT NULL' ); my @list = keys %hash; @@ -437,9 +437,9 @@ sub CmdFactStats { return &formListReply(0, $prefix, @list); } elsif ($type =~ /^new$/i) { - my %hash = &sqlSelectColHash("factoids", - "factoid_key,created_time", undef, - "WHERE created_time IS NOT NULL" + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,created_time', undef, + 'WHERE created_time IS NOT NULL' ); my %age; @@ -452,24 +452,24 @@ sub CmdFactStats { } if (scalar keys %age == 0) { - return "sorry, no new factoids."; + return 'sorry, no new factoids.'; } my @list; foreach (sort {$a <=> $b} keys %age) { - push(@list, join(",", keys %{ $age{$_} })); + push(@list, join(',', keys %{ $age{$_} })); } - my $prefix = "new factoids in the last 24hours "; + my $prefix = 'new factoids in the last 24hours '; return &formListReply(0, $prefix, @list); } elsif ($type =~ /^part(ial)?dupe$/i) { - ### requires "custom" select statement... oh well... + ### requires 'custom' select statement... oh well... my $start_time = &timeget(); # form length|key and key=length hash list. - &status("factstats(partdupe): forming length hash list."); - my $query = "SELECT factoid_key,factoid_value,length(factoid_value) AS length FROM factoids WHERE length(factoid_value) >= 192 ORDER BY length"; + &status('factstats(partdupe): forming length hash list.'); + my $query = 'SELECT factoid_key,factoid_value,length(factoid_value) AS length FROM factoids WHERE length(factoid_value) >= 192 ORDER BY length'; my $sth = $dbh->prepare($query); &ERROR("factstats(partdupe): => '$query'.") unless $sth->execute; @@ -482,7 +482,7 @@ sub CmdFactStats { } $sth->finish; &status("factstats(partdupe): total keys => '". scalar(@key) ."'."); - &status("factstats(partdupe): now deciphering data gathered"); + &status('factstats(partdupe): now deciphering data gathered'); my @length = sort { $a <=> $b } keys %length; my $key; @@ -498,53 +498,53 @@ sub CmdFactStats { if ($key{$_} =~ /^$val/i) { s/([\,\;]+)/\037$1\037/g; s/( and|and )/\037$1\037/g; - push(@sublist,$key." and ".$_); + push(@sublist,$key.' and '.$_); } } } - push(@list, join(" ,",@sublist)) if (scalar @sublist); + push(@list, join(' ,',@sublist)) if (scalar @sublist); } - my $delta_time = sprintf("%.02fs", &timedelta($start_time) ); + my $delta_time = sprintf('%.02fs', &timedelta($start_time) ); &status("factstats(partdupe): $delta_time sec to complete.") if ($delta_time > 0); # bail out on no results. if (scalar @list == 0) { - return "no initial partial duplicate factoids... woohoo."; + return 'no initial partial duplicate factoids... woohoo.'; } # parse the results. - my $prefix = "initial partial dupe factoid "; + my $prefix = 'initial partial dupe factoid '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^profanity$/i) { - my %data = &sqlSelectColHash("factoids", - "factoid_key,factoid_value", undef, - "WHERE factoid_value IS NOT NULL" + my %data = &sqlSelectColHash('factoids', + 'factoid_key,factoid_value', undef, + 'WHERE factoid_value IS NOT NULL' ); my @list; foreach (keys %data) { - push(@list, $_) if (&hasProfanity($_." ".$data{$_})); + push(@list, $_) if (&hasProfanity($_.' '.$data{$_})); } # parse the results. - my $prefix = "Profanity in factoids "; + my $prefix = 'Profanity in factoids '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^redir(ection)?$/i) { - my @list = &searchTable("factoids", "factoid_key", - "factoid_value", "^ see "); + my @list = &searchTable('factoids', 'factoid_key', + 'factoid_value', '^ 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 =~ /^ see( also)? (.*?)\.?$/i) { my $redir = lc $2; - my $redirval = &getFactInfo($redir, "factoid_value"); + my $redirval = &getFactInfo($redir, 'factoid_value'); if (defined $redirval) { $redir{$redir}{$factoid} = 1; } else { @@ -569,9 +569,9 @@ sub CmdFactStats { return &formListReply(1, $prefix, @newlist); } elsif ($type =~ /^request(ed)?$/i) { - my %hash = &sqlSelectColHash("factoids", - "factoid_key,requested_count", undef, - "WHERE requested_count IS NOT NULL", 1 + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,requested_count', undef, + 'WHERE requested_count IS NOT NULL', 1 ); if (!scalar keys %hash) { @@ -589,7 +589,7 @@ sub CmdFactStats { } $total += $count * scalar(@faqtoids); - push(@list, "$count - ". join(", ", @faqtoids)); + push(@list, "$count - ". join(', ', @faqtoids)); } unshift(@list, "\037$total - TOTAL\037"); @@ -597,9 +597,9 @@ sub CmdFactStats { return &formListReply(0, $prefix, @list); } elsif ($type =~ /^reqrate$/i) { - my %hash = &sqlSelectColHash("factoids", + my %hash = &sqlSelectColHash('factoids', "factoid_key,(unix_timestamp() - created_time)/requested_count as rate", undef, - "WHERE requested_by IS NOT NULL and created_time IS NOT NULL ORDER BY rate LIMIT 15", 1 + 'WHERE requested_by IS NOT NULL and created_time IS NOT NULL ORDER BY rate LIMIT 15', 1 ); my $rate; @@ -607,7 +607,7 @@ sub CmdFactStats { my $total = 0; my $users = 0; foreach $rate (sort { $b <=> $a } keys %hash) { - my $f = join(", ", sort keys %{ $hash{$rate} }); + my $f = join(', ', sort keys %{ $hash{$rate} }); my $str = "$f - ".&Time2String($rate); $str =~ s/\002//g; push(@list, $str); @@ -617,9 +617,9 @@ sub CmdFactStats { return &formListReply(0, $prefix, @list); } elsif ($type =~ /^requesters?$/i) { - my %hash = &sqlSelectColHash("factoids", - "factoid_key,requested_by", undef, - "WHERE requested_by IS NOT NULL" + my %hash = &sqlSelectColHash('factoids', + 'factoid_key,requested_by', undef, + 'WHERE requested_by IS NOT NULL' ); my %requester; @@ -646,7 +646,7 @@ sub CmdFactStats { my $total = 0; my $users = 0; foreach $count (sort { $b <=> $a } keys %count) { - my $requester = join(", ", sort keys %{ $count{$count} }); + my $requester = join(', ', sort keys %{ $count{$count} }); $total += $count * scalar(keys %{ $count{$count} }); $users += scalar(keys %{ $count{$count} }); push(@list, "$count by $requester"); @@ -655,12 +655,12 @@ sub CmdFactStats { # should not the above value be the same as collected by # 'requested'? soemthing weird is going on! - my $prefix = "rank of top factoid requesters: "; + my $prefix = 'rank of top factoid requesters: '; return &formListReply(0, $prefix, @list); } elsif ($type =~ /^seefix$/i) { - my @list = &searchTable("factoids", "factoid_key", - "factoid_value", "^see "); + my @list = &searchTable('factoids', 'factoid_key', + 'factoid_value', '^see '); my @newlist; my $fixed = 0; my %loop; @@ -668,12 +668,12 @@ sub CmdFactStats { for (@list) { my $factoid = $_; - my $val = &getFactInfo($factoid, "factoid_value"); + my $val = &getFactInfo($factoid, 'factoid_value'); next unless ($val =~ /^see( also)? (.*?)\.?$/i); my $redirf = lc $2; - my $redir = &getFactInfo($redirf, "factoid_value"); + my $redir = &getFactInfo($redirf, 'factoid_value'); if ($redirf =~ /^\Q$factoid\W$/i) { &delFactoid($factoid); @@ -681,7 +681,7 @@ sub CmdFactStats { } if (defined $redir) { # good. - &setFactInfo($factoid,"factoid_value"," see $redir"); + &setFactInfo($factoid,'factoid_value'," see $redir"); $fixed++; } else { push(@newlist, $redirf); @@ -690,8 +690,7 @@ sub CmdFactStats { # parse the results. &msg($who, "Fixed $fixed factoids."); - &msg($who, "Self looped factoids removed: ". - sort(keys %loop) ) if (scalar keys %loop); + &msg($who, 'Self looped factoids removed: '. keys %loop ) if (scalar keys %loop); my $prefix = "Loose link (dead) redirections in factoids "; return &formListReply(1, $prefix, @newlist); @@ -719,11 +718,11 @@ sub CmdFactStats { $sth->finish; if (scalar @list == 0) { - return "good. no factoids exceed length."; + return 'good. no factoids exceed length.'; } # parse the results. - my $prefix = "factoid key||value exceeding length "; + my $prefix = 'factoid key||value exceeding length '; return &formListReply(1, $prefix, @list); } elsif ($type =~ /^unrequest(ed)?$/i) { @@ -739,7 +738,7 @@ sub CmdFactStats { sub CmdListAuth { my ($query) = @_; my $maxshow = &::getChanConfDefault('maxListReplyCount', 15, $chan); - my @list = &searchTable("factoids","factoid_key", "created_by", "^$query!"); + my @list = &searchTable('factoids','factoid_key', 'created_by', "^$query!"); @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow); my $prefix = "factoid author list by '$query' "; @@ -747,3 +746,5 @@ sub CmdListAuth { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/HTTPDtype.pl b/src/Modules/HTTPDtype.pl index c91ecd0..ac60d61 100644 --- a/src/Modules/HTTPDtype.pl +++ b/src/Modules/HTTPDtype.pl @@ -21,13 +21,15 @@ sub HTTPDtype { $s->write_request(HEAD => "/"); my $sel = IO::Select->new($s); - $line = "Header timeout" unless $sel->can_read(10); + $line = 'Header timeout' unless $sel->can_read(10); ($code, $mess, %h) = $s->read_response_headers; $line = (length($h{Server}) > 0) ? $h{Server} : "Couldn't fetch headers from $HOST"; - &::performStrictReply($line||"Unknown Error Condition"); + &::performStrictReply($line||'Unknown Error Condition'); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Kernel.pl b/src/Modules/Kernel.pl index 1a762b8..12ae9d0 100644 --- a/src/Modules/Kernel.pl +++ b/src/Modules/Kernel.pl @@ -12,7 +12,7 @@ sub kernelGetInfo { } sub Kernel { - my $retval = "Linux kernel versions"; + my $retval = 'Linux kernel versions'; my @now = &kernelGetInfo(); if (!scalar @now) { &::msg($::who, "failed."); @@ -20,8 +20,8 @@ sub Kernel { } if ($::who =~ /^\#/) { - &::msg($::who, "No, I won't harass the entire channel."); - return undef; + &::msg($::who, "No, I won't harass the entire channel."); + return undef; } foreach $line (@now) { @@ -37,7 +37,7 @@ sub Kernel { $line =~ s/ for 2.4//; $line =~ s/ for 2.2//; $line =~ s/ is: */: /; - $retval .= ", " . $line; + $retval .= ', ' . $line; } &::performStrictReply($retval); } @@ -48,7 +48,7 @@ sub kernelAnnounce { my @old; if (!scalar @now) { - &::DEBUG("kA: failure to retrieve."); + &::DEBUG('kA: failure to retrieve.'); return; } @@ -96,3 +96,5 @@ sub kernelAnnounce { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Math.pl b/src/Modules/Math.pl index b91f8fe..a3b966b 100644 --- a/src/Modules/Math.pl +++ b/src/Modules/Math.pl @@ -7,26 +7,26 @@ use strict; use vars qw($message); my %digits = ( - "first", "1", - "second", "2", - "third", "3", - "fourth", "4", - "fifth", "5", - "sixth", "6", - "seventh", "7", - "eighth", "8", - "ninth", "9", - "tenth", "10", - "one", "1", - "two", "2", - "three", "3", - "four", "4", - "five", "5", - "six", "6", - "seven", "7", - "eight", "8", - "nine", "9", - "ten", "10" + 'first', '1', + 'second', '2', + 'third', '3', + 'fourth', '4', + 'fifth', '5', + 'sixth', '6', + 'seventh', '7', + 'eighth', '8', + 'ninth', '9', + 'tenth', '10', + 'one', '1', + 'two', '2', + 'three', '3', + 'four', '4', + 'five', '5', + 'six', '6', + 'seven', '7', + 'eight', '8', + 'nine', '9', + 'ten', '10' ); sub perlMath { @@ -60,13 +60,13 @@ sub perlMath { while ($locMsg =~ /(log\s*((\d+\.?\d*)|\d*\.?\d+))\s*/) { my ($exp, $res) = ($1, $2); - my $val = ($res) ? log($res) : "Infinity"; + my $val = ($res) ? log($res) : 'Infinity'; $locMsg =~ s/$exp/+$val/g; } while ($locMsg =~ /(bin2dec ([01]+))/) { my $exp = $1; - my $val = join ("", unpack("B*",$2)) ; + my $val = join ('', unpack('B*',$2)) ; $locMsg =~ s/$exp/+$val/g; } @@ -121,11 +121,11 @@ sub perlMath { &FIXME("math: locMsg => '$locMsg'..."); } else { &status("math: could not really compute."); - $locMsg = ""; + $locMsg = ''; } } } else { - $locMsg = ""; + $locMsg = ''; } if (defined $locMsg and $locMsg ne $message) { @@ -138,3 +138,5 @@ sub perlMath { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/NewUnits.pl b/src/Modules/NewUnits.pl deleted file mode 100644 index 2e4f25f..0000000 --- a/src/Modules/NewUnits.pl +++ /dev/null @@ -1,31 +0,0 @@ -# Units.pl: convert units of measurement -# Author: M-J. Dominus (mjd-perl-units-id-iut+buobvys+@plover.com) -# License: GPL, Copyright (C) 1996,1999 -# NOTE: Integrated into blootbot by xk. - -package NewUnits; - -#use strict; # TODO - - -sub convertUnits { - my ($from,$to) = @_; - - if ($from =~ /([+-]?[\d\.]+(?:e[+-]?[\d]+)?)\s+(temp[CFK])/){ - $from = qq|${2}(${1})|; - } - - my $units = new IO::File; - open $units, '-|', 'units', $from, $to or &::DEBUG("Unable to run units: $!") and return; - my $response = readline ($units); - if ($response =~ /\s+\*\s+([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/ or $response =~ /\t([+-]?[\d\.]+(?:e[+-]?[\d]+)?)/){ - &::performStrictReply(sprintf("$from is approximately \002%.6g\002 $to", $1)); - } - else { - &::performStrictReply("$from cannot be converted to ${to}: $response"); - } - return; -} - - -1; diff --git a/src/Modules/News.pl b/src/Modules/News.pl index d284004..07c037a 100644 --- a/src/Modules/News.pl +++ b/src/Modules/News.pl @@ -35,13 +35,8 @@ sub Parse { &readNews(); } - if ($::msgType ne "private") { - if ($who =~ /^#/){ - &::msg($who, "I'm not noticing the entire channel. /msg me instead"); - return; - } - &::notice($who, "I'm not noticing the entire channel. /msg me instead"); - return; + if ($::msgType ne 'private') { + $chan = $::chan; } if (defined $what and $what =~ s/^($::mask{chan})\s*//) { @@ -123,8 +118,8 @@ sub Parse { } elsif ($what =~ /^(un)?notify$/i) { my $state = ($1) ? 0 : 1; - # TODO: don't notify even if "News" is called. - if (&::IsChanConf("newsNotifyAll") <= 0) { + # TODO: don't notify even if 'News' is called. + if (&::IsChanConf('newsNotifyAll') <= 0) { &::DEBUG("news: chan => $chan, ::chan => $::chan."); &::notice($who, "not available for this channel or disabled altogether."); return; @@ -142,7 +137,7 @@ sub Parse { } else { # state = 0 my $x = $::newsuser{$chan}{$who}; if (defined $x and ($x == 0 or $x == -1)) { - &::notice($who, "notify already disabled"); + &::notice($who, 'notify already disabled'); return; } $::newsuser{$chan}{$who} = -1; @@ -155,7 +150,7 @@ sub Parse { } sub readNews { - my $file = "$::bot_base_dir/blootbot-news.txt"; + my $file = "$::bot_base_dir/infobot-news.txt"; if (! -f $file or -z $file) { return; } @@ -203,9 +198,9 @@ sub readNews { return unless ($ci or $cn or $cu); &::status("News: read ". - $ci. &::fixPlural(" item", $ci). " for ". - $cn. &::fixPlural(" chan", $cn). ", ". - $cu. &::fixPlural(" user", $cu), " cache" + $ci. &::fixPlural(' item', $ci). ' for '. + $cn. &::fixPlural(' chan', $cn). ', '. + $cu. &::fixPlural(' user', $cu), ' cache' ); } @@ -216,7 +211,7 @@ sub writeNews { } # should define this at the top of file. - my $file = "$::bot_base_dir/blootbot-news.txt"; + my $file = "$::bot_base_dir/infobot-news.txt"; if (fileno NEWS) { &::ERROR("News: write: fileno NEWS exists, should never happen."); @@ -249,7 +244,7 @@ sub writeNews { } # TODO: show how many users we wrote down. - if (&::getChanConfList("newsKeepRead")) { + if (&::getChanConfList('newsKeepRead')) { # old users are removed in newsFlush(), perhaps it should be # done here. @@ -271,7 +266,7 @@ sub add { my($str) = @_; if (!defined $chan or !defined $str or $str =~ /^\s*$/) { - &::help("news add"); + &::help('news add'); return; } @@ -286,7 +281,7 @@ sub add { } $::news{$chan}{$str}{Time} = time(); - my $expire = &::getChanConfDefault("newsDefaultExpire",7, $chan); + my $expire = &::getChanConfDefault('newsDefaultExpire',7, $chan); $::news{$chan}{$str}{Expire} = time() + $expire*60*60*24; $::news{$chan}{$str}{Author} = $::who; # case! @@ -307,7 +302,7 @@ sub del { my $item = 0; if (!defined $what) { - &::help("news del"); + &::help('news del'); return; } @@ -355,7 +350,7 @@ sub del { if (exists $::news{$chan}{$what}) { my $auth = 0; $auth++ if ($::who eq $::news{$chan}{$what}{Author}); - $auth++ if (&::IsFlag("o")); + $auth++ if (&::IsFlag('o')); if (!$auth) { # TODO: show when it'll expire. @@ -376,7 +371,7 @@ sub list { return; } - if (&::IsChanConf("newsKeepRead") > 0) { + if (&::IsChanConf('newsKeepRead') > 0) { my $x = $::newsuser{$chan}{$who}; if (defined $x and ($x == 0 or $x == -1)) { @@ -409,7 +404,7 @@ sub list { } my $timestr = &::Time2String(time() - $newest); &::msg($who, "|= Last updated $timestr ago."); - &::msg($who, " \037Num\037 \037Item ".(" "x40)." \037"); + &::msg($who, " \037Num\037 \037Item ".(' 'x40)." \037"); # &::DEBUG("news: list: expire = $expire"); # &::DEBUG("news: list: eno = $eno"); @@ -418,7 +413,7 @@ sub list { foreach ( &getNewsAll() ) { my $subtopic = $_; my $setby = $::news{$chan}{$subtopic}{Author}; - my $chr = (exists $::News{$chan}{$subtopic}{Text}) ? "" : "*"; + my $chr = (exists $::News{$chan}{$subtopic}{Text}) ? '' : '*'; if (!defined $subtopic) { &::DEBUG("news: warn: subtopic == undef."); @@ -446,7 +441,7 @@ sub read { my($str) = @_; if (!defined $chan or !defined $str or $str =~ /^\s*$/) { - &::help("news read"); + &::help('news read'); return; } @@ -471,7 +466,7 @@ sub read { } if (!exists $::news{$chan}{$item}{Text}) { - &::notice($who, "Someone forgot to add info to this news item"); + &::notice($who, 'Someone forgot to add info to this news item'); return; } @@ -516,8 +511,8 @@ sub read { sub mod { my($item, $str) = split /\s+/, $_[0], 2; - if (!defined $item or $item eq "" or $str =~ /^\s*$/) { - &::help("news mod"); + if (!defined $item or $item eq '' or $str =~ /^\s*$/) { + &::help('news mod'); return; } @@ -544,10 +539,10 @@ sub mod { # TODO: make code safer. my $done = 0; # TODO: use eval to deal with flags easily. - if ($flags eq "") { + if ($flags eq '') { $done++ if (!$done and $mod_news =~ s/\Q$op\E/$np/); $done++ if (!$done and $mod_nnews =~ s/\Q$op\E/$np/); - } elsif ($flags eq "g") { + } elsif ($flags eq 'g') { $done++ if ($mod_news =~ s/\Q$op\E/$np/g); $done++ if ($mod_nnews =~ s/\Q$op\E/$np/g); } @@ -603,8 +598,8 @@ sub set { $what = $1 if ($args =~ s/^(\S+)\s*//); $value = $args; - if ($item eq "") { - &::help("news set"); + if ($item eq '') { + &::help('news set'); return; } @@ -622,7 +617,7 @@ sub set { } my $ok = 0; - my @elements = ("Expire","Text"); + my @elements = ('Expire','Text'); foreach (@elements) { next unless ($what =~ /^$_$/i); $what = $_; @@ -646,7 +641,7 @@ sub set { return; } - if ($what eq "Expire") { + if ($what eq 'Expire') { # TODO: use do_set(). my $time = 0; @@ -702,7 +697,7 @@ sub set { # &::DEBUG("news: who => '$who'"); my $author = $::news{$chan}{$news}{Author}; $auth++ if ($::who eq $author); - $auth++ if (&::IsFlag("o")); + $auth++ if (&::IsFlag('o')); if (!defined $author) { &::DEBUG("news: news{$chan}{$news}{Author} is not defined! auth'd anyway"); $::news{$chan}{$news}{Author} = $::who; @@ -756,7 +751,7 @@ sub latest { } $::chan = $chan; - return if (&::IsChanConf("newsNotifyAll") <= 0); + return if (&::IsChanConf('newsNotifyAll') <= 0); # I don't understand this code ;) $t = 1 if (!defined $t); @@ -796,7 +791,7 @@ sub latest { # scalar @new, !$flag my $unread = scalar @new; my $total = scalar keys %{ $::news{$chan} }; - if (!$flag && &::IsChanConf("newsTellUnread") <= 0) { + if (!$flag && &::IsChanConf('newsTellUnread') <= 0) { return; } @@ -1033,3 +1028,5 @@ sub stats { sub AUTOLOAD { &::AUTOLOAD(@_); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/OnJoin.pl b/src/Modules/OnJoin.pl index 9a603c1..5ef7aa9 100644 --- a/src/Modules/OnJoin.pl +++ b/src/Modules/OnJoin.pl @@ -48,7 +48,7 @@ sub Cmdonjoin { my $nick = $3; my $msg = $5; - # get options + # get options my $strict = &getChanConf('onjoinStrict'); my $ops = &getChanConf('onjoinOpsOnly'); @@ -111,7 +111,7 @@ sub Cmdonjoin { &sqlDelete('onjoin', { nick => $nick, channel => $ch }); my $insert = &sqlInsert('onjoin', { nick => $nick, channel => $ch, message => $msg, modified_by => $who, modified_time => time() }); if ($insert){ - &performReply("ok"); + &performReply('ok'); } else{ &performReply('whoops. database error'); @@ -120,3 +120,5 @@ sub Cmdonjoin { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Plug.pl b/src/Modules/Plug.pl index 067b391..d80a1db 100644 --- a/src/Modules/Plug.pl +++ b/src/Modules/Plug.pl @@ -39,7 +39,7 @@ sub Plug { my $retval = "i could not get the headlines."; if (scalar @results) { - my $prefix = "Plug Headlines "; + my $prefix = 'Plug Headlines '; my @list = &plugParse(@results); $retval = &::formListReply(0, $prefix, @list); } @@ -103,3 +103,5 @@ sub plugAnnounce { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Quote.pl b/src/Modules/Quote.pl index 147c230..0fafefc 100644 --- a/src/Modules/Quote.pl +++ b/src/Modules/Quote.pl @@ -20,7 +20,7 @@ sub commify { sub Quote { my $stock = shift; - my @results = &::getURL("http://quote.yahoo.com/d/quotes.csv" . + my @results = &::getURL('http://quote.yahoo.com/d/quotes.csv' . "?s=$stock&f=sl1d1t1c1ohgv&e=.csv"); @@ -45,7 +45,7 @@ sub Quote { "Opened $open, Volume $newvol, Change $change"; } - if ($reply eq "") { + if ($reply eq '') { $reply = "i couldn't get the quote for $stock. sorry. :("; } @@ -53,3 +53,5 @@ sub Quote { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/RSSFeeds.pl b/src/Modules/RSSFeeds.pl new file mode 100644 index 0000000..035ea98 --- /dev/null +++ b/src/Modules/RSSFeeds.pl @@ -0,0 +1,163 @@ +# +# RSSTest.pl: RSS Tractker hacked from Plug.pl/Rss.pl +# Author: Dan McGrath +# 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 () { + 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 () { + 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 diff --git a/src/Modules/RootWarn.pl b/src/Modules/RootWarn.pl index fc30550..37f7ac1 100644 --- a/src/Modules/RootWarn.pl +++ b/src/Modules/RootWarn.pl @@ -21,7 +21,7 @@ sub rootWarn { &status('RootWarn: Detected root user; notifying user'); } else { &status('RootWarn: Detected root user; notifying nick and channel.'); - &msg($chan, "ROO".("O" x int(rand 8))."T has landed!"); + &msg($chan, 'ROO'.('O' x int(rand 8))."T has landed!"); } if ($_ = &getFactoid('root')) { @@ -57,7 +57,7 @@ sub rootWarn { $attempt++; ### TODO: OPTIMIZE THIS. # ok... don't record the attempt if nick==root. - return if ($nick eq "root"); + return if ($nick eq 'root'); &sqlSet('rootwarn', { nick => lc($nick) }, { attempt => $attempt, @@ -81,8 +81,8 @@ sub CmdrootWarn { } # reply #1. - $reply = "there ".&fixPlural("has",$count) ." been \002$count\002 ". - &fixPlural("rooter",$count) ." warned about root."; + $reply = 'there '.&fixPlural('has',$count) ." been \002$count\002 ". + &fixPlural('rooter',$count) ." warned about root."; if ($param{'DBType'} !~ /^(pg|my)sql$/i) { &FIXME("rootwarn does not yet support non-{my,pg}sql."); @@ -103,8 +103,8 @@ sub CmdrootWarn { if ($found) { $reply .= " Of which, \002$found\002 ". - &fixPlural("rooter",$found)." ". - &fixPlural("has",$found). + &fixPlural('rooter',$found).' '. + &fixPlural('has',$found). " done it at least 3 times."; } @@ -112,3 +112,5 @@ sub CmdrootWarn { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Rss.pl b/src/Modules/Rss.pl index a9c39e9..68df8d4 100644 --- a/src/Modules/Rss.pl +++ b/src/Modules/Rss.pl @@ -25,4 +25,5 @@ sub Rss::Rss { } 1; -# vim: ts=2 sw=2 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Search.pl b/src/Modules/Search.pl index a71bd9c..6541c0c 100644 --- a/src/Modules/Search.pl +++ b/src/Modules/Search.pl @@ -17,12 +17,12 @@ sub Search { $type =~ s/s$//; # nice work-around. - if ($type eq "value") { + if ($type eq 'value') { # search by value. - @list = &::searchTable("factoids", "factoid_key", "factoid_value", $str); + @list = &::searchTable('factoids', 'factoid_key', 'factoid_value', $str); } else { # search by key. - @list = &::searchTable("factoids", "factoid_key", "factoid_key", $str); + @list = &::searchTable('factoids', 'factoid_key', 'factoid_key', $str); } @list=grep(!/\#DEL\#$/,@list) if (scalar(@list) > $maxshow); @@ -35,3 +35,5 @@ sub Search { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Topic.pl b/src/Modules/Topic.pl index 2a07c2e..36c1a3f 100644 --- a/src/Modules/Topic.pl +++ b/src/Modules/Topic.pl @@ -33,7 +33,7 @@ sub topicDecipher { } my $subtopic = $_; - my $owner = "Unknown"; + my $owner = 'Unknown'; if (/(.*)\s+\((.*?)\)$/) { $subtopic = $1; @@ -60,10 +60,10 @@ sub topicCipher { foreach (@_) { my ($subtopic, $setby) = split /\|\|/; - if ($setby =~ /^(unknown|)$/i) { - push(@topic, $subtopic); - } else { + if ($param{'topicAuthor'} eq '1' and (!$setby =~ /^(unknown|)$/i)) { push(@topic, "$subtopic ($setby)"); + } else { + push(@topic, "$subtopic"); } } @@ -101,7 +101,7 @@ sub topicNew { return 1; } - if (defined $updateMsg && $updateMsg ne "") { + if (defined $updateMsg && $updateMsg ne '') { &msg($who, $updateMsg); } @@ -113,7 +113,7 @@ sub topicNew { $conn->topic($chan, $topic); &topicAddHistory($chan, $topic); } else { - $conn->topic($chan, " "); + $conn->topic($chan, ' '); } return 1; @@ -125,10 +125,10 @@ sub topicAddHistory { my ($chan, $topic) = @_; my $dupe = 0; - return 1 if ($topic eq ""); # required fix. + return 1 if ($topic eq ''); # required fix. foreach (@{ $topic{$chan}{'History'} }) { - next if ($_ ne "" and $_ ne $topic); + next if ($_ ne '' and $_ ne $topic); # checking length is required. # slightly weird to put a return statement in a loop. @@ -153,21 +153,27 @@ sub topicAddHistory { sub do_add { my ($chan, $args) = @_; - if ($args eq "") { - &help("topic add"); + if ($args eq '') { + &help('topic add'); return; } # heh, joeyh. 19990819. -xk if ($who =~ /\|\|/) { - &msg($who, "error: you have an invalid nick, loser!"); + &msg($who, 'error: you have an invalid nick, loser!'); return; } - return if ($channels{$chan}{t} and !&hasFlag("T")); + return if ($channels{$chan}{t} and !&hasFlag('T')); my @prev = &topicDecipher($chan); - my $new = "$args ($orig{who})"; + my $new; + # If bot new to chan and topic is blank, it still got a (owner). This is fix + if ($param{'topicAuthor'} eq '1') { + $new = "$args ($orig{who})"; + } else { + $new = "$args"; + } $topic{$chan}{'What'} = "Added '$args'."; if (scalar @prev) { @@ -175,7 +181,7 @@ sub do_add { $new = &topicCipher(@prev, $str); } - &topicNew($chan, $new, ""); + &topicNew($chan, $new, ''); } # cmd: delete. @@ -185,12 +191,12 @@ sub do_delete { my $topiccount = scalar @subtopics; if ($topiccount == 0) { - &msg($who, "No topic set."); + &msg($who, 'No topic set.'); return; } - if ($args eq "") { - &help("topic del"); + if ($args eq '') { + &help('topic del'); return; } @@ -209,8 +215,8 @@ sub do_delete { } my @delete; - foreach (split ",", $args) { - next if ($_ eq ""); + foreach (split ',', $args) { + next if ($_ eq ''); # change to hash list instead of array? if (/^(\d+)-(\d+)$/) { @@ -225,7 +231,7 @@ sub do_delete { return; } - $topic{$chan}{'What'} = "Deleted ".join("/",@delete); + $topic{$chan}{'What'} = 'Deleted '.join("/",@delete); } foreach (@delete) { @@ -240,7 +246,7 @@ sub do_delete { my ($subtopic,$whoby) = split('\|\|', $subtopics[$_-1]); - $whoby = "unknown" if ($whoby eq ""); + $whoby = 'unknown' if ($whoby eq ''); &msg($who, "Deleting topic: $subtopic ($whoby)"); undef $subtopics[$_-1]; @@ -252,7 +258,7 @@ sub do_delete { push(@newtopics, $_); } - &topicNew($chan, &topicCipher(@newtopics), ""); + &topicNew($chan, &topicCipher(@newtopics), ''); } # cmd: list @@ -288,8 +294,8 @@ sub do_list { sub do_modify { my ($chan, $args) = @_; - if ($args eq "") { - &help("topic mod"); + if ($args eq '') { + &help('topic mod'); return; } @@ -312,8 +318,8 @@ sub do_modify { my $topic = $topic{$chan}{'Current'}; ### TODO: use m### to make code safe! - if (($flags eq "g" and $topic =~ s/\Q$op\E/$np/g) || - ($flags eq "" and $topic =~ s/\Q$op\E/$np/) + if (($flags eq 'g' and $topic =~ s/\Q$op\E/$np/g) || + ($flags eq '' and $topic =~ s/\Q$op\E/$np/) ) { $_ = "Modifying topic with sar s/$op/$np/."; @@ -332,8 +338,8 @@ sub do_modify { sub do_move { my ($chan, $args) = @_; - if ($args eq "") { - &help("topic mv"); + if ($args eq '') { + &help('topic mv'); return; } @@ -402,7 +408,7 @@ sub do_move { undef @subtopics; # lets reuse this array. foreach (@newtopics) { - next if (!defined $_ or $_ eq ""); + next if (!defined $_ or $_ eq ''); push(@subtopics, $_); } @@ -416,7 +422,7 @@ sub do_shuffle { my @subtopics = &topicDecipher($chan); my @newtopics; - $topic{$chan}{'What'} = "shuffled"; + $topic{$chan}{'What'} = 'shuffled'; foreach (&makeRandom(scalar @subtopics)) { push(@newtopics, $subtopics[$_]); @@ -451,8 +457,8 @@ sub do_history { sub do_restore { my ($chan, $args) = @_; - if ($args eq "") { - &help("topic restore"); + if ($args eq '') { + &help('topic restore'); return; } @@ -486,7 +492,7 @@ sub do_rehash { my ($chan) = @_; $_ = "Rehashing topic..."; - $topic{$chan}{'What'} = "Rehash"; + $topic{$chan}{'What'} = 'Rehash'; &topicNew($chan, $topic{$chan}{'Current'}, $_, 1); } @@ -498,7 +504,7 @@ sub do_info { if (exists $topic{$chan}{'Who'} and exists $topic{$chan}{'Time'}) { $reply = "topic on \002$chan\002 was last set by ". $topic{$chan}{'Who'}. ". This was done ". - &Time2String(time() - $topic{$chan}{'Time'}) ." ago". + &Time2String(time() - $topic{$chan}{'Time'}) .' ago'. ". Length: ".length($topic{$chan}{'Current'}); my $change = $topic{$chan}{'What'}; $reply .= ". Change => $change" if (defined $change); @@ -553,16 +559,18 @@ sub Topic { } else { ### HELP: - if ($cmd ne "" and $cmd !~ /^help/i) { + if ($cmd ne '' and $cmd !~ /^help/i) { &msg($who, "Invalid command [$cmd]."); &msg($who, "Try 'help topic'."); return; } - &help("topic"); + &help('topic'); } return; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Units.pl b/src/Modules/Units.pl index ff16e7e..3f7a6e2 100644 --- a/src/Modules/Units.pl +++ b/src/Modules/Units.pl @@ -1,556 +1,31 @@ # 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 () { - 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 diff --git a/src/Modules/Uptime.pl b/src/Modules/Uptime.pl index ac962f0..5c74316 100644 --- a/src/Modules/Uptime.pl +++ b/src/Modules/Uptime.pl @@ -83,11 +83,9 @@ sub uptimeWriteFile { } close OUT; - &status("--- Saved uptime records."); - - return unless defined $conn; - - $conn->schedule(&getRandomInt("1800-3600"), \&uptimeWriteFile, ""); + &status('--- Saved uptime records.'); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/UserDCC.pl b/src/Modules/UserDCC.pl index b7f56eb..d6c306b 100644 --- a/src/Modules/UserDCC.pl +++ b/src/Modules/UserDCC.pl @@ -48,7 +48,7 @@ sub userDCC { if ($message =~ /^tellme(\s+(.*))?$/i) { my $args = $2; if ($args =~ /^\s*$/) { - &help("tellme"); + &help('tellme'); return; } @@ -60,12 +60,12 @@ sub userDCC { # 4op. if ($message =~ /^4op(\s+($mask{chan}))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $chan = $2; - if ($chan eq "") { - &help("4op"); + if ($chan eq '') { + &help('4op'); return; } @@ -86,13 +86,13 @@ sub userDCC { # opme. if ($message =~ /^opme(\s+($mask{chan}))?$/i) { - return unless (&hasFlag("o")); - return unless (&hasFlag("A")); + return unless (&hasFlag('o')); + return unless (&hasFlag('A')); my $chan = $2; - if ($chan eq "") { - &help("4op"); + if ($chan eq '') { + &help('4op'); return; } @@ -104,13 +104,13 @@ sub userDCC { # backlog. if ($message =~ /^backlog(\s+(.*))?$/i) { - return unless (&hasFlag("o")); - return unless (&IsParam("backlog")); + return unless (&hasFlag('o')); + return unless (&IsParam('backlog')); my $num = $2; my $max = $param{'backlog'}; if (!defined $num) { - &help("backlog"); + &help('backlog'); return; } elsif ($num !~ /^\d+/) { &msg($who, "error: argument is not positive integer."); @@ -132,8 +132,8 @@ sub userDCC { # dump variables. if ($message =~ /^dumpvars$/i) { - return unless (&hasFlag("o")); - return unless (&IsParam("DumpVars")); + return unless (&hasFlag('o')); + return unless (&IsParam('DumpVars')); &status("Dumping all variables..."); &dumpallvars(); @@ -154,12 +154,12 @@ sub userDCC { # kick. if ($message =~ /^kick(\s+(.*?))$/) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $arg = $2; - if ($arg eq "") { - &help("kick"); + if ($arg eq '') { + &help('kick'); return; } my @args = split(/\s+/, $arg); @@ -182,11 +182,11 @@ sub userDCC { # mode. if ($message =~ /^mode(\s+(.*))?$/) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); my ($chan,$mode) = split /\s+/,$2,2; - if ($chan eq "") { - &help("mode"); + if ($chan eq '') { + &help('mode'); return; } @@ -207,12 +207,12 @@ sub userDCC { # part. if ($message =~ /^part(\s+(\S+))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $jchan = $2; if ($jchan !~ /^$mask{chan}$/) { &msg($who, "error, invalid chan."); - &help("part"); + &help('part'); return; } @@ -228,12 +228,12 @@ sub userDCC { # lobotomy. sometimes we want the bot to be _QUIET_. if ($message =~ /^(lobotomy|bequiet)$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); if ($lobotomized) { &performReply("i'm already lobotomized"); } else { - &performReply("i have been lobotomized"); + &performReply('i have been lobotomized'); $lobotomized = 1; } @@ -242,10 +242,10 @@ sub userDCC { # unlobotomy. if ($message =~ /^(unlobotomy|benoisy)$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); if ($lobotomized) { - &performReply("i have been unlobotomized, woohoo"); + &performReply('i have been unlobotomized, woohoo'); $lobotomized = 0; delete $cache{lobotomy}; # undef $cache{lobotomy}; # ?? @@ -258,7 +258,7 @@ sub userDCC { # op. if ($message =~ /^op(\s+(.*))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my ($opee) = lc $2; my @chans; @@ -305,7 +305,7 @@ sub userDCC { # deop. if ($message =~ /^deop(\s+(.*))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my ($opee) = lc $2; my @chans; @@ -352,41 +352,31 @@ sub userDCC { # say. if ($message =~ s/^say\s+(\S+)\s+(.*)//) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my ($chan,$msg) = (lc $1, $2); &DEBUG("chan => '$1', msg => '$msg'."); - # TODO: add nick destination. - if (&validChan($chan)) { - &msg($chan, $msg); - } else { - &msg($who,"i'm not on \002$chan\002, sorry."); - } + &msg($chan, $msg); return; } # do. if ($message =~ s/^do\s+(\S+)\s+(.*)//) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my ($chan,$msg) = (lc $1, $2); &DEBUG("chan => '$1', msg => '$msg'."); - # TODO: add nick destination. - if (&validChan($chan)) { - &action($chan, $msg); - } else { - &msg($who,"i'm not on \002$chan\002, sorry."); - } + &action($chan, $msg); return; } # die. if ($message =~ /^die$/) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); &doExit(); @@ -397,7 +387,7 @@ sub userDCC { # global factoid substitution. if ($message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$|) { my ($delim,$op,$np) = ($1, $2, $3); - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); ### TODO: support flags to do full-on global. # incorrect format. @@ -408,8 +398,8 @@ sub userDCC { ### TODO: fix up $op to support mysql/sqlite/pgsql ### TODO: => add db/sql specific function to fix this. - my @list = &searchTable("factoids", "factoid_key", - "factoid_value", $op); + my @list = &searchTable('factoids', 'factoid_key', + 'factoid_value', $op); if (!scalar @list) { &performReply("Expression didn't match anything."); @@ -422,7 +412,7 @@ sub userDCC { } &status("gsubst: going to alter ".scalar(@list)." factoids."); - &performReply("going to alter ".scalar(@list)." factoids."); + &performReply('going to alter '.scalar(@list)." factoids."); my $error = 0; foreach (@list) { @@ -440,7 +430,7 @@ sub userDCC { &performReply("that's too long (or was long)"); return; } - &setFactInfo($faqtoid, "factoid_value", $result); + &setFactInfo($faqtoid, 'factoid_value', $result); &status("update: '$faqtoid' =is=> '$result'; was '$was'"); } else { &WARN("subst: that's weird... thought we found the string ($op) in '$faqtoid'."); @@ -453,17 +443,17 @@ sub userDCC { } &performReply("Ok... did s/$op/$np/ for ". - (scalar(@list) - $error)." factoids"); + (scalar(@list) - $error).' factoids'); return; } # jump. if ($message =~ /^jump(\s+(\S+))?$/i) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); - if ($2 eq "") { - &help("jump"); + if ($2 eq '') { + &help('jump'); return; } @@ -486,7 +476,7 @@ sub userDCC { # reload. if ($message =~ /^reload$/i) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); &status("USER reload $who"); &performStrictReply("reloading..."); @@ -498,7 +488,7 @@ sub userDCC { # reset. if ($message =~ /^reset$/i) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); &msg($who,"resetting..."); my @done; @@ -511,26 +501,26 @@ sub userDCC { push(@done, $_); sleep 1; } - &DEBUG("before clearircvars"); + &DEBUG('before clearircvars'); &clearIRCVars(); - &DEBUG("before joinnextchan"); + &DEBUG('before joinnextchan'); &joinNextChan(); - &DEBUG("after joinnextchan"); + &DEBUG('after joinnextchan'); &status("USER reset $who"); - &msg($who,"reset complete"); + &msg($who,'reset complete'); return; } # rehash. if ($message =~ /^rehash$/) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); &msg($who,"rehashing..."); - &restart("REHASH"); + &restart('REHASH'); &status("USER rehash $who"); - &msg($who,"rehashed"); + &msg($who,'rehashed'); return; } @@ -543,7 +533,7 @@ sub userDCC { my @args = split /[\s\t]+/, $2; # hrm. if (scalar @args != 1) { - &help("chaninfo"); + &help('chaninfo'); return; } @@ -578,14 +568,14 @@ sub userDCC { } if (!scalar @chans) { - push(@chans, "_default"); + push(@chans, '_default'); $no_chan = 1; } my($what,$val) = split /[\s\t]+/, $args, 2; ### TODO: "cannot set values without +m". - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); # READ ONLY. if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) { @@ -612,17 +602,17 @@ sub userDCC { } ### TODO: move to UserDCC again. - if ($cmd eq "chanset" and !defined $what) { + if ($cmd eq 'chanset' and !defined $what) { &DEBUG("showing channel conf."); foreach $chan (@chans) { if ($chan eq '_default') { - &performStrictReply("Default channel settings"); + &performStrictReply('Default channel settings'); } else { &performStrictReply("chan: $chan (see _default also)"); } my @items; - my $str = ""; + my $str = ''; foreach (sort keys %{ $chanconf{$chan} }) { my $newstr = join(', ', @items); ### TODO: make length use channel line limit? @@ -652,12 +642,12 @@ sub userDCC { } if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); my $args = $3; my $no_chan = 0; if (!defined $args) { - &help("chanunset"); + &help('chanunset'); return; } @@ -668,7 +658,7 @@ sub userDCC { $delete = ($1) ? 1 : 0; } else { &VERB("no chan arg; setting to default.",2); - $chan = "_default"; + $chan = '_default'; $no_chan = 1; } @@ -677,7 +667,7 @@ sub userDCC { return; } - if ($args ne "") { + if ($args ne '') { if (!&getChanConf($args,$chan)) { &performStrictReply("$args does not exist for $chan"); @@ -686,7 +676,7 @@ sub userDCC { my @chans = &ChanConfList($args); &DEBUG("scalar chans => ".scalar(@chans) ); - if (scalar @chans == 1 and $chans[0] eq "_default" and !$no_chan) { + if (scalar @chans == 1 and $chans[0] eq '_default' and !$no_chan) { &performStrictReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans."); my $val = $chanconf{$_}{_default}; @@ -740,7 +730,7 @@ sub userDCC { my(@args) = split /[\s\t]+/, $2 || ''; if (scalar @args != 1) { - &help("newpass"); + &help('newpass'); return; } @@ -760,7 +750,7 @@ sub userDCC { my(@args) = split /[\s\t]+/, $2 || ''; if (!scalar @args) { - &help("chpass"); + &help('chpass'); return; } @@ -777,7 +767,7 @@ sub userDCC { if (scalar @args == 1) { # del pass. - if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) { &performStrictReply("cannot remove passwd of others."); return; } @@ -811,7 +801,7 @@ sub userDCC { my(@args) = split /[\s\t]+/, $2 || ''; if (!scalar @args) { - &help("chattr"); + &help('chattr'); return; } @@ -842,9 +832,9 @@ sub userDCC { &DEBUG("who => $who"); &DEBUG("verifyUser => $verifyUser"); - if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) { &performStrictReply("cannto change attributes of others."); - return "REPLY"; + return 'REPLY'; } my $state; @@ -862,7 +852,7 @@ sub userDCC { next if ($flags =~ /\Q$_\E/); $flags .= $_; } else { - if (&IsParam("owner") + if (&IsParam('owner') and $param{owner} =~ /^\Q$user\E$/i and $flags =~ /[nmo]/ ) { @@ -892,13 +882,13 @@ sub userDCC { if ($message =~ /^chnick(\s+(.*))?$/) { my(@args) = split /[\s\t]+/, $2 || ''; - if ($who eq "_default") { + if ($who eq '_default') { &WARN("$who or verifyuser tried to run chnick."); - return "REPLY"; + return 'REPLY'; } if (!scalar @args or scalar @args > 2) { - &help("chnick"); + &help('chnick'); return; } @@ -927,9 +917,9 @@ sub userDCC { return; } - if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) { &performStrictReply("cannto change nick of others."); - return "REPLY" if ($who eq "_default"); + return 'REPLY' if ($who eq '_default'); return; } @@ -948,7 +938,7 @@ sub userDCC { } if ($message =~ /^([-+])host(\s+(.*))?$/) { - my $cmd = $1."host"; + my $cmd = $1.'host'; my(@args) = split /[\s\t]+/, $3 || ''; my $state = ($1 eq "+") ? 1 : 0; @@ -957,14 +947,14 @@ sub userDCC { return; } - if ($who eq "_default") { + if ($who eq '_default') { &WARN("$who or verifyuser tried to run $cmd."); - return "REPLY"; + return 'REPLY'; } my ($user,$mask); if ($args[0] =~ /^$mask{nick}$/i) { # - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); $user = &getUser($args[0]); $mask = $args[1]; } else { # @@ -979,11 +969,11 @@ sub userDCC { } if (!defined $mask) { - &performStrictReply("Hostmasks for $user: " . join(" ", keys %{$users{$user}{HOSTS}})); + &performStrictReply("Hostmasks for $user: " . join(' ', keys %{$users{$user}{HOSTS}})); return; } - if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) { &performStrictReply("cannto change masks of others."); return; } @@ -1031,7 +1021,7 @@ sub userDCC { } if ($message =~ /^([-+])ban(\s+(.*))?$/) { - my $cmd = $1."ban"; + my $cmd = $1.'ban'; my $flatarg = $3; my(@args) = split /[\s\t]+/, $3 || ''; my $state = ($1 eq "+") ? 1 : 0; @@ -1052,7 +1042,7 @@ sub userDCC { if ($flatarg =~ s/^($mask{chan})\s*//) { $chan = $1; } else { - $chan = "*"; # _default instead? + $chan = '*'; # _default instead? } if ($state == 0) { # delete. @@ -1091,7 +1081,7 @@ sub userDCC { $reason = $1; } - if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) { &performStrictReply("cannto change masks of others."); return; } @@ -1113,7 +1103,7 @@ sub userDCC { my $arg = $2; if (!defined $arg) { - &help("whois"); + &help('whois'); return; } @@ -1128,7 +1118,7 @@ sub userDCC { foreach (keys %{ $users{$user} }) { my $ref = ref $users{$user}{$_}; - if ($ref eq "HASH") { + if ($ref eq 'HASH') { my $type = $_; ### DOES NOT WORK??? foreach (keys %{ $users{$user}{$type} }) { @@ -1148,7 +1138,7 @@ sub userDCC { my $arg = $2; if (defined $arg) { - if ($arg ne "_default" and !&validChan($arg) ) { + if ($arg ne '_default' and !&validChan($arg) ) { &performStrictReply("error: chan $chan is invalid."); return; } @@ -1168,7 +1158,7 @@ sub userDCC { foreach (keys %{ $bans{$c} }) { my $val = $bans{$c}{$_}; - if (ref $val eq "ARRAY") { + if (ref $val eq 'ARRAY') { my @array = @{ $val }; &performStrictReply(" $_: @array"); } else { @@ -1201,11 +1191,11 @@ sub userDCC { } if ($message =~ /^save$/) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); &writeUserFile(); &writeChanFile(); - &performStrictReply("saved user and chan files"); + &performStrictReply('saved user and chan files'); return; } @@ -1216,9 +1206,9 @@ sub userDCC { # ignore. if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $state = ($1 eq "+") ? 1 : 0; - my $str = $1."ignore"; + my $str = $1.'ignore'; my $args = $3; if (!$args) { @@ -1253,7 +1243,7 @@ sub userDCC { if ($args =~ s/^($mask{chan}|\*)\s*//) { $chan = $1; } else { - $chan = "*"; + $chan = '*'; } # time. @@ -1310,7 +1300,7 @@ sub userDCC { foreach (keys %{ $ignore{$c} }) { my $ref = ref $ignore{$c}{$_}; - if ($ref eq "ARRAY") { + if ($ref eq 'ARRAY') { my @array = @{ $ignore{$c}{$_} }; &performStrictReply(" $_: @array"); } else { @@ -1326,7 +1316,7 @@ sub userDCC { # adduser/deluser. if ($message =~ /^(add|del)user(\s+(.*))?$/i) { my $str = $1; - my $strstr = $1."user"; + my $strstr = $1.'user'; my @args = split /\s+/, $3 || ''; my $args = $3; my $state = ($str =~ /^(add)$/) ? 1 : 0; @@ -1412,7 +1402,7 @@ sub userDCC { my @time; foreach (sort { $a <=> $b } keys %time) { - my $str = join(", ", sort keys %{ $time{$_} }); + my $str = join(', ', sort keys %{ $time{$_} }); &DEBUG("time => $_, str => $str"); push(@time, "$str (".&Time2String($_).")"); } @@ -1425,7 +1415,7 @@ sub userDCC { } # quite a cool hack: reply in DCC CHAT. - $msgType = "chat" if (exists $dcc{'CHAT'}{$who}); + $msgType = 'chat' if (exists $dcc{'CHAT'}{$who}); my $done = 0; $done++ if &parseCmdHook($message); @@ -1436,7 +1426,9 @@ sub userDCC { return; } - return "REPLY"; + return 'REPLY'; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/UserInfo.pl b/src/Modules/UserInfo.pl index e35373b..a172d47 100644 --- a/src/Modules/UserInfo.pl +++ b/src/Modules/UserInfo.pl @@ -9,13 +9,13 @@ use strict; -my $orderOfInfo = "RN,J,C,W,D"; +my $orderOfInfo = 'RN,J,C,W,D'; my %infoDesc = ( - "RN" => "Real Name", - "J" => "Occupation", - "C" => "Contact", - "W" => "URL", - "D" => "Description", + 'RN' => 'Real Name', + 'J' => 'Occupation', + 'C' => 'Contact', + 'W' => 'URL', + 'D' => 'Description', ); sub UserInfo2Hash { @@ -61,7 +61,7 @@ sub UserInfoGet { } my $result; - if ($result = &getFactoid($query." info")) { + if ($result = &getFactoid($query.' info')) { # good. } else { # bad. &performReply("No User Information on \002$query\002"); @@ -160,7 +160,7 @@ sub UserInfoSet { $userInfo{$info} = $what; } - &setFactInfo($who." info", "factoid_value", &Hash2UserInfo(%userInfo)); + &setFactInfo($who.' info', 'factoid_value', &Hash2UserInfo(%userInfo)); if ($new) { &DEBUG("UIS: locking '$who info'."); &DEBUG("UIS: nuh => '$nuh'."); @@ -170,3 +170,5 @@ sub UserInfoSet { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/W3Search.pl b/src/Modules/W3Search.pl index eee5ff0..26af692 100644 --- a/src/Modules/W3Search.pl +++ b/src/Modules/W3Search.pl @@ -7,7 +7,7 @@ package W3Search; use strict; use vars qw(@W3Search_engines $W3Search_regex); @W3Search_engines = qw(AltaVista Dejanews Excite Gopher HotBot Infoseek - Lycos Magellan PLweb SFgate Simple Verity Google); + Lycos Magellan PLweb SFgate Simple Verity Google z); $W3Search_regex = join '|', @W3Search_engines; my $maxshow = 5; @@ -28,42 +28,37 @@ sub W3Search { return unless &::loadPerlModule("WWW::Search"); eval { - if ($where eq 'Google') { - # key is your Google API key. - # Get it from http://api.google.com/createkey - $Search = new WWW::Search('Google',key => '') - } - else { - $Search = new WWW::Search($where); - } - if (!defined $Search) { - &::msg($::who, "$where is invalid search."); - return; + $Search = new WWW::Search($where, agent_name => 'Mozilla/4.5'); + }; + + if (!defined $Search) { + &::msg($::who, "$where is invalid search."); + return; + } + + my $Query = WWW::Search::escape_query($what); + $Search->native_query($Query, + { + num => 10, +# search_debug => 2, +# search_parse_debug => 2, } - - my $Query = WWW::Search::escape_query($what); - $Search->native_query($Query,{ num => 10, - search_debug => 2, - search_parse_debug => 2, - } - ); - $Search->http_proxy($::param{'httpProxy'}) if (&::IsParam("httpProxy")); - #my $max = $Search->maximum_to_retrieve(10); # DOES NOT WORK. + ); + $Search->http_proxy($::param{'httpProxy'}) if (&::IsParam('httpProxy')); + #my $max = $Search->maximum_to_retrieve(10); # DOES NOT WORK. - my (@results, $count, $r); - $count=0; + my (@results, $count, $r); $retval = "$where says \002$what\002 is at "; - while ($r = $Search->next_result()) { - my $url = $r->url(); - $retval .= ' or ' if ($count > 0); - $retval .= $url; - last if ++$count >= $maxshow; - } - - $retval = "$where was unable to find any results for \002$what\002" unless $count > 0; - - &::performStrictReply($retval); + while ($r = $Search->next_result()) { + my $url = $r->url(); + $retval .= ' or ' if ($count > 0); + $retval .= $url; + last if ++$count >= $maxshow; } -} + + &::performStrictReply($retval); +} + 1; - + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Weather.pl b/src/Modules/Weather.pl index ecf37cf..d6a2f80 100644 --- a/src/Modules/Weather.pl +++ b/src/Modules/Weather.pl @@ -51,7 +51,7 @@ sub queryText { } my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(10); my $request = new HTTP::Request('GET', "http://weather.noaa.gov/weather/current/$station.html"); @@ -64,7 +64,7 @@ sub queryText { . " or http://www.nws.noaa.gov/tg/siteloc.shtml" . " for ICAO locations codes)."; } else { - return "Something failed in connecting to the NOAA web" + return 'Something failed in connecting to the NOAA web' . " server. Try again later."; } } @@ -105,7 +105,7 @@ sub queryText { if ($time) { if ($wxmode eq 'metar' && defined($feat{'ob'})) { - return ("METAR " . $place . ": " . $feat{'ob'}); + return ('METAR ' . $place . ": " . $feat{'ob'}); } $result = "$place; $id; last updated: $time"; @@ -132,6 +132,8 @@ if (0) { 1; +# vim:ts=4:sw=4:expandtab:tw=80 + __END__ =head1 NAME diff --git a/src/Modules/Wingate.pl b/src/Modules/Wingate.pl index bb93593..ae3e973 100644 --- a/src/Modules/Wingate.pl +++ b/src/Modules/Wingate.pl @@ -12,7 +12,7 @@ use strict; my $select = IO::Select->new; sub Wingates { - my $file = "$::blootbot_base_dir/$::param{'ircUser'}.wingate"; + my $file = "$::infobot_base_dir/$::param{'ircUser'}.wingate"; my @hosts; open(IN, $file); @@ -73,7 +73,7 @@ sub Wingate { &::status("Wingate: RUNNING ON $host BY $::who."); if (&::IsChanConf('wingateBan') > 0) { - &::ban("*!*\@$host", ""); + &::ban("*!*\@$host", ''); } my $reason = &::getChanConf('wingateKick'); @@ -96,3 +96,5 @@ sub Wingate { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/Zippy.pl b/src/Modules/Zippy.pl index d496537..fbddb76 100644 --- a/src/Modules/Zippy.pl +++ b/src/Modules/Zippy.pl @@ -13,7 +13,7 @@ my $no_zippy; # Can't think of any situation in which this won't work.. sub zippy::get { my @yows; - &::DEBUG("Reading zippy data"); + &::DEBUG('Reading zippy data'); while () { chomp; push @yows, $_; @@ -31,6 +31,8 @@ sub zippy::get { 1; +# vim:ts=4:sw=4:expandtab:tw=80 + =pod =head1 NAME diff --git a/src/Modules/babelfish.pl b/src/Modules/babelfish.pl index 850292b..fcefe4e 100644 --- a/src/Modules/babelfish.pl +++ b/src/Modules/babelfish.pl @@ -63,7 +63,7 @@ sub babelfishParam { $to = $lang_code{$to}; my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); # Let's pretend $ua->agent("Mozilla/5.0 " . $ua->agent); $ua->timeout(5); @@ -145,3 +145,5 @@ if (0) { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/botmail.pl b/src/Modules/botmail.pl index 846d611..587cc55 100644 --- a/src/Modules/botmail.pl +++ b/src/Modules/botmail.pl @@ -15,7 +15,7 @@ sub parse { my($what) = @_; if (!defined $what or $what =~ /^\s*$/) { - &::help("botmail"); + &::help('botmail'); return; } @@ -36,8 +36,8 @@ sub parse { } sub stats { - my $botmail = &::countKeys("botmail"); - &::msg($::who, "I have \002$botmail\002 ". &::fixPlural("message", $botmail). "."); + my $botmail = &::countKeys('botmail'); + &::msg($::who, "I have \002$botmail\002 ". &::fixPlural('message', $botmail). "."); } ##### @@ -46,7 +46,7 @@ sub check { my($recipient, $always) = @_; $recipient ||= $::who; - my %from = &::sqlSelectColHash("botmail", "srcwho,time", { + my %from = &::sqlSelectColHash('botmail', "srcwho,time", { dstwho => lc $recipient } ); my $t = keys %from; @@ -64,7 +64,7 @@ sub check { sub next { my($recipient) = @_; - my %hash = &::sqlSelectRowHash("botmail", "*", { + my %hash = &::sqlSelectRowHash('botmail', '*', { dstwho => lc $recipient } ); @@ -75,7 +75,7 @@ sub next { my $ago = &::Time2String(time() - $hash{'time'}); &::msg($recipient, "From $hash{srcwho} ($hash{srcuh}) on $date ($ago ago):"); &::msg($recipient, $hash{'msg'}); - &::sqlDelete("botmail", { 'dstwho'=>$hash{dstwho}, 'srcwho'=>$hash{srcwho}}); + &::sqlDelete('botmail', { 'dstwho'=>$hash{dstwho}, 'srcwho'=>$hash{srcwho}}); } } @@ -90,9 +90,10 @@ sub add { # only support 1 botmail with unique dstwho/srcwho to have same # functionality as botmail from infobot. - my %hash = &::sqlSelectRowHash("botmail", "*", { - srcwho => &::sqlQuote(lc $::who), - dstwho => &::sqlQuote(lc $recipient) + # Note: I removed the &::sqlQuote reference. Seems to be working and inserting fine without it here. -- troubled + my %hash = &::sqlSelectRowHash('botmail', '*', { + srcwho => lc $::who, + dstwho => lc $recipient } ); if (scalar (keys %hash) > 1) { @@ -100,7 +101,7 @@ sub add { return; } - &::sqlReplace("botmail", { + &::sqlInsert('botmail', { 'dstwho' => lc $recipient, 'srcwho' => lc $::who, 'srcuh' => $::nuh, @@ -112,3 +113,5 @@ sub add { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/case.pl b/src/Modules/case.pl index c41937c..0d5c932 100644 --- a/src/Modules/case.pl +++ b/src/Modules/case.pl @@ -9,7 +9,8 @@ package case; sub upper { my($message) = @_; - &::performStrictReply(uc $message); + # make it green like an old terminal + &::performStrictReply("\00303" . uc $message); } sub lower { @@ -18,3 +19,5 @@ sub lower { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/countdown.pl b/src/Modules/countdown.pl index 912a463..60abd6a 100644 --- a/src/Modules/countdown.pl +++ b/src/Modules/countdown.pl @@ -93,3 +93,5 @@ sub countdown { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/dice.pl b/src/Modules/dice.pl index 7783618..ebcd0b4 100755 --- a/src/Modules/dice.pl +++ b/src/Modules/dice.pl @@ -191,3 +191,5 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =cut + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/dns.pl b/src/Modules/dns.pl index 415444d..1893b3a 100644 --- a/src/Modules/dns.pl +++ b/src/Modules/dns.pl @@ -51,4 +51,5 @@ sub dns::query { } 1; -# vim: ts=2 sw=2 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/hex2ip.pl b/src/Modules/hex2ip.pl new file mode 100644 index 0000000..6ac4585 --- /dev/null +++ b/src/Modules/hex2ip.pl @@ -0,0 +1,44 @@ +# +# hex2ip.pl: Convert hex gateway idents to an IP (eg:ABCDEF12) +# Author: Dan McGrath +# 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 diff --git a/src/Modules/insult.pl b/src/Modules/insult.pl index e39fbcc..57acc2d 100644 --- a/src/Modules/insult.pl +++ b/src/Modules/insult.pl @@ -14,12 +14,12 @@ sub Insult { my @adjs; my @amts; my @nouns; - &::DEBUG("Reading insult data"); + &::DEBUG('Reading insult data'); while () { chomp; - push(@adjs, split(" ", $1)) if /^adj\s*(.*)/; - push(@amts, split(" ", $1)) if /^amt\s*(.*)/; - push(@nouns, split(" ", $1)) if /^noun\s*(.*)/; + push(@adjs, split(' ', $1)) if /^adj\s*(.*)/; + push(@amts, split(' ', $1)) if /^amt\s*(.*)/; + push(@nouns, split(' ', $1)) if /^noun\s*(.*)/; } grep(s/\|/ /g, @adjs); grep(s/\|/ /g, @amts); @@ -32,13 +32,15 @@ sub Insult { my $adj2 = @adjs[rand(@adjs)]; my $noun = @nouns[rand(@nouns)]; my $whois = "$insultwho is"; - $whois = "You are" if ($insultwho eq $::who or $insultwho eq "me"); + $whois = 'You are' if ($insultwho eq $::who or $insultwho eq 'me'); &::performStrictReply("$whois nothing but a$n $adj $amt of $adj2 $noun"); } 1; +# vim:ts=4:sw=4:expandtab:tw=80 + __DATA__ # # configuration file for colorado insult server diff --git a/src/Modules/md5.pl b/src/Modules/md5.pl index 440e603..d32cf83 100644 --- a/src/Modules/md5.pl +++ b/src/Modules/md5.pl @@ -9,9 +9,11 @@ package md5; sub md5 { my($message) = @_; - return unless &::loadPerlModule("Digest::MD5"); + return unless &::loadPerlModule('Digest::MD5'); &::performStrictReply(&Digest::MD5::md5_hex($message)); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/nickometer.pl b/src/Modules/nickometer.pl index 881153e..b5790e3 100644 --- a/src/Modules/nickometer.pl +++ b/src/Modules/nickometer.pl @@ -46,7 +46,7 @@ sub query { ### TODO: compact with map? my @list; foreach (sort {$b <=> $a} keys %nickometer) { - my $str = join(", ", sort keys %{ $nickometer{$_} }); + my $str = join(', ', sort keys %{ $nickometer{$_} }); push(@list, "$str ($_%)"); } @@ -58,7 +58,7 @@ sub query { my $percentage = &nickometer($term); if ($percentage =~ /NaN/) { - $percentage = "off the scale"; + $percentage = 'off the scale'; } else { $percentage = sprintf("%0.4f", $percentage); $percentage =~ s/(\.\d+)0+$/$1/; @@ -143,7 +143,7 @@ sub nickometer ($) { $text =~ s/^([^\[\]]*) (\[) (.*) (\]) ([^\[\]]*) $/$1$3$5/x) { print "Removed $2$4 outside parentheses; nick now $_\n" if $verbose; - &punish(15, "brackets"); + &punish(15, 'brackets'); } my $parentheses = $text =~ tr/(){}[]/(){}[]/; &punish(&slow_pow(10, $parentheses), @@ -267,3 +267,5 @@ sub punish ($$) { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/pager.pl b/src/Modules/pager.pl index 3d21175..6ebd76c 100644 --- a/src/Modules/pager.pl +++ b/src/Modules/pager.pl @@ -64,14 +64,14 @@ sub pager::page { } my $channel = $::chan || 'infobot'; - # TODO disallow use from private message? $chan="_default" + # TODO disallow use from private message? $chan='_default' &::status("pager: from $from <$fromaddr>, to $to <$toaddr>, msg \"$msg\""); my %headers = ( To => "$to <$toaddr>", From => "$from <$fromaddr>", Subject => "Message from $channel!", - 'X-Mailer' => "blootbot", + 'X-Mailer' => 'infobot', ); # my $logmsg; @@ -98,5 +98,6 @@ sub pager::page { &::performStrictReply($retval); } -"pager"; -# vim: ts=2 sw=2 +'pager'; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/piglatin.pl b/src/Modules/piglatin.pl index d15135b..7e1bcd4 100644 --- a/src/Modules/piglatin.pl +++ b/src/Modules/piglatin.pl @@ -14,7 +14,7 @@ sub piglatin # FIXME: does not handle: # non-trailing punctuation and hyphens - # y as vowel "style" -> "ylestay" + # y as vowel 'style' -> 'ylestay' # contractions for my $word (split /\s+/, $text) { my ($pigword, $postfix); @@ -40,3 +40,5 @@ sub piglatin } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/reverse.pl b/src/Modules/reverse.pl index a6e2fd6..5a82310 100644 --- a/src/Modules/reverse.pl +++ b/src/Modules/reverse.pl @@ -9,7 +9,9 @@ package reverse; sub reverse { my($message) = @_; - &::performStrictReply(join("",reverse(split("",$message)))); + &::performStrictReply(join('',reverse(split('',$message)))); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/scramble.pl b/src/Modules/scramble.pl index fbe91c5..96fce80 100644 --- a/src/Modules/scramble.pl +++ b/src/Modules/scramble.pl @@ -44,7 +44,7 @@ sub scramble } # shuffle the middle letters - $new_middle = join "", List::Util::shuffle(split //, $middle); + $new_middle = join '', List::Util::shuffle(split //, $middle); } while (($cnt < 10) && ($middle eq $new_middle)); @@ -56,7 +56,9 @@ sub scramble # been included in the original string $scrambled =~ s/\s+$//; - &::performStrictReply($scrambled||"Unknown Error Condition"); + &::performStrictReply($scrambled||'Unknown Error Condition'); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/slashdot.pl b/src/Modules/slashdot.pl index 7b94b09..297af5b 100644 --- a/src/Modules/slashdot.pl +++ b/src/Modules/slashdot.pl @@ -37,7 +37,7 @@ sub Slashdot { my $retval = "i could not get the headlines."; if (scalar @results) { - my $prefix = "Slashdot Headlines "; + my $prefix = 'Slashdot Headlines '; my @list = &slashdotParse(@results); $retval = &::formListReply(0, $prefix, @list); } @@ -101,3 +101,5 @@ sub slashdotAnnounce { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/spell.pl b/src/Modules/spell.pl index f6ff889..f8d38bd 100644 --- a/src/Modules/spell.pl +++ b/src/Modules/spell.pl @@ -15,7 +15,7 @@ use strict; sub spell::spell { my $query = shift; if ($query =~ m/[^[:alpha:]]/) { - return("only one word of alphabetic characters supported"); + return('only one word of alphabetic characters supported'); } my $binary; @@ -33,11 +33,11 @@ sub spell::spell { } if (!$binary) { - return("no binary found."); + return('no binary found.'); } if (!&::validExec($query)) { - return("argument appears to be fuzzy."); + return('argument appears to be fuzzy.'); } my $reply = "I can't find alternate spellings for '$query'"; @@ -77,4 +77,5 @@ sub spell::query { } 1; -# vim: ts=2 sw=2 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/wikipedia.pl b/src/Modules/wikipedia.pl index 9117b87..52cc05c 100644 --- a/src/Modules/wikipedia.pl +++ b/src/Modules/wikipedia.pl @@ -1,4 +1,4 @@ -# This program is distributed under the same terms as blootbot. +# This program is distributed under the same terms as infobot. package wikipedia; use strict; @@ -50,7 +50,7 @@ sub wikipedia_lookup { &::DEBUG("wikipedia($phrase)"); my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); # Let's pretend $ua->agent("Mozilla/5.0 " . $ua->agent); $ua->timeout(5); @@ -137,7 +137,7 @@ sub wikipedia_lookup { #$text = substr($text, 0, 330); #$text =~ s/(.+)\.([^.]*)$/$1./g; - return("At " . $url . " (URL), Wikipedia explains: " . $text, + return('At ' . $url . " (URL), Wikipedia explains: " . $text, 1); } } @@ -150,7 +150,7 @@ sub wikipedia_get_text { &::DEBUG("wikipedia_get_text($article)"); my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); # Let's pretend $ua->agent("Mozilla/5.0 " . $ua->agent); $ua->timeout(5); @@ -174,19 +174,19 @@ sub wikipedia_get_text { } elsif (/#REDIRECT\s*\[\[(.*?)\]\]/i) { $redirect = $1; $redirect =~ tr/ /_/; - &::DEBUG("wiki redirect to " . $redirect); + &::DEBUG('wiki redirect to ' . $redirect); last; } elsif (/]*>(.*)/) { $text = '"' . $1; } elsif (/(.*)<\/text>/) { - $text = $text . " " . $1 . '"'; + $text = $text . ' ' . $1 . '"'; last; } elsif ($text) { - $text = $text . " " . $_; + $text = $text . ' ' . $_; } } &::DEBUG("wikipedia returned text: " . $text . - ", redirect " . $redirect. "\n"); + ', redirect ' . $redirect. "\n"); if (!$redirect and !$text) { return ($res->as_string); @@ -198,3 +198,5 @@ sub wikipedia_get_text { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/wtf.pl b/src/Modules/wtf.pl index e654f36..f79da4f 100644 --- a/src/Modules/wtf.pl +++ b/src/Modules/wtf.pl @@ -35,7 +35,7 @@ sub wtf::wtf { return("argument appears to be fuzzy."); } - my $reply =""; + my $reply =''; foreach (`$binary '$query' 2>&1`){ $reply .= $_; } @@ -50,4 +50,5 @@ sub wtf::query { } 1; -# vim: ts=2 sw=2 + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/zfi.pl b/src/Modules/zfi.pl index 103f56f..13cc5ef 100644 --- a/src/Modules/zfi.pl +++ b/src/Modules/zfi.pl @@ -45,7 +45,7 @@ sub queryText { my $res_return = 5; my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(10); @@ -101,5 +101,6 @@ sub query { } 1; -# vim: shiftwidth=2 tabstop=2 __END__ + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Modules/zsi.pl b/src/Modules/zsi.pl index b11c277..41f7d4f 100644 --- a/src/Modules/zsi.pl +++ b/src/Modules/zsi.pl @@ -45,7 +45,7 @@ sub queryText { my $res_return = 5; my $ua = new LWP::UserAgent; - $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam("httpProxy")); + $ua->proxy('http', $::param{'httpProxy'}) if (&::IsParam('httpProxy')); $ua->timeout(10); @@ -101,5 +101,7 @@ sub query { } 1; -# vim: shiftwidth=2 tabstop=2 + +# vim:ts=4:sw=4:expandtab:tw=80 + __END__ diff --git a/src/Net.pl b/src/Net.pl index 035ceba..e1f0910 100644 --- a/src/Net.pl +++ b/src/Net.pl @@ -84,10 +84,10 @@ sub ftpGet { my $delta_time = &timedelta($start_time); if ($delta_time > 0 and $verbose_ftp) { &status(sprintf("FTP: %.02f sec to complete.", $delta_time)); - my ($rateunit,$rate) = ("B", $size / $delta_time); + my ($rateunit,$rate) = ('B', $size / $delta_time); if ($rate > 1024) { $rate /= 1024; - $rateunit = "kB"; + $rateunit = 'kB'; } &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate)); } @@ -153,7 +153,7 @@ sub getURL { return unless &loadPerlModule("LWP::UserAgent"); $ua = new LWP::UserAgent; - $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy"); + $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy'); if (defined $post) { $req = new HTTP::Request('POST',$url); @@ -189,7 +189,7 @@ sub getURLAsFile { } $ua = new LWP::UserAgent; - $ua->proxy('http', $param{'httpProxy'}) if &IsParam("httpProxy"); + $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy'); $req = HTTP::Request->new('GET', $url); &status("getURLAsFile: getting '$url' as '$file'"); $res = $ua->request($req, $file); @@ -205,3 +205,5 @@ sub getURLAsFile { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Process.pl b/src/Process.pl index 36cffd4..f21cb02 100644 --- a/src/Process.pl +++ b/src/Process.pl @@ -36,19 +36,19 @@ sub process { # hack to support channel +o as "+o" in bot user file. # requires +O in user file. # is $who arg lowercase? - if (exists $channels{$chan}{o}{ $orig{who} } && &IsFlag("O") eq "O") { + if (exists $channels{$chan}{o}{ $orig{who} } && &IsFlag('O') eq 'O') { &status("Gave $who/$chan +o (+O)\'ness"); - $users{$userHandle}{FLAGS} .= "o"; + $users{$userHandle}{FLAGS} .= 'o'; } # check if we have our head intact. if ($lobotomized) { - if ($addressed and IsFlag("o") eq "o") { + if ($addressed and IsFlag('o') eq 'o') { my $delta_time = time() - ($cache{lobotomy}{$who} || 0); &msg($who, "give me an unlobotomy.") if ($delta_time > 60*60); $cache{lobotomy}{$who} = time(); } - return 'LOBOTOMY' unless IsFlag("A"); + return 'LOBOTOMY' unless IsFlag('A'); } # talkMethod. @@ -68,8 +68,8 @@ sub process { $2 =~ /^($mask{chan})(\s+(\S+))?/; my($joinchan, $key) = (lc $1, $3); - if ($joinchan eq "") { - &help("join"); + if ($joinchan eq '') { + &help('join'); return; } @@ -78,7 +78,7 @@ sub process { return; } - if (&IsFlag("o") ne "o") { + if (&IsFlag('o') ne 'o') { if (!exists $chanconf{$joinchan}) { &msg($who, "I am not allowed to join $joinchan."); return; @@ -109,7 +109,7 @@ sub process { } if (!scalar @array or scalar @array > 2) { - &help("identify"); + &help('identify'); return; } @@ -151,7 +151,7 @@ sub process { } if (scalar @array != 1) { - &help("pass"); + &help('pass'); return; } @@ -171,7 +171,7 @@ sub process { if ($first) { &performStrictReply("First time user... adding you as Master."); - $users{$who}{FLAGS} = "aemnorst"; + $users{$who}{FLAGS} = 'aemnorst'; } my $crypt = $users{$who}{PASS}; @@ -199,7 +199,7 @@ sub process { } # allowOutsiders. - if (&IsParam("disallowOutsiders") and $msgType =~ /private/i) { + if (&IsParam('disallowOutsiders') and $msgType =~ /private/i) { my $found = 0; foreach (keys %channels) { @@ -262,7 +262,7 @@ sub process { } # customized random message. - my $tmp = (rand() < 0.5) ? ", $who" : ""; + my $tmp = (rand() < 0.5) ? ", $who" : ''; &performStrictReply( &getRandom(keys %{ $lang{'hello'} }) . $tmp ); return; } @@ -298,7 +298,7 @@ sub process { # karma. set... if ($msgType =~ /public/i && $message =~ /^(\S+)(--|\+\+)\s*$/ && - $addressed && &IsChanConfOrWarn("karma") + $addressed && &IsChanConfOrWarn('karma') ) { # to request factoids such as "g++" or "libstdc++", append "?" to the query. my ($term,$inc) = (lc $1,$2); @@ -308,17 +308,15 @@ sub process { return; } - my $karma = &sqlSelect("stats", "counter", - { nick => $term, type => "karma" }) || 0; + my $karma = &sqlSelect('stats', 'counter', + { nick => $term, type => 'karma' }) || 0; if ($inc eq '++') { $karma++; } else { $karma--; } - &sqlReplace("stats", { - nick => $term, - type => "karma", + &sqlSet('stats', {'nick' => $term, type => 'karma', channel => 'PRIVATE'}, { 'time' => time(), counter => $karma, } ); @@ -327,7 +325,7 @@ sub process { } # here's where the external routines get called. - # if they return anything but null, that's the "answer". + # if they return anything but null, that's the 'answer'. if ($addressed) { my $er = &Modules(); if (!defined $er) { @@ -335,7 +333,7 @@ sub process { } # allow administration of bot via messages (default is DCC CHAT only) - if (&IsFlag("A")) { + if (&IsFlag('A')) { &loadMyModule('UserDCC'); $er = &userDCC(); if (!defined $er) { @@ -349,7 +347,7 @@ sub process { } } - if (&IsParam("factoids") and $param{'DBType'} =~ /^(mysql|sqlite(2)?|pgsql)$/i) { + if (&IsParam('factoids') and $param{'DBType'} =~ /^(mysql|sqlite(2)?|pgsql)$/i) { &FactoidStuff(); } elsif ($param{'DBType'} =~ /^none$/i) { return "NO FACTOIDS."; @@ -361,3 +359,5 @@ sub process { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/Shm.pl b/src/Shm.pl index 646c209..73b30fa 100644 --- a/src/Shm.pl +++ b/src/Shm.pl @@ -15,7 +15,7 @@ sub openSHM { my $IPC_PRIVATE = 0; my $size = 2000; - if (&IsParam("noSHM")) { + if (&IsParam('noSHM')) { &status("Shared memory: Disabled. WARNING: bot may become unreliable"); return 0; } @@ -51,7 +51,7 @@ sub shmRead { my $size = 3*80; my $retval = ''; - return '' if (&IsParam("noSHM")); + return '' if (&IsParam('noSHM')); if (shmread($key,$retval,$position,$size)) { #&DEBUG("shmRead($key): $retval"); @@ -73,7 +73,7 @@ sub shmWrite { my $position = 0; my $size = 80*3; - return if (&IsParam("noSHM")); + return if (&IsParam('noSHM')); $shm_keys{$keys}{accessed} = 1; @@ -93,7 +93,7 @@ sub shmWrite { my $read = &shmRead($key); $read =~ s/\0+//g; - if ($read eq "") { + if ($read eq '') { $str = sprintf("%s:%d:%d: ", $param{ircUser}, $bot_pid, time()); } else { $str = $read ."||". $str; @@ -241,8 +241,8 @@ sub shmFlush { return if ($$ != $::bot_pid); # fork protection. if (@_) { - &ScheduleThis(15, "shmFlush"); - return if ($_[0] eq "2"); + &ScheduleThis(15, 'shmFlush'); + return if ($_[0] eq '2'); } my $time; @@ -284,7 +284,9 @@ sub shmFlush { } } - &shmWrite($shm,"") if ($shmmsg ne ""); + &shmWrite($shm,'') if ($shmmsg ne ''); } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/UserExtra.pl b/src/UserExtra.pl index 12ec9c3..3a33008 100644 --- a/src/UserExtra.pl +++ b/src/UserExtra.pl @@ -6,7 +6,7 @@ use strict; use vars qw($message $arg $qWord $verb $lobotomized $who $result $chan $conn $msgType $query $talkchannel $ident $memusage); -use vars qw(%channels %chanstats %cmdstats %count %ircstats %param +use vars qw(%channels %chanstats %cmdstats %count %forked %ircstats %param %cache %mask %userstats); ### hooks get added in CommandHooks.pl. @@ -19,15 +19,16 @@ sub chaninfo { my $chan = lc shift(@_); my $mode; - if ($chan eq "") { # all channels. + if ($chan eq '') { # all channels. my $i = keys %channels; - my $reply = "I'm on \002$i\002 ".&fixPlural("channel",$i); + my $reply = "I'm on \002$i\002 ".&fixPlural('channel',$i); my $tucount = 0; # total user count. my $uucount = 0; # unique user count. + my %chans; my @array; ### line 1. - foreach (sort keys %channels) { + foreach (keys %channels) { if ( /^\s*$/ or / / ) { &status("chanstats: fe channels: chan == NULL."); #&ircCheck(); @@ -35,8 +36,10 @@ sub chaninfo { } next if (/^_default$/); - my $str = sprintf("%s/%d", $_, scalar(keys %{ $channels{$_}{''} })); - push(@array, $str); + $chans{$_} = scalar(keys %{ $channels{$_}{''} }); + } + foreach $chan (sort {$chans{$b} <=> $chans{$a}} keys %chans) { + push(@array, "$chan/" . $chans{$chan}); } &performStrictReply($reply.": ".join(', ', @array)); @@ -57,10 +60,10 @@ sub chaninfo { my $chans = scalar(keys %channels); &performStrictReply( - "i've cached \002$tucount\002 ". &fixPlural("user",$tucount). - ", \002$uucount\002 unique ". &fixPlural("user",$uucount). + "i've cached \002$tucount\002 ". &fixPlural('user',$tucount). + ", \002$uucount\002 unique ". &fixPlural('user',$uucount). ", distributed over \002$chans\002 ". - &fixPlural("channel", $chans)."." + &fixPlural('channel', $chans)."." ); &ircCheck(); @@ -83,7 +86,7 @@ sub chaninfo { push(@array, "\002$int\002 ". &fixPlural($_,$int)); } my $reply = "On \002$chan\002, there ". - &fixPlural("has",scalar(@array)). " been ". + &fixPlural('has',scalar(@array)). " been ". &IJoin(@array); # Step 1b: check channel inconstencies. @@ -107,13 +110,13 @@ sub chaninfo { # Step 2: undef @array; my $type; - foreach ("v","o","") { + foreach ('v','o','') { my $int = scalar(keys %{ $channels{$chan}{$_} }); next unless ($int); - $type = "Voice" if ($_ eq "v"); - $type = "Opped" if ($_ eq "o"); - $type = "Total" if ($_ eq ""); + $type = 'Voice' if ($_ eq 'v'); + $type = 'Opped' if ($_ eq 'o'); + $type = 'Total' if ($_ eq ''); push(@array,"\002$int\002 $type"); } @@ -167,7 +170,7 @@ sub cmdstats { # Factoid extension info. xk++ sub factinfo { my $faqtoid = lc shift(@_); - my $query = ""; + my $query = ''; if ($faqtoid =~ /^\-(\S+)(\s+(.*))$/) { &msg($who,"error: individual factoid info queries not supported as yet."); @@ -184,15 +187,15 @@ sub factinfo { sub factstats { my $type = shift(@_); - &Forker("Factoids", sub { + &Forker('Factoids', sub { &performStrictReply( &CmdFactStats($type) ); } ); } sub karma { my $target = lc( shift || $who ); - my $karma = &sqlSelect("stats", "counter", - { nick => $target, type => "karma" }) || 0; + my $karma = &sqlSelect('stats', 'counter', + { nick => $target, type => 'karma'}) || 0; if ($karma != 0) { &performStrictReply("$target has karma of $karma"); @@ -249,7 +252,7 @@ sub tell { &status("tell: target = $target, query = $query"); - # "intrusive". + # 'intrusive'. # if ($target !~ /^$mask{chan}$/ and !&IsNickInAnyChan($target)) { # &msg($who, "No, $target is not in any of my chans."); # return; @@ -271,7 +274,7 @@ sub tell { # no such factoid. if (!defined $result || $result =~ /^0?$/) { $who = $target; - $msgType = "private"; + $msgType = 'private'; # support command redirection. # recursive cmdHooks aswell :) @@ -316,12 +319,12 @@ sub countryStats { return; } - if ($chan eq "") { + if ($chan eq '') { $chan = $_[0]; } - if ($chan eq "") { - &help("countrystats"); + if ($chan eq '') { + &help('countrystats'); return; } @@ -364,7 +367,7 @@ sub do_countrystats { } # TODO: move this into a scheduler - $msgType = "private"; + $msgType = 'private'; &performStrictReply( &formListReply(0, "Country Stats ", @list) ); delete $cache{countryStats}; @@ -379,13 +382,13 @@ sub userCommands { # conversion: ascii. if ($message =~ /^(asci*|chr) (\d+)$/) { &DEBUG("ascii/chr called ..."); - return unless (&IsChanConfOrWarn("allowConv")); + return unless (&IsChanConfOrWarn('allowConv')); &DEBUG("ascii/chr called"); $arg = $2; $result = chr($arg); - $result = "NULL" if ($arg == 0); + $result = 'NULL' if ($arg == 0); &performReply( sprintf("ascii %s is '%s'", $arg, $result) ); @@ -394,12 +397,12 @@ sub userCommands { # conversion: ord. if ($message =~ /^ord(\s+(.*))$/) { - return unless (&IsChanConfOrWarn("allowConv")); + return unless (&IsChanConfOrWarn('allowConv')); $arg = $2; if (!defined $arg or length $arg != 1) { - &help("ord"); + &help('ord'); return; } @@ -418,11 +421,11 @@ sub userCommands { # hex. if ($message =~ /^hex(\s+(.*))?$/i) { - return unless (&IsChanConfOrWarn("allowConv")); + return unless (&IsChanConfOrWarn('allowConv')); my $arg = $2; if (!defined $arg) { - &help("hex"); + &help('hex'); return; } @@ -442,40 +445,27 @@ sub userCommands { } # crypt. - if ($message =~ /^crypt(\s+(.*))?$/i) { - my @args = split /\s+/, $2; - - if (!scalar @args or scalar @args > 2) { - &help("crypt"); - return; - } - - if (scalar @args == 2) { -# disable cause $1$ will use md5 -# if (length $args[0] != 2) { -# &msg($who, "invalid format..."); -# return; -# } - - &performStrictReply( crypt($args[1], $args[0]) ); + if ($message =~ /^crypt\s+(\S*)?\s*(.*)?$/i) { +&status("crypt: $1:$2:$3"); + if ("$2" ne '') { + &performStrictReply(crypt($2, $1)); } else { - &performStrictReply( &mkcrypt($args[0]) ); + &performStrictReply(&mkcrypt($1)); } - return; } # cycle. if ($message =~ /^(cycle)(\s+(\S+))?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $chan = lc $3; - if ($chan eq "") { + if ($chan eq '') { if ($msgType =~ /public/) { $chan = $talkchannel; &DEBUG("cycle: setting chan to '$chan'."); } else { - &help("cycle"); + &help('cycle'); return; } } @@ -487,7 +477,7 @@ sub userCommands { &msg($chan, "I'm coming back. (courtesy of $who)"); &part($chan); -### &ScheduleThis(5, "getNickInUse") if (@_); +### &ScheduleThis(5, 'getNickInUse') if (@_); &status("Schedule rejoin in 5secs to $chan by $who."); $conn->schedule(5, sub { &joinchan($chan); }); @@ -496,7 +486,7 @@ sub userCommands { # reload. if ($message =~ /^reload$/i) { - return unless (&hasFlag("n")); + return unless (&hasFlag('n')); &status("USER reload $who"); &performStrictReply("reloading..."); @@ -507,21 +497,21 @@ sub userCommands { # redir. if ($message =~ /^redir(\s+(.*))?/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $factoid = $2; if (!defined $factoid) { - &help("redir"); + &help('redir'); return; } my $val = &getFactInfo($factoid, "factoid_value"); - if (!defined $val or $val eq "") { + if (!defined $val or $val eq '') { &msg($who, "error: '$factoid' does not exist."); return; } &DEBUG("val => '$val'."); - my @list = &searchTable("factoids", "factoid_key", + my @list = &searchTable('factoids', "factoid_key", "factoid_value", "^$val\$"); if (scalar @list == 1) { @@ -562,12 +552,12 @@ sub userCommands { my $reply = $3; if (!defined $reply) { - &help("rot13"); + &help('rot13'); return; } my $num = $1 % 26; - my $upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - my $lower="abcdefghijklmnopqrstuvwxyz"; + my $upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + my $lower='abcdefghijklmnopqrstuvwxyz'; my $to=substr($upper,$num).substr($upper,0,$num).substr($lower,$num).substr($lower,0,$num); eval "\$reply =~ tr/$upper$lower/$to/;"; @@ -679,7 +669,7 @@ sub userCommands { my $startString = scalar(gmtime $^T); my $upString = &Time2String(time() - $^T); my ($puser,$psystem,$cuser,$csystem) = times; - my $factoids = &countKeys("factoids"); + my $factoids = &countKeys('factoids'); my $forks = 0; foreach (keys %forked) { $forks += scalar keys %{ $forked{$_} }; @@ -693,20 +683,20 @@ sub userCommands { &performStrictReply( "Since $startString, there have been". " \002$count{'Update'}\002 ". - &fixPlural("modification", $count{'Update'}). + &fixPlural('modification', $count{'Update'}). ", \002$count{'Question'}\002 ". - &fixPlural("question",$count{'Question'}). + &fixPlural('question',$count{'Question'}). ", \002$count{'Dunno'}\002 ". - &fixPlural("dunno",$count{'Dunno'}). + &fixPlural('dunno',$count{'Dunno'}). ", \002$count{'Moron'}\002 ". - &fixPlural("moron",$count{'Moron'}). + &fixPlural('moron',$count{'Moron'}). " and \002$count{'Commands'}\002 ". - &fixPlural("command",$count{'Commands'}). + &fixPlural('command',$count{'Commands'}). ". I have been awake for $upString this session, and ". "currently reference \002$factoids\002 factoids. ". "I'm using about \002$memusage\002 ". "kB of memory. With \002$forks\002 active ". - &fixPlural("fork",$forks). + &fixPlural('fork',$forks). ". Process time user/system $puser/$psystem child $cuser/$csystem" ); @@ -714,9 +704,9 @@ sub userCommands { } # wantNick. xk++ - # FIXME does not try to get nick "back", just switches nicks + # FIXME does not try to get nick 'back', just switches nicks if ($message =~ /^wantNick\s(.*)?$/i) { - return unless (&hasFlag("o")); + return unless (&hasFlag('o')); my $wantnick = lc $1; my $mynick = $conn->nick(); @@ -739,7 +729,7 @@ sub userCommands { my $str = "someone is using nick $wantnick; GHOSTing"; &status($str); &msg($who, $str); - &msg("NickServ", "GHOST $wantnick $param{'nickServ_pass'}"); + &msg('NickServ', "GHOST $wantnick $param{'nickServ_pass'}"); $conn->schedule(5, sub { &status("going to change nick from $mynick to $wantnick after GHOST."); @@ -752,7 +742,9 @@ sub userCommands { return; } - return "CONTINUE"; + return 'CONTINUE'; } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/core.pl b/src/core.pl index ecbcee5..936f31c 100644 --- a/src/core.pl +++ b/src/core.pl @@ -47,8 +47,8 @@ $SIG{'__WARN__'} = 'doWarn'; # initialize variables. $last{buflen} = 0; -$last{say} = ""; -$last{msg} = ""; +$last{say} = ''; +$last{msg} = ''; $userHandle = "_default"; $wingaterun = time(); $firsttime = 1; @@ -78,23 +78,22 @@ $nottime = 0; $notsize = 0; $notcount = 0; ### -$bot_release = "1.3.3"; -if ( -d "CVS" ) { - use POSIX qw(strftime); - $bot_release .= strftime(" cvs (%Y%m%d)", gmtime( (stat("CVS"))[9] ) ); -} -$bot_version = "blootbot $bot_release -- $^O"; -$noreply = "NOREPLY"; +open(VERSION, ' || "(unknown version)"; +chomp($bot_release); +close(VERSION); +$bot_version = "infobot $bot_release -- $^O"; +$noreply = 'NOREPLY'; ########## ### misc commands. ### sub whatInterface { - if (!&IsParam("Interface") or $param{'Interface'} =~ /IRC/) { - return "IRC"; + if (!&IsParam('Interface') or $param{'Interface'} =~ /IRC/) { + return 'IRC'; } else { - return "CLI"; + return 'CLI'; } } @@ -113,7 +112,7 @@ sub doExit { &status("parent caught SIG$sig (pid $$).") if (defined $sig); &status("--- Start of quit."); - $ident ||= "blootbot"; # lame hack. + $ident ||= 'infobot'; # lame hack. &status("Memory Usage: $memusage KiB"); @@ -131,13 +130,13 @@ sub doExit { &sqlCloseDB(); &closeSHM($shm); - if (&IsParam("dumpvarsAtExit")) { + if (&IsParam('dumpvarsAtExit')) { &loadMyModule('DumpVars'); &dumpallvars(); } - &symdumpAll() if (&IsParam("symdumpAtExit")); + &symdumpAll() if (&IsParam('symdumpAtExit')); &closeLog(); - &closeSQLDebug() if (&IsParam("SQLDebug")); + &closeSQLDebug() if (&IsParam('SQLDebug')); &status("--- QUIT."); } else { # child. @@ -158,7 +157,7 @@ sub doWarn { } # Usage: &IsParam($param); -# blootbot.config specific. +# infobot.config specific. sub IsParam { my $param = $_[0]; @@ -206,7 +205,7 @@ sub getChanConfList { &WARN("multiple items found?"); } - if ($chanconf{$chan}{$param} eq "0") { + if ($chanconf{$chan}{$param} eq '0') { $chan{$chan} = -1; } else { $chan{$chan} = 1; @@ -224,7 +223,7 @@ sub IsChanConf { my($param) = shift; # knocked tons of bugs with this! :) - my $debug = 0; # 1 if ($param eq "whatever"); + my $debug = 0; # 1 if ($param eq 'whatever'); if (!defined $param) { &WARN("IsChanConf: param == NULL."); @@ -251,7 +250,7 @@ sub IsChanConf { if (!defined $msgType) { $nomatch++; } else { - $nomatch++ if ($msgType eq ""); + $nomatch++ if ($msgType eq ''); $nomatch++ unless ($msgType =~ /^(public|private)$/i); } @@ -317,7 +316,7 @@ sub getChanConf { if (!defined $chanconf{$c[0]}{$param} and ($c ne '_default')) { return &getChanConf($param, '_default'); } - #&DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"'); + &DEBUG("gCC: $param,$c \"" . $chanconf{$c[0]}{$param} . '"'); return $chanconf{$c[0]}{$param}; } @@ -372,9 +371,9 @@ sub findChanConf { } sub showProc { - my ($prefix) = $_[0] || ""; + my ($prefix) = $_[0] || ''; - if ($^O eq "linux") { + if ($^O eq 'linux') { if (!open(IN, "/proc/$$/status")) { &ERROR("cannot open '/proc/$$/status'."); return; @@ -385,7 +384,7 @@ sub showProc { } close IN; - } elsif ($^O eq "netbsd") { + } elsif ($^O eq 'netbsd') { $memusage = int( (stat "/proc/$$/mem")[7]/1024 ); } elsif ($^O =~ /^(free|open)bsd$/) { @@ -393,11 +392,11 @@ sub showProc { $memusage = $info[20]; } else { - $memusage = "UNKNOWN"; + $memusage = 'UNKNOWN'; return; } - if (defined $memusageOld and &IsParam("DEBUG")) { + if (defined $memusageOld and &IsParam('DEBUG')) { # it's always going to be increase. my $delta = $memusage - $memusageOld; my $str; @@ -428,25 +427,25 @@ sub setup { &status("--- Started logging."); # read. - &loadLang($bot_data_dir. "/blootbot.lang"); + &loadLang($bot_data_dir. "/infobot.lang"); &loadIRCServers(); &readUserFile(); &readChanFile(); &loadMyModulesNow(); # must be after chan file. $shm = &openSHM(); - &openSQLDebug() if (&IsParam("SQLDebug")); + &openSQLDebug() if (&IsParam('SQLDebug')); &sqlOpenDB($param{'DBName'}, $param{'DBType'}, $param{'SQLUser'}, $param{'SQLPass'}); &checkTables(); - &status("Setup: ". &countKeys("factoids") ." factoids."); - &getChanConfDefault("sendPrivateLimitLines", 3, $chan); - &getChanConfDefault("sendPrivateLimitBytes", 1000, $chan); - &getChanConfDefault("sendPublicLimitLines", 3, $chan); - &getChanConfDefault("sendPublicLimitBytes", 1000, $chan); - &getChanConfDefault("sendNoticeLimitLines", 3, $chan); - &getChanConfDefault("sendNoticeLimitBytes", 1000, $chan); + &status("Setup: ". &countKeys('factoids') ." factoids."); + &getChanConfDefault('sendPrivateLimitLines', 3, $chan); + &getChanConfDefault('sendPrivateLimitBytes', 1000, $chan); + &getChanConfDefault('sendPublicLimitLines', 3, $chan); + &getChanConfDefault('sendPublicLimitBytes', 1000, $chan); + &getChanConfDefault('sendNoticeLimitLines', 3, $chan); + &getChanConfDefault('sendNoticeLimitBytes', 1000, $chan); $param{tempDir} =~ s#\~/#$ENV{HOME}/#; @@ -456,7 +455,7 @@ sub setup { sub setupConfig { $param{'VERBOSITY'} = 1; - &loadConfig($bot_config_dir."/blootbot.config"); + &loadConfig($bot_config_dir."/infobot.config"); foreach ( qw(ircNick ircUser ircName DBType tempDir) ) { next if &IsParam($_); @@ -484,7 +483,7 @@ sub setupConfig { } sub startup { - if (&IsParam("DEBUG")) { + if (&IsParam('DEBUG')) { &status("enabling debug diagnostics."); # I thought disabling this reduced memory usage by 1000 KiB. use diagnostics; @@ -502,13 +501,13 @@ sub shutdown { &status("--- shutdown called."); # hack. - $ident ||= "blootbot"; + $ident ||= 'infobot'; - if (!&isFileUpdated("$bot_state_dir/blootbot.users", $wtime_userfile)) { + if (!&isFileUpdated("$bot_state_dir/infobot.users", $wtime_userfile)) { &writeUserFile() } - if (!&isFileUpdated("$bot_state_dir/blootbot.chan", $wtime_chanfile)) { + if (!&isFileUpdated("$bot_state_dir/infobot.chan", $wtime_chanfile)) { &writeChanFile(); } @@ -537,10 +536,10 @@ sub restart { &ircCheck(); # heh, evil! - &DCCBroadcast("-HUP called.","m"); + &DCCBroadcast("-HUP called.",'m'); &shutdown($sig); - &loadConfig($bot_config_dir."/blootbot.config"); - &reloadAllModules() if (&IsParam("DEBUG")); + &loadConfig($bot_config_dir."/infobot.config"); + &reloadAllModules() if (&IsParam('DEBUG')); &setup(); &status("--- End of $sig."); @@ -566,7 +565,7 @@ sub loadConfig { next unless /\S/; my ($set,$key,$val) = split(/\s+/, $_, 3); - if ($set ne "set") { + if ($set ne 'set') { &status("loadConfig: invalid line '$_'."); next; } @@ -585,3 +584,5 @@ sub loadConfig { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/dbi.pl b/src/dbi.pl index c7400b0..9e1a664 100644 --- a/src/dbi.pl +++ b/src/dbi.pl @@ -72,14 +72,19 @@ sub sqlOpenDB { $db = "dbname=$db.sqlite"; } elsif ($type =~ /^pg/i) { $db = "dbname=$db"; - $type = "Pg"; + $type = 'Pg'; } my $dsn = "DBI:$type:$db"; - my $hoststr = ""; + my $hoststr = ''; # SQLHost should be unset for SQLite if (exists $param{'SQLHost'} and $param{'SQLHost'}) { - $dsn .= ":$param{SQLHost}"; + # PostgreSQL requires ";" and keyword 'host'. See perldoc Pg -- troubled + if ($type eq 'Pg') { + $dsn .= ";host=$param{SQLHost}"; + } else { + $dsn .= ":$param{SQLHost}"; + } $hoststr = " to $param{'SQLHost'}"; } # SQLite ignores $user and $pass @@ -105,7 +110,7 @@ sub sqlCloseDB { return 0 unless ($dbh); my $x = $param{SQLHost}; - my $hoststr = ($x) ? " to $x" : ""; + my $hoststr = ($x) ? " to $x" : ''; &status("Closed DBI connection$hoststr."); $dbh->disconnect(); @@ -276,7 +281,7 @@ sub sqlSet { return; } - if (!defined $data_href or ref($data_href) ne "HASH") { + if (!defined $data_href or ref($data_href) ne 'HASH') { &WARN("sqlSet: data_href == NULL."); return; } @@ -309,7 +314,7 @@ sub sqlSet { sub sqlUpdate { my ($table, $data_href, $where_href) = @_; - if (!defined $data_href or ref($data_href) ne "HASH") { + if (!defined $data_href or ref($data_href) ne 'HASH') { &WARN("sqlSet: data_href == NULL."); return 0; } @@ -317,7 +322,7 @@ sub sqlUpdate { my $where = &hashref2where($where_href) if ($where_href); my $update = &hashref2update($data_href) if ($data_href); - &sqlRaw("Update", "UPDATE $table SET $update WHERE $where"); + &sqlRaw('Update', "UPDATE $table SET $update WHERE $where"); return 1; } @@ -326,9 +331,10 @@ sub sqlUpdate { # Usage: &sqlInsert($table, $data_href, $other); sub sqlInsert { my ($table, $data_href, $other) = @_; - # note: if $other == 1, add "DELAYED" to function instead. + # note: if $other == 1, add 'DELAYED' to function instead. + # note: ^^^ doesnt actually do anything lol. Need code to s/1/DELAYED/ below -- troubled - if (!defined $data_href or ref($data_href) ne "HASH") { + if (!defined $data_href or ref($data_href) ne 'HASH') { &WARN("sqlInsert: data_href == NULL."); return; } @@ -344,18 +350,18 @@ sub sqlInsert { &sqlRaw("Insert($table)", sprintf( "INSERT %s INTO %s (%s) VALUES (%s)", - ($other || ""), $table, join(',',@k), join(',',@v) + ($other || ''), $table, join(',',@k), join(',',@v) ) ); return 1; } ##### -# Usage: &sqlReplace($table, $data_href); +# Usage: &sqlReplace($table, $data_href, [$pkey]); sub sqlReplace { - my ($table, $data_href) = @_; + my ($table, $data_href, $pkey) = @_; - if (!defined $data_href or ref($data_href) ne "HASH") { + if (!defined $data_href or ref($data_href) ne 'HASH') { &WARN("sqlReplace: data_href == NULL."); return; } @@ -369,10 +375,29 @@ sub sqlReplace { return; } - &sqlRaw("Replace($table)", sprintf( - "REPLACE INTO %s (%s) VALUES (%s)", - $table, join(',',@k), join(',',@v) - ) ); + + if ($param{'DBType'} =~ /^pgsql$/i) { + # OK, heres the scoop. There is currently no REPLACE INTO in Pgsql. + # However, the bot already seems to search for factoids before insert + # anyways. Perhaps we could change this to a generic INSERT INTO so + # we can skip the seperate sql? -- troubled to: TimRiker + # PGSql syntax: UPDATE table SET key = 'value', key2 = 'value2' WHERE key = 'value' + +# &sqlRaw("Replace($table)", sprintf( +# "INSERT INTO %s (%s) VALUES (%s)", +# $table, join(',',@k), join(',',@v) +# )); + &WARN("DEBUG: ($pkey = ) " . sprintf( + "REPLACE INTO %s (%s) VALUES (%s)", + $table, join(',',@k), join(',',@v) + )); + + } else { + &sqlRaw("Replace($table)", sprintf( + "REPLACE INTO %s (%s) VALUES (%s)", + $table, join(',',@k), join(',',@v) + )); + } return 1; } @@ -382,14 +407,14 @@ sub sqlReplace { sub sqlDelete { my ($table, $where_href) = @_; - if (!defined $where_href or ref($where_href) ne "HASH") { + if (!defined $where_href or ref($where_href) ne 'HASH') { &WARN("sqlDelete: where_href == NULL."); return; } my $where = &hashref2where($where_href); - &sqlRaw("Delete", "DELETE FROM $table WHERE $where"); + &sqlRaw('Delete', "DELETE FROM $table WHERE $where"); return 1; } @@ -469,7 +494,7 @@ sub hashref2where { return; } - if (ref($href) ne "HASH") { + if (ref($href) ne 'HASH') { &WARN("hashref2where: href is not HASH ref (href => $href)"); return; } @@ -492,7 +517,7 @@ sub hashref2where { sub hashref2update { my ($href) = @_; - if (ref($href) ne "HASH") { + if (ref($href) ne 'HASH') { &WARN("hashref2update: href is not HASH ref."); return; } @@ -518,7 +543,7 @@ sub hashref2update { sub hashref2array { my ($href) = @_; - if (ref($href) ne "HASH") { + if (ref($href) ne 'HASH') { &WARN("hashref2update: href is not HASH ref."); return; } @@ -546,7 +571,7 @@ sub hashref2array { # Usage: &countKeys($table, [$col]); sub countKeys { my ($table, $col) = @_; - $col ||= "*"; + $col ||= '*'; return (&sqlRawReturn("SELECT count($col) FROM $table"))[0]; } @@ -627,18 +652,20 @@ sub searchTable { } sub sqlCreateTable { - my($table) = @_; + my($table, $dbtype) = @_; my(@path) = ($bot_data_dir, ".","..","../.."); my $found = 0; my $data; + $dbtype = lc $dbtype; foreach (@path) { - my $file = "$_/setup/$table.sql"; + my $file = "$_/setup/$dbtype/$table.sql"; next unless ( -f $file ); open(IN, $file); while () { chop; + next if $_ =~ /^--/; $data .= $_; } @@ -686,6 +713,31 @@ sub checkTables { } # create database not needed for SQLite + + } elsif ($param{DBType} =~ /^pgsql$/i) { + # $sql_showDB = SQL to select the DB list + # $sql_showTBL = SQL to select all tables for the current connection + + my $sql_showDB = "SELECT datname FROM pg_database"; + my $sql_showTBL = "SELECT tablename FROM pg_tables \ + WHERE schemaname = 'public'"; + + foreach ( &sqlRawReturn($sql_showDB) ) { + $database_exists++ if ($_ eq $param{'DBName'}); + } + + unless ($database_exists) { + &status("Creating PostgreSQL database $param{'DBName'}"); + &status("(actually, not really, please read the INSTALL file)"); + } + + # retrieve a list of db's from the server. This code is from mysql above, please check -- troubled + my @tables = map {s/^\`//; s/\`$//; $_;} &sqlRawReturn($sql_showTBL); + if ($#tables == -1){ + @tables = $dbh->tables; + } + &status("Tables: ".join(',',@tables)); + @db{@tables} = (1) x @tables; } foreach ( qw(botmail connections factoids rootwarn seen stats onjoin) ) { @@ -698,8 +750,10 @@ sub checkTables { $cache{create_table}{$_} = 1; - &sqlCreateTable($_); + &sqlCreateTable($_, $param{DBType}); } } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/logger.pl b/src/logger.pl index 6e80e6c..8309a14 100644 --- a/src/logger.pl +++ b/src/logger.pl @@ -16,7 +16,7 @@ use vars qw(%param %file %cache); $logtime = time(); $logcount = 0; $logrepeat = 0; -$logold = ""; +$logold = ''; $param{VEBOSITY} ||= 1; # lame fix for preload @@ -73,7 +73,7 @@ sub cl { # logging support. sub openLog { - return unless (&IsParam("logfile")); + return unless (&IsParam('logfile')); $file{log} = $param{'logfile'}; my $error = 0; @@ -90,13 +90,14 @@ sub openLog { $error++; } - if (&IsParam("logType") and $param{'logType'} =~ /DAILY/i) { + if (&IsParam('logType') and $param{'logType'} =~ /DAILY/i) { my ($day,$month,$year) = (gmtime time())[3,4,5]; $logDate = sprintf("%04d%02d%02d",$year+1900,$month+1,$day); $file{log} .= $logDate; } if (open(LOG, ">>$file{log}")) { + binmode(LOG, ":encoding(UTF-8)"); &status("Opened logfile $file{log}."); LOG->autoflush(1); } else { @@ -106,7 +107,7 @@ sub openLog { sub closeLog { # lame fix for paramlogfile. - return unless (&IsParam("logfile")); + return unless (&IsParam('logfile')); return unless (defined fileno LOG); close LOG; @@ -117,7 +118,7 @@ sub closeLog { # Usage: &compress($file); sub compress { my ($file) = @_; - my @compress = ("/usr/bin/bzip2","/bin/gzip"); + my @compress = ('/usr/bin/bzip2','/bin/bzip2','/bin/gzip'); my $okay = 0; if (! -f $file) { @@ -148,7 +149,7 @@ sub compress { } sub DEBUG { - return unless (&IsParam("DEBUG")); + return unless (&IsParam('DEBUG')); &status("${b_green}!DEBUG!$ob $_[0]"); } @@ -158,7 +159,7 @@ sub ERROR { } sub WARN { - return unless (&IsParam("WARN")); + return unless (&IsParam('WARN')); return if ($_[0] =~ /^PERL: Subroutine \S+ redefined at/); @@ -174,11 +175,11 @@ sub TODO { } sub VERB { - if (!&IsParam("VERBOSITY")) { + if (!&IsParam('VERBOSITY')) { # NOTHING. - } elsif ($param{'VERBOSITY'} eq "1" and $_[1] <= 1) { + } elsif ($param{'VERBOSITY'} eq '1' and $_[1] <= 1) { &status($_[0]); - } elsif ($param{'VERBOSITY'} eq "2" and $_[1] <= 2) { + } elsif ($param{'VERBOSITY'} eq '2' and $_[1] <= 2) { &status($_[0]); } } @@ -206,10 +207,10 @@ sub status { # if it's not a scalar, attempt to warn and fix. my $ref = ref $input; - if (defined $ref and $ref ne "") { + if (defined $ref and $ref ne '') { &WARN("status: 'input' is not scalar ($ref)."); - if ($ref eq "ARRAY") { + if ($ref eq 'ARRAY') { foreach (@$input) { &WARN("status: '$_'."); } @@ -277,12 +278,12 @@ sub status { $status = "[$statcount] ".$input; } - if (&IsParam("backlog")) { + if (&IsParam('backlog')) { push(@backlog, $status); # append to end. shift(@backlog) if (scalar @backlog > $param{'backlog'}); } - if (&IsParam("VERBOSITY")) { + if (&IsParam('VERBOSITY')) { if ($statcountfix) { printf $_red."!%6d!".$ob." ", $statcount; } else { @@ -337,19 +338,19 @@ sub status { } # log the line into a file. - return unless (&IsParam("logfile")); + return unless (&IsParam('logfile')); return unless (defined fileno LOG); # remove control characters from logging to LOGFILE. for ($input) { - last if (&IsParam("logColors")); + last if (&IsParam('logColors')); s/\e\[[0-9;]+m//g; # escape codes. s/[\cA-\c_]//g; # control chars. } $input = "FORK($$) ".$input if ($statcountfix); my $date; - if (&IsParam("logType") and $param{'logType'} =~ /DAILY/i) { + if (&IsParam('logType') and $param{'logType'} =~ /DAILY/i) { $date = sprintf("%02d:%02d.%02d", (gmtime $time)[2,1,0]); my ($day,$month,$year) = (gmtime $time)[3,4,5]; @@ -375,9 +376,11 @@ sub debug_perl { &status("WARN: cannot open $file: $!"); return; } + binmode(IN, ":encoding(UTF-8)"); # TODO: better filename. open(OUT, ">>debug.log"); + binmode(OUT, ":encoding(UTF-8)"); print OUT "DEBUG: $str\n"; # note: cannot call external functions because SIG{} does not allow us to. @@ -412,6 +415,7 @@ sub openSQLDebug { delete $param{'SQLDebug'}; return 0; } + binmode(SQLDEBUG, ":encoding(UTF-8)"); &status("Opened SQL Debug file: $param{'SQLDebug'}"); return 1; @@ -424,7 +428,7 @@ sub closeSQLDebug { } sub SQLDebug { - return unless (&IsParam("SQLDebug")); + return unless (&IsParam('SQLDebug')); return unless (fileno SQLDEBUG); @@ -432,3 +436,5 @@ sub SQLDebug { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 diff --git a/src/modules.pl b/src/modules.pl index bcbd328..3bb2bfa 100644 --- a/src/modules.pl +++ b/src/modules.pl @@ -7,7 +7,7 @@ use strict; -use vars qw($AUTOLOAD $no_timehires); +use vars qw($AUTOLOAD $no_timehires $bot_version $bot_release); ### ### REQUIRED MODULES. @@ -44,7 +44,7 @@ sub loadCoreModules { } $moduleAge{$mod} = (stat $mod)[9]; - &showProc(" ($_)") if (&IsParam("DEBUG")); + &showProc(" ($_)") if (&IsParam('DEBUG')); } } @@ -71,7 +71,7 @@ sub loadDBModules { } sub loadFactoidsModules { - if (!&IsParam("factoids")) { + if (!&IsParam('factoids')) { &status("Factoid support DISABLED."); return; } @@ -88,7 +88,7 @@ sub loadFactoidsModules { } $moduleAge{$mod} = (stat $mod)[9]; - &showProc(" ($_)") if (&IsParam("DEBUG")); + &showProc(" ($_)") if (&IsParam('DEBUG')); } } @@ -115,7 +115,7 @@ sub loadIRCModules { # hrm... use another config option besides DEBUG to display # change in memory usage. - &status("Loading Modules \"$mod\"") if (!&IsParam("DEBUG")); + &status("Loading Modules \"$mod\"") if (!&IsParam('DEBUG')); eval "require \"$mod\""; if ($@) { &ERROR("require \"$mod\" => $@"); @@ -124,7 +124,7 @@ sub loadIRCModules { } $moduleAge{$mod} = (stat $mod)[9]; - &showProc(" ($_)") if (&IsParam("DEBUG")); + &showProc(" ($_)") if (&IsParam('DEBUG')); } } @@ -154,10 +154,17 @@ sub loadMyModulesNow { ### rename to moduleReloadAll? sub reloadAllModules { - my $retval = ""; + my $retval = ''; &VERB("Module: reloading all.",2); + # Reload version and save + open(VERSION," || "(unknown version)"; + chomp($bot_release); + $bot_version = "infobot $bot_release -- $^O"; + close(VERSION); + # obscure usage of map and regex :) foreach (map { s/.*?\/?src/src/; $_ } keys %moduleAge) { $retval .= &reloadModule($_); @@ -171,7 +178,7 @@ sub reloadAllModules { sub reloadModule { my ($mod) = @_; my $file = (grep /\/$mod/, keys %INC)[0]; - my $retval = ""; + my $retval = ''; # don't reload if it's not our module. if ($mod =~ /::/ or $mod !~ /pl$/) { @@ -347,3 +354,5 @@ sub getPerlFiles { } 1; + +# vim:ts=4:sw=4:expandtab:tw=80 -- 2.39.2

(.*)$@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@^
(.*)@i) +- { +- print "**Found First Description**\n" if 2 <= $self->{_debug}; +- $mDesc = $1; +- if (not $mDesc =~ m@ @) +- { +- $mDesc =~ s/<.*?>//g; +- $mDesc = $mDesc . '
' if not $mDesc =~ m@
@; +- $hit->description($mDesc); +- $state = $HITS; +- } +- } +- elsif ($state eq $HITS && +- m@^(\.(.+))@i || +- m@^
(.*)\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|
<.*?>.*?
|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 ([\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|(.*?)
<.*?>|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@^